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. Dismiss Notice

What is GLSL's texelFetch in Unity's unlit shader?

Discussion in 'Shaders' started by zhutianlun810, Mar 6, 2019.

  1. zhutianlun810

    zhutianlun810

    Joined:
    Sep 17, 2017
    Posts:
    162
    Hello,

    The line in GLSL is:
     texelFetch(source0, gl_FragCoord.xy + offset, 0).rgb;

    Firstly, I tried CG's texel2Dfetch, but Unity cannot recognize it. Then I tried:
    float3 n = tex2D(_MainTex, i.uv + offset * _MainTex_TexelSize.xy).xyz;

    I thought the result should be same because my _MainTex's size is same as my screen. However it gave me incorrect image.
     
    Last edited: Mar 6, 2019
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,236
    texelFetch is an OpenGL 3.0 feature, which is equivalent to Direct3D 10. Unity's shaders are generally written in Direct3D 9 style HLSL, which has no direct equivalent.

    The closest while still using DX9 HLSL would be to use quantized UVs like this:
    Code (csharp):
    1. float2 uv = (floor(i.uv * _MainTex_TexelSize.zw) + 0.5) * _MainTex_TexelSize.xy;
    2. float3 n = tex2Dlod(_MainTex, float4(uv, 0, 0)).xyz;
    Your offset, assuming it's an offset in texels, would be added after the + 0.5 inside the parentheses. ie:
    Code (csharp):
    1. float2 uv = (floor(i.uv * _MainTex_TexelSize.zw) + 0.5 + offset) * _MainTex_TexelSize.xy;
    Otherwise you can mix DX9 and DX11 HLSL, you just need to define your textures in a different way, then you can use Load() which is the DX11 equivalent.
    Code (csharp):
    1. // outside of the shader function
    2. texure2D _MainTex; // use this instead of sampler2D
    3.  
    4. // in shader function
    5. float3 n = _MainTex.Load((i.uv * _MainTex_TexelSize.zw) + offset).xyz;
     
  3. zhutianlun810

    zhutianlun810

    Joined:
    Sep 17, 2017
    Posts:
    162
    Thanks for your answer.
    But the second method seems not work. My offset is float2 type and i.uv is a float2 type. But the editor warn me that it need a int3 type?

    Shader error in 'Unlit/estimateGaussian': 'Load': no matching 1 parameter intrinsic method; Possible intrinsic methods are: Texture2D<float4>.Load(int3) Texture2D<float4>.Load(int3, int2) Texture2D<float4>.Load(int3, int2, out uint status) at line 57 (on d3d11)


    I am confused that why do I need a int3 to sample a texture. A texture is a 2D image. So it does not nake sense to me to use a int3 to sample a texture.

    And what is tex2D(sampler2d, i.uv)'s equivalence in dx11?
     
    Last edited: Mar 6, 2019
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,236
    Oops, right.

    _MainTex.Load(int3(uv, 0));

    Because you need to select the mip map. GLSL's fetch has the same thing, that's the trailing zero on that call.

    Technically you can also provide an explicit offset using that "int3, int2" form the error message mentions.
    _MainTex.Load(int3(i.uv.xy * _MainTex_TexelSize.zw, 0), offset)

    Sample.
    https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-to-sample
     
  5. zhutianlun810

    zhutianlun810

    Joined:
    Sep 17, 2017
    Posts:
    162
    Thanks, Bgolus. You are always such helpful.
     
  6. psomgeorg

    psomgeorg

    Joined:
    Mar 16, 2019
    Posts:
    99

    I wanted to use a texture which was created via a drawmeshinstancedindirect render (and it was the rendertexture) in my shader to see the result and used that command. However i get this kind of result. I just want to implement weighted order independent transparency and i have to render twice the particles and save them in a texture and sample that output to the main shader
    upload_2019-9-6_19-29-6.png
    This is the formula
     

    Attached Files:

  7. psomgeorg

    psomgeorg

    Joined:
    Mar 16, 2019
    Posts:
    99
    Also this is the output of the renderTexture if i set the render target to the camera.
    upload_2019-9-6_19-32-7.png
     
  8. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    Code (CSharp):
    1. Shader "Unlit/distributePoints"
    2. {
    3. Properties
    4. {
    5.   _MainTex("Texture", 2D) = "black" {}
    6. _Intensity("Intensity",Range(0,1)) = 1
    7.   g("Size",Range(1,10)) = 1
    8.   k("factor",Range(1,10)) = 1
    9. }
    10.   SubShader
    11. {
    12.   Tags { "RenderType" = "Opaque" }
    13.   LOD 100
    14.   Pass
    15.   {
    16.   Name "Update"
    17.    CGPROGRAM
    18.    #pragma vertex vert
    19.    #pragma fragment frag
    20.    // make fog work
    21.    #pragma multi_compile_fog
    22.    #include "UnityCG.cginc"
    23. //  #include "UnityCustomRenderTexture.cginc"
    24.    struct appdata
    25.    {
    26.     float4 vertex : POSITION;
    27.     float2 uv : TEXCOORD0;
    28.    };
    29.    struct v2f
    30.    {
    31.     float2 uv : TEXCOORD0;
    32.     UNITY_FOG_COORDS(1)
    33.     float4 vertex : SV_POSITION;
    34.    };
    35.    sampler2D _MainTex;
    36.    float4 _MainTex_ST, _MainTex_TexelSize;
    37.    float _Intensity;
    38.     float g,k;
    39.    v2f vert(appdata v)
    40.    {
    41.     v2f o;
    42.     o.vertex = UnityObjectToClipPos(v.vertex);
    43.     o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    44.     UNITY_TRANSFER_FOG(o,o.vertex);
    45.     return o;
    46.    }
    47.     fixed4 frag(v2f i) : SV_Target
    48.      {
    49.       // sample the texture
    50.       fixed4 col = tex2D(_MainTex, i.uv);
    51.     col = 0;
    52.  
    53.      float2 R=_MainTex_TexelSize.zw;
    54.  
    55.        float2 fragCoord = (i.uv *R);
    56.    
    57.       //float g = floor(size*R.y /1024.0);
    58.    
    59.  
    60.       float   r = g * k;
    61.    
    62.    
    63.      float  d = 0.66* fragCoord.x / R.x / k + _Intensity;
    64.  
    65.       int n = floor(k);
    66.  
    67.       float t = 1e9, v, _t;
    68.       float2 V, P, _P;
    69.       for (int j = 0;j < n*n;j++)
    70.       {
    71.        V = fragCoord / g + float2(j%n, ((float)j) / n);
    72.       // float2 uv =V / R;
    73.        //v = tex2D(_MainTex, uv).r;
    74.  
    75.    
    76.      
    77.        fragCoord = (floor(V/R * _MainTex_TexelSize.zw) + 0.5) * _MainTex_TexelSize.xy;
    78.        v = tex2Dlod(_MainTex, float4(fragCoord, 0, 0)).x;
    79.      
    80.  
    81.        if (v < t)
    82.        {
    83.         _t = t;
    84.         t = v;
    85.         _P = P;
    86.         P = V;
    87.        }
    88.        else if (v < _t)
    89.        {
    90.         _t = v;
    91.         _P = V;
    92.        }
    93.       }
    94.    
    95.       // t = tex2D(_MainTex, i.uv).r;
    96.    
    97.  
    98.       if (t < d)
    99.       {
    100. #define distx      length(2.*frac(fragCoord / r) - 1.0)
    101. #define dist      length( 2.* frac( ( ceil(P) - fragCoord/g ) / k )  - 1. )
    102. #define shape(v)  smoothstep(1.,1.-4./r, v )      
    103. #define shapex(v)  0.5*max(0.,1.-v)    // disc shape
    104. #define hue(v)  (1. - 1.5*(v) * float4(.8,.6,1,0) )
    105.  
    106.      v = dist;
    107.        v = shape(v);
    108.        col += v * 1;
    109.        if (_t < d)
    110.        {
    111.         t = _t;
    112.         P = _P;
    113.         col += (1. - v) * shape(dist) * 1;
    114.        }
    115.      }
    116.  
    117.     return col;
    118.      }
    119.    
    120.  
    121.      ENDCG
    122.     }
    123. }
    124. }
    https://www.shadertoy.com/view/4ldczS, how about this texelFetch? This not work...
     
  9. flyer19

    flyer19

    Joined:
    Aug 26, 2016
    Posts:
    77
    confuse with this.