- 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
}