Revision: 16713
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16713
Author:   broken
Date:     2008-09-24 09:38:12 +0200 (Wed, 24 Sep 2008)

Log Message:
-----------
Volumetrics:

* Now it's possible to render with the camera inside a volume. I'm not sure how 
this goes with overlapping volumes yet, will look at it. But it allows nice 
things like this :)
http://mke3.net/blender/devel/rendering/volumetrics/clouds_sky.mov

* Sped up shading significantly by not doing any shading if the density
of the current sample is less than 0.01 (there's nothing to shade there 
anyway!) Speeds up around 200% on that clouds scene.

* Fixed a bug in global texture coordinates for volume textures

Modified Paths:
--------------
    branches/sim_physics/source/blender/render/intern/include/shading.h
    branches/sim_physics/source/blender/render/intern/source/rayshade.c
    branches/sim_physics/source/blender/render/intern/source/texture.c
    branches/sim_physics/source/blender/render/intern/source/volumetric.c
    branches/sim_physics/source/blender/src/buttons_shading.c

Modified: branches/sim_physics/source/blender/render/intern/include/shading.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/shading.h 
2008-09-24 03:12:10 UTC (rev 16712)
+++ branches/sim_physics/source/blender/render/intern/include/shading.h 
2008-09-24 07:38:12 UTC (rev 16713)
@@ -33,6 +33,7 @@
 struct StrandSegment;
 struct StrandPoint;
 struct ObjectInstanceRen obi;
+struct Isect;
 
 /* shadeinput.c */
 

Modified: branches/sim_physics/source/blender/render/intern/source/rayshade.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/rayshade.c 
2008-09-24 03:12:10 UTC (rev 16712)
+++ branches/sim_physics/source/blender/render/intern/source/rayshade.c 
2008-09-24 07:38:12 UTC (rev 16713)
@@ -274,9 +274,10 @@
                        ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
                        shi->mat= vlr->mat;             /* shi->mat is being 
set in nodetree */
                }
-               else
-                       shade_material_loop(shi, shr);
-               
+               else {
+                       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);
+               }
                /* raytrace likes to separate the spec color */
                VECSUB(shr->diff, shr->combined, shr->spec);
        }       

Modified: branches/sim_physics/source/blender/render/intern/source/texture.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/texture.c  
2008-09-24 03:12:10 UTC (rev 16712)
+++ branches/sim_physics/source/blender/render/intern/source/texture.c  
2008-09-24 07:38:12 UTC (rev 16713)
@@ -1503,6 +1503,7 @@
                        }
                        else if(mtex->texco==TEXCO_GLOB) {                      
                                
                           VECCOPY(co, xyz);
+                          MTC_Mat4MulVecfl(R.viewinv, co);
                        }
                        else continue;  // can happen when texco defines 
disappear and it renders old files
 

Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c       
2008-09-24 03:12:10 UTC (rev 16712)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c       
2008-09-24 07:38:12 UTC (rev 16713)
@@ -138,6 +138,15 @@
        VecMulVecf(em, em, col);
 }
 
+void vol_get_scattering_fac(ShadeInput *shi, float *scatter_fac, float *co, 
float density)
+{
+       //float col[3] = {0.0, 0.0, 0.0};
+       //do_volume_tex(shi, co, MAP_EMIT+MAP_COL, col, &emission);
+       
+       *scatter_fac = shi->mat->vol_scattering;
+}
+
+
 void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co)
 {
        float dummy = 1.0f;
@@ -282,12 +291,16 @@
        for(go=lights->first; go; go= go->next)
        {
                float lacol[3] = {0.f, 0.f, 0.f};
+               float scatter_fac;
        
                lar= go->lampren;
                if (lar==NULL) continue;
                
                vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density);
                
+               vol_get_scattering_fac(shi, &scatter_fac, co, density);
+               VecMulf(lacol, scatter_fac);
+               
                /* isotropic phase function */
                VecMulf(lacol, 1.0f / (4.f * M_PI));
        
@@ -330,9 +343,13 @@
 
 static void vol_trace_behind(ShadeInput *shi, float *co, Isect *isect_first, 
float *col)
 {
+       RayFace *rforig=NULL;
+       Isect isect;
+       float maxsize = RE_ray_tree_max_size(R.raytree);
+       
        if (isect_first != NULL) {
-               /* found an intersection, 
-                * either back of volume object or another object */
+               /* there was already a ray intersection - 
+                * either the back of volume object or another object */
                ObjectInstanceRen *obi= RAY_OBJECT_GET(&R, isect_first->ob);
 
                if (obi != shi->obi) {
@@ -340,32 +357,39 @@
                        shade_intersection(shi, col, isect_first);
                        return;
                } else {
-                       /* trace a new ray onwards behind the volume */
-                       Isect isect;
-                       float maxsize = RE_ray_tree_max_size(R.raytree);
-                       
-                       VECCOPY(isect.start, co);
-                       isect.end[0] = co[0] + shi->view[0] * maxsize;
-                       isect.end[1] = co[1] + shi->view[1] * maxsize;
-                       isect.end[2] = co[2] + shi->view[2] * maxsize;
-                       
-                       isect.faceorig= isect_first->face;      
-                       isect.mode= RE_RAY_MIRROR;
-                       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))
-                               shade_intersection(shi, col, &isect);
-                       else
-                               shadeSkyView(col, co, shi->view, NULL);
-                               
-                       return;
+                       rforig = isect_first->face;
                }
        }
        
-       col[0] = col[1] = col[2] = 0.0f;
+       /* get ready to trace a new ray behind the volume */
+       VECCOPY(isect.start, co)
+       
+       if (rforig == NULL) {
+               /* if there's no original ray intersection then the original 
+                * shaded surface is the inside of the volume at the far 
bounds. 
+                * We can use this face for the raytrace orig face */
+               isect.faceorig= (RayFace *)shi->vlr;
+       } else {
+               isect.faceorig= rforig;
+       }
+       
+       isect.end[0] = isect.start[0] + shi->view[0] * maxsize;
+       isect.end[1] = isect.start[1] + shi->view[1] * maxsize;
+       isect.end[2] = isect.start[2] + shi->view[2] * maxsize;
+       
+       isect.mode= RE_RAY_MIRROR;
+       isect.oborig= RAY_OBJECT_SET(&R, shi->obi);
+       isect.face_last= NULL;
+       isect.ob_last= 0;
+       isect.lay= -1;
+       
+       /* check to see if there's anything behind the volume, otherwise shade 
the sky */
+       if(RE_ray_tree_intersect(R.raytree, &isect)) {
+               shade_intersection(shi, col, &isect);
+       } else {
+               shadeSkyView(col, co, shi->view, NULL);
+       }
+       
 }
 
 static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, 
float *endco, Isect *isect)
@@ -392,8 +416,6 @@
        VecMulVecf(radiance, tr, col_behind);   
        tr[0] = tr[1] = tr[2] = 1.0f;
 
-
-
        /* ray marching */
        nsteps = (int)ceil(VecLenf(co, endco) / stepsize);
        
@@ -408,28 +430,31 @@
        for (s = 0; s < nsteps; s++) {
                if (s > 0) density = vol_get_density(shi, step_sta);
        
-               /* *** transmittance and emission *** */
+               /* there's only any point shading here
+                * if there's actually some density to shade! */
+               if (density > 0.01f) {
                
-               /* transmittance component (alpha) */
-               vol_get_attenuation(shi, tau, step_sta, step_end, density, 
stepsize);
-               tr[0] *= exp(-tau[0]);
-               tr[1] *= exp(-tau[1]);
-               tr[2] *= exp(-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, density);
-               vol_get_scattering(shi, step_scatter, step_end, stepsize, 
density);
-               
-               VecAddf(d_radiance, step_emit, step_scatter);
-               
-               /*   Lv += Tr * (Lve() + Ld) */
-               VecMulVecf(d_radiance, tr, d_radiance);
-               VecMulf(d_radiance, stepsize);
-               
-               VecAddf(radiance, radiance, d_radiance);        
+                       /* transmittance component (alpha) */
+                       vol_get_attenuation(shi, tau, step_sta, step_end, 
density, stepsize);
+                       tr[0] *= exp(-tau[0]);
+                       tr[1] *= exp(-tau[1]);
+                       tr[2] *= exp(-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, density);
+                       vol_get_scattering(shi, step_scatter, step_end, 
stepsize, density);
+                       
+                       VecAddf(d_radiance, step_emit, step_scatter);
+                       
+                       /*   Lv += Tr * (Lve() + Ld) */
+                       VecMulVecf(d_radiance, tr, d_radiance);
+                       VecMulf(d_radiance, stepsize);
+                       
+                       VecAddf(radiance, radiance, d_radiance);        
+               }
 
                VECCOPY(step_sta, step_end);
                VecAddf(step_end, step_end, stepvec);
@@ -479,15 +504,32 @@
 
        memset(shr, 0, sizeof(ShadeResult));
 
-       if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, 
VOL_BOUNDS_DEPTH)) {
+       /* if original normal is facing away from the camera, 
+        * then we're inside the volume already.
+        * so integrate from the camera to the shading coord */
+       //if (INPR(shi->orignor, shi->view) < 0.0f) {
+       if (shi->flippednor) {
                
+               const float co_cam[3] = {0.0, 0.0, 0.0};
+               volumeintegrate(shi, col, co_cam, shi->co, NULL);
+               
+               shr->combined[0] = col[0];
+               shr->combined[1] = col[1];
+               shr->combined[2] = col[2];
+               shr->combined[3] = 1.0f;
+               shr->alpha = col[3];
+               
+               VECCOPY(shr->diff, shr->combined);
+               
+       }
+       else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, 
VOL_BOUNDS_DEPTH)) {
                volumeintegrate(shi, col, shi->co, hitco, &is);
                
-               /* hit */
+
                shr->combined[0] = col[0];
                shr->combined[1] = col[1];
                shr->combined[2] = col[2];
-               shr->combined[3] = 0.0f;
+               shr->combined[3] = 1.0f;
                shr->alpha = col[3];
                
                VECCOPY(shr->diff, shr->combined);
@@ -496,7 +538,7 @@
                /* no hit */
                shr->combined[0] = 0.0f;
                shr->combined[1] = 0.0f;
-               shr->combined[2] = 0.0f;
-               shr->combined[3] = shr->alpha =  0.0f;
+               shr->combined[2] = 1.0f;
+               shr->combined[3] = shr->alpha =  1.0f;
        }
 }

Modified: branches/sim_physics/source/blender/src/buttons_shading.c
===================================================================
--- branches/sim_physics/source/blender/src/buttons_shading.c   2008-09-24 
03:12:10 UTC (rev 16712)
+++ branches/sim_physics/source/blender/src/buttons_shading.c   2008-09-24 
07:38:12 UTC (rev 16713)
@@ -4250,7 +4250,7 @@
        
        uiBlockBeginAlign(block);
        uiDefButF(block, NUM, B_MATPRV, "Absorption: ",
-               X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption), 0.0, 
5.0, 0, 0, "Multiplier for absorption");
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption), 0.0, 
10.0, 10, 0, "Multiplier for absorption");
        uiDefButF(block, COL, B_MATPRV, "",
                X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption_col), 0, 
0, 0, B_MATCOL, "");
        
@@ -4266,6 +4266,11 @@
        uiBlockEndAlign(block);
        
        yco -= YSPACE;
+       
+       uiDefButF(block, NUM, B_MATPRV, "Scattering: ",
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_scattering), 0.0, 
10.0, 10, 0, "Multiplier for scattering");
+       
+       yco -= YSPACE;
                
        uiBlockBeginAlign(block);
        uiDefButBitS(block, TOG, MA_VOL_ATTENUATED, B_MATPRV, "Shading",


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to