Get world-wide position in the shader of the new PostProcessing Unity stack?

How to get the absolute position of xyz in the pixel world in the Unity New PostProcessing shader framework? Many thanks!

Shader "Hidden/Filter/Test" {
    HLSLINCLUDE
        #include "../../PostProcessing/Shaders/StdLib.hlsl"
        TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
        float4 Frag(VaryingsDefault i) : SV_Target {
            float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);

            // what the world position of this color pixel ...?

            return color;
        }
    ENDHLSL
    SubShader {
        Cull Off ZWrite Off ZTest Always
        Pass {
            HLSLPROGRAM
                #pragma vertex VertDefault
                #pragma fragment Frag
            ENDHLSL
        }
    }
}
+4
source share
1 answer

Lez said right In your comments:

You are missing the #include "UnityCG.cginc", which is required for most built-in functions, including access to macros UNITY_*.

but the problem is that you are using "UnityCG.cginc"PostProcessing stack 2 with the same functions. In Unity, the built-in shader.so I decide to find it in the standard unity of shaders:

In Unity Archive shader you can find UNITY_MATRIX_MVPInStandard\CGIncludes\UnityShaderVariables.cginc

#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

Using World Space

Shader "Hidden/Filter/Test" {
    HLSLINCLUDE
        #include "../../PostProcessing/Shaders/StdLib.hlsl"
        #define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

        TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);

                struct v2f {
                  float4 vertex : SV_POSITION;
                  float3 worldPos : TEXCOORD0;
                  float2 texcoord : TEXCOORD1;
                  float2 texcoordStereo : TEXCOORD2;
              };

            struct appdata {
                  float4 vertex : POSITION;
              };

            v2f VertDefault(appdata v) {
                  v2f o;

                  o.worldPos = mul (unity_ObjectToWorld, v.vertex);
                  o.vertex = float4(v.vertex.xy, 0.0, 1.0);
                  o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);

                #if UNITY_UV_STARTS_AT_TOP
                    o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
                #endif

                    o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
                  return o;
              }

              float4 Frag(v2f i) : SV_Target {
                  float worldPos = i.worldPos;

                  float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);

                  return float4(i.worldPos,1);
              }


            ENDHLSL
            SubShader {
            Cull Off ZWrite Off ZTest Always
            Pass {
            HLSLPROGRAM
                #pragma vertex VertDefault
                #pragma fragment Frag


            ENDHLSL
        }
    }
}

Adding a World Position to StdLib.hlsl

worldpos StdLib.hlsl, It In PostProcessing-2\Assets\PostProcessing\Shaders, :

StdLib.hlsl,

#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

struct VaryingsDefault
{
    float4 vertex : SV_POSITION;
    float2 texcoord : TEXCOORD0;
    float2 texcoordStereo : TEXCOORD1;
    float3 worldPos : TEXCOORD2;
};

VaryingsDefault VertDefault(AttributesDefault v)
{
    VaryingsDefault o;
    o.vertex = float4(v.vertex.xy, 0.0, 1.0);
    o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);
    o.worldPos = mul (unity_ObjectToWorld, v.vertex);

#if UNITY_UV_STARTS_AT_TOP
    o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif

    o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);

    return o;
}

, World Space Is Easy!

Shader "Hidden/Filter/Test" {
    HLSLINCLUDE
        #include "../../PostProcessing/Shaders/StdLib.hlsl"

        float4 Frag(VaryingsDefault i) : SV_Target {
            return float4(i.worldPos,1);//Using World Position!
        }


            ENDHLSL
            SubShader {
            Cull Off ZWrite Off ZTest Always
            Pass {
            HLSLPROGRAM
                #pragma vertex VertDefault
                #pragma fragment Frag


            ENDHLSL
        }
    }
}

Update

Image

https://www.youtube.com/watch?v=uMOOcmp6FrM

script :

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class DepthBuffToWorldPosDemo : MonoBehaviour
    {
        public Material material;
        private new Camera camera;
        private new Transform transform;

        private void Start()
        {
            camera = GetComponent<Camera>();
            transform = GetComponent<Transform>();
        }

         void OnRenderImage(RenderTexture source, RenderTexture destination)
        {

            // NOTE: code was ported from: https://gamedev.stackexchange.com/questions/131978/shader-reconstructing-position-from-depth-in-vr-through-projection-matrix

            var p = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
            p[2, 3] = p[3, 2] = 0.0f;
            p[3, 3] = 1.0f;
            var clipToWorld = Matrix4x4.Inverse(p * camera.worldToCameraMatrix) * Matrix4x4.TRS(new Vector3(0, 0, -p[2,2]), Quaternion.identity, Vector3.one);
            material.SetMatrix("clipToWorld", clipToWorld);

            Graphics.Blit(source, destination, material);

        }

}

Unity Postprocessing

Unity Shader:

Shader "Hidden/DepthBuffToWorldPos"
{

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 5.0

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float3 worldDirection : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

            float4x4 clipToWorld;

            v2f vert (appdata v)
            {
                v2f o;

                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;

                float4 clip = float4(o.vertex.xy, 0.0, 1.0);
                o.worldDirection = mul(clipToWorld, clip) - _WorldSpaceCameraPos;

                return o;
            }

            sampler2D_float _CameraDepthTexture;
            float4 _CameraDepthTexture_ST;

            float4 frag (v2f i) : SV_Target
            {
                float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
                depth = LinearEyeDepth(depth);
                float3 worldspace = i.worldDirection * depth + _WorldSpaceCameraPos;

                float4 color = float4(worldspace, 1.0);
                return color;
            }
            ENDCG
        }
    }
}

Shader "Hidden/Filter/Test" {
        HLSLINCLUDE
             #include "../../PostProcessing/Shaders/StdLib.hlsl"
            #define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)
            #include "HLSLSupport.cginc"
            #pragma fragmentoption ARB_precision_hint_nicest

            TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
            float4x4 clipToWorld;



                    struct v2f {
                      float4 vertex : SV_POSITION;
                     float3 worldDirection : TEXCOORD0;
                      float3 screenPos : TEXCOORD1;
                      float2 texcoord : TEXCOORD2;
                      float2 texcoordStereo : TEXCOORD3;

                  };

                struct appdata {
                      float4 vertex : POSITION;
                  };

                            sampler2D_float _CameraDepthTexture;
            float4 _CameraDepthTexture_ST;

                v2f VertDefault(appdata v) {
                      v2f o;

                      o.vertex = float4(v.vertex.xy, 0.0, 1.0);
                      o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);

                                    float4 clip = float4(o.vertex.xy, 0.0, 1.0);
                o.worldDirection = mul(clipToWorld, clip) - _WorldSpaceCameraPos;

                    #if UNITY_UV_STARTS_AT_TOP
                        o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
                    #endif

                      // Correct flip when rendering with a flipped projection matrix.
                      // (I've observed this differing between the Unity scene & game views)
                      o.screenPos.y *= _ProjectionParams.x;
                      o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                      o.screenPos = o.vertex.xyw;

                        o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
                      return o;
                  }

                  float4 Frag(v2f i) : SV_Target {
                float2 screenUV = (i.screenPos.xy / i.screenPos.z) * 0.5f + 0.5f;
                float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,screenUV);
                depth = LinearEyeDepth(depth);
                float3 worldspace = i.worldDirection * depth + _WorldSpaceCameraPos;

                float4 color = float4(worldspace, 1.0);
                return color;
                  }


                ENDHLSL
                SubShader {
                Cull Off ZWrite Off ZTest Always
                Pass {
                HLSLPROGRAM
                    #pragma vertex VertDefault
                    #pragma fragment Frag


                ENDHLSL
            }
        }
    }

StdLib.hlsl

StdLibFixed.hlsl

#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)
#include "HLSLSupport.cginc"
#pragma fragmentoption ARB_precision_hint_nicest

float4x4 clipToWorld;


struct VaryingsDefault
{
float4 vertex : SV_POSITION;
float3 worldDirection : TEXCOORD0;
float3 screenPos : TEXCOORD1;
float2 texcoord : TEXCOORD2;
float2 texcoordStereo : TEXCOORD3;
};



    sampler2D_float _CameraDepthTexture;
float4 _CameraDepthTexture_ST;



VaryingsDefault VertDefault(AttributesDefault v)
{
VaryingsDefault o;

o.vertex = float4(v.vertex.xy, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);

float4 clip = float4(o.vertex.xy, 0.0, 1.0);
o.worldDirection = mul(clipToWorld, clip) - _WorldSpaceCameraPos;

#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif

// Correct flip when rendering with a flipped projection matrix.
// (I've observed this differing between the Unity scene & game views)
o.screenPos.y *= _ProjectionParams.x;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.screenPos = o.vertex.xyw;


o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
return o;
}

, World Space Is Easy!

Shader "Hidden/Filter/Test" {
        HLSLINCLUDE
            #include "../StdLib.hlsl"


                  float4 Frag(v2f i) : SV_Target {
                float2 screenUV = (i.screenPos.xy / i.screenPos.z) * 0.5f + 0.5f;
                float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,screenUV);
                depth = LinearEyeDepth(depth);
                float3 worldspace = i.worldDirection * depth + _WorldSpaceCameraPos;

                float4 color = float4(worldspace, 1.0);
                return color;
                  }


                ENDHLSL
                SubShader {
                Cull Off ZWrite Off ZTest Always
                Pass {
                HLSLPROGRAM
                    #pragma vertex VertDefault
                    #pragma fragment Frag


                ENDHLSL
            }
        }
    }
+1

Source: https://habr.com/ru/post/1695251/


All Articles