Status:
High confidence of defect, but unverified whether a live shader consumes it yet.
Source version:
Carbon v5.0.0, commit 342fbe5
Content version:
TQ build 3444265
Note
I do not have a runnable Carbon build, this was identified while implimenting JS equivilent PerObjectData packers.
Source:
trinity/trinity/Eve/SpaceObject/Children/EveChildBehaviorSystem.cpp:599-608
m_vsData.worldTransformLast = Transpose( m_worldTransform );
UpdateTransform( localToWorldTransform );
m_vsData.worldTransform = Transpose( m_worldTransform );
m_vsData.invWorldTransform = Inverse( m_worldTransform ); // <-- no Transpose
Description
EveChildBehaviorSystem stores an untransposed inverse world matrix. Every other filler of EveSpaceObjectVSData.invWorldTransform inverts the alrady-transposed matrix, which yields the transposed inverse:
EveChildMesh.cpp:949 — Inverse( m_vsData.worldTransform )
EveChildContainer.cpp:584 — Inverse( m_vsData.worldTransform )
EveSpaceObject2.cpp:638 — Transpose( m_invWorldTransform )
Because Inverse(Wᵀ) == Inverse(W)ᵀ, those three agree.
This one does not: it stores Inverse(W), the transpose of what the shader reads everywhere else.
Any shader path that consumes invWorldTransform for a behaviour-system child transforms by the transpose of the intended matrix. For a rotation-free or uniformly-scaled placement the two coincide, which is why this can sit unnoticed; under a rotated placement the inverse-transform result is wrong. Whether anything currently samples that field for this class is not established here.
Status:
High confidence of defect, but unverified whether a live shader consumes it yet.
Source version:
Carbon v5.0.0, commit 342fbe5
Content version:
TQ build 3444265
Note
I do not have a runnable Carbon build, this was identified while implimenting JS equivilent PerObjectData packers.
Source:
trinity/trinity/Eve/SpaceObject/Children/EveChildBehaviorSystem.cpp:599-608Description
EveChildBehaviorSystemstores an untransposed inverse world matrix. Every other filler ofEveSpaceObjectVSData.invWorldTransforminverts the alrady-transposed matrix, which yields the transposed inverse:EveChildMesh.cpp:949—Inverse( m_vsData.worldTransform )EveChildContainer.cpp:584—Inverse( m_vsData.worldTransform )EveSpaceObject2.cpp:638—Transpose( m_invWorldTransform )Because
Inverse(Wᵀ) == Inverse(W)ᵀ, those three agree.This one does not: it stores
Inverse(W), the transpose of what the shader reads everywhere else.Any shader path that consumes
invWorldTransformfor a behaviour-system child transforms by the transpose of the intended matrix. For a rotation-free or uniformly-scaled placement the two coincide, which is why this can sit unnoticed; under a rotated placement the inverse-transform result is wrong. Whether anything currently samples that field for this class is not established here.