2

Say you have a trivial Unity shader. It does not at all use any texture. It grabs simply the position ..

void vert (inout appdata_full v, out Input o) 
{
    UNITY_INITIALIZE_OUTPUT(Input,o);
    o.localPos = v.vertex.xyz;
}

and then draws a square ..

enter image description here

the quad in the example has been stretch about 3:1 using the transform.

If in the shader we simply knew the scaling (or, just the ratios) we could very easily draw "square squares"

enter image description here

This is obviously a common, everyday technique for things like billboarding, 2D images and backgrounds etc.

In current unity (2018) how the heck do you simply get the current scaling of the object, in Cg?

This is one of those crazy Unity things that is (1) totally undocumented (2) where the only information available about it is as much as 13 years old, I mean some of the folks involved may be deceased (3) it has changed drastically in different Unity versions, so often discussion about it is just totally wrong. Sigh.

How to do it? Can you?

Currently I just have a trivial script pass in the value, which is OK but a bit shoddy.

Fattie
  • 27,874
  • 70
  • 431
  • 719

1 Answers1

5

The scale of the transform is baked into the world matrix. If your object is not rotated then you can fetch it directly with a little bit of swizzling, but most likely you want to do something like this:

half3 ObjectScale() {
return half3(
    length(unity_ObjectToWorld._m00_m10_m20),
    length(unity_ObjectToWorld._m01_m11_m21),
    length(unity_ObjectToWorld._m02_m12_m22)
);

}

heads-up: this implementation is dependent on the API, you might need to use some DEFINE to deal with this in DX/OGL, since the matrix format is different (row vs column order).

there's also different way to access matrices components: https://learn.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-per-component-math

like the examples in this thread https://forum.unity.com/threads/can-i-get-the-scale-in-the-transform-of-the-object-i-attach-a-shader-to-if-so-how.418345/

Brice V.
  • 861
  • 4
  • 7
  • thanks @BriceV. That seems an expensive way to do it eh? Maybe I was just wrong in thinking it's an obvious value that should be accessible to a shader. :/ – Fattie Jan 14 '19 at 19:29
  • a constant would be nice ofc :) if performance is critical then you should set the value by script like you said. Per vertex it's probably not that bad really, and there's ways to optimize this, like computing distances squared using dot(), and doing a single sqrt() ? up for you to try :) – Brice V. Jan 15 '19 at 22:05
  • "if performance is critical then you should set the value by script like you said" I believe you've really given the answer there, BV. The simple fact is ............. ***you can not get it*** in the shader. It makes perfect sense when you think about it. – Fattie Jan 15 '19 at 23:47
  • Maybe this not exposed to way you expect it because of the influence of dynamic batching, where your quads would be combined into a single mesh with an identity transform – Brice V. Jan 16 '19 at 23:22