Fixing tangent and binormal logic

This commit is contained in:
Bastiaan Olij 2018-11-17 12:11:35 +11:00
parent 6ed1be9637
commit bcef4b8dc6
6 changed files with 57 additions and 34 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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]);

View file

@ -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

View file

@ -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++;