You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
4.1 KiB
115 lines
4.1 KiB
Shader "Hidden/kMotion/ObjectMotionVectors" |
|
{ |
|
SubShader |
|
{ |
|
Pass |
|
{ |
|
// Lightmode tag required setup motion vector parameters by C++ (legacy Unity) |
|
Tags{ "LightMode" = "MotionVectors" } |
|
|
|
HLSLPROGRAM |
|
// Required to compile gles 2.0 with standard srp library |
|
#pragma prefer_hlslcc gles |
|
#pragma exclude_renderers d3d11_9x |
|
#pragma target 3.0 |
|
|
|
//-------------------------------------- |
|
// GPU Instancing |
|
#pragma multi_compile_instancing |
|
|
|
#pragma vertex vert |
|
#pragma fragment frag |
|
|
|
// ------------------------------------- |
|
// Includes |
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" |
|
|
|
|
|
#if defined(USING_STEREO_MATRICES) |
|
float4x4 _PrevViewProjMStereo[2]; |
|
#define _PrevViewProjM _PrevViewProjMStereo[unity_StereoEyeIndex] |
|
#else |
|
#define _PrevViewProjM _PrevViewProjMatrix |
|
#endif |
|
|
|
// ------------------------------------- |
|
// Structs |
|
struct Attributes |
|
{ |
|
float4 position : POSITION; |
|
float3 positionOld : TEXCOORD4; |
|
UNITY_VERTEX_INPUT_INSTANCE_ID |
|
}; |
|
|
|
struct Varyings |
|
{ |
|
float4 positionCS : SV_POSITION; |
|
float4 positionVP : TEXCOORD0; |
|
float4 previousPositionVP : TEXCOORD1; |
|
UNITY_VERTEX_INPUT_INSTANCE_ID |
|
UNITY_VERTEX_OUTPUT_STEREO |
|
}; |
|
|
|
// ------------------------------------- |
|
// Vertex |
|
Varyings vert(Attributes input) |
|
{ |
|
Varyings output = (Varyings)0; |
|
|
|
UNITY_SETUP_INSTANCE_ID(input); |
|
UNITY_TRANSFER_INSTANCE_ID(input, output); |
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); |
|
|
|
output.positionCS = TransformObjectToHClip(input.position.xyz); |
|
|
|
// this works around an issue with dynamic batching |
|
// potentially remove in 5.4 when we use instancing |
|
#if defined(UNITY_REVERSED_Z) |
|
output.positionCS.z -= unity_MotionVectorsParams.z * output.positionCS.w; |
|
#else |
|
output.positionCS.z += unity_MotionVectorsParams.z * output.positionCS.w; |
|
#endif |
|
|
|
output.positionVP = mul(UNITY_MATRIX_VP, mul(UNITY_MATRIX_M, input.position)); |
|
|
|
const float4 prevPos = (unity_MotionVectorsParams.x == 1) ? float4(input.positionOld, 1) : input.position; |
|
output.previousPositionVP = mul(_PrevViewProjM, mul(unity_MatrixPreviousM, prevPos)); |
|
|
|
return output; |
|
} |
|
|
|
// ------------------------------------- |
|
// Fragment |
|
half4 frag(Varyings input) : SV_Target |
|
{ |
|
UNITY_SETUP_INSTANCE_ID(input); |
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); |
|
|
|
// Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled |
|
bool forceNoMotion = unity_MotionVectorsParams.y == 0.0; |
|
if (forceNoMotion) |
|
{ |
|
return float4(0.0, 0.0, 0.0, 0.0); |
|
} |
|
|
|
// Calculate positions |
|
float4 posVP = input.positionVP; |
|
float4 prevPosVP = input.previousPositionVP; |
|
posVP.xy *= rcp(posVP.w); |
|
prevPosVP.xy *= rcp(prevPosVP.w); |
|
|
|
// Calculate velocity |
|
float2 velocity = (posVP.xy - prevPosVP.xy); |
|
#if UNITY_UV_STARTS_AT_TOP |
|
velocity.y = -velocity.y; |
|
#endif |
|
|
|
// Convert from Clip space (-1..1) to NDC 0..1 space. |
|
// Note it doesn't mean we don't have negative value, we store negative or positive offset in NDC space. |
|
// Note: ((positionCS * 0.5 + 0.5) - (previousPositionCS * 0.5 + 0.5)) = (velocity * 0.5) |
|
return float4(velocity.xy * 0.5, 0, 0); |
|
} |
|
ENDHLSL |
|
} |
|
} |
|
}
|
|
|