diff options
Diffstat (limited to 'intern/cycles/kernel/svm/svm_geometry.h')
-rw-r--r-- | intern/cycles/kernel/svm/svm_geometry.h | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 22741bdb067..c4d03c1f948 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN /* Geometry Node */ -__device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; @@ -28,7 +28,23 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou case NODE_GEOM_P: data = sd->P; break; case NODE_GEOM_N: data = sd->N; break; #ifdef __DPDU__ - case NODE_GEOM_T: data = normalize(sd->dPdu); break; + case NODE_GEOM_T: { + /* try to create spherical tangent from generated coordinates */ + int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND; + + if(attr_offset != ATTR_STD_NOT_FOUND) { + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f); + object_normal_transform(kg, sd, &data); + data = cross(sd->N, normalize(cross(data, sd->N)));; + } + else { + /* otherwise use surface derivatives */ + data = normalize(sd->dPdu); + } + + break; + } #endif case NODE_GEOM_I: data = sd->I; break; case NODE_GEOM_Ng: data = sd->Ng; break; @@ -40,7 +56,7 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou stack_store_float3(stack, out_offset, data); } -__device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -48,16 +64,16 @@ __device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, switch(type) { case NODE_GEOM_P: data = sd->P + sd->dP.dx; break; case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); break; - default: svm_node_geometry(sd, stack, type, out_offset); return; + default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } -__device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -65,12 +81,12 @@ __device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, switch(type) { case NODE_GEOM_P: data = sd->P + sd->dP.dy; break; case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); break; - default: svm_node_geometry(sd, stack, type, out_offset); return; + default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } |