[Bf-blender-cvs] [6e4c398] temp-cycles-microdisplacement: Set normals properly for subdivision meshes

Mai Lavelle noreply at git.blender.org
Mon Apr 11 14:54:20 CEST 2016


Commit: 6e4c39805bf148040d3d56fe47c2dc4ce43e3d3e
Author: Mai Lavelle
Date:   Tue Dec 1 06:47:58 2015 -0500
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rB6e4c39805bf148040d3d56fe47c2dc4ce43e3d3e

Set normals properly for subdivision meshes

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

M	intern/cycles/render/mesh.cpp
M	intern/cycles/subd/subd_dice.cpp
M	intern/cycles/subd/subd_patch.cpp
M	intern/cycles/subd/subd_patch.h
M	intern/cycles/subd/subd_split.cpp

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

diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index eba7fb2..d158ff3 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1451,16 +1451,36 @@ void Mesh::tessellate(DiagSplit *split)
 {
 	int num_faces = triangles.size();
 
+	add_face_normals();
+
+	Attribute *attr_vF = attributes.find(ATTR_STD_FACE_NORMAL);
+	float3 *vF = attr_vF->data_float3();
+
+	Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
+	float3 *vN = attr_vN->data_float3();
+
 	for(int f = 0; f < num_faces; f++) {
 		if(!forms_quad[f]) {
 			/* triangle */
 			LinearTrianglePatch* patch = new LinearTrianglePatch();
 			float3 *hull = patch->hull;
+			float3 *normals = patch->normals;
 
 			for(int i = 0; i < 3; i++) {
 				hull[i] = verts[triangles[f].v[i]];
 			}
 
+			if(smooth[f]) {
+				for(int i = 0; i < 3; i++) {
+					normals[i] = vN[triangles[f].v[i]];
+				}
+			}
+			else {
+				for(int i = 0; i < 3; i++) {
+					normals[i] = vF[f];
+				}
+			}
+
 			split->split_triangle(patch);
 			delete patch;
 		}
@@ -1468,12 +1488,25 @@ void Mesh::tessellate(DiagSplit *split)
 			/* quad */
 			LinearQuadPatch* patch = new LinearQuadPatch();
 			float3 *hull = patch->hull;
+			float3 *normals = patch->normals;
 
 			hull[0] = verts[triangles[f  ].v[0]];
 			hull[1] = verts[triangles[f  ].v[1]];
 			hull[3] = verts[triangles[f  ].v[2]];
 			hull[2] = verts[triangles[f+1].v[2]];
 
+			if(smooth[f]) {
+				normals[0] = vN[triangles[f  ].v[0]];
+				normals[1] = vN[triangles[f  ].v[1]];
+				normals[3] = vN[triangles[f  ].v[2]];
+				normals[2] = vN[triangles[f+1].v[2]];
+			}
+			else {
+				for(int i = 0; i < 4; i++) {
+					normals[i] = vF[f];
+				}
+			}
+
 			split->split_quad(patch);
 			delete patch;
 
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 54f40de..28248f5 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -58,10 +58,9 @@ void EdgeDice::reserve(int num_verts, int num_tris)
 
 int EdgeDice::add_vert(Patch *patch, float2 uv)
 {
-	float3 P, N, dPdu, dPdv;
+	float3 P, N;
 
-	patch->eval(&P, &dPdu, &dPdv, uv.x, uv.y);
-	N = normalize(cross(dPdu, dPdv));
+	patch->eval(&P, NULL, NULL, &N, uv.x, uv.y);
 
 	assert(vert_offset < params.mesh->verts.size());
 
@@ -81,7 +80,7 @@ int EdgeDice::add_vert(Patch *patch, float2 uv)
 
 void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2)
 {
-	params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth);
+	params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth, false);
 
 	if(params.ptex) {
 		Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
@@ -159,7 +158,7 @@ float3 QuadDice::eval_projected(SubPatch& sub, float u, float v)
 	float2 uv = map_uv(sub, u, v);
 	float3 P;
 
-	sub.patch->eval(&P, NULL, NULL, uv.x, uv.y);
+	sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
 	if(params.camera)
 		P = transform_perspective(&params.camera->worldtoraster, P);
 
diff --git a/intern/cycles/subd/subd_patch.cpp b/intern/cycles/subd/subd_patch.cpp
index 0db46ec..e75f88a 100644
--- a/intern/cycles/subd/subd_patch.cpp
+++ b/intern/cycles/subd/subd_patch.cpp
@@ -57,7 +57,7 @@ static void decasteljau_bicubic(float3 *P, float3 *du, float3 *dv, const float3
 
 /* Linear Quad Patch */
 
-void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v)
+void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
 {
 	float3 d0 = interp(hull[0], hull[1], u);
 	float3 d1 = interp(hull[2], hull[3], u);
@@ -68,6 +68,10 @@ void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float
 		*dPdu = interp(hull[1] - hull[0], hull[3] - hull[2], v);
 		*dPdv = interp(hull[2] - hull[0], hull[3] - hull[1], u);
 	}
+
+	if(N) {
+		*N = normalize(interp(interp(normals[0], normals[1], u), interp(normals[2], normals[3], u), v));
+	}
 }
 
 BoundBox LinearQuadPatch::bound()
@@ -82,7 +86,7 @@ BoundBox LinearQuadPatch::bound()
 
 /* Linear Triangle Patch */
 
-void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v)
+void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
 {
 	*P = u*hull[0] + v*hull[1] + (1.0f - u - v)*hull[2];
 
@@ -90,6 +94,10 @@ void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, f
 		*dPdu = hull[0] - hull[2];
 		*dPdv = hull[1] - hull[2];
 	}
+
+	if(N) {
+		*N = normalize(u*normals[0] + v*normals[1] + (1.0f - u - v)*normals[2]);
+	}
 }
 
 BoundBox LinearTrianglePatch::bound()
@@ -104,9 +112,11 @@ BoundBox LinearTrianglePatch::bound()
 
 /* Bicubic Patch */
 
-void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v)
+void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
 {
 	decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
+
+	assert(N == NULL);
 }
 
 BoundBox BicubicPatch::bound()
diff --git a/intern/cycles/subd/subd_patch.h b/intern/cycles/subd/subd_patch.h
index 9be4606..bfa0441 100644
--- a/intern/cycles/subd/subd_patch.h
+++ b/intern/cycles/subd/subd_patch.h
@@ -25,7 +25,7 @@ CCL_NAMESPACE_BEGIN
 class Patch {
 public:
 	virtual ~Patch() {}
-	virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v) = 0;
+	virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v) = 0;
 	virtual bool is_triangle() { return false; }
 	virtual BoundBox bound() = 0;
 	virtual int ptex_face_id() { return -1; }
@@ -36,8 +36,9 @@ public:
 class LinearQuadPatch : public Patch {
 public:
 	float3 hull[4];
+	float3 normals[4];
 
-	void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v);
+	void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
 	bool is_triangle() { return false; }
 	BoundBox bound();
 };
@@ -47,8 +48,9 @@ public:
 class LinearTrianglePatch : public Patch {
 public:
 	float3 hull[3];
+	float3 normals[3];
 
-	void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v);
+	void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
 	bool is_triangle() { return true; }
 	BoundBox bound();
 };
@@ -59,7 +61,7 @@ class BicubicPatch : public Patch {
 public:
 	float3 hull[16];
 
-	void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v);
+	void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
 	bool is_triangle() { return false; }
 	BoundBox bound();
 };
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 14a8931..2be82bf 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -53,7 +53,7 @@ float3 DiagSplit::project(Patch *patch, float2 uv)
 {
 	float3 P;
 
-	patch->eval(&P, NULL, NULL, uv.x, uv.y);
+	patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
 	if(params.camera)
 		P = transform_point(&params.objecttoworld, P);




More information about the Bf-blender-cvs mailing list