Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

World position in fixed?

Discussion in 'Shaders' started by CloudKid, Dec 15, 2015.

  1. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    Hello.
    I recently started programming shaders, and I'm trying to understand what everything does, and how it all works.

    I just made this shader, which cuts a part of a 2d sprite taking into account a given rect. This works as intended

    Code (CSharp):
    1. Shader "Test/CutSquare"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    8.      
    9.         _StartCorner ("Start corner", Vector) = (0, 0, 0, 0)
    10.     }
    11.  
    12.     SubShader
    13.     {
    14.         Tags
    15.         {
    16.             "Queue"="Transparent"
    17.             "IgnoreProjector"="True"
    18.             "RenderType"="Transparent"
    19.             "PreviewType"="Plane"
    20.             "CanUseSpriteAtlas"="True"
    21.         }
    22.  
    23.         Cull Off
    24.         Lighting Off
    25.         ZWrite Off
    26.         Fog { Mode Off }
    27.         Blend One OneMinusSrcAlpha
    28.  
    29.         Pass
    30.         {
    31.         CGPROGRAM
    32.             #pragma vertex vert
    33.             #pragma fragment frag
    34.             #pragma multi_compile DUMMY PIXELSNAP_ON
    35.             #include "UnityCG.cginc"
    36.  
    37.             struct appdata_t
    38.             {
    39.                 float4 vertex   : POSITION;
    40.                 float4 color    : COLOR;
    41.                 float2 texcoord : TEXCOORD0;
    42.             };
    43.  
    44.             struct v2f
    45.             {
    46.                 float4 vertex   : SV_POSITION;
    47.                 fixed4 color    : COLOR;
    48.                 half2 texcoord  : TEXCOORD0;
    49.                 fixed2 pos : TEXCOORD1;
    50.             };
    51.  
    52.             fixed4 _Color;
    53.             fixed4 _StartCorner;
    54.  
    55.  
    56.             v2f vert(appdata_t IN)
    57.             {
    58.                 v2f OUT;
    59.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    60.                 OUT.texcoord = IN.texcoord;
    61.                 OUT.pos =  mul( _Object2World, IN.vertex);
    62.                 OUT.color = IN.color * _Color;
    63.                 #ifdef PIXELSNAP_ON
    64.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    65.                 #endif
    66.  
    67.                 return OUT;
    68.             }
    69.          
    70.             sampler2D _MainTex;
    71.             float _TestBool;
    72.  
    73.             fixed4 frag(v2f IN) : SV_Target
    74.             {
    75.                 fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
    76.              
    77.                 c.a *=1 - step(_StartCorner.x, IN.pos.x) * step (IN.pos.y, _StartCorner.y) *
    78.                           step(IN.pos.x, _StartCorner.z) * step (_StartCorner.w, IN.pos.y);
    79.                        
    80.                 c.rgb *= c.a;
    81.  
    82.                 return c;
    83.             }
    84.         ENDCG
    85.         }
    86.     }
    87. }

    I was trying to make it as efficient as I can (you can post some suggestions if you have some ideas), when I notice that my variable "pos", in which I store my world position of a pixel, can be of type fixed and the code works as intended. Also my input _StartCorner is also fixed, but everything works grate, regardless of what coords I am using as input.

    I thought that fixed is only between -2 and 2 with a precision on 1/256 (no idea what this means), and for world position we should use float.
     
  2. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    Oh, I just read this:
    "In practice, exactly which type will be used for float/half/fixed depends on the platform and the GPU. General summary.
    Is it because my pc treats it as float?
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    The fixed format must support a minimum range between -2 and +2 with a precision of 1/256, but there's no maximum requirements so some hardware could decided fixed actually means a 32 bit float. That still fulfills the requirements of a -2 to +2 range. Most modern desktop hardware doesn't bother with fixed because their half or float performance is so well optimized there's no reason to have lower precision formats.


    Btw the 1/256 precision thing is about how float stores numbers.
    http://floating-point-gui.de/

    In simple terms a fixed number format that only supported exactly the required range and precision can only store numbers in 0.00390625 (1/256) steps. So you can have 0.0 (zero), or 0.00390625, but not 0.00251537 or even 0.004. Both of those will end up being stored as 0.00390625.

    Similarly a number greater than 2 or less than -2 would just be clamped to 2 and -2.

    In reality it's more complicated than this and more than likely the precision near 0.0 is better than 1/256 and it only gets close to being that low at around -2 and +2 numbers and likely can produce numbers slightly above or below 2.
     
    Last edited: Dec 15, 2015
    CloudKid likes this.
  4. Flailer

    Flailer

    Joined:
    Apr 1, 2014
    Posts:
    66
    Can't remember where I read it, but on Desktop, fixed, half, float are all just set to float32, so that's why it makes zero difference. Put that on a mobile device and all kinds of errors will start to happen.