Fix #139753: Discontinuity in mesh tangent without UV map
when there is no uv, we call the function `map_to_sphere()` to create temporary uv for computing the tangent. It could happen that a triangle has vertices with the u coordinates going across the line where u wraps from 1 to 0. In this case, just computing the difference of the u coordinates results in the wrong triangle area. To fix this problem, we compute distance in toroidal (wrap around) space. This is safe for coordinates generated by `map_to_sphere()` function, because it is not supposed to map the positions of a triangle to u coordinates that span larger than 0.5. Pull Request: https://projects.blender.org/blender/blender/pulls/139880
This commit is contained in:
parent
1dfe8047d3
commit
ee578cc738
@ -67,7 +67,7 @@ struct MikkMeshWrapper {
|
|||||||
{
|
{
|
||||||
/* TODO: Check whether introducing a template boolean in order to
|
/* TODO: Check whether introducing a template boolean in order to
|
||||||
* turn this into a constexpr is worth it. */
|
* turn this into a constexpr is worth it. */
|
||||||
if (uv != nullptr) {
|
if (has_uv()) {
|
||||||
const int corner_index = CornerIndex(face_num, vert_num);
|
const int corner_index = CornerIndex(face_num, vert_num);
|
||||||
const float2 tfuv = uv[corner_index];
|
const float2 tfuv = uv[corner_index];
|
||||||
return mikk::float3(tfuv.x, tfuv.y, 1.0f);
|
return mikk::float3(tfuv.x, tfuv.y, 1.0f);
|
||||||
@ -101,6 +101,11 @@ struct MikkMeshWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_uv() const
|
||||||
|
{
|
||||||
|
return uv != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const Mesh *mesh;
|
const Mesh *mesh;
|
||||||
|
|
||||||
const float3 *normal;
|
const float3 *normal;
|
||||||
|
@ -253,6 +253,11 @@ template<typename Mesh> class Mikktspace {
|
|||||||
return mesh.GetTexCoord(f, v);
|
return mesh.GetTexCoord(f, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_uv() const
|
||||||
|
{
|
||||||
|
return mesh.has_uv();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -522,9 +527,16 @@ template<typename Mesh> class Mikktspace {
|
|||||||
const float3 t2 = getTexCoord(triangle.vertices[1]);
|
const float3 t2 = getTexCoord(triangle.vertices[1]);
|
||||||
const float3 t3 = getTexCoord(triangle.vertices[2]);
|
const float3 t3 = getTexCoord(triangle.vertices[2]);
|
||||||
|
|
||||||
const float t21x = t2.x - t1.x;
|
float t21x = t2.x - t1.x;
|
||||||
|
float t31x = t3.x - t1.x;
|
||||||
|
if (!has_uv()) {
|
||||||
|
/* Compute edge length in toroidal space, since the u generated by `map_to_sphere()` might
|
||||||
|
* go cross the seam. */
|
||||||
|
t21x -= floorf(t21x + 0.5f);
|
||||||
|
t31x -= floorf(t31x + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
const float t21y = t2.y - t1.y;
|
const float t21y = t2.y - t1.y;
|
||||||
const float t31x = t3.x - t1.x;
|
|
||||||
const float t31y = t3.y - t1.y;
|
const float t31y = t3.y - t1.y;
|
||||||
const float3 d1 = v2 - v1, d2 = v3 - v1;
|
const float3 d1 = v2 - v1, d2 = v3 - v1;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ struct SGLSLEditMeshToTangent {
|
|||||||
mikk::float3 GetTexCoord(const uint face_num, const uint vert_index)
|
mikk::float3 GetTexCoord(const uint face_num, const uint vert_index)
|
||||||
{
|
{
|
||||||
const BMLoop *l = GetLoop(face_num, vert_index);
|
const BMLoop *l = GetLoop(face_num, vert_index);
|
||||||
if (cd_loop_uv_offset != -1) {
|
if (has_uv()) {
|
||||||
const float *uv = (const float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
const float *uv = (const float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||||
return mikk::float3(uv[0], uv[1], 1.0f);
|
return mikk::float3(uv[0], uv[1], 1.0f);
|
||||||
}
|
}
|
||||||
@ -130,6 +130,11 @@ struct SGLSLEditMeshToTangent {
|
|||||||
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_uv()
|
||||||
|
{
|
||||||
|
return cd_loop_uv_offset != -1;
|
||||||
|
}
|
||||||
|
|
||||||
Span<float3> face_normals;
|
Span<float3> face_normals;
|
||||||
Span<float3> corner_normals;
|
Span<float3> corner_normals;
|
||||||
Span<std::array<BMLoop *, 3>> looptris;
|
Span<std::array<BMLoop *, 3>> looptris;
|
||||||
|
@ -70,6 +70,11 @@ struct BKEMeshToTangent {
|
|||||||
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_uv() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
OffsetIndices<int> faces; /* faces */
|
OffsetIndices<int> faces; /* faces */
|
||||||
const int *corner_verts; /* faces vertices */
|
const int *corner_verts; /* faces vertices */
|
||||||
const float (*positions)[3]; /* vertices */
|
const float (*positions)[3]; /* vertices */
|
||||||
@ -227,7 +232,7 @@ struct SGLSLMeshToTangent {
|
|||||||
int3 tri;
|
int3 tri;
|
||||||
int face_index;
|
int face_index;
|
||||||
uint loop_index = GetLoop(face_num, vert_num, tri, face_index);
|
uint loop_index = GetLoop(face_num, vert_num, tri, face_index);
|
||||||
if (mloopuv != nullptr) {
|
if (has_uv()) {
|
||||||
const float2 &uv = mloopuv[loop_index];
|
const float2 &uv = mloopuv[loop_index];
|
||||||
return mikk::float3(uv[0], uv[1], 1.0f);
|
return mikk::float3(uv[0], uv[1], 1.0f);
|
||||||
}
|
}
|
||||||
@ -281,6 +286,11 @@ struct SGLSLMeshToTangent {
|
|||||||
copy_v4_fl4(tangent[loop_index], T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
copy_v4_fl4(tangent[loop_index], T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_uv() const
|
||||||
|
{
|
||||||
|
return mloopuv != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Span<float3> face_normals;
|
Span<float3> face_normals;
|
||||||
Span<float3> corner_normals;
|
Span<float3> corner_normals;
|
||||||
const int3 *corner_tris;
|
const int3 *corner_tris;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:cd07487f8bb71a4199fb15cf994599317670ca806757fdae24c00c85a26d3be2
|
oid sha256:7fa3ab720f94fa70de22f70f9e87bd74b8cc06bff20a82352b53ee24d02e14d8
|
||||||
size 28659
|
size 28195
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4a3a786cd629cbd7074a40c5ece486d6dccd031e8cafdf41ad5bd62f9c1afb1a
|
oid sha256:e69131fc75964401791a7a13a29d50a44e04699f29f8ff23d827ddbd75899d3a
|
||||||
size 20981
|
size 20489
|
||||||
|
@ -43,8 +43,6 @@ BLOCKLIST = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
BLOCKLIST_METAL = [
|
BLOCKLIST_METAL = [
|
||||||
# Blocked due to difference in tangent space calculation (to be fixed).
|
|
||||||
"tangent_no_uv.blend",
|
|
||||||
# Blocked due to difference in volume lightprobe bakes (to be fixed).
|
# Blocked due to difference in volume lightprobe bakes (to be fixed).
|
||||||
"clamp_.*.blend",
|
"clamp_.*.blend",
|
||||||
"shadow_all_max_bounces.blend",
|
"shadow_all_max_bounces.blend",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user