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.
 
 
 

101 lines
3.6 KiB

Shader "Custom/TiltShift"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
ZTest Always ZWrite Off Cull Off Blend Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
float _TiltShift_CenterOffset;
float _TiltShift_FocusWidth;
float _TiltShift_FalloffRange;
float _TiltShift_MaxBlurRadius;
int _TiltShift_SampleCount;
// _BlitTexture and _BlitTexture_TexelSize are provided by Blit.hlsl
// _BlitTexture_TexelSize: (1/w, 1/h, w, h)
// sampler_LinearClamp is provided by GlobalSamplers.hlsl (included via Blit.hlsl)
// Returns blur radius in pixels for a given vertical UV coordinate.
float ComputeBlurRadius(float uvY)
{
float dist = abs(uvY - 0.5 + _TiltShift_CenterOffset);
float halfFocus = _TiltShift_FocusWidth * 0.5;
float range = max(_TiltShift_FalloffRange, 0.001);
return smoothstep(halfFocus, halfFocus + range, dist) * _TiltShift_MaxBlurRadius;
}
// Gaussian blur in an arbitrary direction.
// direction: offset per sample step in UV space (already multiplied by texelSize)
float4 GaussianBlur(float2 uv, float2 stepUV)
{
int n = max(1, _TiltShift_SampleCount);
float4 color = 0;
float totalWeight = 0;
[loop]
for (int i = -n; i <= n; i++)
{
// t in [-1, 1]; weight peaks at centre and falls near edges.
float t = float(i) / float(n);
float weight = exp(-4.5 * t * t);
float2 sampleUV = uv + stepUV * float(i);
color += SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearClamp, sampleUV, 0) * weight;
totalWeight += weight;
}
return color / totalWeight;
}
float4 HorizontalBlur(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
float radius = ComputeBlurRadius(uv.y);
if (radius < 0.5)
return SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearClamp, uv, 0);
// stepUV: one step in the horizontal direction, spread over [−radius, +radius] pixels
int n = max(1, _TiltShift_SampleCount);
float2 stepUV = float2((radius / float(n)) * _BlitTexture_TexelSize.x, 0.0);
return GaussianBlur(uv, stepUV);
}
float4 VerticalBlur(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
float radius = ComputeBlurRadius(uv.y);
if (radius < 0.5)
return SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearClamp, uv, 0);
int n = max(1, _TiltShift_SampleCount);
float2 stepUV = float2(0.0, (radius / float(n)) * _BlitTexture_TexelSize.y);
return GaussianBlur(uv, stepUV);
}
ENDHLSL
// Pass 0 — Horizontal blur
Pass
{
Name "TiltShift_H"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment HorizontalBlur
ENDHLSL
}
// Pass 1 — Vertical blur
Pass
{
Name "TiltShift_V"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment VerticalBlur
ENDHLSL
}
}
}