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
This commit is contained in:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -402,6 +402,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
|
||||
* re-interpolating them constantly for shading */
|
||||
|
@@ -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);
|
||||
|
@@ -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 {
|
||||
|
@@ -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)
|
||||
|
@@ -37,6 +37,7 @@ static bNodeSocketTemplate sh_node_light_path_out[]= {
|
||||
{ SOCK_FLOAT, 0, "Is Singular Ray", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_FLOAT, 0, "Is Reflection Ray", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_FLOAT, 0, "Is Transmission Ray", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_FLOAT, 0, "Ray Length", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user