Search Unity

Problem with moving tiled texture for screen-space snow effect

Discussion in 'Shaders' started by illinoischan, Jul 18, 2019.

  1. illinoischan

    illinoischan

    Joined:
    Jul 18, 2019
    Posts:
    2
    I can't seem to figure out how to make it so the tiled texture does not follow the camera... It's a shader that creates snow in screen space. Here's a video of what I'm talking about:



    Here's the frag code in question:
    Code (CSharp):
    1. half4 frag (v2f i) : SV_Target
    2.             {
    3.                 half3 normal;
    4.                 float depth;
    5.                 DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, i.uv), depth, normal);
    6.                 normal = mul((float3x3)_CamToWorld, normal);
    7.                 // find out snow amount
    8.                 half snowAmount = normal.g;
    9.                 half scale = (_BottomThreshold + 1 - _TopThreshold) / 1 + 1;
    10.                 snowAmount = saturate( (snowAmount - _BottomThreshold) * scale);
    11.                 // find out snow color
    12.                 float2 p11_22 = float2(unity_CameraProjection._11, unity_CameraProjection._22);
    13.                 float3 vpos = float3( (i.uv * 2 - 1) / p11_22, -1) * depth;
    14.                 float4 wpos = mul(_CamToWorld, float4(vpos, 1));
    15.                 wpos += float4(_WorldSpaceCameraPos, 0) / _ProjectionParams.x;
    16.                 wpos *= _SnowTexScale * _ProjectionParams.z;
    17.                 half4 snowColor = tex2D(_SnowTex, wpos.xz) * _SnowColor;
    18.                 // get color and lerp to snow texture
    19.                 half4 col = tex2D(_MainTex, i.uv);
    20.                 return lerp(col, snowColor, snowAmount);
    21.             }
    Is there anyway to 'fix the uvs' so that the texture does not move with the camera? Also for bonus points I'm also thinking of adding shadows to this as well, but not really sure how to do that either.
    Thanks!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    7,003
    Remove this line, this is what's making it follow the camera:
    wpos += float4(_WorldSpaceCameraPos, 0) / _ProjectionParams.x;

    That's a lot harder. Borderline impossible depending on your setup. Basically, if you're using any baked lighting, there's no way to do it at all as a purely screen space based effect.

    For real time lighting, if your running this shader as part of the opaque queue, you should be able to access the screen space shadow texture trivially. You just need to make your shader work like any other opaque lit shader.
    https://catlikecoding.com/unity/tutorials/rendering/part-7/

    Alternatively, if you're using the deferred rendering path, you can make things work like a full screen deferred decal and directly modify the gbuffers. Then real time or masked shadows will apply automatically.
     
  3. illinoischan

    illinoischan

    Joined:
    Jul 18, 2019
    Posts:
    2
    The reason the line of code is in is there is because without it there's a a weird scrolling behaviour which seems to get worse the more the camera looks down, so I think the line is necessary in the way this is currently implemented.

    Is there perhaps a way I can 'counter' the motion of the camera and then scroll the UV in the opposite direction?