Search Unity

Question Getting global position in a Skybox shader

Discussion in 'Shader Graph' started by fernancp444, May 30, 2021.

  1. fernancp444

    fernancp444

    Joined:
    Mar 31, 2020
    Posts:
    4
    I'm trying to write a custom shader for a skybox and I'm having trouble understanding how to properly get the global position of a vertex in the skybox. For instance, suppose I want to paint the upper half of the skybox white, and the bottom one black. I would have thought I had to do something like this:

    Code (CSharp):
    1. float3 _worldPos;
    2.  
    3.             v2f vert (appdata v)
    4.             {
    5.                 v2f o;
    6.                 o.vertex = UnityObjectToClipPos(v.vertex);
    7.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    8.                 UNITY_TRANSFER_FOG(o,o.vertex);
    9.                 //ray from camera to vertex
    10.                 _worldPos = normalize(mul((float3x3)unity_ObjectToWorld, v.vertex.xyz));
    11.                 return o;
    12.             }
    13.  
    14.             fixed4 frag (v2f i) : SV_Target
    15.             {
    16.                 half4 out = float4(0.0,0.0,0.0,1.0);
    17.                 if (_worldPos.y > 0.0)
    18.                     out = float4(1.0,1.0,1.0,1.0);
    19.                 return out;
    20.             }
    this however just draws everything black. I guess I'm inbterpreting wrongly the line that I'm using to calculate
    _worldPos
    in the vertex shader? However if I understand properly what the matrix
    unity_ObjectToWorld
    and what the input of the vertex shader are, that should be OK.
    What's the problem here? Or is there something I just don't understand about how the GPU is running this that I'm not supposed to write to
    _worldPos
    in the vertex shader and then use it in the fragment shader?
     
    Last edited: May 30, 2021
  2. fernancp444

    fernancp444

    Joined:
    Mar 31, 2020
    Posts:
    4
    I'll write a bit of an answer to myself, which might be wrong.

    I'm now under the understanding that parameters defined outside the vertex and fragment shaders are "global" parameters common to all instances of any given vertex or fragment, so that each individual fragment, as it's processed, should have all its relevant unique information in its input structure, so I should do something like

    Code (CSharp):
    1. struct v2f
    2. {
    3.     float2 uv : TEXCOORD0;
    4.     UNITY_FOG_COORDS(1)
    5.     float4 vertex : SV_POSITION;
    6.     float3 worldPos : WORLDPOS;
    7. };
    and then set the appropriate worldPos in the vertex shader, to then be processed in the fragment shader. This now works the way I intended it to.

    I have two questions, the first one is whether this understanding is correct. The second is about the semantic, without the : WORLDPOS after the definition of the float3, unity complains that the semantic is missing. I just wrote WORLDPOS and it worked, but any information about what this semantic does exactly if it's something non-standard like this?

    Thanks!
     
    Last edited: May 30, 2021