svn merge -r 22571:22800 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender-staging.git] / source / blender / render / intern / source / rayshade.c
index 7e2cb4c6992e3d10b049573ec00f06485a998b41..8cb11d11762166a22c919a84f35a472918f67437 100644 (file)
@@ -55,6 +55,7 @@
 #include "pixelshading.h"
 #include "shading.h"
 #include "texture.h"
+#include "volumetric.h"
 
 #include "RE_raytrace.h"
 #include "rayobject.h"
@@ -117,6 +118,7 @@ RayObject *  RE_rayobject_create(int type, int size)
 RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {};
 #endif
 
+
 void freeraytree(Render *re)
 {
        ObjectInstanceRen *obi;
@@ -359,9 +361,7 @@ void makeraytree(Render *re)
        re->i.infostr= "Raytree finished";
 }
 
-
-
-static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
+void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
 {
        ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob;
        VlakRen *vlr= (VlakRen*)is->hit.face;
@@ -416,8 +416,14 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
                shade_input_flip_normals(shi);
 
        shade_input_set_shade_texco(shi);
-       
-       if(is->mode==RE_RAY_SHADOW_TRA) {
+       if (shi->mat->material_type == MA_TYPE_VOLUME) {
+               if(ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {
+                       shade_volume_shadow(shi, shr, is);
+               } else {
+                       shade_volume_outside(shi, shr);
+               }
+       }
+       else if(is->mode==RE_RAY_SHADOW_TRA) {
                /* temp hack to prevent recursion */
                if(shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) {
                        ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
@@ -431,9 +437,20 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
                        ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
                        shi->mat= vlr->mat;             /* shi->mat is being set in nodetree */
                }
-               else
-                       shade_material_loop(shi, shr);
-               
+               else {
+                       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);
        }       
@@ -1391,15 +1408,20 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
                        }
                        
                        if(shi->combinedflag & SCE_PASS_REFLECT) {
+                               /* values in shr->spec can be greater then 1.0.
+                                * In this case the mircol uses a zero blending factor, so ignoring it is ok.
+                                * Fixes bug #18837 - when the spec is higher then 1.0,
+                                * diff can become a negative color - Campbell  */
                                
-                               f= fr*(1.0f-shr->spec[0]);      f1= 1.0f-i;
-                               diff[0]= f*mircol[0] + f1*diff[0];
+                               f1= 1.0f-i;
                                
-                               f= fg*(1.0f-shr->spec[1]);      f1= 1.0f-i;
-                               diff[1]= f*mircol[1] + f1*diff[1];
+                               diff[0] *= f1;
+                               diff[1] *= f1;
+                               diff[2] *= f1;
                                
-                               f= fb*(1.0f-shr->spec[2]);      f1= 1.0f-i;
-                               diff[2]= f*mircol[2] + f1*diff[2];
+                               if(shr->spec[0]<1.0f)   diff[0] += mircol[0] * (fr*(1.0f-shr->spec[0]));
+                               if(shr->spec[1]<1.0f)   diff[1] += mircol[1] * (fg*(1.0f-shr->spec[1]));
+                               if(shr->spec[2]<1.0f)   diff[2] += mircol[2] * (fb*(1.0f-shr->spec[2]));
                        }
                }
        }
@@ -1456,11 +1478,15 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
                shi.nodes= origshi->nodes;
                
                shade_ray(is, &shi, &shr);
-               if (traflag & RAY_TRA)
-                       d= shade_by_transmission(is, &shi, &shr);
-               
-               /* mix colors based on shadfac (rgb + amount of light factor) */
-               addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
+               if (shi.mat->material_type == MA_TYPE_SURFACE) {
+                       if (traflag & RAY_TRA)
+                               d= shade_by_transmission(is, &shi, &shr);
+                       
+                       /* mix colors based on shadfac (rgb + amount of light factor) */
+                       addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
+               } else if (shi.mat->material_type == MA_TYPE_VOLUME) {
+                       addAlphaLight(is->col, shr.combined, shr.alpha, 1.0f);
+               }
                
                if(depth>0 && is->col[3]>0.0f) {
                        
@@ -1712,7 +1738,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
        RE_RC_INIT(isec, *shi);
        isec.orig.ob   = shi->obi;
        isec.orig.face = shi->vlr;
-       isec.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK;
+       isec.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK | RE_SKIP_VLR_NON_SOLID_MATERIAL;
        isec.hint = 0;
 
        isec.hit.ob   = 0;