Search Unity

unity_ObjectToWorld does not contain translation?

Discussion in 'Shaders' started by fredlllll, Jan 11, 2019.

  1. fredlllll

    fredlllll

    Joined:
    Nov 20, 2014
    Posts:
    13
    Me again,

    now this might only be me being blind again, but i have the suspicion that unity_ObjectToWorld does not contain any translation information.

    so here is a minimal shader to test that: (also great that the forum does not have a codetag for shaders)
    Code (csharp):
    1. Shader "Custom/TranslationTest"
    2. {
    3.     Properties
    4.     {
    5.     }
    6.     SubShader
    7.     {
    8.         Tags { "RenderType"="Opaque" }
    9.         LOD 200
    10.  
    11.         CGPROGRAM
    12.         #pragma surface surf Standard fullforwardshadows
    13.  
    14.         struct Input
    15.         {
    16.             float3 worldPos;
    17.         };
    18.  
    19.         void surf (Input IN, inout SurfaceOutputStandard o)
    20.         {
    21.             o.Albedo = mul(unity_ObjectToWorld, float3(0.1, 0.1, 0.1));
    22.         }
    23.         ENDCG
    24.     }
    25.     FallBack "Diffuse"
    26. }
    27.  
    so you see all i do is transform a small vector with the worldmatrix. i would expect the translation to also come to play here, but nope, results look like this


    the two colored ones have scale 2 on x and y, so that channel gets scaled, rotation also gets applied (color changes with rotation when scale is applied). but with the front cube u see that the x part of the vector does not get translated (or any other axis for that matter). now what am i doing wrong? where can i get the translation info? im running 2018.3.0f2
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    That's because unity_ObjectToWorld is a 4x4 matrix, and you're multiplying a float3 which ignores the position. You're only seeing scale and rotation have any effect because that's all you're extracting from it.

    Try:
    o.Albedo = mul(unity_ObjectToWorld, float4(0.1, 0.1, 0.1, 1.0)).xyz;

    Note you may still not see any color change if you view this in the game view. That's because of batching.
     
  3. fredlllll

    fredlllll

    Joined:
    Nov 20, 2014
    Posts:
    13
    thanks it worked, i knew it had to be a small detail.
     
  4. trunghieu974

    trunghieu974

    Joined:
    Jun 19, 2015
    Posts:
    25
    could you help me to explain, why multiplying a float 3 is ignores the position? Thank you :D
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Because in a 4x4 3D transform matrix the first 3x3 section holds the rotation and scale. The last column of the 4x4 holds the translation. If you multiply a float4x4 by a float3 it only applies the 3x3 (or rather 3x4 and multiplies the last column by zero). If you want to apply the full transform you want to use a float4 with a w of 1.0.
     
    Silas-VuCity and trunghieu974 like this.
  6. trunghieu974

    trunghieu974

    Joined:
    Jun 19, 2015
    Posts:
    25
    i got it, thank you very much :D