Revision: 18191
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18191
Author:   broken
Date:     2008-12-31 06:08:04 +0100 (Wed, 31 Dec 2008)

Log Message:
-----------
Volume rendering

* Fixed an old problem where if both the camera and a solid surface were 
inside a volume, the volume wouldn't attenuate in front of the surface (was 
visible in the blender conference art festival clouds animation:

http://mke3.net/blender/devel/rendering/volumetrics/vol_shade_cam_inside.mov

* Initial support for refracting solids inside volumes. I might be able to 
make this work better, but not sure at the moment. It's a bit dodgy, 
limited by the code that does the recursive ray shading - it's really not 
set up for this kind of thing and could use a refactor very much.

Modified Paths:
--------------
    branches/sim_physics/source/blender/render/intern/include/volumetric.h
    branches/sim_physics/source/blender/render/intern/source/rayshade.c
    branches/sim_physics/source/blender/render/intern/source/shadeinput.c
    branches/sim_physics/source/blender/render/intern/source/volumetric.c

Modified: branches/sim_physics/source/blender/render/intern/include/volumetric.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/volumetric.h      
2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/include/volumetric.h      
2008-12-31 05:08:04 UTC (rev 18191)
@@ -30,8 +30,9 @@
 float vol_get_density(struct ShadeInput *shi, float *co);
 void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float 
stepsize, float density);
 
-void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
-void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, 
struct Isect *last_is);
+void shade_volume_outside(ShadeInput *shi, ShadeResult *shr);
+void shade_volume_inside(ShadeInput *shi, ShadeResult *shr);
+void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, 
struct Isect *last_is);
 
 #define STEPSIZE_VIEW  0
 #define STEPSIZE_SHADE 1
@@ -40,4 +41,7 @@
 #define VOL_IS_SAMEMATERIAL            2
 
 #define VOL_BOUNDS_DEPTH       0
-#define VOL_BOUNDS_SS          1
\ No newline at end of file
+#define VOL_BOUNDS_SS          1
+
+#define VOL_SHADE_OUTSIDE      0
+#define VOL_SHADE_INSIDE       1
\ No newline at end of file

Modified: branches/sim_physics/source/blender/render/intern/source/rayshade.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/rayshade.c 
2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/source/rayshade.c 
2008-12-31 05:08:04 UTC (rev 18191)
@@ -276,9 +276,9 @@
        
        if (shi->mat->material_type == MA_VOLUME) {
                if(ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {
-                       volume_trace_shadow(shi, shr, is);
+                       shade_volume_shadow(shi, shr, is);
                } else {
-                       shade_volume_loop(shi, shr);
+                       shade_volume_outside(shi, shr);
                }
        }
        else if(is->mode==RE_RAY_SHADOW_TRA) 
@@ -295,7 +295,18 @@
                        shi->mat= vlr->mat;             /* shi->mat is being 
set in nodetree */
                }
                else {
-                       shade_material_loop(shi, shr);
+                       int tempdepth;
+                       /* XXX dodgy business here, set ray depth to -1
+                        * to ignore raytrace in shade_material_loop()
+                        * this could really use a refactor --Matt */
+                       if (shi->volume_depth == 0) {
+                               tempdepth = shi->depth;
+                               shi->depth = -1;
+                               shade_material_loop(shi, shr);
+                               shi->depth = tempdepth;
+                       } else {
+                               shade_material_loop(shi, shr);
+                       }
                }
                /* raytrace likes to separate the spec color */
                VECSUB(shr->diff, shr->combined, shr->spec);
@@ -467,7 +478,7 @@
                
                shi.mask= origshi->mask;
                shi.osatex= origshi->osatex;
-               shi.depth= 1;                                   /* only used to 
indicate tracing */
+               shi.depth = origshi->depth + 1;                                 
/* only used to indicate tracing */
                shi.thread= origshi->thread;
                //shi.sample= 0; // memset above, so dont need this
                shi.xs= origshi->xs;
@@ -482,6 +493,7 @@
                memset(&shr, 0, sizeof(ShadeResult));
                
                shade_ray(&isec, &shi, &shr);
+
                if (traflag & RAY_TRA)
                        d= shade_by_transmission(&isec, &shi, &shr);
                

Modified: branches/sim_physics/source/blender/render/intern/source/shadeinput.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/shadeinput.c       
2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/source/shadeinput.c       
2008-12-31 05:08:04 UTC (rev 18191)
@@ -121,7 +121,7 @@
        }
        
        /* depth >= 1 when ray-shading */
-       if(shi->depth==0) {
+       if(shi->depth >= 0 && (shi->depth < MAX2(shi->mat->ray_depth_tra, 
shi->mat->ray_depth))) {
                if(R.r.mode & R_RAYTRACE) {
                        if(shi->ray_mirror!=0.0f || ((shi->mat->mode & 
MA_RAYTRANSP) && shr->alpha!=1.0f)) {
                                /* ray trace works on combined, but gives pass 
info */
@@ -132,16 +132,13 @@
                if(shi->mat->mode & MA_RAYTRANSP) 
                        if((shi->layflag & SCE_LAY_SKY) && 
(R.r.alphamode==R_ADDSKY))
                                shr->alpha= 1.0f;
-       }       
+       }
+       
+       if(R.r.mode & R_RAYTRACE) {
+               shade_volume_inside(shi, shr);
+       }
 }
 
-/* delivers a fully filled in ShadeResult, for all passes */
-void shade_volume_loop(ShadeInput *shi, ShadeResult *shr)
-{
-       if(R.r.mode & R_RAYTRACE) volume_trace(shi, shr);
-}
-
-
 /* do a shade, finish up some passes, apply mist */
 void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
 {
@@ -157,8 +154,12 @@
                memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
                shi->har= shi->mat->har;
                
-               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);
+               if (shi->mat->material_type == MA_SOLID) {
+                       shade_material_loop(shi, shr);
+               } else if (shi->mat->material_type == MA_VOLUME) {
+                       if(R.r.mode & R_RAYTRACE)
+                               shade_volume_outside(shi, shr);
+               }
        }
        
        /* copy additional passes */

Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c       
2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c       
2008-12-31 05:08:04 UTC (rev 18191)
@@ -548,7 +548,7 @@
        shi_new.mask= shi->mask;
        shi_new.osatex= shi->osatex;
        shi_new.thread= shi->thread;
-       shi_new.depth= 1;
+       shi_new.depth = shi->depth + 1;
        shi_new.volume_depth= shi->volume_depth + 1;
        shi_new.xs= shi->xs;
        shi_new.ys= shi->ys;
@@ -601,19 +601,32 @@
 }
 
 /* the main entry point for volume shading */
-void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr)
+static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int 
inside_volume)
 {
        float hitco[3], col[4] = {0.f,0.f,0.f,0.f};
+       int trace_behind = 1;
        Isect is;
 
-       memset(shr, 0, sizeof(ShadeResult));
+       /* check for shading an internal face a volume object directly */
+       if (inside_volume == VOL_SHADE_INSIDE) {
+               trace_behind = 0;
+       }
+       if (inside_volume == VOL_SHADE_OUTSIDE) {
+               if (shi->flippednor)
+                       inside_volume = VOL_SHADE_INSIDE;
+       }
 
-       /* if 1st hit normal is facing away from the camera, 
-        * then we're inside the volume already. */
-       if (shi->flippednor) {
-               /* trace behind the 1st hit point */
-               vol_trace_behind(shi, shi->vlr, shi->co, col);
+       if (inside_volume == VOL_SHADE_INSIDE) {
                
+               if (trace_behind) {
+                       /* trace behind the volume object */
+                       vol_trace_behind(shi, shi->vlr, shi->co, col);
+               } else {
+                       /* we're tracing through the volume between the camera 
+                        * and a solid surface, so use that pre-shaded radiance 
*/
+                       QUATCOPY(col, shr->combined);
+               }
+               
                /* shade volume from 'camera' to 1st hit point */
                volumeintegrate(shi, col, shi->camera_co, shi->co);
                
@@ -673,7 +686,7 @@
 
 /* Traces a shadow through the object, 
  * pretty much gets the transmission over a ray path */
-void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, 
struct Isect *last_is)
+void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, 
struct Isect *last_is)
 {
        float hitco[3];
        float tr[3] = {1.0,1.0,1.0};
@@ -724,3 +737,33 @@
        }
 }
 
+
+/* delivers a fully filled in ShadeResult, for all passes */
+void shade_volume_outside(ShadeInput *shi, ShadeResult *shr)
+{
+       memset(shr, 0, sizeof(ShadeResult));
+       
+       volume_trace(shi, shr, VOL_SHADE_OUTSIDE);
+}
+
+
+void shade_volume_inside(ShadeInput *shi, ShadeResult *shr)
+{
+       MatInside *m;
+       Material *mat_backup;
+       
+       if (BLI_countlist(&R.render_volumes_inside) == 0) return;
+       
+       mat_backup = shi->mat;
+       
+//     for (m=R.render_volumes_inside.first; m; m=m->next) {
+//             printf("matinside: ma: %s \n", m->ma->id.name+2);
+//     }
+
+       m = R.render_volumes_inside.first;
+       shi->mat = m->ma;
+       
+       volume_trace(shi, shr, VOL_SHADE_INSIDE);
+
+       shi->mat = mat_backup;
+}
\ No newline at end of file


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

Reply via email to