Index: source/blender/render/intern/source/texture.c =================================================================== --- source/blender/render/intern/source/texture.c (revision 14978) +++ source/blender/render/intern/source/texture.c (working copy) @@ -1451,7 +1451,142 @@ return in; } +void do_volume_tex(ShadeInput *shi, float *xyz, float *col, float *alpha, float *emit) +{ + MTex *mtex; + Tex *tex; + TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; + int tex_nr, rgbnor= 0; + float co[3], texvec[3]; + float fact, stencilTin=1.0; + + if (R.r.scemode & R_NO_TEX) return; + /* here: test flag if there's a tex (todo) */ + + for(tex_nr=0; tex_nrmat->septex & (1<mat->mtex[tex_nr]) { + mtex= shi->mat->mtex[tex_nr]; + tex= mtex->tex; + if(tex==0) continue; + + /* which coords */ + if(mtex->texco==TEXCO_OBJECT) { + Object *ob= mtex->object; + ob= mtex->object; + if(ob) { + VECCOPY(co, xyz); + if(mtex->texflag & MTEX_OB_DUPLI_ORIG) { + if(shi->obi && shi->obi->duplitexmat) + MTC_Mat4MulVecfl(shi->obi->duplitexmat, co); + } + MTC_Mat4MulVecfl(ob->imat, co); + } + } + else if(mtex->texco==TEXCO_GLOB) { + VECCOPY(co, xyz); + } + else continue; // can happen when texco defines disappear and it renders old files + texres.nor= NULL; + + if(tex->type==TEX_IMAGE) { + continue; /* not supported yet */ + } + else { + /* placement */ + if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); + else texvec[0]= mtex->size[0]*(mtex->ofs[0]); + + if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); + else texvec[1]= mtex->size[1]*(mtex->ofs[1]); + + if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); + else texvec[2]= mtex->size[2]*(mtex->ofs[2]); + } + + + rgbnor= multitex(tex, co, NULL, NULL, 0, &texres); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ + + /* texture output */ + + if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { + texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + rgbnor-= TEX_RGB; + } + if(mtex->texflag & MTEX_NEGATIVE) { + if(rgbnor & TEX_RGB) { + texres.tr= 1.0-texres.tr; + texres.tg= 1.0-texres.tg; + texres.tb= 1.0-texres.tb; + } + texres.tin= 1.0-texres.tin; + } + if(mtex->texflag & MTEX_STENCIL) { + if(rgbnor & TEX_RGB) { + fact= texres.ta; + texres.ta*= stencilTin; + stencilTin*= fact; + } + else { + fact= texres.tin; + texres.tin*= stencilTin; + stencilTin*= fact; + } + } + + + if(mtex->mapto & (MAP_COL)) { + float tcol[3], colfac; + + /* stencil maps on the texture control slider, not texture intensity value */ + colfac= mtex->colfac*stencilTin; + + tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb; + + if((rgbnor & TEX_RGB)==0) { + tcol[0]= mtex->r; + tcol[1]= mtex->g; + tcol[2]= mtex->b; + } + else if(mtex->mapto & MAP_ALPHA) { + texres.tin= stencilTin; + } + else texres.tin= texres.ta; + + if(mtex->mapto & MAP_COL) { + texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype); + } + } + + if(mtex->mapto & MAP_VARS) { + /* stencil maps on the texture control slider, not texture intensity value */ + float varfac= mtex->varfac*stencilTin; + + if(rgbnor & TEX_RGB) { + if(texres.talpha) texres.tin= texres.ta; + else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + } + + if(mtex->mapto & MAP_EMIT) { + int flip= mtex->maptoneg & MAP_EMIT; + + *emit = texture_value_blend(mtex->def_var, *emit, texres.tin, varfac, mtex->blendtype, flip); + if(*emit<0.0) *emit= 0.0; + } + if(mtex->mapto & MAP_ALPHA) { + int flip= mtex->maptoneg & MAP_ALPHA; + + *alpha = texture_value_blend(mtex->def_var, *alpha, texres.tin, varfac, mtex->blendtype, flip); + CLAMP(*alpha, 0.0, 1.0); + } + } + } + } +} + void do_material_tex(ShadeInput *shi) { MTex *mtex; Index: source/blender/render/intern/source/shadeinput.c =================================================================== --- source/blender/render/intern/source/shadeinput.c (revision 14978) +++ source/blender/render/intern/source/shadeinput.c (working copy) @@ -135,7 +135,13 @@ } } +/* delivers a fully filled in ShadeResult, for all passes */ +void shade_volume_loop(ShadeInput *shi, ShadeResult *shr) +{ + volume_trace(shi, shr); +} + /* do a shade, finish up some passes, apply mist */ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) { @@ -151,7 +157,8 @@ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); shi->har= shi->mat->har; - shade_material_loop(shi, shr); + if (shi->mat->material_type == MA_SOLID) shade_material_loop(shi, shr); + else if (shi->mat->material_type == MA_VOLUME) shade_volume_loop(shi, shr); } /* copy additional passes */ Index: source/blender/render/intern/source/shadeoutput.c =================================================================== --- source/blender/render/intern/source/shadeoutput.c (revision 14978) +++ source/blender/render/intern/source/shadeoutput.c (working copy) @@ -58,7 +58,7 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -static ListBase *get_lights(ShadeInput *shi) +ListBase *get_lights(ShadeInput *shi) { if(shi->light_override) Index: source/blender/render/intern/source/volumetric.c =================================================================== --- source/blender/render/intern/source/volumetric.c (revision 0) +++ source/blender/render/intern/source/volumetric.c (revision 0) @@ -0,0 +1,394 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Farsthary (Raul FHernandez), Matt Ebb. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "RE_shader_ext.h" +#include "RE_raytrace.h" + +#include "DNA_material_types.h" +#include "DNA_group_types.h" +#include "DNA_lamp_types.h" + +#include "render_types.h" +#include "shading.h" + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ +/* only to be used here in this file, it's for speed */ +extern struct Render R; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static int vol_backface_intersect_check(Isect *is, int ob, RayFace *face) +{ + VlakRen *vlr = (VlakRen *)face; + + /* only consider faces away, so overlapping layers + * of foward facing geometry don't cause the ray to stop */ + return (INPR(is->vec, vlr->n) < 0.0f); +} + +#define VOL_IS_SAMEOBJECT 1 +#define VOL_IS_SAMEMATERIAL 2 + +int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco) +{ + /* TODO: Box or sphere intersection types could speed things up */ + + /* raytrace method */ + Isect isect; + float maxsize = RE_ray_tree_max_size(R.raytree); + + /* TODO: use object's bounding box to calculate max size */ + VECCOPY(isect.start, co); + isect.end[0] = co[0] + vec[0] * maxsize; + isect.end[1] = co[1] + vec[1] * maxsize; + isect.end[2] = co[2] + vec[2] * maxsize; + + isect.mode= RE_RAY_MIRROR; + isect.faceorig= (RayFace*)shi->vlr; + isect.oborig= RAY_OBJECT_SET(&R, shi->obi); + isect.face_last= NULL; + isect.ob_last= 0; + isect.lay= -1; + + if(RE_ray_tree_intersect(R.raytree, &isect)) + { + float isvec[3]; + + VECCOPY(isvec, isect.vec); + hitco[0] = isect.start[0] + isect.labda*isvec[0]; + hitco[1] = isect.start[1] + isect.labda*isvec[1]; + hitco[2] = isect.start[2] + isect.labda*isvec[2]; + + return 1; + } else { + return 0; + } +} + +float vol_get_density(struct ShadeInput *shi, float *co) +{ + float density = shi->mat->alpha; + float emit_fac=0.0f; + float col[3] = {0.0, 0.0, 0.0}; + + /* do any density gain stuff here */ + + do_volume_tex(shi, co, col, &density, &emit_fac); + + return density; +} + +/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. + * Used in the relationship Transmittance = e^(-attenuation) + * can be textured with 'alpha' */ +void vol_get_attenuation(ShadeInput *shi, float *tau, float *co, float *endco, float density, float stepsize) +{ + /* input density = density at co */ + + float dist; + float absorption = shi->mat->vol_absorption; + int s, nsteps; + float step_vec[3], step_sta[3], step_end[3]; + + dist = VecLenf(co, endco); + + nsteps = (int)ceil(dist / stepsize); + + if (nsteps == 1) { + /* homogenous volume within the sampled distance */ + tau[0] = tau[1] = tau[2] = dist * density; + VecMulf(tau, absorption); + return; + } else { + tau[0] = tau[1] = tau[2] = 0.0; + } + + VecSubf(step_vec, endco, co); + VecMulf(step_vec, 1.0f / nsteps); + + VECCOPY(step_sta, co); + VecAddf(step_end, step_sta, step_vec); + + for (s = 0; s < nsteps; s++) { + + if (s > 0) density = vol_get_density(shi, step_sta); + + tau[0] += stepsize * density; + tau[1] += stepsize * density; + tau[2] += stepsize * density; + + if (s < nsteps-1) { + VECCOPY(step_sta, step_end); + VecAddf(step_end, step_end, step_vec); + } + } + VecMulf(tau, absorption); +} + +/* compute emission component, amount of radiance to add per segment + * can be textured with 'emit' */ +void vol_get_emission(ShadeInput *shi, float *em, float *co, float *endco, float density) +{ + float emission = shi->mat->emit; + + em[0] = em[1] = em[2] = density * emission; +} + +void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *col, float stepsize, float density) +{ + float visifac, lv[3], lampdist; + float lacol[3]; + float tau[3], tr[3]={1.0,1.0,1.0}; + float hitco[3], *atten_co; + + if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return; + if ((lar->lay & shi->lay)==0) return; + if (lar->energy == 0.0) return; + + visifac= lamp_get_visibility(lar, co, lv, &lampdist); + if(visifac==0.0f) return; + + lacol[0] = lar->r; + lacol[1] = lar->g; + lacol[2] = lar->b; + + if(lar->mode & LA_TEXTURE) { + shi->osatex= 0; + do_lamp_tex(lar, lv, shi, lacol); + } + + VecMulf(lacol, visifac*lar->energy); + + if (shi->mat->vol_shadeflag & MA_VOL_ATTENUATED) { + /* find minimum of volume bounds, or lamp coord */ + + if (ELEM(lar->type, LA_SUN, LA_HEMI)) + VECCOPY(lv, lar->vec); + + VecMulf(lv, -1.0f); + + if (vol_get_bounds(shi, co, lv, hitco)) { + if (ELEM(lar->type, LA_SUN, LA_HEMI)) + atten_co = hitco; + else if ( lampdist < VecLenf(co, hitco) ) + atten_co = lar->co; + else + atten_co = hitco; + + atten_co = lar->co; + + vol_get_attenuation(shi, tau, co, atten_co, density, shi->mat->vol_shade_stepsize); + tr[0] = exp(-tau[0]); + tr[1] = exp(-tau[1]); + tr[2] = exp(-tau[2]); + + VecMulVecf(lacol, lacol, tr); + } + else { + /* point is on the outside edge of the volume, + * therefore no attenuation, full transmission + * radiance from lamp remains unchanged */ + } + } + + VecAddf(col, col, lacol); +} + +/* shadows -> trace a ray to find blocker geometry + - if blocker is outside the volume, use standard shadow functions + - if blocker is inside the volume, use raytracing + -- (deep shadow maps could potentially slot in here too I suppose) + - attenuate from current point, to blocked point or volume bounds +*/ + +/* single scattering only for now */ +void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float *endco, float stepsize, float density) +{ + GroupObject *go; + ListBase *lights; + LampRen *lar; + float col[3] = {0.f, 0.f, 0.f}; + + lights= get_lights(shi); + for(go=lights->first; go; go= go->next) + { + float lacol[3] = {0.f, 0.f, 0.f}; + + lar= go->lampren; + if (lar==NULL) continue; + + vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density); + + /* isotropic phase function */ + VecMulf(lacol, 1.0f / (4.f * M_PI)); + + VecMulf(lacol, density); + + VecAddf(col, col, lacol); + } + + + + VECCOPY(scatter, col); +} + + + +static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco) +{ + float total_tau; + float total_tr[3]; + float tr[3] = {1.f, 1.f, 1.f}; /* total transmittance */ + float radiance[3] = {0.f, 0.f, 0.f}, d_radiance[3] = {0.f, 0.f, 0.f}; + float stepsize = shi->mat->vol_stepsize; + int nsteps; + float vec[3], stepvec[3] = {0.0, 0.0, 0.0}; + float step_tau[3], step_emit[3], step_scatter[3] = {0.0, 0.0, 0.0}; + int s; + float step_sta[3], step_end[3], step_offs[3] = {0.0, 0.0, 0.0}; + float alpha_fac, emit_fac=0.0f, tex_col[3]; + + /* multiply col_behind with beam transmittance over entire distance */ +/* + // get col_behind + + // get total transmittance + vol_get_attenuation(shi, total_tau, start, dist, stepsize); + total_tr[0] = exp(-total_tau[0]); + total_tr[1] = exp(-total_tau[1]); + total_tr[2] = exp(-total_tau[2]); + VecMulVecf(radiance, total_tr, col_behind); +*/ + + /* ray marching */ + nsteps = (int)ceil(VecLenf(co, endco) / stepsize); + + VecSubf(vec, endco, co); + VECCOPY(stepvec, vec); + VecMulf(stepvec, 1.0f / nsteps); + + VECCOPY(step_sta, co); + VecAddf(step_end, step_sta, stepvec); + + + /* get radiance from all points along the ray due to participating media */ + for (s = 0; s < nsteps; s++) { + float density = vol_get_density(shi, step_sta); + + /* *** transmittance and emission *** */ + + /* transmittance component (alpha) */ + vol_get_attenuation(shi, step_tau, step_sta, step_end, density, stepsize); + tr[0] *= exp(-step_tau[0]); + tr[1] *= exp(-step_tau[1]); + tr[2] *= exp(-step_tau[2]); + + /* Terminate raymarching if transmittance is small */ + //if (rgb_to_luminance(tr[0], tr[1], tr[2]) < 1e-3) break; + + /* incoming light via emission or scattering (additive) */ + vol_get_emission(shi, step_emit, step_sta, step_end, density); + vol_get_scattering(shi, step_scatter, step_end, step_end, stepsize, density); + + VecAddf(d_radiance, step_emit, step_scatter); + + /* Lv += Tr * (Lve() + Ld) */ + VecMulVecf(d_radiance, tr, d_radiance); + VecAddf(radiance, radiance, d_radiance); + + if (s < nsteps-1) { + VECCOPY(step_sta, step_end); + VecAddf(step_end, step_end, stepvec); + } + } + + VecMulf(radiance, stepsize); + VECCOPY(col, radiance); + + /* + Incoming radiance = + outgoing radiance from behind surface * beam transmittance/attenuation + + + added radiance from all points along the ray due to participating media + --> radiance for each segment = + radiance added by scattering + + radiance added by emission + * beam transmittance/attenuation + + + -- To find transmittance: + compute optical thickness with tau (perhaps involving monte carlo integration) + return exp(-tau) + + -- To find radiance from segments along the way: + find radiance for one step: + - loop over lights and weight by phase function + + - single scattering + : integrate over sphere + + then multiply each step for final exit radiance + */ +} + +void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr) +{ + Isect isect; + float hitco[3], col[3]; + + memset(shr, 0, sizeof(ShadeResult)); + + if (vol_get_bounds(shi, shi->co, shi->view, hitco)) { + + volumeintegrate(shi, col, shi->co, hitco); + + /* hit */ + shr->alpha = 1.0f; + shr->combined[0] = col[0]; + shr->combined[1] = col[1]; + shr->combined[2] = col[2]; + + QUATCOPY(shr->diff, shr->combined); + } + else { + /* no hit */ + shr->combined[0] = 0.0f; + shr->combined[1] = 0.0f; + shr->combined[2] = 0.0f; + shr->combined[3] = shr->alpha = 0.0f; + } +} \ No newline at end of file Index: source/blender/render/intern/include/volumetric.h =================================================================== --- source/blender/render/intern/include/volumetric.h (revision 0) +++ source/blender/render/intern/include/volumetric.h (revision 0) @@ -0,0 +1,29 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Farsthary (Raul FHernandez), Matt Ebb. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr); \ No newline at end of file Index: source/blender/render/intern/include/texture.h =================================================================== --- source/blender/render/intern/include/texture.h (revision 14978) +++ source/blender/render/intern/include/texture.h (working copy) @@ -56,6 +56,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag); void do_material_tex(struct ShadeInput *shi); void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf); +void do_volume_tex(ShadeInput *shi, float *xyz, float *col, float *alpha, float *emit); void init_render_textures(Render *re); Index: source/blender/render/intern/include/shading.h =================================================================== --- source/blender/render/intern/include/shading.h (revision 14978) +++ source/blender/render/intern/include/shading.h (working copy) @@ -52,6 +52,7 @@ /* also the node shader callback */ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); +void shade_volume_loop(struct ShadeInput *shi, struct ShadeResult *shr); void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip); @@ -85,6 +86,7 @@ void ambient_occlusion_to_diffuse(struct ShadeInput *shi, float *diff); void ambient_occlusion(struct ShadeInput *shi); +ListBase *get_lights(struct ShadeInput *shi); float lamp_get_visibility(struct LampRen *lar, float *co, float *lv, float *dist); void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float *shadfac, int do_real); Index: source/blender/makesdna/DNA_material_types.h =================================================================== --- source/blender/makesdna/DNA_material_types.h (revision 14978) +++ source/blender/makesdna/DNA_material_types.h (working copy) @@ -62,6 +62,16 @@ float translucency; /* end synced with render_types.h */ + short material_type; /* solid, halo, volumetric */ + short pad4[3]; + + /* volumetrics */ + float vol_alphathresh; + float vol_stepsize, vol_shade_stepsize; + float vol_absorption; + short vol_shadeflag; + short vpad[3]; + float fresnel_mir, fresnel_mir_i; float fresnel_tra, fresnel_tra_i; float filter; /* filter added, for raytrace transparency and transmissivity */ @@ -152,6 +162,12 @@ /* for render */ #define MA_IS_USED 1 +/* material_type */ +#define MA_SOLID 0 +#define MA_PTHALO 1 +#define MA_VOLUME 2 +#define MA_VOLUMESOLID 3 + /* mode (is int) */ #define MA_TRACEBLE 1 #define MA_SHADOW 2 @@ -324,5 +340,10 @@ /* sss_flag */ #define MA_DIFF_SSS 1 +/* vol_shadeflag */ +#define MA_VOL_SHADED 1 +#define MA_VOL_ATTENUATED 2 +#define MA_VOL_SHADOWED 4 + #endif Index: source/blender/src/previewrender.c =================================================================== --- source/blender/src/previewrender.c (revision 14978) +++ source/blender/src/previewrender.c (working copy) @@ -283,6 +283,8 @@ /* turn on raytracing if needed */ if(mat->mode_l & (MA_RAYTRANSP|MA_RAYMIRROR)) sce->r.mode |= R_RAYTRACE; + if(mat->material_type == MA_VOLUME) + sce->r.mode |= R_RAYTRACE; if(mat->sss_flag & MA_DIFF_SSS) sce->r.mode |= R_SSS; Index: source/blender/src/buttons_shading.c =================================================================== --- source/blender/src/buttons_shading.c (revision 14978) +++ source/blender/src/buttons_shading.c (working copy) @@ -4025,7 +4025,7 @@ } -static void material_panel_material(Material *ma) +static void material_panel_material_solid(Material *ma) { uiBlock *block; float *colpoin = NULL; @@ -4112,6 +4112,44 @@ } +static void material_panel_material_volume(Material *ma) +{ + uiBlock *block; + short yco=PANEL_YMAX; + + block= uiNewBlock(&curarea->uiblocks, "material_panel_material_volume", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Volume", "Material", PANELX, PANELY, PANELW, PANELH)==0) return; + + uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_MATPRV, "Step Size: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_stepsize), 0.001, 100.0, 10, 2, "Ray marching step size"); + /* uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_alphathresh), 0.0, 1.0, 10, 2, "Threshold to stop tracing"); + */ + uiDefButF(block, NUMSLI, B_MATPRV, "Density: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->alpha), 0.0, 1.0, 0, 0, "Base opacity value"); + uiDefButF(block, NUM, B_MATPRV, "Absorption: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption), 0.0, 5.0, 0, 0, "Multiplier for absorption"); + uiBlockEndAlign(block); + + yco -= YSPACE; + + uiDefButF(block, NUMSLI, B_MATPRV, "Emit: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->emit), 0.0, 2.0, 0, 0, "Emission component"); + + yco -= YSPACE; + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, MA_VOL_ATTENUATED, B_MATPRV, "Shading", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shadeflag), 0, 0, 0, 0, "Uses absorption for light attenuation"); + uiDefButF(block, NUM, B_MATPRV, "Step Size: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shade_stepsize), 0.001, 100.0, 10, 2, "Step"); + uiBlockEndAlign(block); + +} + static void material_panel_nodes(Material *ma) { bNode *node; @@ -4150,7 +4188,7 @@ block= uiNewBlock(&curarea->uiblocks, "material_panel_links", UI_EMBOSS, UI_HELV, curarea->win); /* 310 makes sorting code to put it right after preview panel */ - if(uiNewPanel(curarea, block, "Links and Pipeline", "Material", 310, 0, 318, 204)==0) return; + if(uiNewPanel(curarea, block, "Links and Pipeline", "Material", 310, 0, 338, 204)==0) return; /* Links from object to material/nodes */ uiDefBut(block, ROUNDBOX, 0, "", 5, 90, 310, 110, NULL, 7.0, 0.0, 15 , 20, ""); @@ -4243,8 +4281,11 @@ uiDefButBitI(block, TOG, MA_ONLYCAST, B_MATPRV,"OnlyCast", 85,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes faces cast shadows only, not rendered"); uiDefButBitI(block, TOG, MA_TRACEBLE, B_NOP,"Traceable", 160,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes material detectable by ray tracing"); uiDefButBitI(block, TOG, MA_SHADBUF, B_MATPRV, "Shadbuf", 235,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes material cast shadows from shadow buffer lamps"); - + uiBlockEndAlign(block); + uiDefButS(block, MENU, B_MATPRV, "Material Type %t|Solid %x0|Halo %x1|Volume %x2", + 10, -15, 300, 20, &(ma->material_type), 0.0, 0.0, 0, 0, ""); + } static void material_panel_preview(Material *ma) @@ -4301,21 +4342,26 @@ ma= editnode_get_active_material(ma); if(ma) { - material_panel_material(ma); - material_panel_ramps(ma); - material_panel_shading(ma); - - if (G.scene->r.renderer==R_INTERN) - material_panel_tramir(ma); - else { - if(ma->YF_ar==0.f) { - ma->YF_ar = ma->YF_ag = ma->YF_ab = 1; - ma->YF_dscale = 1; + if (ma->material_type == MA_SOLID) { + material_panel_material_solid(ma); + material_panel_ramps(ma); + material_panel_shading(ma); + + if (G.scene->r.renderer==R_INTERN) + material_panel_tramir(ma); + else { + if(ma->YF_ar==0.f) { + ma->YF_ar = ma->YF_ag = ma->YF_ab = 1; + ma->YF_dscale = 1; + } + material_panel_tramir_yafray(ma); } - material_panel_tramir_yafray(ma); + + material_panel_sss(ma); + + } else if (ma->material_type == MA_VOLUME) { + material_panel_material_volume(ma); } - - material_panel_sss(ma); material_panel_texture(ob, ma); mtex= ma->mtex[ ma->texact ]; Index: source/blender/blenlib/BLI_arithb.h =================================================================== --- source/blender/blenlib/BLI_arithb.h (revision 14978) +++ source/blender/blenlib/BLI_arithb.h (working copy) @@ -246,6 +246,7 @@ void VecAddf(float *v, float *v1, float *v2); void VecSubf(float *v, float *v1, float *v2); +void VecMulVecf(float *v, float *v1, float *v2); void VecLerpf(float *target, float *a, float *b, float t); void VecMidf(float *v, float *v1, float *v2); Index: source/blender/blenlib/intern/arithb.c =================================================================== --- source/blender/blenlib/intern/arithb.c (revision 14978) +++ source/blender/blenlib/intern/arithb.c (working copy) @@ -2087,6 +2087,13 @@ v[2]= v1[2]- v2[2]; } +void VecMulVecf(float *v, float *v1, float *v2) +{ + v[0] = v1[0] * v2[0]; + v[1] = v1[1] * v2[1]; + v[2] = v1[2] * v2[2]; +} + void VecLerpf(float *target, float *a, float *b, float t) { float s = 1.0f-t; @@ -3213,6 +3220,12 @@ return d; } +float rgb_to_luminance(float r, float g, float b) +{ + /* Rec. 709 HDTV */ + return (0.2126*r + 0.7152*g + 0.0722*b); +} + void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) { int i; Index: source/blender/blenloader/intern/readfile.c =================================================================== --- source/blender/blenloader/intern/readfile.c (revision 14978) +++ source/blender/blenloader/intern/readfile.c (working copy) @@ -7610,6 +7610,7 @@ if(main->versionfile == 245 && main->subversionfile < 17) { ModifierData *md; Object *ob; + Material *ma; for(ob = main->object.first; ob; ob= ob->id.next) { for(md=ob->modifiers.first; md; ) { @@ -7629,6 +7630,10 @@ md = md->next; } } + + for(ma=main->mat.first; ma; ma= ma->id.next) { + if (ma->vol_shade_stepsize < 0.001f) ma->vol_shade_stepsize = 0.1f; + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 14978) +++ CMakeLists.txt (working copy) @@ -54,12 +54,12 @@ #----------------------------------------------------------------------------- # Set default config options OPTION(WITH_PLAYER "Build Player" OFF) -OPTION(WITH_GAMEENGINE "Enable Game Engine" ON) -OPTION(WITH_BULLET "Enable Bullet (Physics Engine)" ON) +OPTION(WITH_GAMEENGINE "Enable Game Engine" OFF) +OPTION(WITH_BULLET "Enable Bullet (Physics Engine)" OFF) OPTION(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON) OPTION(WITH_VERSE "Enable Verse (http://verse.blender.org)" OFF) OPTION(WITH_ELBEEM "Enable Elbeem (Fluid Simulation)" ON) -OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF) +OPTION(WITH_QUICKTIME "Enable Quicktime Support" ON) OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON) OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF) OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) @@ -313,22 +313,28 @@ SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) - INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) - IF(OPENAL_FOUND) - SET(WITH_OPENAL ON) - SET(OPENAL_LIB ${OPENAL_LIBRARY}) - SET(OPENAL_INC ${OPENAL_INCLUDE_DIR}) - ELSE(OPENAL_FOUND) - SET(WITH_OPENAL OFF) - ENDIF(OPENAL_FOUND) + #INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + #IF(OPENAL_FOUND) + # SET(WITH_OPENAL ON) + # SET(OPENAL_LIB ${OPENAL_LIBRARY}) + # SET(OPENAL_INC ${OPENAL_INCLUDE_DIR}) + #ELSE(OPENAL_FOUND) + # SET(WITH_OPENAL OFF) + #ENDIF(OPENAL_FOUND) + + SET(WITH_OPENAL ON) + SET(OPENAL ${LIBDIR}/openal) + SET(OPENAL_INC ${OPENAL}/include) + SET(OPENAL_LIBPATH ${OPENAL}/lib) + SET(OPENAL_LIB openal) SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/) - SET(PYTHON_VERSION 2.3) + SET(PYTHON_VERSION 2.5) SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "") SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "") SET(PYTHON_LIB "") SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "") - SET(PYTHON_LINKFLAGS "-u __dummy -u _PyMac_Error -framework System -framework Python") + SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python") SET(GETTEXT ${LIBDIR}/gettext) SET(GETTEXT_INC "${GETTEXT}/include")