[Bf-blender-cvs] [d118d74] temp-cycles-microdisplacement: Attribute interpolation for ngons

Mai Lavelle noreply at git.blender.org
Fri Jun 24 19:26:43 CEST 2016


Commit: d118d74ba393e04e0af6baae346b25675a928cf6
Author: Mai Lavelle
Date:   Tue Jun 21 06:14:05 2016 -0400
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBd118d74ba393e04e0af6baae346b25675a928cf6

Attribute interpolation for ngons

===================================================================

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/kernel/geom/geom_triangle.h
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/attribute.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/subd/subd_dice.cpp

===================================================================

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index b384035..3f22355 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -584,6 +584,7 @@ static void create_mesh(Scene *scene,
 	int numfaces = b_mesh.tessfaces.length();
 	int numtris = 0;
 	int total_corners = 0;
+	int num_ngons = 0;
 	bool use_loop_normals = b_mesh.use_auto_smooth();
 
 	BL::Mesh::vertices_iterator v;
@@ -595,13 +596,14 @@ static void create_mesh(Scene *scene,
 			numtris += (vi[3] == 0)? 1: 2;
 		}
 		else {
+			num_ngons += (vi[3] == 0)? 1: 0;
 			total_corners += (vi[3] == 0)? 3: 4;
 		}
 	}
 
 	/* allocate memory */
 	mesh->reserve_mesh(numverts, numtris);
-	mesh->reserve_subd_faces(numfaces, total_corners);
+	mesh->reserve_subd_faces(numfaces, num_ngons, total_corners);
 
 	/* create vertex coordinates and normals */
 	for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 0d57d02..12b31c5 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -246,7 +246,32 @@ ccl_device_inline uint subd_triangle_patch_face(KernelGlobals *kg, int patch)
 
 ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals *kg, int patch)
 {
-	return kernel_tex_fetch(__patches, patch+1).y;
+	return kernel_tex_fetch(__patches, patch+1).y & 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 = kernel_tex_fetch(__patches, patch+1);
+	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 */
@@ -271,20 +296,17 @@ ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa
 		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);
+		float f3 = kernel_tex_fetch(__attributes_float, offset + v.w);
 
-		if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-			float f3 = kernel_tex_fetch(__attributes_float, offset + v.w);
-
-			a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
-			b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
-			c = mix(mix(f0, f1, uv[2].x), mix(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;
+		if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+			f1 = (f1+f0)*0.5f;
+			f3 = (f3+f0)*0.5f;
 		}
 
+		a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+		b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+		c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #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;
@@ -293,30 +315,28 @@ ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa
 		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 p = offset + subd_triangle_patch_face(kg, patch)*4;
+		int corners[4];
+		subd_triangle_patch_corners(kg, patch, corners);
 
 		float2 uv[3];
 		subd_triangle_patch_uv(kg, sd, uv);
 
 		float a, b, c;
 
-		float f0 = kernel_tex_fetch(__attributes_float, p + 0);
-		float f1 = kernel_tex_fetch(__attributes_float, p + 1);
-		float f2 = kernel_tex_fetch(__attributes_float, p + 2);
+		float f0 = kernel_tex_fetch(__attributes_float, corners[0] + offset);
+		float f1 = kernel_tex_fetch(__attributes_float, corners[1] + offset);
+		float f2 = kernel_tex_fetch(__attributes_float, corners[2] + offset);
+		float f3 = kernel_tex_fetch(__attributes_float, corners[3] + offset);
 
-		if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-			float f3 = kernel_tex_fetch(__attributes_float, p + 3);
-
-			a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
-			b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
-			c = mix(mix(f0, f1, uv[2].x), mix(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;
+		if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+			f1 = (f1+f0)*0.5f;
+			f3 = (f3+f0)*0.5f;
 		}
 
+		a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+		b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+		c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #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;
@@ -352,20 +372,17 @@ ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const Shader
 		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));
+		float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w));
 
-		if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-			float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w));
-
-			a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
-			b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
-			c = mix(mix(f0, f1, uv[2].x), mix(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;
+		if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+			f1 = (f1+f0)*0.5f;
+			f3 = (f3+f0)*0.5f;
 		}
 
+		a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+		b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+		c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #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;
@@ -374,7 +391,8 @@ ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const Shader
 		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 p = offset + subd_triangle_patch_face(kg, patch)*4;
+		int corners[4];
+		subd_triangle_patch_corners(kg, patch, corners);
 
 		float2 uv[3];
 		subd_triangle_patch_uv(kg, sd, uv);
@@ -383,34 +401,27 @@ ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const Shader
 		float3 f0, f1, f2, f3;
 
 		if(elem == ATTR_ELEMENT_CORNER) {
-			f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 0));
-			f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 1));
-			f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 2));
+			f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + offset));
+			f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + offset));
+			f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + offset));
+			f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + offset));
 		}
 		else {
-			f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 0));
-			f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 1));
-			f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 2));
+			f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + offset));
+			f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + offset));
+			f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + offset));
+			f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + offset));
 		}
 
-		if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-			if(elem == ATTR_ELEMENT_CORNER) {
-				f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 3));
-			}
-			else {
-				f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 3));
-			}
-
-			a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
-			b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
-			c = mix(mix(f0, f1, uv[2].x), mix(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;
+		if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+			f1 = (f1+f0)*0.5f;
+			f3 = (f3+f0)*0.5f;
 		}
 
+		a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+		b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+		c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #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 - (

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list