-
-
Notifications
You must be signed in to change notification settings - Fork 36k
Description
glTF files assume that morph target data is specified as relative adjustments, and three.js assumes that the data in morph target buffers is absolute.
This leads to a few obvious memory/performance caveats - the morph target data needs to be duplicated and modified during import - but also leads to inability to use a very narrow type for position deltas.
For example, when data is quantized with gltfpack (which makes the glTF files technically invalid right now but this will change soon: KhronosGroup/glTF#1673), the positions typically use UInt16 and morph target deltas use Int16. However, very frequently the morph target delta range is small enough to fit in Int8 - because three.js attempts to reconstruct the absolute position however, attempting to encode Int8 deltas leads to decoding issues on three.js side. Babylon.JS handles files like this perfectly.
I'd like to fix this - the obvious tactical fix is changing the morph target attribute cloning to assume the type of the base attribute, not morph target. However, I'd like to check - what are the thoughts of fixing this by adding support to three.js for relative morph target data?
In theory, the formulas are compatible to not require any shader code duplication - specifically, this equation that three.js currently uses:
basePosition
+ weight0 * ( morphPosition0 - basePosition )
+ weight1 * ( morphPosition1 - basePosition )
and this equation that glTF assumes:
basePosition
+ weight0 * glTFmorphPosition0
+ weight1 * glTFmorphPosition1
can be reformulated as:
weightBase * basePosition
+ weight0 * morphPosition0
+ weight1 * morphPosition1
After which for glTF style files the shader needs [1, weight0, weight1, ...]
as an input, whereas normally you'd pass [1 - weight0 - weight1 - ..., weight0, weight1, ...]
as an input. So by adding some sort of flag to three.js mesh (e.g. morphTargetsAreDeltas
) and a bit of JS code to compute the weights correctly, we could support both with minimal cost.