[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