Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/geom/geom_subd_triangle.h')
-rw-r--r--intern/cycles/kernel/geom/geom_subd_triangle.h765
1 files changed, 401 insertions, 364 deletions
diff --git a/intern/cycles/kernel/geom/geom_subd_triangle.h b/intern/cycles/kernel/geom/geom_subd_triangle.h
index 251e070c21f..8d5b3c12833 100644
--- a/intern/cycles/kernel/geom/geom_subd_triangle.h
+++ b/intern/cycles/kernel/geom/geom_subd_triangle.h
@@ -22,455 +22,492 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline uint subd_triangle_patch(KernelGlobals *kg, const ShaderData *sd)
{
- return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
+ return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
}
/* UV coords of triangle within patch */
-ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg, const ShaderData *sd, float2 uv[3])
+ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg,
+ const ShaderData *sd,
+ float2 uv[3])
{
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- uv[0] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.x);
- uv[1] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.y);
- uv[2] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.z);
+ uv[0] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.x);
+ uv[1] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.y);
+ uv[2] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.z);
}
/* Vertex indices of patch */
ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals *kg, int patch)
{
- uint4 indices;
+ uint4 indices;
- indices.x = kernel_tex_fetch(__patches, patch+0);
- indices.y = kernel_tex_fetch(__patches, patch+1);
- indices.z = kernel_tex_fetch(__patches, patch+2);
- indices.w = kernel_tex_fetch(__patches, patch+3);
+ indices.x = kernel_tex_fetch(__patches, patch + 0);
+ indices.y = kernel_tex_fetch(__patches, patch + 1);
+ indices.z = kernel_tex_fetch(__patches, patch + 2);
+ indices.w = kernel_tex_fetch(__patches, patch + 3);
- return indices;
+ return indices;
}
/* Originating face for patch */
ccl_device_inline uint subd_triangle_patch_face(KernelGlobals *kg, int patch)
{
- return kernel_tex_fetch(__patches, patch+4);
+ return kernel_tex_fetch(__patches, patch + 4);
}
/* Number of corners on originating face */
ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals *kg, int patch)
{
- return kernel_tex_fetch(__patches, patch+5) & 0xffff;
+ return kernel_tex_fetch(__patches, patch + 5) & 0xffff;
}
/* Indices of the four corners that are used by the patch */
ccl_device_inline void subd_triangle_patch_corners(KernelGlobals *kg, int patch, int corners[4])
{
- uint4 data;
-
- data.x = kernel_tex_fetch(__patches, patch+4);
- data.y = kernel_tex_fetch(__patches, patch+5);
- data.z = kernel_tex_fetch(__patches, patch+6);
- data.w = kernel_tex_fetch(__patches, patch+7);
-
- int num_corners = data.y & 0xffff;
-
- if(num_corners == 4) {
- /* quad */
- corners[0] = data.z;
- corners[1] = data.z+1;
- corners[2] = data.z+2;
- corners[3] = data.z+3;
- }
- else {
- /* ngon */
- int c = data.y >> 16;
-
- corners[0] = data.z + c;
- corners[1] = data.z + mod(c+1, num_corners);
- corners[2] = data.w;
- corners[3] = data.z + mod(c-1, num_corners);
- }
+ uint4 data;
+
+ data.x = kernel_tex_fetch(__patches, patch + 4);
+ data.y = kernel_tex_fetch(__patches, patch + 5);
+ data.z = kernel_tex_fetch(__patches, patch + 6);
+ data.w = kernel_tex_fetch(__patches, patch + 7);
+
+ int num_corners = data.y & 0xffff;
+
+ if (num_corners == 4) {
+ /* quad */
+ corners[0] = data.z;
+ corners[1] = data.z + 1;
+ corners[2] = data.z + 2;
+ corners[3] = data.z + 3;
+ }
+ else {
+ /* ngon */
+ int c = data.y >> 16;
+
+ corners[0] = data.z + c;
+ corners[1] = data.z + mod(c + 1, num_corners);
+ corners[2] = data.w;
+ corners[3] = data.z + mod(c - 1, num_corners);
+ }
}
/* Reading attributes on various subdivision triangle elements */
-ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
+ccl_device_noinline float subd_triangle_attribute_float(
+ KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd);
#ifdef __PATCH_EVAL__
- if(desc.flags & ATTR_SUBDIVIDED) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- float2 dpdu = uv[0] - uv[2];
- float2 dpdv = uv[1] - uv[2];
-
- /* p is [s, t] */
- float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
-
- float a, dads, dadt;
- a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+ if (desc.flags & ATTR_SUBDIVIDED) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ float2 dpdu = uv[0] - uv[2];
+ float2 dpdv = uv[1] - uv[2];
+
+ /* p is [s, t] */
+ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
+
+ float a, dads, dadt;
+ a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx || dy) {
+ float dsdu = dpdu.x;
+ float dtdu = dpdu.y;
+ float dsdv = dpdv.x;
+ float dtdv = dpdv.y;
+
+ if (dx) {
+ float dudx = sd->du.dx;
+ float dvdx = sd->dv.dx;
+
+ float dsdx = dsdu * dudx + dsdv * dvdx;
+ float dtdx = dtdu * dudx + dtdv * dvdx;
+
+ *dx = dads * dsdx + dadt * dtdx;
+ }
+ if (dy) {
+ float dudy = sd->du.dy;
+ float dvdy = sd->dv.dy;
+
+ float dsdy = dsdu * dudy + dsdv * dvdy;
+ float dtdy = dtdu * dudy + dtdv * dvdy;
+
+ *dy = dads * dsdy + dadt * dtdy;
+ }
+ }
+# endif
+
+ return a;
+ }
+ else
+#endif /* __PATCH_EVAL__ */
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
+
+ return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ uint4 v = subd_triangle_patch_indices(kg, patch);
+
+ float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x);
+ float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y);
+ float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z);
+ float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w);
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx || dy) {
- float dsdu = dpdu.x;
- float dtdu = dpdu.y;
- float dsdv = dpdv.x;
- float dtdv = dpdv.y;
-
- if(dx) {
- float dudx = sd->du.dx;
- float dvdx = sd->dv.dx;
-
- float dsdx = dsdu*dudx + dsdv*dvdx;
- float dtdx = dtdu*dudx + dtdv*dvdx;
-
- *dx = dads*dsdx + dadt*dtdx;
- }
- if(dy) {
- float dudy = sd->du.dy;
- float dvdy = sd->dv.dy;
-
- float dsdy = dsdu*dudy + dsdv*dvdy;
- float dtdy = dtdu*dudy + dtdv*dvdy;
-
- *dy = dads*dsdy + dadt*dtdy;
- }
- }
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return a;
- }
- else
-#endif /* __PATCH_EVAL__ */
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
- return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
+ int corners[4];
+ subd_triangle_patch_corners(kg, patch, corners);
- uint4 v = subd_triangle_patch_indices(kg, patch);
+ float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset);
+ float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset);
+ float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset);
+ float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset);
- float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x);
- float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y);
- float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z);
- float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w);
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- int corners[4];
- subd_triangle_patch_corners(kg, patch, corners);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else {
+ if (dx)
+ *dx = 0.0f;
+ if (dy)
+ *dy = 0.0f;
- float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset);
- float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset);
- float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset);
- float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset);
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
-#endif
-
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-
- return 0.0f;
- }
+ return 0.0f;
+ }
}
-ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
+ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float2 *dx,
+ float2 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd);
#ifdef __PATCH_EVAL__
- if(desc.flags & ATTR_SUBDIVIDED) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- float2 dpdu = uv[0] - uv[2];
- float2 dpdv = uv[1] - uv[2];
-
- /* p is [s, t] */
- float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
-
- float2 a, dads, dadt;
-
- a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx || dy) {
- float dsdu = dpdu.x;
- float dtdu = dpdu.y;
- float dsdv = dpdv.x;
- float dtdv = dpdv.y;
-
- if(dx) {
- float dudx = sd->du.dx;
- float dvdx = sd->dv.dx;
-
- float dsdx = dsdu*dudx + dsdv*dvdx;
- float dtdx = dtdu*dudx + dtdv*dvdx;
-
- *dx = dads*dsdx + dadt*dtdx;
- }
- if(dy) {
- float dudy = sd->du.dy;
- float dvdy = sd->dv.dy;
-
- float dsdy = dsdu*dudy + dsdv*dvdy;
- float dtdy = dtdu*dudy + dtdv*dvdy;
-
- *dy = dads*dsdy + dadt*dtdy;
- }
- }
-#endif
-
- return a;
- }
- else
-#endif /* __PATCH_EVAL__ */
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
-
- return kernel_tex_fetch(__attributes_float2, desc.offset + subd_triangle_patch_face(kg, patch));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- uint4 v = subd_triangle_patch_indices(kg, patch);
-
- float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
- float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
- float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
- float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ if (desc.flags & ATTR_SUBDIVIDED) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ float2 dpdu = uv[0] - uv[2];
+ float2 dpdv = uv[1] - uv[2];
+
+ /* p is [s, t] */
+ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
+
+ float2 a, dads, dadt;
+
+ a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx || dy) {
+ float dsdu = dpdu.x;
+ float dtdu = dpdu.y;
+ float dsdv = dpdv.x;
+ float dtdv = dpdv.y;
+
+ if (dx) {
+ float dudx = sd->du.dx;
+ float dvdx = sd->dv.dx;
+
+ float dsdx = dsdu * dudx + dsdv * dvdx;
+ float dtdx = dtdu * dudx + dtdv * dvdx;
+
+ *dx = dads * dsdx + dadt * dtdx;
+ }
+ if (dy) {
+ float dudy = sd->du.dy;
+ float dvdy = sd->dv.dy;
+
+ float dsdy = dsdu * dudy + dsdv * dvdy;
+ float dtdy = dtdu * dudy + dtdv * dvdy;
+
+ *dy = dads * dsdy + dadt * dtdy;
+ }
+ }
+# endif
+
+ return a;
+ }
+ else
+#endif /* __PATCH_EVAL__ */
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
+
+ return kernel_tex_fetch(__attributes_float2,
+ desc.offset + subd_triangle_patch_face(kg, patch));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ uint4 v = subd_triangle_patch_indices(kg, patch);
+
+ float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
+ float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
+ float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
+ float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
- int corners[4];
- subd_triangle_patch_corners(kg, patch, corners);
+ int corners[4];
+ subd_triangle_patch_corners(kg, patch, corners);
- float2 f0, f1, f2, f3;
+ float2 f0, f1, f2, f3;
- f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
- f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
- f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
- f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
+ f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
+ f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
+ f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
+ f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
- float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else {
- if(dx) *dx = make_float2(0.0f, 0.0f);
- if(dy) *dy = make_float2(0.0f, 0.0f);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else {
+ if (dx)
+ *dx = make_float2(0.0f, 0.0f);
+ if (dy)
+ *dy = make_float2(0.0f, 0.0f);
- return make_float2(0.0f, 0.0f);
- }
+ return make_float2(0.0f, 0.0f);
+ }
}
-ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
+ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ const AttributeDescriptor desc,
+ float3 *dx,
+ float3 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd);
#ifdef __PATCH_EVAL__
- if(desc.flags & ATTR_SUBDIVIDED) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- float2 dpdu = uv[0] - uv[2];
- float2 dpdv = uv[1] - uv[2];
-
- /* p is [s, t] */
- float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
-
- float3 a, dads, dadt;
-
- if(desc.element == ATTR_ELEMENT_CORNER_BYTE) {
- a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
- }
- else {
- a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
- }
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx || dy) {
- float dsdu = dpdu.x;
- float dtdu = dpdu.y;
- float dsdv = dpdv.x;
- float dtdv = dpdv.y;
-
- if(dx) {
- float dudx = sd->du.dx;
- float dvdx = sd->dv.dx;
-
- float dsdx = dsdu*dudx + dsdv*dvdx;
- float dtdx = dtdu*dudx + dtdv*dvdx;
-
- *dx = dads*dsdx + dadt*dtdx;
- }
- if(dy) {
- float dudy = sd->du.dy;
- float dvdy = sd->dv.dy;
-
- float dsdy = dsdu*dudy + dsdv*dvdy;
- float dtdy = dtdu*dudy + dtdv*dvdy;
-
- *dy = dads*dsdy + dadt*dtdy;
- }
- }
-#endif
-
- return a;
- }
- else
-#endif /* __PATCH_EVAL__ */
- if(desc.element == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch)));
- }
- else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- uint4 v = subd_triangle_patch_indices(kg, patch);
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z));
- float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w));
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ if (desc.flags & ATTR_SUBDIVIDED) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ float2 dpdu = uv[0] - uv[2];
+ float2 dpdv = uv[1] - uv[2];
+
+ /* p is [s, t] */
+ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
+
+ float3 a, dads, dadt;
+
+ if (desc.element == ATTR_ELEMENT_CORNER_BYTE) {
+ a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+ }
+ else {
+ a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
+ }
+
+# ifdef __RAY_DIFFERENTIALS__
+ if (dx || dy) {
+ float dsdu = dpdu.x;
+ float dtdu = dpdu.y;
+ float dsdv = dpdv.x;
+ float dtdv = dpdv.y;
+
+ if (dx) {
+ float dudx = sd->du.dx;
+ float dvdx = sd->dv.dx;
+
+ float dsdx = dsdu * dudx + dsdv * dvdx;
+ float dtdx = dtdu * dudx + dtdv * dvdx;
+
+ *dx = dads * dsdx + dadt * dtdx;
+ }
+ if (dy) {
+ float dudy = sd->du.dy;
+ float dvdy = sd->dv.dy;
+
+ float dsdy = dsdu * dudy + dsdv * dvdy;
+ float dtdy = dtdu * dudy + dtdv * dvdy;
+
+ *dy = dads * dsdy + dadt * dtdy;
+ }
+ }
+# endif
+
+ return a;
+ }
+ else
+#endif /* __PATCH_EVAL__ */
+ if (desc.element == ATTR_ELEMENT_FACE) {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+ return float4_to_float3(
+ kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch)));
+ }
+ else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ uint4 v = subd_triangle_patch_indices(kg, patch);
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z));
+ float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w));
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
- float2 uv[3];
- subd_triangle_patch_uv(kg, sd, uv);
-
- int corners[4];
- subd_triangle_patch_corners(kg, patch, corners);
-
- float3 f0, f1, f2, f3;
-
- if(desc.element == ATTR_ELEMENT_CORNER) {
- f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset));
- f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset));
- f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset));
- f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset));
- }
- else {
- f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset));
- f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset));
- f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset));
- f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset));
- }
-
- if(subd_triangle_patch_num_corners(kg, patch) != 4) {
- f1 = (f1+f0)*0.5f;
- f3 = (f3+f0)*0.5f;
- }
-
- float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
- float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
- float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+
+ int corners[4];
+ subd_triangle_patch_corners(kg, patch, corners);
+
+ float3 f0, f1, f2, f3;
+
+ if (desc.element == ATTR_ELEMENT_CORNER) {
+ f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset));
+ f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset));
+ f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset));
+ f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset));
+ }
+ else {
+ f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset));
+ f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset));
+ f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset));
+ f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset));
+ }
+
+ if (subd_triangle_patch_num_corners(kg, patch) != 4) {
+ f1 = (f1 + f0) * 0.5f;
+ f3 = (f3 + f0) * 0.5f;
+ }
+
+ float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+ float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+ float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
- if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
+ if (dx)
+ *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c;
+ if (dy)
+ *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c;
#endif
- return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
- }
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c;
+ }
+ else {
+ if (dx)
+ *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if (dy)
+ *dy = make_float3(0.0f, 0.0f, 0.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
CCL_NAMESPACE_END