Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/geom/triangle.h
| Show All 23 Lines | |||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| /* Normal on triangle. */ | /* Normal on triangle. */ | ||||
| ccl_device_inline float3 triangle_normal(KernelGlobals kg, ccl_private ShaderData *sd) | ccl_device_inline float3 triangle_normal(KernelGlobals kg, ccl_private ShaderData *sd) | ||||
| { | { | ||||
| /* load triangle vertices */ | /* load triangle vertices */ | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); | ||||
| const float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0)); | const float3 v0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0); | ||||
| const float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1)); | const float3 v1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1); | ||||
| const float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2)); | const float3 v2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2); | ||||
| /* return normal */ | /* return normal */ | ||||
| if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { | if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { | ||||
| return normalize(cross(v2 - v0, v1 - v0)); | return normalize(cross(v2 - v0, v1 - v0)); | ||||
| } | } | ||||
| else { | else { | ||||
| return normalize(cross(v1 - v0, v2 - v0)); | return normalize(cross(v1 - v0, v2 - v0)); | ||||
| } | } | ||||
| } | } | ||||
| /* Point and normal on triangle. */ | /* Point and normal on triangle. */ | ||||
| ccl_device_inline void triangle_point_normal(KernelGlobals kg, | ccl_device_inline void triangle_point_normal(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| int prim, | int prim, | ||||
| float u, | float u, | ||||
| float v, | float v, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *Ng, | ccl_private float3 *Ng, | ||||
| ccl_private int *shader) | ccl_private int *shader) | ||||
| { | { | ||||
| /* load triangle vertices */ | /* load triangle vertices */ | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | ||||
| float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0)); | float3 v0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0); | ||||
| float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1)); | float3 v1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1); | ||||
| float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2)); | float3 v2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2); | ||||
| /* compute point */ | /* compute point */ | ||||
| float t = 1.0f - u - v; | float t = 1.0f - u - v; | ||||
| *P = (u * v0 + v * v1 + t * v2); | *P = (u * v0 + v * v1 + t * v2); | ||||
| /* get object flags */ | /* get object flags */ | ||||
| int object_flag = kernel_tex_fetch(__object_flag, object); | int object_flag = kernel_tex_fetch(__object_flag, object); | ||||
| /* compute normal */ | /* compute normal */ | ||||
| if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { | if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { | ||||
| *Ng = normalize(cross(v2 - v0, v1 - v0)); | *Ng = normalize(cross(v2 - v0, v1 - v0)); | ||||
| } | } | ||||
| else { | else { | ||||
| *Ng = normalize(cross(v1 - v0, v2 - v0)); | *Ng = normalize(cross(v1 - v0, v2 - v0)); | ||||
| } | } | ||||
| /* shader`*/ | /* shader`*/ | ||||
| *shader = kernel_tex_fetch(__tri_shader, prim); | *shader = kernel_tex_fetch(__tri_shader, prim); | ||||
| } | } | ||||
| /* Triangle vertex locations */ | /* Triangle vertex locations */ | ||||
| ccl_device_inline void triangle_vertices(KernelGlobals kg, int prim, float3 P[3]) | ccl_device_inline void triangle_vertices(KernelGlobals kg, int prim, float3 P[3]) | ||||
| { | { | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | ||||
| P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0)); | P[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0); | ||||
| P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1)); | P[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1); | ||||
| P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2)); | P[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2); | ||||
| } | } | ||||
| /* Triangle vertex locations and vertex normals */ | /* Triangle vertex locations and vertex normals */ | ||||
| ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg, | ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg, | ||||
| int prim, | int prim, | ||||
| float3 P[3], | float3 P[3], | ||||
| float3 N[3]) | float3 N[3]) | ||||
| { | { | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | ||||
| P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0)); | P[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0); | ||||
| P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1)); | P[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1); | ||||
| P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2)); | P[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2); | ||||
| N[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x)); | N[0] = kernel_tex_fetch(__tri_vnormal, tri_vindex.x); | ||||
| N[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); | N[1] = kernel_tex_fetch(__tri_vnormal, tri_vindex.y); | ||||
| N[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); | N[2] = kernel_tex_fetch(__tri_vnormal, tri_vindex.z); | ||||
| } | } | ||||
| /* Interpolate smooth vertex normal from vertices */ | /* Interpolate smooth vertex normal from vertices */ | ||||
| ccl_device_inline float3 | ccl_device_inline float3 | ||||
| triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v) | triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v) | ||||
| { | { | ||||
| /* load triangle vertices */ | /* load triangle vertices */ | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | ||||
| float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x)); | float3 n0 = kernel_tex_fetch(__tri_vnormal, tri_vindex.x); | ||||
| float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); | float3 n1 = kernel_tex_fetch(__tri_vnormal, tri_vindex.y); | ||||
| float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); | float3 n2 = kernel_tex_fetch(__tri_vnormal, tri_vindex.z); | ||||
| float3 N = safe_normalize((1.0f - u - v) * n2 + u * n0 + v * n1); | float3 N = safe_normalize((1.0f - u - v) * n2 + u * n0 + v * n1); | ||||
| return is_zero(N) ? Ng : N; | return is_zero(N) ? Ng : N; | ||||
| } | } | ||||
| ccl_device_inline float3 triangle_smooth_normal_unnormalized( | ccl_device_inline float3 triangle_smooth_normal_unnormalized( | ||||
| KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v) | KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v) | ||||
| { | { | ||||
| /* load triangle vertices */ | /* load triangle vertices */ | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | ||||
| float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x)); | float3 n0 = kernel_tex_fetch(__tri_vnormal, tri_vindex.x); | ||||
| float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); | float3 n1 = kernel_tex_fetch(__tri_vnormal, tri_vindex.y); | ||||
| float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); | float3 n2 = kernel_tex_fetch(__tri_vnormal, tri_vindex.z); | ||||
| /* ensure that the normals are in object space */ | /* ensure that the normals are in object space */ | ||||
| if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) { | if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) { | ||||
| object_inverse_normal_transform(kg, sd, &n0); | object_inverse_normal_transform(kg, sd, &n0); | ||||
| object_inverse_normal_transform(kg, sd, &n1); | object_inverse_normal_transform(kg, sd, &n1); | ||||
| object_inverse_normal_transform(kg, sd, &n2); | object_inverse_normal_transform(kg, sd, &n2); | ||||
| } | } | ||||
| float3 N = (1.0f - u - v) * n2 + u * n0 + v * n1; | float3 N = (1.0f - u - v) * n2 + u * n0 + v * n1; | ||||
| return is_zero(N) ? Ng : N; | return is_zero(N) ? Ng : N; | ||||
| } | } | ||||
| /* Ray differentials on triangle */ | /* Ray differentials on triangle */ | ||||
| ccl_device_inline void triangle_dPdudv(KernelGlobals kg, | ccl_device_inline void triangle_dPdudv(KernelGlobals kg, | ||||
| int prim, | int prim, | ||||
| ccl_private float3 *dPdu, | ccl_private float3 *dPdu, | ||||
| ccl_private float3 *dPdv) | ccl_private float3 *dPdv) | ||||
| { | { | ||||
| /* fetch triangle vertex coordinates */ | /* fetch triangle vertex coordinates */ | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); | ||||
| const float3 p0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0)); | const float3 p0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0); | ||||
| const float3 p1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1)); | const float3 p1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1); | ||||
| const float3 p2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2)); | const float3 p2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2); | ||||
| /* compute derivatives of P w.r.t. uv */ | /* compute derivatives of P w.r.t. uv */ | ||||
| *dPdu = (p0 - p2); | *dPdu = (p0 - p2); | ||||
| *dPdv = (p1 - p2); | *dPdv = (p1 - p2); | ||||
| } | } | ||||
| /* Reading attributes on various triangle elements */ | /* Reading attributes on various triangle elements */ | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | ccl_device float3 triangle_attribute_float3(KernelGlobals kg, | ||||
| ccl_private float3 *dx, | ccl_private float3 *dx, | ||||
| ccl_private float3 *dy) | ccl_private float3 *dy) | ||||
| { | { | ||||
| if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) { | if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) { | ||||
| float3 f0, f1, f2; | float3 f0, f1, f2; | ||||
| if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { | if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); | ||||
| f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x)); | f0 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x); | ||||
| f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y)); | f1 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y); | ||||
| f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z)); | f2 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z); | ||||
| } | } | ||||
| else { | else { | ||||
| const int tri = desc.offset + sd->prim * 3; | const int tri = desc.offset + sd->prim * 3; | ||||
| f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0)); | f0 = kernel_tex_fetch(__attributes_float3, tri + 0); | ||||
| f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1)); | f1 = kernel_tex_fetch(__attributes_float3, tri + 1); | ||||
| f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2)); | f2 = kernel_tex_fetch(__attributes_float3, tri + 2); | ||||
| } | } | ||||
| #ifdef __RAY_DIFFERENTIALS__ | #ifdef __RAY_DIFFERENTIALS__ | ||||
| if (dx) | if (dx) | ||||
| *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2; | *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2; | ||||
| if (dy) | if (dy) | ||||
| *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2; | *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2; | ||||
| #endif | #endif | ||||
| return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; | return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; | ||||
| } | } | ||||
| else { | else { | ||||
| #ifdef __RAY_DIFFERENTIALS__ | #ifdef __RAY_DIFFERENTIALS__ | ||||
| if (dx) | if (dx) | ||||
| *dx = make_float3(0.0f, 0.0f, 0.0f); | *dx = make_float3(0.0f, 0.0f, 0.0f); | ||||
| if (dy) | if (dy) | ||||
| *dy = make_float3(0.0f, 0.0f, 0.0f); | *dy = make_float3(0.0f, 0.0f, 0.0f); | ||||
| #endif | #endif | ||||
| if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { | if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { | ||||
| const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : | const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : | ||||
| desc.offset; | desc.offset; | ||||
| return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset)); | return kernel_tex_fetch(__attributes_float3, offset); | ||||
| } | } | ||||
| else { | else { | ||||
| return make_float3(0.0f, 0.0f, 0.0f); | return make_float3(0.0f, 0.0f, 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ccl_device float4 triangle_attribute_float4(KernelGlobals kg, | ccl_device float4 triangle_attribute_float4(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| const AttributeDescriptor desc, | const AttributeDescriptor desc, | ||||
| ccl_private float4 *dx, | ccl_private float4 *dx, | ||||
| ccl_private float4 *dy) | ccl_private float4 *dy) | ||||
| { | { | ||||
| if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER | | if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER | | ||||
| ATTR_ELEMENT_CORNER_BYTE)) { | ATTR_ELEMENT_CORNER_BYTE)) { | ||||
| float4 f0, f1, f2; | float4 f0, f1, f2; | ||||
| if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { | if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { | ||||
| const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); | const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); | ||||
| f0 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x); | f0 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.x); | ||||
| f1 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y); | f1 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.y); | ||||
| f2 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z); | f2 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.z); | ||||
| } | } | ||||
| else { | else { | ||||
| const int tri = desc.offset + sd->prim * 3; | const int tri = desc.offset + sd->prim * 3; | ||||
| if (desc.element == ATTR_ELEMENT_CORNER) { | if (desc.element == ATTR_ELEMENT_CORNER) { | ||||
| f0 = kernel_tex_fetch(__attributes_float3, tri + 0); | f0 = kernel_tex_fetch(__attributes_float4, tri + 0); | ||||
| f1 = kernel_tex_fetch(__attributes_float3, tri + 1); | f1 = kernel_tex_fetch(__attributes_float4, tri + 1); | ||||
| f2 = kernel_tex_fetch(__attributes_float3, tri + 2); | f2 = kernel_tex_fetch(__attributes_float4, tri + 2); | ||||
| } | } | ||||
| else { | else { | ||||
| f0 = color_srgb_to_linear_v4( | f0 = color_srgb_to_linear_v4( | ||||
| color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0))); | color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0))); | ||||
| f1 = color_srgb_to_linear_v4( | f1 = color_srgb_to_linear_v4( | ||||
| color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1))); | color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1))); | ||||
| f2 = color_srgb_to_linear_v4( | f2 = color_srgb_to_linear_v4( | ||||
| color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2))); | color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2))); | ||||
| Show All 15 Lines | if (dx) | ||||
| *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | ||||
| if (dy) | if (dy) | ||||
| *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); | ||||
| #endif | #endif | ||||
| if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { | if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { | ||||
| const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : | const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : | ||||
| desc.offset; | desc.offset; | ||||
| return kernel_tex_fetch(__attributes_float3, offset); | return kernel_tex_fetch(__attributes_float4, offset); | ||||
| } | } | ||||
| else { | else { | ||||
| return make_float4(0.0f, 0.0f, 0.0f, 0.0f); | return make_float4(0.0f, 0.0f, 0.0f, 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||