Search Unity

Quad passed in Graphics.Blit is different from standard Quad?

Discussion in 'Shaders' started by MattijsKneppersMM, Jun 24, 2019.

  1. MattijsKneppersMM

    MattijsKneppersMM

    Joined:
    Nov 2, 2016
    Posts:
    4
    I have a shader that derives its screen coordinates from vertex coordinates in a custom way, without using the standard UnityObjectToClipPos method.

    When applying this to a quad, the results are different than when rendering this to a render texture in a Graphics.Blit.

    When using the same shader (below) a) to render to a Quad directly and b) to Graphics.Blit to a render texture, this is what I see:


    left: shader applied to standard Unity quad, right: shader applied in Graphic.Blit to render texture.

    This is the shader:

    Code (CSharp):
    1. Shader "Unlit/Blittest"
    2. Shader "Unlit/Blittest"
    3. {
    4.     Properties {}
    5.     SubShader
    6.     {
    7.         Tags { "RenderType"="Opaque" }
    8.         LOD 100
    9.  
    10.         Pass
    11.         {
    12.             CGPROGRAM
    13.             #pragma vertex vert
    14.             #pragma fragment frag
    15.  
    16.             #include "UnityCG.cginc"
    17.  
    18.             struct appdata
    19.             {
    20.                 float4 vertex : POSITION;
    21.             };
    22.  
    23.             struct v2f
    24.             {
    25.                 float4 vertex : SV_POSITION;
    26.                 float4 origpos : TEXCOORD0;
    27.             };
    28.  
    29.             v2f vert (appdata v)
    30.             {
    31.                 v2f o;
    32.                 o.origpos = v.vertex;
    33.                 o.vertex = UnityObjectToClipPos(v.vertex);
    34.                 return o;
    35.             }
    36.  
    37.             fixed4 frag (v2f i) : SV_Target
    38.             {
    39.                 return fixed4(frac(i.origpos.x), frac(i.origpos.y), 0, 1);
    40.             }
    41.             ENDCG
    42.         }
    43.     }
    44. }
    45.  
    46.  

    So upon further inspection, it seems that the Quad passed in to Graphics.Blit has vertex coordinates ranging from 0 to 1, whereas the standard Unity Quad ranges from -0.5 to 0.5.

    Could this be correct or am I missing something? The docs say:

    Blit sets dest as the render target, sets source _MainTex property on the material, and draws a full-screen quad.Blit sets dest as the render target, sets source _MainTex property on the material, and draws a full-screen quad.​

    This doesn't mention that the quad drown by Blit is a different quad than the standard. If I'm correct it might be useful to add that info there.
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    It doesn't, but you are right, it's different.
     
  3. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    It's to do with the clip space transformation and as such how the vertex information is stored. In the case of the regular quad, the vertices are stored in relation to the mesh origin, hence they are placed equally far from the centre. In order to be displayed on screen, the vertices need to be transformed first into world space, then view space and finally clip space using the projection matrix. However, in the case of the Blit quad, this needs to cover the whole screen no matter what. This can be done very easily by using an 'ortho' matrix, removing the 3D camera-projection elements, thus allowing the vertices to be defined directly in relation to their position on screen; in this case in the range of [0,1]. Hope that helps.
     
    CyrilGhys likes this.