- Home /
 
"Motion vectors" and "depth with normals" from camera's target texture
Is there a way to get motion vectors and depth with normals from camera by it's target texture, or in some other way? I cannot use global shader variables _CameraMotionVectorsTexture and _CameraDepthNormalsTexture because I use two cameras. I want to access only data from my second camera and not from the main camera. Thanks in advance.
Answer by MichaI · Sep 23, 2019 at 07:42 PM
Ok, I figured it out, I used OnRenderImage method and called inside Graphics.Blit with material that using my shader, inside which I am getting this textures through _CameraMotionVectorsTexture, and _CameraDepthNormalsTexture samplers (in my case _CameraDepthNormalsTexture didn't worked so I used _LastCameraDepthNormalsTexture). Inside fragment shader I combine them and return to target texture. But motion vector texture gives me weird results and I don't know exactly how to use it. At least I managed to get to work normals with depth. I post code and shader in case someone needs it.
Code:
 public Camera Cam
 {
    get
    {
         if(_cam == null)
         {
             _cam = GetComponent<Camera>();
         }
         return _cam;
    }
    set
    {
         _cam = value;
     }
 }
 private Camera _cam;
     
 protected void Awake()
 {
     Cam.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.DepthNormals;
 }
     
 private Material _onRenderMaterial;
 protected Material OnRenderMaterial
 {
     get
     {
         if(null == _onRenderMaterial)
         {
             _onRenderMaterial = new Material(Shader.Find("Hidden/GrassPhysics/OnRenderCamera"));
         }
         return _onRenderMaterial;
     }
 }
     
 private void OnRenderImage(RenderTexture source, RenderTexture destination)
 {
     Matrix4x4 viewToWorld = Cam.cameraToWorldMatrix;
     OnRenderMaterial.SetMatrix("_viewToWorld", viewToWorld);
     Graphics.Blit(source, destination, OnRenderMaterial);
 }
 
               Shader:
 Shader "Hidden/GrassPhysics/OnRenderCamera" {
 
     Properties
     {
     }
     SubShader
     {
         Cull Off
         ZWrite Off
         ZTest Always
 
         Pass
         {
             CGPROGRAM
             #pragma vertex vertexShader
             #pragma fragment fragmentShader
 
             #include "UnityCG.cginc"
 
             struct vertexInput
             {
             float4 vertex : POSITION;
             float2 uv : TEXCOORD0;
             };
 
             struct vertexOutput
             {
             float2 uv : TEXCOORD0;
             float4 position : SV_POSITION;
             };
 
             vertexOutput vertexShader(vertexInput i)
             {
             vertexOutput o;
             o.position = UnityObjectToClipPos(i.vertex);
             o.uv = i.uv;
             return o;
             }
 
             uniform sampler2D _CameraMotionVectorsTexture;
             uniform sampler2D _LastCameraDepthNormalsTexture;
             float4x4 _viewToWorld;
 
             float4 fragmentShader(vertexOutput i) : SV_TARGET
             {
                 float4 col = tex2D(_LastCameraDepthNormalsTexture, i.uv);
 
                 //decode depthnormal
                 float3 normal;
                 float depth;
                 DecodeDepthNormal(col, depth, normal);
 #ifdef UNITY_REVERSED_Z
                 depth = 1 - depth;
 #endif
                 normal = mul((float3x3)_viewToWorld, normal);
                 return float4(depth,normal.rb,1);
             }
             ENDCG
         }
     }
     Fallback Off
 }
 
                
              Your answer