Search Unity

Is it possible to apply a uv offset with world space coordinates?

Discussion in 'Shaders' started by Julian_Nementic, May 10, 2019.

  1. Julian_Nementic

    Julian_Nementic

    Joined:
    Jan 10, 2014
    Posts:
    9
    I am trying to create fake 2D drop shadows for a game with sprites on different z-layers and a perspective camera. The current setup looks like this:

    2D-FakeShadows.PNG
    The blue and red rectangles represent walls which receive a fake shadow. The Shadow is actually just a sheared quad. Because we would like to fake a simple perspective, I offset the UVs of the shadow object by an amount determined via its z-depth. The depth is rendered with a simple second camera to a RenderTexture.

    The current shader code achieve roughly what we would like the effect to look, but there is an issue, because the uv offset scales with the size of the shadow object, which means that bigger shadows are offset a larger amount.

    This sounds like it should be easily fixed, if the offset would not be applied directly in uv space, but actually transformed in a way that scales with the world space position/size so that the offset is constant in world space and not dependent on the shadow size.

    Code (csharp):
    1. fixed4 depthBuffer = tex2D(_DepthTexture, screenPos);
    2.  
    3. float rangeMin = -10;
    4. float rangeMax = 50;
    5. fixed depth = 1 - saturate((IN.worldPos.z - rangeMin) / (rangeMax - rangeMin));
    6.  
    7. float dif = (depth -  depthBuffer.x);
    8.  
    9. float normalizedXoffset = 0.25; // one side max 0.25
    10. float normalizedYoffset = 0.5; // max 0.5
    11.  
    12. float xscale = 1 / (1 - normalizedXoffset * 2);
    13. float yscale = 1 / (1 - normalizedYoffset);
    14.  
    15. // Scale the UV, so there is place to shift the uvs
    16. float2 uv = (IN.texcoord * float2(xscale, yscale ) - float2((xscale-1)/2, 0));
    17.  
    18. //Offset the UV dependent on the y depth
    19. float depthOffsetX = dif * _ShadowOffsetScaleX;
    20. float depthOffsetY = dif * _ShadowOffsetScaleY;
    21.  
    22. // Here we offset the uv by an amount determined via the z-depth.
    23. // However, this scales with the size of the shadows, which we don't want.
    24. uv += float2(depthOffsetX, depthOffsetY);
    25.  
    26. // Idea: Can we transform between uv and world space so that we can apply the
    27. // offset in world space or scale the offset by an amount determined via the
    28. // world space position similar to this?
    29. // uvWorld = ConvertToWorld(uv)
    30. // uvWorld += float2(depthOffsetX, depthOffsetY);
    31. // uv = ConvertToUV(uvWorld);