From d64661b5078cd4781bd58fce6fadedac511c4132 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 May 2012 17:03:46 +0000 Subject: Cycles: add Ray Length output to Light Path node. This gives the distance travelled by the last light ray. One use case for this might be to do absorption. Patch #31232 by Agustin benavidez, see this blog post for details: http://agus3d.blogspot.com.ar/2012/05/blender-cycles-ray-length-node-output.html --- intern/cycles/kernel/kernel_emission.h | 6 +++--- intern/cycles/kernel/kernel_shader.h | 7 +++++-- intern/cycles/kernel/kernel_types.h | 3 +++ intern/cycles/kernel/svm/svm_light_path.h | 1 + intern/cycles/kernel/svm/svm_types.h | 3 ++- intern/cycles/render/nodes.cpp | 8 ++++++++ 6 files changed, 22 insertions(+), 6 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index cd7701a0c75..0ef1425e68a 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN /* Direction Emission */ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, - LightSample *ls, float u, float v, float3 I, float time) + LightSample *ls, float u, float v, float3 I, float t, float time) { /* setup shading at emitter */ ShaderData sd; @@ -40,7 +40,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, else #endif { - shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, time); + shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time); ls->Ng = sd.Ng; /* no path flag, we're evaluating this for all closures. that's weak but @@ -87,7 +87,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, return false; /* evaluate closure */ - float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, sd->time); + float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, ls.t, sd->time); if(is_zero(light_eval)) return false; diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index e4edc480272..af821bad868 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -77,6 +77,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, sd->N = Ng; sd->I = -ray->D; sd->shader = shader; + sd->ray_length = isect->t; /* smooth normal */ if(sd->shader & SHADER_SMOOTH_NORMAL) @@ -127,7 +128,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, __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 time) + int shader, int object, int prim, float u, float v, float t, float time) { /* vectors */ sd->P = P; @@ -145,6 +146,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, sd->u = u; sd->v = v; #endif + sd->ray_length = t; /* detect instancing, for non-instanced the object index is -object-1 */ #ifdef __INSTANCING__ @@ -242,7 +244,7 @@ __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, TIME_INVALID); + shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID); } /* ShaderData setup from ray into background */ @@ -259,6 +261,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData #ifdef __MOTION__ sd->time = ray->time; #endif + sd->ray_length = 0.0f; #ifdef __INSTANCING__ sd->object = ~0; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index bf48ec8c000..85ee16fc5c6 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -401,6 +401,9 @@ typedef struct ShaderData { /* motion blur sample time */ float time; + + /* length of the ray being shaded */ + float ray_length; #ifdef __MOTION__ /* object <-> world space transformations, cached to avoid diff --git a/intern/cycles/kernel/svm/svm_light_path.h b/intern/cycles/kernel/svm/svm_light_path.h index 1b13fd93a0f..ebbcb5be61f 100644 --- a/intern/cycles/kernel/svm/svm_light_path.h +++ b/intern/cycles/kernel/svm/svm_light_path.h @@ -33,6 +33,7 @@ __device void svm_node_light_path(ShaderData *sd, float *stack, uint type, uint case NODE_LP_reflection: info = (path_flag & PATH_RAY_REFLECT)? 1.0f: 0.0f; break; case NODE_LP_transmission: info = (path_flag & PATH_RAY_TRANSMIT)? 1.0f: 0.0f; break; case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break; + case NODE_LP_ray_length: info = sd->ray_length; break; } stack_store_float(stack, out_offset, info); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index fa7c211b5f9..8037c3964a9 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -115,7 +115,8 @@ typedef enum NodeLightPath { NODE_LP_singular, NODE_LP_reflection, NODE_LP_transmission, - NODE_LP_backfacing + NODE_LP_backfacing, + NODE_LP_ray_length } NodeLightPath; typedef enum NodeTexCoord { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7039f5b6412..fd26c552f21 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1623,6 +1623,7 @@ LightPathNode::LightPathNode() add_output("Is Singular Ray", SHADER_SOCKET_FLOAT); add_output("Is Reflection Ray", SHADER_SOCKET_FLOAT); add_output("Is Transmission Ray", SHADER_SOCKET_FLOAT); + add_output("Ray Length", SHADER_SOCKET_FLOAT); } void LightPathNode::compile(SVMCompiler& compiler) @@ -1671,6 +1672,13 @@ void LightPathNode::compile(SVMCompiler& compiler) compiler.stack_assign(out); compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, out->stack_offset); } + + out = output("Ray Length"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, out->stack_offset); + } + } void LightPathNode::compile(OSLCompiler& compiler) -- cgit v1.2.3