Search Unity

Missing something about vertex position in clip space

Discussion in 'Shaders' started by TheValar, Apr 28, 2016.

  1. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    760
    Ok so I'm trying to wrap my head around shaders. One very simple thing that I've read over and over again is that to get a vertex position in screen space you do
    Code (CSharp):
    1. mul(UNITY_MATRIX_MVP, v.vertex);
    and you should get a float4 with x and y ranging from -1 to 1.

    When I do this I'm getting a value that ranges from 0 to screen width/height;

    EX:
    Code (CSharp):
    1. Shader "Unlit/VertexPositionShader"
    2. {
    3.     Properties
    4.     {
    5.     }
    6.     SubShader
    7.     {
    8.         Tags { "RenderType"="Opaque" }
    9.  
    10.         Pass
    11.         {
    12.             CGPROGRAM
    13.             #pragma vertex vert
    14.             #pragma fragment frag
    15.  
    16.             struct appdata
    17.             {
    18.                 float4 vertex : POSITION;
    19.             };
    20.  
    21.             struct v2f
    22.             {
    23.                 float4 vertex : SV_POSITION;
    24.             };
    25.            
    26.             v2f vert (appdata v)
    27.             {
    28.                 v2f o;
    29.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    30.                 return o;
    31.             }
    32.            
    33.             fixed4 frag (v2f i) : SV_Target
    34.             {
    35.                 fixed4 col;
    36.                 if (i.vertex.x > _ScreenParams.x/2)
    37.                     col = 0;//black
    38.                 else
    39.                     col = 1;//white
    40.                 return col;
    41.             }
    42.             ENDCG
    43.         }
    44.     }
    45. }
    The Result is
    ShaderIssue.png

    Am I missing something here?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    There's some weirdness that happens with the SV_POSITION output from the vertex shader, specifically that value doesn't necessarily get to the fragment shader unmodified. Most likely you're getting the VPOS, which is the pixel coordinate the rasterization calculates from the SV_POSITION. If you want the clip space position you'll want to add another interpolant to be passed from the vertex shader to the fragment shader, like float4 clipPos : TEXCOORD0;

    Also, even then you'll need to do clipPos.xy / clipPos.w to get it into -1 to 1 ranges. You should download the built in shader source and look at the functions for getting screen space positions like in the particle shaders for getting the depth texture UV.
     
    Last edited: Apr 30, 2016
  3. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    760
    Thanks a lot for the info. I will definitely take a look at some of the built in shader source code to get a better idea. Good to know I'm not totally missing something :D