您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

241 行
7.8 KiB

Shader "Hidden/HDRenderPipeline/FinalPass"
{
Properties
{
_MainTex ("Texture", any) = "" {}
}
HLSLINCLUDE
#pragma target 4.5
#include "Color.hlsl"
#include "Common.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl"
#include "ColorGrading.hlsl"
#include "Bloom.hlsl"
TEXTURE2D(_MainTex);
SAMPLER2D(sampler_MainTex);
float4 _MainTex_TexelSize;
TEXTURE2D(_AutoExposure);
SAMPLER2D(sampler_AutoExposure);
TEXTURE2D(_LogLut);
SAMPLER2D(sampler_LogLut);
float4 _LogLut_Params;
float _Exposure;
TEXTURE2D(_BloomTex);
SAMPLER2D(sampler_BloomTex);
float4 _BloomTex_TexelSize;
float2 _Bloom_Settings; // x: sampleScale, y: bloom.intensity
TEXTURE2D(_Bloom_DirtTex);
SAMPLER2D(sampler_Bloom_DirtTex);
float _Bloom_DirtIntensity;
float4 _NeutralTonemapperParams1;
float4 _NeutralTonemapperParams2;
float _ChromaticAberration_Amount;
TEXTURE2D(_ChromaticAberration_Lut);
SAMPLER2D(sampler_ChromaticAberration_Lut);
float3 _Vignette_Color;
float4 _Vignette_Settings; // x: intensity, y: smoothness, zw: center (uv space)
TEXTURE2D(_DitheringTex);
SAMPLER2D(sampler_DitheringTex);
float4 _DitheringCoords;
struct Attributes
{
float3 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.vertex = TransformWorldToHClip(input.vertex);
output.texcoord = input.texcoord.xy;
return output;
}
// Neutral tonemapping (Hable/Hejl/Frostbite)
// Input is linear RGB
float3 NeutralCurve(float3 x, float a, float b, float c, float d, float e, float f)
{
return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
}
float3 NeutralTonemap(float3 x, float4 params1, float4 params2)
{
// ACES supports negative color values and WILL output negative values when coming from ACES or ACEScg
// Make sure negative channels are clamped to 0.0 as this neutral tonemapper can't deal with them properly
x = max((0.0).xxx, x);
// Tonemap
float a = params1.x;
float b = params1.y;
float c = params1.z;
float d = params1.w;
float e = params2.x;
float f = params2.y;
float whiteLevel = params2.z;
float whiteClip = params2.w;
float3 whiteScale = (1.0).xxx / NeutralCurve(whiteLevel, a, b, c, d, e, f);
x = NeutralCurve(x * whiteScale, a, b, c, d, e, f);
x *= whiteScale;
// Post-curve white point adjustment
x /= whiteClip.xxx;
return x;
}
float4 Frag(Varyings input) : SV_Target
{
float2 uv = input.texcoord;
float3 color = (0.0).xxx;
// Chromatic Aberration
// Inspired by the method described in "Rendering Inside" [Playdead 2016]
// https://twitter.com/pixelmager/status/717019757766123520
#if CHROMATIC_ABERRATION
{
float2 coords = 2.0 * uv - 1.0;
float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;
float2 diff = end - uv;
int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, 16);
float2 delta = diff / samples;
float2 pos = uv;
float3 sum = (0.0).xxx, filterSum = (0.0).xxx;
for (int i = 0; i < samples; i++)
{
float t = (i + 0.5) / samples;
float3 s = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, pos, 0).rgb;
float3 filter = SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_Lut, sampler_ChromaticAberration_Lut, float2(t, 0.0), 0).rgb;
sum += s * filter;
filterSum += filter;
pos += delta;
}
color = sum / filterSum;
}
#else
{
color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv).rgb;
}
#endif
#if EYE_ADAPTATION
{
float autoExposure = SAMPLE_TEXTURE2D(_AutoExposure, sampler_AutoExposure, uv).r;
color *= autoExposure;
}
#endif
#if BLOOM
{
float3 bloom = UpsampleFilter(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uv, _BloomTex_TexelSize.xy, _Bloom_Settings.x) * _Bloom_Settings.y; // Flipped
color += bloom;
#if BLOOM_LENS_DIRT
{
float3 dirt = SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, uv).rgb * _Bloom_DirtIntensity; // Flipped
color += bloom * dirt;
}
#endif
}
#endif
#if VIGNETTE
{
float2 d = abs(uv - _Vignette_Settings.zw) * _Vignette_Settings.x;
d.x *= _ScreenParams.x / _ScreenParams.y;
float vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y);
color *= lerp(_Vignette_Color, (1.0).xxx, vfactor);
}
#endif
color *= _Exposure; // Exposure is in ev units (or 'stops'), precomputed CPU-side
#if NEUTRAL_GRADING
{
color = NeutralTonemap(color, _NeutralTonemapperParams1, _NeutralTonemapperParams2);
}
#elif CUSTOM_GRADING
{
float3 uvw = saturate(LinearToLogC(color));
// Strip lut format where `height = sqrt(width)`
uvw.z *= _LogLut_Params.z;
float shift = floor(uvw.z);
uvw.xy = uvw.xy * _LogLut_Params.z * _LogLut_Params.xy + _LogLut_Params.xy * 0.5;
uvw.x += shift * _LogLut_Params.y;
uvw.xyz = lerp(
SAMPLE_TEXTURE2D(_LogLut, sampler_LogLut, uvw.xy).rgb,
SAMPLE_TEXTURE2D(_LogLut, sampler_LogLut, uvw.xy + float2(_LogLut_Params.y, 0)).rgb,
uvw.z - shift
);
color = uvw;
}
#else
{
color = saturate(color);
}
#endif
#if DITHERING
{
// Symmetric triangular distribution on [-1,1] with maximal density at 0
float noise = SAMPLE_TEXTURE2D(_DitheringTex, sampler_DitheringTex, uv * _DitheringCoords.xy + _DitheringCoords.zw).a * 2.0 - 1.0;
noise = sign(noise) * (1.0 - sqrt(1.0 - abs(noise)));
color = SRGBToLinear(LinearToSRGB(color) + noise / 255.0);
}
#endif
return float4(color, 1.0);
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma multi_compile __ NEUTRAL_GRADING CUSTOM_GRADING
#pragma multi_compile __ EYE_ADAPTATION
#pragma multi_compile __ BLOOM
#pragma multi_compile __ BLOOM_LENS_DIRT
#pragma multi_compile __ CHROMATIC_ABERRATION
#pragma multi_compile __ VIGNETTE
#pragma multi_compile __ DITHERING
ENDHLSL
}
}
Fallback Off
}