Cycles: add Transparent Depth output to Light Path node.
authorCarlo Andreacchio <carlorules@gmail.com>
Mon, 21 Apr 2014 12:20:29 +0000 (14:20 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 21 Apr 2014 12:44:36 +0000 (14:44 +0200)
This can for example be useful if you want to manually terminate the path at
some point and use a color other than black.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D454

14 files changed:
intern/cycles/kernel/kernel_displace.h
intern/cycles/kernel/kernel_emission.h
intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_shadow.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/kernel_volume.h
intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/osl/osl_services.h
intern/cycles/kernel/shaders/node_light_path.osl
intern/cycles/kernel/svm/svm_light_path.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.cpp
source/blender/nodes/shader/nodes/node_shader_light_path.c

index c50e21666602a831c06dd15536c8727c2eaec53d..1935f72ce951757eeaf30bdedc42a99e4642b261 100644 (file)
@@ -55,7 +55,7 @@ ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *inpu
 #endif
 
                /* setup shader data */
-               shader_setup_from_background(kg, &sd, &ray, 0);
+               shader_setup_from_background(kg, &sd, &ray, 0, 0);
 
                /* evaluate */
                int flag = 0; /* we can't know which type of BSDF this is for */
index bb61b2111fecb7effef18cce84a055a855a0af85..4c4f15c0e0a1df4f5e5e78e51850698ee139afce 100644 (file)
@@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN
 /* Direction Emission */
 
 ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
-       LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce)
+       LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce)
 {
        /* setup shading at emitter */
        ShaderData sd;
@@ -37,13 +37,13 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
                ray.dP = differential3_zero();
                ray.dD = dI;
 
-               shader_setup_from_background(kg, &sd, &ray, bounce+1);
+               shader_setup_from_background(kg, &sd, &ray, bounce+1, transparent_bounce);
                eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
        }
        else
 #endif
        {
-               shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1);
+               shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, transparent_bounce);
 
                ls->Ng = sd.Ng;
 
@@ -65,7 +65,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
 
 ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
        float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
-       bool *is_lamp, int bounce)
+       bool *is_lamp, int bounce, int transparent_bounce)
 {
        LightSample ls;
 
@@ -88,7 +88,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
        differential3 dD = differential3_zero();
 
        /* evaluate closure */
-       float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce);
+       float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce, transparent_bounce);
 
        if(is_zero(light_eval))
                return false;
@@ -183,7 +183,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
 
 /* Indirect Lamp Emission */
 
-ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission, int bounce)
+ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission, int bounce, int transparent_bounce)
 {
        LightSample ls;
        int lamp = lamp_light_eval_sample(kg, randt);
@@ -204,7 +204,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
        }
 #endif
 
-       float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce);
+       float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce, transparent_bounce);
 
        if(!(path_flag & PATH_RAY_MIS_SKIP)) {
                /* multiple importance sampling, get regular light pdf,
@@ -219,7 +219,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
 
 /* Indirect Background */
 
-ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce)
+ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce, int transparent_bounce)
 {
 #ifdef __BACKGROUND__
        int shader = kernel_data.background.surface_shader;
@@ -235,7 +235,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int
 
        /* evaluate background closure */
        ShaderData sd;
-       shader_setup_from_background(kg, &sd, ray, bounce+1);
+       shader_setup_from_background(kg, &sd, ray, bounce+1, transparent_bounce);
 
        float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
 
index 2764d0e0f197a6c6f9088f76875ab2caea93e341..14182dfb4420f67e1521261ad7ec4b69efbb104b 100644 (file)
@@ -72,7 +72,7 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
                        light_ray.time = sd->time;
 #endif
 
-                       if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+                       if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
                                /* trace shadow ray */
                                float3 shadow;
 
@@ -157,7 +157,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
                                        float light_u, light_v;
                                        path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
 
-                                       if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+                                       if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
                                                /* trace shadow ray */
                                                float3 shadow;
 
@@ -186,7 +186,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
                                        if(kernel_data.integrator.num_all_lights)
                                                light_t = 0.5f*light_t;
 
-                                       if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+                                       if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
                                                /* trace shadow ray */
                                                float3 shadow;
 
@@ -204,7 +204,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
                        path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
 
                        /* sample random light */
-                       if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+                       if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
                                /* trace shadow ray */
                                float3 shadow;
 
@@ -248,7 +248,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
                        float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
                        float3 emission;
 
-                       if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce))
+                       if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce, state.transparent_bounce))
                                path_radiance_accum_emission(L, throughput, emission, state.bounce);
                }
 #endif
@@ -275,7 +275,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
                if(!hit) {
 #ifdef __BACKGROUND__
                        /* sample background shader */
-                       float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
+                       float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce, state.transparent_bounce);
                        path_radiance_accum_background(L, throughput, L_background, state.bounce);
 #endif
 
@@ -284,7 +284,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
 
                /* setup shading */
                ShaderData sd;
-               shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
+               shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
                float rbsdf = path_state_rng_1D(kg, rng, &state, PRNG_BSDF);
                shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
 #ifdef __BRANCHED_PATH__
@@ -490,7 +490,7 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
                        light_ray.time = sd->time;
 #endif
 
-                       if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+                       if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
                                /* trace shadow ray */
                                float3 shadow;
 
@@ -637,7 +637,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
                        float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
                        float3 emission;
 
-                       if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce))
+                       if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce, state.transparent_bounce))
                                path_radiance_accum_emission(&L, throughput, emission, state.bounce);
                }
 #endif
@@ -674,7 +674,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 
 #ifdef __BACKGROUND__
                        /* sample background shader */
-                       float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
+                       float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce, state.transparent_bounce);
                        path_radiance_accum_background(&L, throughput, L_background, state.bounce);
 #endif
 
@@ -683,7 +683,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
 
                /* setup shading */
                ShaderData sd;
-               shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
+               shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
                float rbsdf = path_state_rng_1D(kg, rng, &state, PRNG_BSDF);
                shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
 
@@ -851,7 +851,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
                                light_ray.time = sd.time;
 #endif
 
-                               if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) {
+                               if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce, state.transparent_bounce)) {
                                        /* trace shadow ray */
                                        float3 shadow;
 
@@ -1100,7 +1100,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
                        VolumeSegment volume_segment;
                        ShaderData volume_sd;
 
-                       shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce);
+                       shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce, state.transparent_bounce);
                        kernel_volume_decoupled_record(kg, &state,
                                &volume_ray, &volume_sd, &volume_segment, heterogeneous);
 
@@ -1196,7 +1196,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
 
 #ifdef __BACKGROUND__
                        /* sample background shader */
-                       float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
+                       float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce, state.transparent_bounce);
                        path_radiance_accum_background(&L, throughput, L_background, state.bounce);
 #endif
 
@@ -1205,7 +1205,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
 
                /* setup shading */
                ShaderData sd;
-               shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
+               shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
                shader_eval_surface(kg, &sd, 0.0f, state.flag, SHADER_CONTEXT_MAIN);
                shader_merge_closures(&sd);
 
index 7aa9cfbcccce18a6fb00ae08110144f5c27b632f..a731446954a8623cec8a1874a48c9dc019e0b255 100644 (file)
@@ -49,7 +49,7 @@ ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd
 #endif
 
 ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
-       const Intersection *isect, const Ray *ray, int bounce)
+       const Intersection *isect, const Ray *ray, int bounce, int transparent_bounce)
 {
 #ifdef __INSTANCING__
        sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
@@ -67,6 +67,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
        sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
        sd->ray_length = isect->t;
        sd->ray_depth = bounce;
+       sd->transparent_depth = transparent_bounce;
 
 #ifdef __UV__
        sd->u = isect->u;
@@ -228,7 +229,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
 
 ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
        const float3 P, const float3 Ng, const float3 I,
-       int shader, int object, int prim, float u, float v, float t, float time, int bounce)
+       int shader, int object, int prim, float u, float v, float t, float time, int bounce, int transparent_bounce)
 {
        /* vectors */
        sd->P = P;
@@ -250,6 +251,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
 #endif
        sd->ray_length = t;
        sd->ray_depth = bounce;
+       sd->transparent_depth = transparent_bounce;
 
        /* detect instancing, for non-instanced the object index is -object-1 */
 #ifdef __INSTANCING__
@@ -347,12 +349,12 @@ ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
 
        /* watch out: no instance transform currently */
 
-       shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0);
+       shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0, 0);
 }
 
 /* ShaderData setup from ray into background */
 
-ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce)
+ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce)
 {
        /* vectors */
        sd->P = ray->D;
@@ -366,6 +368,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
 #endif
        sd->ray_length = 0.0f;
        sd->ray_depth = bounce;
+       sd->transparent_depth = transparent_bounce;
 
 #ifdef __INSTANCING__
        sd->object = PRIM_NONE;
@@ -395,7 +398,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
 
 /* ShaderData setup from point inside volume */
 
-ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce)
+ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce)
 {
        /* vectors */
        sd->P = ray->P;
@@ -409,6 +412,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
 #endif
        sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
        sd->ray_depth = bounce;
+       sd->transparent_depth = transparent_bounce;
 
 #ifdef __INSTANCING__
        sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
index 971dca38fc5e341109899c6ca41e7e1b065c545a..f53c032ca7b1ec3e6089fc3d2d25e9c0fd13ed72 100644 (file)
@@ -95,7 +95,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
 
                                /* setup shader data at surface */
                                ShaderData sd;
-                               shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1);
+                               shader_setup_from_ray(kg, &sd, &isect, ray, ps.bounce+1, ps.transparent_bounce);
 
                                /* attenuation from transparent surface */
                                if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
index 6b14b3935e0fc83cf448ab37be5e6eaa8329dbdf..5bc4ad5a13d9f25a71920e8099431762d394530f 100644 (file)
@@ -609,6 +609,9 @@ typedef struct ShaderData {
        /* ray bounce depth */
        int ray_depth;
 
+       /* ray transparent depth */
+       int transparent_depth;
+
 #ifdef __RAY_DIFFERENTIALS__
        /* differential of P. these are orthogonal to Ng, not N */
        differential3 dP;
index 7928bdc4ff176b04c62128e484c38c2bd0b6b9e8..b3c97cfac7f9b33013846d614a669de3ffb8892f 100644 (file)
@@ -184,7 +184,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
 ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg, PathState *state, Ray *ray, float3 *throughput)
 {
        ShaderData sd;
-       shader_setup_from_volume(kg, &sd, ray, state->bounce);
+       shader_setup_from_volume(kg, &sd, ray, state->bounce, state->transparent_bounce);
 
        if(volume_stack_is_heterogeneous(kg, state->volume_stack))
                kernel_volume_shadow_heterogeneous(kg, state, ray, &sd, throughput);
@@ -828,7 +828,7 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
        /* debugging code to compare decoupled ray marching */
        VolumeSegment segment;
 
-       shader_setup_from_volume(kg, sd, ray, state->bounce);
+       shader_setup_from_volume(kg, sd, ray, state->bounce, state->transparent_bounce);
        kernel_volume_decoupled_record(kg, state, ray, sd, &segment, heterogeneous);
 
        VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, throughput, &tmp_rng, &segment);
@@ -837,7 +837,7 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
 
        return result;
 #else
-       shader_setup_from_volume(kg, sd, ray, state->bounce);
+       shader_setup_from_volume(kg, sd, ray, state->bounce, state->transparent_bounce);
 
        if(heterogeneous)
                return kernel_volume_integrate_heterogeneous(kg, state, ray, sd, L, throughput, &tmp_rng);
index d5edd04d8a59b1f9e86d8357b1a4f5b9ea4b2e6a..8f437755bb942f228d58c66eaf4ebf477de94165 100644 (file)
@@ -85,6 +85,7 @@ ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
 #endif
 ustring OSLRenderServices::u_path_ray_length("path:ray_length");
 ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
+ustring OSLRenderServices::u_path_transparent_depth("path:transparent_depth");
 ustring OSLRenderServices::u_trace("trace");
 ustring OSLRenderServices::u_hit("hit");
 ustring OSLRenderServices::u_hitdist("hitdist");
@@ -701,6 +702,11 @@ bool OSLRenderServices::get_background_attribute(KernelGlobals *kg, ShaderData *
                int f = sd->ray_depth;
                return set_attribute_int(f, type, derivatives, val);
        }
+       else if (name == u_path_transparent_depth) {
+               /* Ray Depth */
+               int f = sd->transparent_depth;
+               return set_attribute_int(f, type, derivatives, val);
+       }
        else if (name == u_ndc) {
                /* NDC coordinates with special exception for otho */
                OSLThreadData *tdata = kg->osl_tdata;
@@ -1031,8 +1037,9 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustri
                                        /* lazy shader data setup */
                                        ShaderData *original_sd = (ShaderData *)(sg->renderstate);
                                        int bounce = original_sd->ray_depth + 1;
+                                       int transparent_bounce = original_sd->transparent_depth;
 
-                                       shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray, bounce);
+                                       shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray, bounce, transparent_bounce);
                                        tracedata->setup = true;
                                }
 
index 479b6da1afb520eaa2bc2b416a222ae02a0135f2..c3ea12253e9352bc88f8cd1143c73971e52876fa 100644 (file)
@@ -144,6 +144,7 @@ public:
        static ustring u_curve_tangent_normal;
        static ustring u_path_ray_length;
        static ustring u_path_ray_depth;
+       static ustring u_path_transparent_depth;
        static ustring u_trace;
        static ustring u_hit;
        static ustring u_hitdist;
index 599c7f5a2625b9f32c6cb85a6f959f65cf27839d..95fbcabf9170e2ec6db298eccb426627b929ada6 100644 (file)
@@ -26,7 +26,8 @@ shader node_light_path(
        output float IsTransmissionRay = 0.0,
        output float IsVolumeScatterRay = 0.0,
        output float RayLength = 0.0,
-       output float RayDepth = 0.0)
+       output float RayDepth = 0.0,
+       output float TransparentDepth = 0.0)
 {
        IsCameraRay = raytype("camera");
        IsShadowRay = raytype("shadow");
@@ -42,5 +43,9 @@ shader node_light_path(
        int ray_depth;
        getattribute("path:ray_depth", ray_depth);
        RayDepth = (float)ray_depth;
+
+       int transparent_depth;
+       getattribute("path:transparent_depth", transparent_depth);
+       TransparentDepth = (float)transparent_depth;
 }
 
index 8968146c5e29ab8fa1ae3e60315229b89e657a80..da544c63ae0aa0690fedcd7df1bd1f7fbe94a36c 100644 (file)
@@ -34,6 +34,7 @@ ccl_device void svm_node_light_path(ShaderData *sd, float *stack, uint type, uin
                case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break;
                case NODE_LP_ray_length: info = sd->ray_length; break;
                case NODE_LP_ray_depth: info = (float)sd->ray_depth; break;
+               case NODE_LP_ray_transparent: info = sd->transparent_depth; break;
        }
 
        stack_store_float(stack, out_offset, info);
index 866208106dc0f9cbf9f50995e63049174da94f08..86bb3f048dcc8b61b9d93e1b659b1c343de0e2ae 100644 (file)
@@ -160,7 +160,8 @@ typedef enum NodeLightPath {
        NODE_LP_volume_scatter,
        NODE_LP_backfacing,
        NODE_LP_ray_length,
-       NODE_LP_ray_depth
+       NODE_LP_ray_depth,
+       NODE_LP_ray_transparent
 } NodeLightPath;
 
 typedef enum NodeLightFalloff {
index 87affcbb49d36cf3fddf7ab051c709e246366f1c..1d59b21d1c5b6a55a05dd80ceed9057985b1c5d4 100644 (file)
@@ -2419,6 +2419,7 @@ LightPathNode::LightPathNode()
        add_output("Is Volume Scatter Ray", SHADER_SOCKET_FLOAT);
        add_output("Ray Length", SHADER_SOCKET_FLOAT);
        add_output("Ray Depth", SHADER_SOCKET_FLOAT);
+       add_output("Transparent Depth", SHADER_SOCKET_FLOAT);
 }
 
 void LightPathNode::compile(SVMCompiler& compiler)
@@ -2486,6 +2487,11 @@ void LightPathNode::compile(SVMCompiler& compiler)
                compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, out->stack_offset);
        }
 
+       out = output("Transparent Depth");
+       if(!out->links.empty()) {
+               compiler.stack_assign(out);
+               compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, out->stack_offset);
+       }
 }
 
 void LightPathNode::compile(OSLCompiler& compiler)
index 9d769b284b1e26d06ae534d49e944288571b400e..023c6ea02a983fe4e92094aa11df90a5c57bb98f 100644 (file)
@@ -39,6 +39,7 @@ static bNodeSocketTemplate sh_node_light_path_out[] = {
        {       SOCK_FLOAT, 0, N_("Is Transmission Ray"),       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       SOCK_FLOAT, 0, N_("Ray Length"),                        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       SOCK_FLOAT, 0, N_("Ray Depth"),                         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_FLOAT, 0, N_("Transparent Depth"),         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       -1, 0, ""       }
 };