Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

When using built-in shader variables

Discussion in 'Shaders' started by orgia, Nov 16, 2017.

  1. orgia

    orgia

    Joined:
    Jun 24, 2017
    Posts:
    14
    hi,

    When we use the built-in shader variables, such as _WorldSpaceCameraPos, why we need to add the .xyz after the variable ,what does it mean, is it a kind of tag? or the property of that variable?
    thanks
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    It's called a swizzle. (And not just by Snoop Dogg ;-) )

    It's not related to built-in shader variables and applies to all vector type variables commonly used in shaders. So besides a float, there is a float2, float3 and float4. You can index the first value as variable[0], but also as variable.x (or variable.r.) Much like Unity's Vector4 in scripts.

    The nice thing about these swizzles is that you can combine them. So instead of:
    float3(variable.x, variable.y, variable.z)
    You can just write:
    variable.xyz

    You can read more about it here:
    https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling
    https://msdn.microsoft.com/nl-nl/library/windows/desktop/bb219869.aspx

    Off topic: I do like the name of the shader model 2_x feature "arbitrary swizzling".
     
    orgia likes this.
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    One note here, you do not need to add .xyz to _WorldSpaceCameraPos as it's defined as a float3. The issue is there are some built in shader variables, most infamously _Time, but also _WorldSpaceLightPos0, that are defined as float4 values, but only one or the first three of those values are used most of the time.

    For example, _Time is defined in the documentation as:
    So _Time.x in the shader is equivalent to Time.timeSinceLevelLoad / 20f in c#, and _Time.y is equivalent to Time.timeSinceLevelLoad unmodified.

    _WorldSpaceLightPos0 is a little more interesting as it can either be a directional light or a point/spot light. Unity uses the .z component value to signify which. If _WorldSpaceLightPos0.z == 0 then _WorldSpaceLightPos0.xyz is a normalized direction vector, otherwise _WorldSpaceLightPos0.xyz is a world position. In either case using the full float4 value of _WorldSpaceLightPos0 will likely cause problems for your shader. For example if trying to determine the distance from a world position to the light, doing distance(_WorldSpaceLightPos0, worldPos) in a shader may error on some platforms as it's trying to get the distance between a float4 and a float, or give unexpected results, especially if worldPos is also a float4 value.
     
    orgia likes this.
  4. orgia

    orgia

    Joined:
    Jun 24, 2017
    Posts:
    14
    thanks for replying, very helpful