Browse Source

Fixing tangent and binormal logic

Bastiaan Olij 6 years ago
parent
commit
bcef4b8dc6

+ 1 - 1
editor/import/editor_import_collada.cpp

@@ -771,7 +771,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
 
 						int binormal_pos = (binormal_src->stride ? binormal_src->stride : 3) * p.indices[src + binormal_ofs];
 						ERR_FAIL_INDEX_V(binormal_pos, binormal_src->array.size(), ERR_INVALID_DATA);
-						Vector3 binormal = Vector3(binormal_src->array[binormal_pos + 0], binormal_src->array[binormal_pos + 1], binormal_src->array[binormal_pos + 2]);
+						Vector3 binormal = Vector3(-binormal_src->array[binormal_pos + 0], -binormal_src->array[binormal_pos + 1], -binormal_src->array[binormal_pos + 2]); // Due to Godots face order it seems we need to flip our binormal!
 
 						int tangent_pos = (tangent_src->stride ? tangent_src->stride : 3) * p.indices[src + tangent_ofs];
 						ERR_FAIL_INDEX_V(tangent_pos, tangent_src->array.size(), ERR_INVALID_DATA);

+ 10 - 1
editor/import/editor_scene_importer_gltf.cpp

@@ -899,7 +899,16 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
 				array[Mesh::ARRAY_NORMAL] = _decode_accessor_as_vec3(state, a["NORMAL"], true);
 			}
 			if (a.has("TANGENT")) {
-				array[Mesh::ARRAY_TANGENT] = _decode_accessor_as_floats(state, a["TANGENT"], true);
+				PoolVector<float> tans = _decode_accessor_as_floats(state, a["TANGENT"], true);
+				{ // we need our binormals inversed, so flip our w component.
+					int ts = tans.size();
+					PoolVector<float>::Write w = tans.write();
+
+					for (int j = 3; j < ts; j += 4) {
+						w[j] *= -1.0;
+					}
+				}
+				array[Mesh::ARRAY_TANGENT] = tans;
 			}
 			if (a.has("TEXCOORD_0")) {
 				array[Mesh::ARRAY_TEX_UV] = _decode_accessor_as_vec2(state, a["TEXCOORD_0"], true);

+ 6 - 8
modules/csg/csg_shape.cpp

@@ -201,10 +201,9 @@ void CSGShape::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const flo
 
 	int i = (iFace * 3 + iVert) * 4;
 
-	// Godot seems to want the tangent flipped because our handedness is reversed..
-	surface.tansw[i++] = -fvTangent[0];
-	surface.tansw[i++] = -fvTangent[1];
-	surface.tansw[i++] = -fvTangent[2];
+	surface.tansw[i++] = fvTangent[0];
+	surface.tansw[i++] = fvTangent[1];
+	surface.tansw[i++] = fvTangent[2];
 	surface.tansw[i++] = fSign;
 }
 
@@ -219,11 +218,10 @@ void CSGShape::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const f
 	Vector3 bitangent = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
 	float d = bitangent.dot(normal.cross(tangent));
 
-	// Godot seems to want the tangent flipped because our handedness is reversed..
 	i *= 4;
-	surface.tansw[i++] = -tangent.x;
-	surface.tansw[i++] = -tangent.y;
-	surface.tansw[i++] = -tangent.z;
+	surface.tansw[i++] = tangent.x;
+	surface.tansw[i++] = tangent.y;
+	surface.tansw[i++] = tangent.z;
 	surface.tansw[i++] = d < 0 ? -1 : 1;
 }
 

+ 16 - 0
scene/3d/sprite_3d.cpp

@@ -461,6 +461,13 @@ void Sprite3D::_draw() {
 	int axis = get_axis();
 	normal[axis] = 1.0;
 
+	Plane tangent;
+	if (axis == Vector3::AXIS_X) {
+		tangent = Plane(0, 0, -1, -1);
+	} else {
+		tangent = Plane(1, 0, 0, -1);
+	}
+
 	RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS);
 	VS::get_singleton()->immediate_set_material(immediate, mat);
 
@@ -487,6 +494,7 @@ void Sprite3D::_draw() {
 
 	for (int i = 0; i < 4; i++) {
 		VS::get_singleton()->immediate_normal(immediate, normal);
+		VS::get_singleton()->immediate_tangent(immediate, tangent);
 		VS::get_singleton()->immediate_color(immediate, color);
 		VS::get_singleton()->immediate_uv(immediate, uvs[i]);
 
@@ -761,6 +769,13 @@ void AnimatedSprite3D::_draw() {
 	int axis = get_axis();
 	normal[axis] = 1.0;
 
+	Plane tangent;
+	if (axis == Vector3::AXIS_X) {
+		tangent = Plane(0, 0, -1, -1);
+	} else {
+		tangent = Plane(1, 0, 0, -1);
+	}
+
 	RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS);
 
 	VS::get_singleton()->immediate_set_material(immediate, mat);
@@ -788,6 +803,7 @@ void AnimatedSprite3D::_draw() {
 
 	for (int i = 0; i < 4; i++) {
 		VS::get_singleton()->immediate_normal(immediate, normal);
+		VS::get_singleton()->immediate_tangent(immediate, tangent);
 		VS::get_singleton()->immediate_color(immediate, color);
 		VS::get_singleton()->immediate_uv(immediate, uvs[i]);
 

+ 2 - 2
scene/resources/material.cpp

@@ -699,7 +699,7 @@ void SpatialMaterial::_update_shader() {
 
 	if (features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar
 		code += "\t{\n";
-		code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,BINORMAL*depth_flip.y,NORMAL));\n"; //binormal is negative due to mikktpsace
+		code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace
 
 		if (deep_parallax) {
 			code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
@@ -2277,7 +2277,7 @@ SpatialMaterial::SpatialMaterial() :
 
 	deep_parallax = false;
 	depth_parallax_flip_tangent = false;
-	depth_parallax_flip_binormal = true;
+	depth_parallax_flip_binormal = false;
 	set_depth_deep_parallax_min_layers(8);
 	set_depth_deep_parallax_max_layers(32);
 	set_depth_deep_parallax_flip_tangent(false); //also sets binormal

+ 22 - 22
scene/resources/primitive_meshes.cpp

@@ -306,7 +306,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
 			Vector3 p = Vector3(x * radius * w, y * radius * w, z);
 			points.push_back(p + Vector3(0.0, 0.0, 0.5 * mid_height));
 			normals.push_back(p.normalized());
-			ADD_TANGENT(y, -x, 0.0, -1.0)
+			ADD_TANGENT(-y, x, 0.0, -1.0)
 			uvs.push_back(Vector2(u, v * onethird));
 			point++;
 
@@ -345,7 +345,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
 			Vector3 p = Vector3(x * radius, y * radius, z);
 			points.push_back(p);
 			normals.push_back(Vector3(x, y, 0.0));
-			ADD_TANGENT(y, -x, 0.0, -1.0)
+			ADD_TANGENT(-y, x, 0.0, -1.0)
 			uvs.push_back(Vector2(u, onethird + (v * onethird)));
 			point++;
 
@@ -385,7 +385,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
 			Vector3 p = Vector3(x * radius * w, y * radius * w, z);
 			points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height));
 			normals.push_back(p.normalized());
-			ADD_TANGENT(y, -x, 0.0, -1.0)
+			ADD_TANGENT(-y, x, 0.0, -1.0)
 			uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird)));
 			point++;
 
@@ -514,14 +514,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const {
 			// front
 			points.push_back(Vector3(x, -y, -start_pos.z)); // double negative on the Z!
 			normals.push_back(Vector3(0.0, 0.0, 1.0));
-			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(u, v));
 			point++;
 
 			// back
 			points.push_back(Vector3(-x, -y, start_pos.z));
 			normals.push_back(Vector3(0.0, 0.0, -1.0));
-			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(twothirds + u, v));
 			point++;
 
@@ -568,14 +568,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const {
 			// right
 			points.push_back(Vector3(-start_pos.x, -y, -z));
 			normals.push_back(Vector3(1.0, 0.0, 0.0));
-			ADD_TANGENT(0.0, 0.0, 1.0, -1.0);
+			ADD_TANGENT(0.0, 0.0, -1.0, -1.0);
 			uvs.push_back(Vector2(onethird + u, v));
 			point++;
 
 			// left
 			points.push_back(Vector3(start_pos.x, -y, z));
 			normals.push_back(Vector3(-1.0, 0.0, 0.0));
-			ADD_TANGENT(0.0, 0.0, -1.0, -1.0);
+			ADD_TANGENT(0.0, 0.0, 1.0, -1.0);
 			uvs.push_back(Vector2(u, 0.5 + v));
 			point++;
 
@@ -622,14 +622,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const {
 			// top
 			points.push_back(Vector3(-x, -start_pos.y, -z));
 			normals.push_back(Vector3(0.0, 1.0, 0.0));
-			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(onethird + u, 0.5 + v));
 			point++;
 
 			// bottom
 			points.push_back(Vector3(x, start_pos.y, -z));
 			normals.push_back(Vector3(0.0, -1.0, 0.0));
-			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(twothirds + u, 0.5 + v));
 			point++;
 
@@ -773,7 +773,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
 			Vector3 p = Vector3(x * radius, y, z * radius);
 			points.push_back(p);
 			normals.push_back(Vector3(x, 0.0, z));
-			ADD_TANGENT(-z, 0.0, x, -1.0)
+			ADD_TANGENT(z, 0.0, -x, -1.0)
 			uvs.push_back(Vector2(u, v * 0.5));
 			point++;
 
@@ -799,7 +799,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
 		thisrow = point;
 		points.push_back(Vector3(0.0, y, 0.0));
 		normals.push_back(Vector3(0.0, 1.0, 0.0));
-		ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
+		ADD_TANGENT(1.0, 0.0, 0.0, -1.0)
 		uvs.push_back(Vector2(0.25, 0.75));
 		point++;
 
@@ -816,7 +816,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
 			Vector3 p = Vector3(x * top_radius, y, z * top_radius);
 			points.push_back(p);
 			normals.push_back(Vector3(0.0, 1.0, 0.0));
-			ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
+			ADD_TANGENT(1.0, 0.0, 0.0, -1.0)
 			uvs.push_back(Vector2(u, v));
 			point++;
 
@@ -835,7 +835,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
 		thisrow = point;
 		points.push_back(Vector3(0.0, y, 0.0));
 		normals.push_back(Vector3(0.0, -1.0, 0.0));
-		ADD_TANGENT(-1.0, 0.0, 0.0, -1.0)
+		ADD_TANGENT(1.0, 0.0, 0.0, -1.0)
 		uvs.push_back(Vector2(0.75, 0.75));
 		point++;
 
@@ -852,7 +852,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
 			Vector3 p = Vector3(x * bottom_radius, y, z * bottom_radius);
 			points.push_back(p);
 			normals.push_back(Vector3(0.0, -1.0, 0.0));
-			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0)
+			ADD_TANGENT(1.0, 0.0, 0.0, -1.0)
 			uvs.push_back(Vector2(u, v));
 			point++;
 
@@ -983,7 +983,7 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const {
 			points.push_back(Vector3(-x, 0.0, -z));
 			normals.push_back(Vector3(0.0, 1.0, 0.0));
 			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
-			uvs.push_back(Vector2(u, v));
+			uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */
 			point++;
 
 			if (i > 0 && j > 0) {
@@ -1108,14 +1108,14 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const {
 			/* front */
 			points.push_back(Vector3(start_x + x, -y, -start_pos.z)); // double negative on the Z!
 			normals.push_back(Vector3(0.0, 0.0, 1.0));
-			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(offset_front + u, v));
 			point++;
 
 			/* back */
 			points.push_back(Vector3(start_x + scaled_size_x - x, -y, start_pos.z));
 			normals.push_back(Vector3(0.0, 0.0, -1.0));
-			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(twothirds + offset_back + u, v));
 			point++;
 
@@ -1187,14 +1187,14 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const {
 			/* right */
 			points.push_back(Vector3(right, -y, -z));
 			normals.push_back(normal_right);
-			ADD_TANGENT(0.0, 0.0, 1.0, -1.0);
+			ADD_TANGENT(0.0, 0.0, -1.0, -1.0);
 			uvs.push_back(Vector2(onethird + u, v));
 			point++;
 
 			/* left */
 			points.push_back(Vector3(left, -y, z));
 			normals.push_back(normal_left);
-			ADD_TANGENT(0.0, 0.0, -1.0, -1.0);
+			ADD_TANGENT(0.0, 0.0, 1.0, -1.0);
 			uvs.push_back(Vector2(u, 0.5 + v));
 			point++;
 
@@ -1241,7 +1241,7 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const {
 			/* bottom */
 			points.push_back(Vector3(x, start_pos.y, -z));
 			normals.push_back(Vector3(0.0, -1.0, 0.0));
-			ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+			ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
 			uvs.push_back(Vector2(twothirds + u, 0.5 + v));
 			point++;
 
@@ -1382,7 +1382,7 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
 		tangents.set(i * 4 + 0, 1.0);
 		tangents.set(i * 4 + 1, 0.0);
 		tangents.set(i * 4 + 2, 0.0);
-		tangents.set(i * 4 + 3, 1.0);
+		tangents.set(i * 4 + 3, -1.0);
 
 		static const Vector2 quad_uv[4] = {
 			Vector2(0, 1),
@@ -1468,7 +1468,7 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
 				points.push_back(p);
 				normals.push_back(p.normalized());
 			};
-			ADD_TANGENT(-z, 0.0, x, -1.0)
+			ADD_TANGENT(z, 0.0, -x, -1.0)
 			uvs.push_back(Vector2(u, v));
 			point++;