Fixed cloth tangent generation (#2440)

- The output vectors were not properly filled with zeros when they already had the expected size.
- The tolerance was too large and was causing patches while computing tangents and bitangents.
- The handedness was inverted to what is expected in the shader (which always inverts tangent's w).

Signed-off-by: moraaar <moraaar@amazon.com>
main
moraaar 4 years ago committed by GitHub
parent 7ec6feddb8
commit 26c9853ff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -577,7 +577,7 @@ namespace NvCloth
const AZ::Vector3& renderTangent = renderTangents[renderVertexIndex];
destTangentsBuffer[index].Set(
renderTangent,
1.0f);
-1.0f); // Shader function ConstructTBN inverts w to change bitangent sign, but the bitangents passed are already corrected, so passing -1.0 to counteract.
}
if (destBitangentsBuffer)

@ -11,7 +11,7 @@ namespace NvCloth
{
namespace
{
const float Tolerance = 0.0001f;
const float Tolerance = 1e-7f;
}
bool TangentSpaceHelper::CalculateNormals(
@ -33,7 +33,8 @@ namespace NvCloth
const size_t vertexCount = vertices.size();
// Reset results
outNormals.resize(vertexCount, AZ::Vector3::CreateZero());
outNormals.resize(vertexCount);
AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero());
// calculate the normals per triangle
for (size_t i = 0; i < triangleCount; ++i)
@ -114,8 +115,10 @@ namespace NvCloth
const size_t vertexCount = vertices.size();
// Reset results
outTangents.resize(vertexCount, AZ::Vector3::CreateZero());
outBitangents.resize(vertexCount, AZ::Vector3::CreateZero());
outTangents.resize(vertexCount);
outBitangents.resize(vertexCount);
AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero());
AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero());
// calculate the base vectors per triangle
for (size_t i = 0; i < triangleCount; ++i)
@ -192,9 +195,12 @@ namespace NvCloth
const size_t vertexCount = vertices.size();
// Reset results
outTangents.resize(vertexCount, AZ::Vector3::CreateZero());
outBitangents.resize(vertexCount, AZ::Vector3::CreateZero());
outNormals.resize(vertexCount, AZ::Vector3::CreateZero());
outTangents.resize(vertexCount);
outBitangents.resize(vertexCount);
outNormals.resize(vertexCount);
AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero());
AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero());
AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero());
// calculate the base vectors per triangle
for (size_t i = 0; i < triangleCount; ++i)

@ -124,6 +124,9 @@ namespace UnitTest
const AZStd::vector<AZ::Vector4>& motionConstraints = clothConstraints->GetMotionConstraints();
EXPECT_TRUE(motionConstraints.size() == SimulationParticles.size());
EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(SimulationParticles[0].GetAsVector3(), Tolerance));
EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(SimulationParticles[1].GetAsVector3(), Tolerance));
EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(SimulationParticles[2].GetAsVector3(), Tolerance));
EXPECT_NEAR(motionConstraints[0].GetW(), 6.0f, Tolerance);
EXPECT_NEAR(motionConstraints[1].GetW(), 0.0f, Tolerance);
EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance);
@ -277,6 +280,9 @@ namespace UnitTest
const AZStd::vector<AZ::Vector4>& separationConstraints = clothConstraints->GetSeparationConstraints();
EXPECT_TRUE(motionConstraints.size() == newParticles.size());
EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(newParticles[0].GetAsVector3(), Tolerance));
EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(newParticles[1].GetAsVector3(), Tolerance));
EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(newParticles[2].GetAsVector3(), Tolerance));
EXPECT_NEAR(motionConstraints[0].GetW(), 3.0f, Tolerance);
EXPECT_NEAR(motionConstraints[1].GetW(), 1.5f, Tolerance);
EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance);
@ -285,8 +291,8 @@ namespace UnitTest
EXPECT_NEAR(separationConstraints[0].GetW(), 3.0f, Tolerance);
EXPECT_NEAR(separationConstraints[1].GetW(), 1.5f, Tolerance);
EXPECT_NEAR(separationConstraints[2].GetW(), 0.3f, Tolerance);
EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-3.03902f, 2.80752f, 3.80752f), Tolerance));
EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-1.41659f, 0.651243f, -0.348757f), Tolerance));
EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(6.15313f, -0.876132f, 0.123868f), Tolerance));
EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 3.53553f, 4.53553f), Tolerance));
EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 2.06066f, 1.06066f), Tolerance));
EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(1.0f, -3.74767f, -2.74767f), Tolerance));
}
} // namespace UnitTest

Loading…
Cancel
Save