Skip to content

Instantly share code, notes, and snippets.

@unitycoder
Forked from bgolus/PostDepthToWorldPos.shader
Created October 24, 2023 20:44
Show Gist options
  • Select an option

  • Save unitycoder/75668350667567a36dcdf23f07e93e22 to your computer and use it in GitHub Desktop.

Select an option

Save unitycoder/75668350667567a36dcdf23f07e93e22 to your computer and use it in GitHub Desktop.

Revisions

  1. @bgolus bgolus created this gist Oct 24, 2023.
    92 changes: 92 additions & 0 deletions PostDepthToWorldPos.shader
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    Shader "PostDepthToWorldPos"
    {
    Properties
    {
    }
    SubShader
    {
    Tags { "RenderType"="Transparent" "Queue"="Transparent" }
    LOD 100

    Pass
    {
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    #include "UnityCG.cginc"

    struct appdata
    {
    float4 vertex : POSITION;
    };

    struct v2f
    {
    float4 pos : SV_POSITION;
    };

    v2f vert (appdata v)
    {
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    return o;
    }

    UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
    float4 _CameraDepthTexture_TexelSize;

    // Reconstructs view position from just the pixel position and the camera depth texture
    float3 viewSpacePosAtPixelPosition(float2 vpos)
    {
    float2 uv = vpos * _CameraDepthTexture_TexelSize.xy;
    float3 viewSpaceRay = mul(unity_CameraInvProjection, float4(uv * 2.0 - 1.0, 1.0, 1.0) * _ProjectionParams.z);
    #if UNITY_UV_STARTS_AT_TOP
    uv.y = (1.0 - uv.y);
    uv.y = (uv.y - 0.5) * _ProjectionParams.x + 0.5;
    #endif
    float rawDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(uv, 0.0, 0.0));
    return viewSpaceRay * Linear01Depth(rawDepth);
    }

    // Checks if depth texture is at the far clipping plane
    bool isSkyAtPixelPosition(float2 vpos)
    {
    float2 uv = vpos * _CameraDepthTexture_TexelSize.xy;
    #if UNITY_UV_STARTS_AT_TOP
    uv.y = (1.0 - uv.y);
    uv.y = (uv.y - 0.5) * _ProjectionParams.x + 0.5;
    #endif
    float rawDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(uv, 0.0, 0.0));
    #if UNITY_REVERSED_Z
    bool sky = rawDepth <= 0.0;
    #else
    bool sky = rawDepth >= 1.0;
    #endif
    return sky;
    }

    float3 drawXYZGrid(float3 pos)
    {
    float3 fw = max(fwidth(pos), 0.0001);
    float3 lineWidth = max(0.05, fw);
    float3 grid = 1.0 - abs(frac(pos) * 2.0 - 1.0);
    return smoothstep(lineWidth + fw * 1.5, lineWidth - fw * 1.5, grid);
    }

    fixed4 frag (v2f i) : SV_Target
    {
    float3 viewPos = viewSpacePosAtPixelPosition(i.pos.xy);

    // Camera space and view space are flipped on the Z axis
    float3 worldPos = mul(unity_CameraToWorld, float4(viewPos * float3(1.0, 1.0,-1.0), 1.0));

    float3 col = drawXYZGrid(worldPos);
    col *= isSkyAtPixelPosition(i.pos) ? 0.0 : 1.0;

    return float4(col, 1.0);
    }
    ENDCG
    }
    }
    }