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