0
\$\begingroup\$

I'm trying to apply UV mapping in parent space - ie. taking into account the object's own transformation matrix but no matrices further up the transformation hierarchy.

For example, I'd want to be able to transform a cube mesh (rotate/scale) and have UVs based on that, not the mesh vertices themselves. Then any transforms above that would not impact that object’s UVs.

What’s the best way to access the local transform matrix of an object in a shader in Unity?

I know that I can use objectToWorld to get access to the entire hierarchy’s flattened transform matrix, but I want to specifically access only the bottom most transform (the local one produced by the transform component on an object)

Do I have to pass this in as a custom variable each frame? Or is there a better method to use?

\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

I think you're right that the only way to get this is to pass a custom variable each frame:

public class LocalMatrixToShader : MonoBehaviour
{
    Renderer _renderer;

    static MaterialPropertyBlock _block;
    static int _propertyIndex;

    void Start()
    {
        _renderer = GetComponent<Renderer>();

        if(_block == null) {
            _block = new MaterialPropertyBlock();
            _propertyIndex = Shader.PropertyToID("_LocalMatrix");
        }
    }

    void LateUpdate()
    {
        var worldToParent = transform.parent == null ?
                     Matrix4x4.identity
                     : transform.parent.worldToLocalMatrix;

        var localToParent = worldToParent * transform.localToWorldMatrix;

        _block.SetMatrix(_propertyIndex, localToParent);
        _renderer.SetPropertyBlock(_block);
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ Is there a way to have this update in real-time in the editor then too? \$\endgroup\$ Commented Aug 12, 2019 at 0:43
  • 1
    \$\begingroup\$ [ExecuteInEditMode] and change the business end from LateUpdate to Update. \$\endgroup\$
    – DMGregory
    Commented Aug 12, 2019 at 0:45
  • \$\begingroup\$ Could just as easily construct the local matrix using the localPosition, localRotation and localScale values. \$\endgroup\$ Commented Aug 12, 2019 at 5:00
  • \$\begingroup\$ Sure, localToParent = Matrix4x4.TRS(transform.localPosition, transform.localRotation, transform.localScale); I'm not sure whether this is faster than a matrix multiply — I haven't profiled the two cases against one another. \$\endgroup\$
    – DMGregory
    Commented Aug 12, 2019 at 11:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .