[Bf-blender-cvs] [fd25489] temp-cycles-microdisplacement: Read subdivision attributes in kernel
Mai Lavelle
noreply at git.blender.org
Thu Jun 9 12:11:37 CEST 2016
Commit: fd254892bb11b4afdf7e44f7d8d8a2b53996715f
Author: Mai Lavelle
Date: Wed Jun 8 08:14:19 2016 -0400
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBfd254892bb11b4afdf7e44f7d8d8a2b53996715f
Read subdivision attributes in kernel
We can now store and retrieve attributes for subdivision meshes, tho in some
places behavior of attributes may not be entirely correct yet.
===================================================================
M intern/cycles/kernel/geom/geom_attribute.h
M intern/cycles/kernel/geom/geom_primitive.h
M intern/cycles/kernel/geom/geom_triangle.h
M intern/cycles/kernel/svm/svm_attribute.h
M intern/cycles/util/util_math.h
===================================================================
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
index c7364e9..9ec81f8 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -25,6 +25,8 @@ CCL_NAMESPACE_BEGIN
* Lookup of attributes is different between OSL and SVM, as OSL is ustring
* based while for SVM we use integer ids. */
+ccl_device_inline int subd_triangle_patch(KernelGlobals *kg, const ShaderData *sd);
+
/* Find attribute based on ID */
ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
@@ -37,6 +39,9 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, ui
#ifdef __HAIR__
attr_offset = (ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
#endif
+ if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE && subd_triangle_patch(kg, sd) != ~0) {
+ attr_offset += ATTR_PRIM_SUBD;
+ }
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
while(attr_map.x != id) {
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index b1b1e91..44734d1 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -26,7 +26,10 @@ CCL_NAMESPACE_BEGIN
ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE) {
- return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+ if(subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+ else
+ return subd_triangle_attribute_float(kg, sd, elem, offset, dx, dy);
}
#ifdef __HAIR__
else if(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE) {
@@ -48,7 +51,10 @@ ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *
ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
{
if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE) {
- return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+ if(subd_triangle_patch(kg, sd) == ~0)
+ return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+ else
+ return subd_triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
}
#ifdef __HAIR__
else if(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE) {
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 995dfac..ede5023 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -205,4 +205,202 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData
}
}
+ccl_device_inline int subd_triangle_patch(KernelGlobals *kg, const ShaderData *sd)
+{
+ return __float_as_int(kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)).w);
+}
+
+ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg, const ShaderData *sd, float2 uv[3])
+{
+ float4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
+
+ uv[0].x = kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)).w;
+ uv[0].y = kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x)).w;
+
+ uv[1].x = kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)).w;
+ uv[1].y = kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y)).w;
+
+ uv[2].x = kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)).w;
+ uv[2].y = kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)).w;
+}
+
+ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals *kg, const ShaderData *sd)
+{
+ int patch = subd_triangle_patch(kg, sd);
+ return kernel_tex_fetch(__patches, patch);
+}
+
+ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+ if(elem == ATTR_ELEMENT_FACE) {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+
+ return kernel_tex_fetch(__attributes_float, offset + subd_triangle_patch(kg, sd));
+ }
+ else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+ uint4 v = subd_triangle_patch_indices(kg, sd);
+
+ float a, b, c;
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + v.x);
+ float f1 = kernel_tex_fetch(__attributes_float, offset + v.y);
+ float f2 = kernel_tex_fetch(__attributes_float, offset + v.z);
+
+ if(v.w != ~0) {
+ float f3 = kernel_tex_fetch(__attributes_float, offset + v.w);
+
+ a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, uv[0].x), uv[0].y);
+ b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, uv[1].x), uv[1].y);
+ c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, uv[2].x), uv[2].y);
+ }
+ else {
+ a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - uv[0].y)*f2;
+ b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - uv[1].y)*f2;
+ c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - uv[2].y)*f2;
+ }
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
+ if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
+#endif
+
+ return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
+ }
+ else if(elem == ATTR_ELEMENT_CORNER) {
+ int patch = offset + subd_triangle_patch(kg, sd)*4;
+
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+ uint4 v = subd_triangle_patch_indices(kg, sd);
+
+ float a, b, c;
+
+ float f0 = kernel_tex_fetch(__attributes_float, patch + 0);
+ float f1 = kernel_tex_fetch(__attributes_float, patch + 1);
+ float f2 = kernel_tex_fetch(__attributes_float, patch + 2);
+
+ if(v.w != ~0) {
+ float f3 = kernel_tex_fetch(__attributes_float, patch + 3);
+
+ a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, uv[0].x), uv[0].y);
+ b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, uv[1].x), uv[1].y);
+ c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, uv[2].x), uv[2].y);
+ }
+ else {
+ a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - uv[0].y)*f2;
+ b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - uv[1].y)*f2;
+ c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - uv[2].y)*f2;
+ }
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
+ if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
+#endif
+
+ return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
+ }
+ else {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+
+ return 0.0f;
+ }
+}
+
+ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+ if(elem == 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, offset + subd_triangle_patch(kg, sd)));
+ }
+ else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) {
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+ uint4 v = subd_triangle_patch_indices(kg, sd);
+
+ float3 a, b, c;
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.x));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.y));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.z));
+
+ if(v.w != ~0) {
+ float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w));
+
+ a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, uv[0].x), uv[0].y);
+ b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, uv[1].x), uv[1].y);
+ c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, uv[2].x), uv[2].y);
+ }
+ else {
+ a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - uv[0].y)*f2;
+ b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - uv[1].y)*f2;
+ c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - uv[2].y)*f2;
+ }
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
+ if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
+#endif
+
+ return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
+ }
+ else if(elem == ATTR_ELEMENT_CORNER || elem == ATTR_ELEMENT_CORNER_BYTE) {
+ int patch = offset + subd_triangle_patch(kg, sd)*4;
+
+ float2 uv[3];
+ subd_triangle_patch_uv(kg, sd, uv);
+ uint4 v = subd_triangle_patch_indices(kg, sd);
+
+ float3 a, b, c;
+ float3 f0, f1, f2, f3;
+
+ if(elem == ATTR_ELEMENT_CORNER) {
+ f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 0));
+ f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 1));
+ f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 2));
+ }
+ else {
+ f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 0));
+ f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 1));
+ f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 2));
+ }
+
+ if(v.w != ~0) {
+ if(elem == ATTR_ELEMENT_CORNER) {
+ f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 3));
+ }
+ else {
+ f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 3));
+ }
+
+ a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, uv[0].x), uv[0].y);
+ b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, uv[1].x), uv[1].y);
+ c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, uv[2].x), uv[2].y);
+ }
+ else {
+ a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - uv[0].y)*f2;
+ b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - uv[1].y)*f2;
+ c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - uv[2].y)*f2;
+ }
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = ccl_fetch(sd, du).dx
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list