Packing normal and tangents

This commit is contained in:
sam gateau 2018-09-28 17:49:52 -07:00
parent faf489855c
commit 1ff4c54c1c
2 changed files with 42 additions and 26 deletions

View file

@ -15,11 +15,27 @@ struct PackedBlendshapeOffset {
};
struct BlendshapeOffset {
vec4 position;
vec4 normal;
vec4 tangent;
vec3 position;
<@if USE_NORMAL@>
vec3 normal;
<@endif@>
<@if USE_TANGENT@>
vec3 tangent;
<@endif@>
};
const float oneOver511 = 1.0 / 511.0;
vec3 unpackSnorm3x10_1x2(int packed) {
vec4 unpacked = vec4(
float( (packed & 0x000003FF) - 512 ),
float( ((packed >> 10) & 0x000003FF) - 512 ),
float( ((packed >> 20) & 0x000003FF) - 512 ),
float( (packed >> 30) & 0x00000003 )
);
return clamp(unpacked.xyz * oneOver511, vec3(-1.0), vec3(1.0));
}
#if defined(GPU_GL410)
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
BlendshapeOffset getBlendshapeOffset(int i) {
@ -36,19 +52,20 @@ BlendshapeOffset getBlendshapeOffset(int i) {
}
#else
layout(std140, binding=0) buffer blendshapeOffsetsBuffer {
ivec4 _blendshapeOffsets[];
// BlendshapeOffset _blendshapeOffsets[];
ivec4 _packedBlendshapeOffsets[];
};
BlendshapeOffset getBlendshapeOffset(int i) {
// return _blendshapeOffsets[i];
ivec4 elem_packed = _blendshapeOffsets[i];
ivec4 elem_packed = _packedBlendshapeOffsets[i];
BlendshapeOffset unpacked;
unpacked.position = vec4(unpackHalf2x16(uint(elem_packed.x)), unpackHalf2x16(uint(elem_packed.y)));
unpacked.normal = vec4(0.0);
unpacked.tangent = vec4(0.0);
unpacked.position = vec3(unpackHalf2x16(uint(elem_packed.x)), unpackHalf2x16(uint(elem_packed.y)).x);
<@if USE_NORMAL@>
unpacked.normal = unpackSnorm3x10_1x2((elem_packed.z)).xyz;
<@endif@>
<@if USE_TANGENT@>
unpacked.tangent = unpackSnorm3x10_1x2((elem_packed.w)).xyz;
<@endif@>
return unpacked;
}
@ -63,7 +80,7 @@ void evalBlendshape(int i, vec4 inPosition, out vec4 position
<@endif@>
) {
BlendshapeOffset blendshapeOffset = getBlendshapeOffset(i);
position = inPosition + blendshapeOffset.position;
position = inPosition + vec4(blendshapeOffset.position, 0.0);
<@if USE_NORMAL@>
normal = normalize(inNormal + blendshapeOffset.normal.xyz);
<@endif@>

View file

@ -1691,20 +1691,19 @@ void Blender::run() {
}
#ifdef PACKED_BLENDSHAPE_OFFSET
auto unpacked = unpackedBlendshapeOffsets.data();
auto packed = meshBlendshapeOffsets;
for (int i = 0; i < unpackedBlendshapeOffsets.size(); i++) {
auto pposXY = glm::packHalf2x16(glm::vec2(unpacked->positionOffsetAndSpare));
auto pposZ = glm::packHalf2x16(glm::vec2(unpacked->positionOffsetAndSpare.z, 0.0f));
auto pnor = glm::packSnorm3x10_1x2(glm::vec4(unpacked->normalOffsetAndSpare, 0.0f));
auto ptan = glm::packSnorm3x10_1x2(glm::vec4(unpacked->tangentOffsetAndSpare, 0.0f));
(*packed).packedPosNorTan = glm::uvec4(pposXY, pposZ, pnor, ptan);
unpacked++;
packed++;
}
tbb::parallel_for(tbb::blocked_range<int>(0, unpackedBlendshapeOffsets.size()), [&](const tbb::blocked_range<int>& range) {
auto unpacked = unpackedBlendshapeOffsets.data() + range.begin();
auto packed = meshBlendshapeOffsets + range.begin();
for (auto j = range.begin(); j < range.end(); j++) {
(*packed).packedPosNorTan = glm::uvec4(
glm::packHalf2x16(glm::vec2(unpacked->positionOffsetAndSpare)),
glm::packHalf2x16(glm::vec2(unpacked->positionOffsetAndSpare.z, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->normalOffsetAndSpare, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->tangentOffsetAndSpare, 0.0f)));
unpacked++;
packed++;
}
});
#endif
}