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

Can see grid lines with projector

Discussion in 'Shaders' started by Uthgaard, Feb 4, 2021.

  1. Uthgaard

    Uthgaard

    Joined:
    Dec 17, 2020
    Posts:
    25
    I'm trying to generate caustics, and have tried three different ways. I was not able to get the projectors in the Unity Standard assets to respond to tiling changes, and I lacked the knowledge to figure out why. So I applied a shader I found on stackexchange to the projector. (Code at end of post).

    This shader does exactly what I want, and responds to tiling changes as I'd expect it to. But the problem is that it shows visible grid lines between the textures and I'm not sure why.

    Any assistance figuring out how to properly tile with the Unity Standard Asset projector's default shader, or to get rid of these grid lines in this shader would be much appreciated.

    upload_2021-2-4_4-24-52.png

    Code (CSharp):
    1. Shader "Projector/ProjectorCaustics"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,1,1,0)
    6.         _ShadowTex("Cookie", 2D) = "" {}
    7.         _Size("Grid Size", Float) = 1
    8.     }
    9.         SubShader
    10.         {
    11.         Tags { "RenderType" = "Transparent" "Queue" = "Transparent+100" }
    12.         Pass {
    13.           ZWrite Off
    14.           //Offset - 1, -1
    15.           Fog { Mode Off }
    16.             //ColorMask RGB
    17.             //Blend SrcAlpha OneMinusSrcAlpha
    18.             Blend DstColor One
    19.  
    20.             CGPROGRAM
    21.             #pragma vertex vert
    22.             #pragma fragment frag
    23.             #pragma fragmentoption ARB_fog_exp2
    24.             #pragma fragmentoption ARB_precision_hint_fastest
    25.             #include "UnityCG.cginc"
    26.  
    27.             struct v2f {
    28.              float4 pos : SV_POSITION;
    29.              float2 uv : TEXCOORD0;
    30.             };
    31.  
    32.             uniform sampler2D _ShadowTex;
    33.             float4 _ShadowTex_ST;
    34.             float4 _Color;
    35.             float4x4 unity_Projector;
    36.             fixed _Size;
    37.  
    38.             v2f vert(appdata_tan v) {
    39.              v2f o;
    40.              o.pos = UnityObjectToClipPos(v.vertex);
    41.              o.uv = TRANSFORM_TEX(mul(unity_Projector, v.vertex).xy, _ShadowTex);
    42.              return o;
    43.             }
    44.  
    45.             fixed4 frag(v2f i) : COLOR {
    46.              if (i.uv.x < 1 && i.uv.y < 1)
    47.                  return tex2D(_ShadowTex, fmod(i.uv, 1 / _Size) * _Size) * _Color;
    48.              else
    49.                  return fixed4(0,0,0,0);
    50.             }
    51.         ENDCG
    52.     }
    53.   }
    54. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    The seams are caused by having UVs that have discontinuities interacting with how the GPU determines mip maps. To determine the appropriate mip level GPUs use screen space pixel derivatives, or the difference between one pixel and the ones around it, to see how much the UV value is changing. If there's a sudden large change, it'll drop to a much lower mip level for those pixels. In your case you're using
    fmod()
    which is what's causing the discontinuity.

    I write a bit more about it here in the context of
    frac()
    , though the end result and the solution are the same:
    https://forum.unity.com/threads/str...lines-along-quad-borders.795870/#post-5296011
     
    Uthgaard likes this.
  3. Uthgaard

    Uthgaard

    Joined:
    Dec 17, 2020
    Posts:
    25
    Thanks for the in-depth explanation and link. To be honest shaders are way beyond my level of understanding right now, and I really don't understand the syntax at all. It's mostly done out of necessity. I tried taking the code from one and bringing it into the other, but they used different methods and it broke everything until it was hot pink. I'll just keep trying copy and paste shaders until I get one that works.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    You want to replace
    tex2D
    with
    tex2Dgrad
    . The “trick” is the
    ddx
    and
    ddy
    need to use
    i.uv * _Size
    so the UVs it’s using have the same “scale” as those you’re using for the texture sampling itself.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    Code (CSharp):
    1. if (i.uv.x < 1 && i.uv.y < 1)
    2. {
    3.     float2 dx = ddx(i.uv * _Size);
    4.     float2 dy = ddy(i.uv * _Size);
    5.     return tex2Dgrad(_ShadowTex, fmod(i.uv, 1 / _Size) * _Size, dx, dy) * _Color;
    6. }
    7. else
    8.     return fixed4(0,0,0,0);
     
  6. Uthgaard

    Uthgaard

    Joined:
    Dec 17, 2020
    Posts:
    25
    I got it to work! Thank you! Now to sort out god rays. The Unity Standard Assets collection is kind of a mess right now.

    Speaking of which, I don't suppose you'd know what keeps causing this error? Every time I make a change or import a file this error gets thrown. This shader isn't even used in my project anymore so I'll probably just delete it. But curiosity.

    Code (CSharp):
    1. Shader error in 'Projector/Light': undeclared identifier 'IN' at line 55 (on d3d11)
    And this is line 55.
    Code (CSharp):
    1. fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
     
    Last edited: Feb 5, 2021