keep the normal transforms in float during skinning

FIXES=[342459864]
This commit is contained in:
Mathias Agopian
2024-06-04 13:37:47 -07:00
committed by Mathias Agopian
parent b5d7de06bc
commit bea02427ed
6 changed files with 32 additions and 25 deletions
+2
View File
@@ -7,3 +7,5 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- engine: fix skinning normals with large transforms (b/342459864) [⚠️ **New Material Version**]
+3 -7
View File
@@ -114,6 +114,7 @@ void FSkinningBuffer::setBones(FEngine& engine,
setBones(engine, mHandle, transforms, count, offset);
}
UTILS_UNUSED
static uint32_t packHalf2x16(half2 v) noexcept {
uint32_t lo = getBits(v[0]);
uint32_t hi = getBits(v[1]);
@@ -144,13 +145,8 @@ PerRenderableBoneUib::BoneData FSkinningBuffer::makeBone(mat4f transform) noexce
transform[1],
transform[2]
},
.cof = {
packHalf2x16({ cofactors[0].x, cofactors[0].y }),
packHalf2x16({ cofactors[0].z, cofactors[1].x }),
packHalf2x16({ cofactors[1].y, cofactors[1].z }),
packHalf2x16({ cofactors[2].x, cofactors[2].y })
// cofactor[2][2] is not stored because we don't have space for it
}
.cof0 = cofactors[0],
.cof1x = cofactors[1].x
};
}
@@ -28,7 +28,7 @@
namespace filament {
// update this when a new version of filament wouldn't work with older materials
static constexpr size_t MATERIAL_VERSION = 52;
static constexpr size_t MATERIAL_VERSION = 53;
/**
* Supported shading models
@@ -327,8 +327,9 @@ struct PerRenderableBoneUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
struct alignas(16) BoneData {
// bone transform, last row assumed [0,0,0,1]
math::float4 transform[3];
// 8 first cofactor matrix of transform's upper left
math::uint4 cof;
// 4 first cofactor matrix of transform's upper left
math::float3 cof0;
float cof1x;
};
BoneData bones[CONFIG_MAX_BONE_COUNT];
};
+2 -1
View File
@@ -19,7 +19,8 @@ struct ShadowData {
#if defined(VARIANT_HAS_SKINNING_OR_MORPHING)
struct BoneData {
highp mat3x4 transform; // bone transform is mat4x3 stored in row-major (last row [0,0,0,1])
highp uvec4 cof; // 8 first cofactor matrix of transform's upper left
highp float3 cof0; // 3 first cofactor matrix of transform's upper left
highp float cof1x; // 4th cofactor
};
#endif
+21 -14
View File
@@ -34,25 +34,32 @@ int getVertexIndex() {
#if defined(VARIANT_HAS_SKINNING_OR_MORPHING)
#define MAX_SKINNING_BUFFER_WIDTH 2048u
vec3 mulBoneNormal(vec3 n, uint i) {
vec3 mulBoneNormal(vec3 n, uint j) {
highp mat3 cof;
// the first 8 elements of the cofactor matrix are stored as fp16
highp vec2 x0y0 = unpackHalf2x16(bonesUniforms.bones[i].cof[0]);
highp vec2 z0x1 = unpackHalf2x16(bonesUniforms.bones[i].cof[1]);
highp vec2 y1z1 = unpackHalf2x16(bonesUniforms.bones[i].cof[2]);
highp vec2 x2y2 = unpackHalf2x16(bonesUniforms.bones[i].cof[3]);
// the last element must be computed by hand
highp float a = bonesUniforms.bones[i].transform[0][0];
highp float b = bonesUniforms.bones[i].transform[0][1];
highp float d = bonesUniforms.bones[i].transform[1][0];
highp float e = bonesUniforms.bones[i].transform[1][1];
highp float a = bonesUniforms.bones[j].transform[0][0];
highp float b = bonesUniforms.bones[j].transform[0][1];
highp float c = bonesUniforms.bones[j].transform[0][2];
highp float d = bonesUniforms.bones[j].transform[1][0];
highp float e = bonesUniforms.bones[j].transform[1][1];
highp float f = bonesUniforms.bones[j].transform[1][2];
highp float g = bonesUniforms.bones[j].transform[2][0];
highp float h = bonesUniforms.bones[j].transform[2][1];
highp float i = bonesUniforms.bones[j].transform[2][2];
cof[0].xyz = vec3(x0y0, z0x1.x);
cof[1].xyz = vec3(z0x1.y, y1z1);
cof[2].xyz = vec3(x2y2, a * e - b * d);
cof[0] = bonesUniforms.bones[j].cof0;
cof[1].xyz = vec3(
bonesUniforms.bones[j].cof1x,
a * i - c * g,
c * d - a * f);
cof[2].xyz = vec3(
d * h - e * g,
b * g - a * h,
a * e - b * d);
return normalize(cof * n);
}