123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- Shader "Hidden/Universal Render Pipeline/CameraMotionBlur"
- {
- Properties
- {
- _MainTex("Source", 2D) = "white" {}
- }
- HLSLINCLUDE
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
- TEXTURE2D_X(_MainTex);
- TEXTURE2D_X_FLOAT(_CameraDepthTexture);
- float4x4 _ViewProjM;
- float4x4 _PrevViewProjM;
- float _Intensity;
- float _Clamp;
- float4 _MainTex_TexelSize;
- struct VaryingsCMB
- {
- float4 positionCS : SV_POSITION;
- float4 uv : TEXCOORD0;
- UNITY_VERTEX_OUTPUT_STEREO
- };
- VaryingsCMB VertCMB(Attributes input)
- {
- VaryingsCMB output;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
- output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
- float4 projPos = output.positionCS * 0.5;
- projPos.xy = projPos.xy + projPos.w;
- output.uv.xy = input.uv;
- output.uv.zw = projPos.xy;
- return output;
- }
- float2 ClampVelocity(float2 velocity, float maxVelocity)
- {
- float len = length(velocity);
- return (len > 0.0) ? min(len, maxVelocity) * (velocity * rcp(len)) : 0.0;
- }
- // Per-pixel camera velocity
- float2 GetCameraVelocity(float4 uv)
- {
- float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, uv.xy).r;
- #if UNITY_REVERSED_Z
- depth = 1.0 - depth;
- #endif
- depth = 2.0 * depth - 1.0;
- float3 viewPos = ComputeViewSpacePosition(uv.zw, depth, unity_CameraInvProjection);
- float4 worldPos = float4(mul(unity_CameraToWorld, float4(viewPos, 1.0)).xyz, 1.0);
- float4 prevPos = worldPos;
- float4 prevClipPos = mul(_PrevViewProjM, prevPos);
- float4 curClipPos = mul(_ViewProjM, worldPos);
- float2 prevPosCS = prevClipPos.xy / prevClipPos.w;
- float2 curPosCS = curClipPos.xy / curClipPos.w;
- return ClampVelocity(prevPosCS - curPosCS, _Clamp);
- }
- float3 GatherSample(float sampleNumber, float2 velocity, float invSampleCount, float2 centerUV, float randomVal, float velocitySign)
- {
- float offsetLength = (sampleNumber + 0.5) + (velocitySign * (randomVal - 0.5));
- float2 sampleUV = centerUV + (offsetLength * invSampleCount) * velocity * velocitySign;
- return SAMPLE_TEXTURE2D_X(_MainTex, sampler_PointClamp, sampleUV).xyz;
- }
- half4 DoMotionBlur(VaryingsCMB input, int iterations)
- {
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
- float2 uv = UnityStereoTransformScreenSpaceTex(input.uv.xy);
- float2 velocity = GetCameraVelocity(float4(uv, input.uv.zw)) * _Intensity;
- float randomVal = InterleavedGradientNoise(uv * _MainTex_TexelSize.zw, 0);
- float invSampleCount = rcp(iterations * 2.0);
- half3 color = 0.0;
- UNITY_UNROLL
- for (int i = 0; i < iterations; i++)
- {
- color += GatherSample(i, velocity, invSampleCount, uv, randomVal, -1.0);
- color += GatherSample(i, velocity, invSampleCount, uv, randomVal, 1.0);
- }
- return half4(color * invSampleCount, 1.0);
- }
- ENDHLSL
- SubShader
- {
- Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
- LOD 100
- ZTest Always ZWrite Off Cull Off
- Pass
- {
- Name "Camera Motion Blur - Low Quality"
- HLSLPROGRAM
- #pragma vertex VertCMB
- #pragma fragment Frag
- half4 Frag(VaryingsCMB input) : SV_Target
- {
- return DoMotionBlur(input, 2);
- }
- ENDHLSL
- }
- Pass
- {
- Name "Camera Motion Blur - Medium Quality"
- HLSLPROGRAM
- #pragma vertex VertCMB
- #pragma fragment Frag
- half4 Frag(VaryingsCMB input) : SV_Target
- {
- return DoMotionBlur(input, 3);
- }
- ENDHLSL
- }
- Pass
- {
- Name "Camera Motion Blur - High Quality"
- HLSLPROGRAM
- #pragma vertex VertCMB
- #pragma fragment Frag
- half4 Frag(VaryingsCMB input) : SV_Target
- {
- return DoMotionBlur(input, 4);
- }
- ENDHLSL
- }
- }
- }
|