380 lines
15 KiB
Plaintext
380 lines
15 KiB
Plaintext
Shader "PotaToon/UberPost"
|
||
{
|
||
HLSLINCLUDE
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||
#if UNITY_VERSION >= 202230
|
||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ScreenCoordOverride.hlsl"
|
||
#else
|
||
#include "./PotaToonUtilsFor2021.hlsl"
|
||
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
|
||
TEXTURE2D_X(_BlitTexture);
|
||
#endif
|
||
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
|
||
// #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DynamicScalingClamping.hlsl"
|
||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||
#include "./PotaToonToneMapping.hlsl"
|
||
#include "../ChracterShadow/CharacterShadowInput.hlsl"
|
||
|
||
#pragma multi_compile_local_fragment _ _ENABLE_ALPHA_OUTPUT
|
||
#pragma multi_compile_local_fragment _ _BLOOM_LQ _BLOOM_HQ _BLOOM_LQ_DIRT _BLOOM_HQ_DIRT
|
||
#pragma multi_compile_local_fragment _ _POTA_TOON_TONEMAP_NEUTRAL _POTA_TOON_TONEMAP_ACES _POTA_TOON_TONEMAP_FILMIC _POTA_TOON_TONEMAP_UCHIMURA _POTA_TOON_TONEMAP_TONY _POTA_TOON_TONEMAP_CUSTOM
|
||
|
||
TEXTURE2D_X(_Bloom_Texture);
|
||
TEXTURE2D(_LensDirt_Texture);
|
||
TEXTURE2D_X(_PotaToonCharMask);
|
||
|
||
float _PostExposure;
|
||
float _ScreenRimWidth;
|
||
float _CharGammaAdjust;
|
||
float _LensDirt_Intensity;
|
||
float _ScreenOutlineThickness;
|
||
float _ScreenOutlineEdgeStrength;
|
||
float4 _ScreenOutlineColor;
|
||
float4 _HueSatCon;
|
||
float4 _ColorFilter;
|
||
float4 _ColorBalance;
|
||
float4 _ScreenRimColor;
|
||
float4 _BloomTexture_TexelSize;
|
||
float4 _Bloom_Texture_TexelSize;
|
||
float4 _Bloom_Params;
|
||
float4 _LensDirt_Params;
|
||
|
||
#define BloomIntensity _Bloom_Params.x
|
||
#define BloomTint _Bloom_Params.yzw
|
||
#define LensDirtScale _LensDirt_Params.xy
|
||
#define LensDirtOffset _LensDirt_Params.zw
|
||
#define LensDirtIntensity _LensDirt_Intensity.x
|
||
#define MaxScreenRimDist _ScreenRimColor.a
|
||
#define AlphaScale 1.0
|
||
#define AlphaBias 0.0
|
||
|
||
// Hardcoded dependencies to reduce the number of variants
|
||
#if _BLOOM_LQ || _BLOOM_HQ || _BLOOM_LQ_DIRT || _BLOOM_HQ_DIRT
|
||
#define BLOOM
|
||
#if _BLOOM_LQ_DIRT || _BLOOM_HQ_DIRT
|
||
#define BLOOM_DIRT
|
||
#endif
|
||
#endif
|
||
|
||
void ApplyColorAdjustments(inout half3 colorLinear)
|
||
{
|
||
// White balance in LMS space
|
||
float3 colorLMS = LinearToLMS(colorLinear);
|
||
colorLMS *= _ColorBalance.xyz;
|
||
colorLinear = LMSToLinear(colorLMS);
|
||
|
||
// Do contrast in log after white balance
|
||
float3 colorLog = LinearToLogC(colorLinear);
|
||
colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
|
||
colorLinear = LogCToLinear(colorLog);
|
||
|
||
// Color filter is just an unclipped multiplier
|
||
colorLinear *= _ColorFilter.xyz;
|
||
|
||
// Do NOT feed negative values to the following color ops
|
||
colorLinear = max(0.0, colorLinear);
|
||
|
||
// HSV operations
|
||
float satMult = 1.0;
|
||
float3 hsv = RgbToHsv(colorLinear);
|
||
{
|
||
// Hue Shift & Hue Vs Hue
|
||
float hue = hsv.x + _HueSatCon.x;
|
||
hsv.x = RotateHue(hue, 0.0, 1.0);
|
||
}
|
||
colorLinear = HsvToRgb(hsv);
|
||
|
||
// Global saturation
|
||
float luma = GetLuminance(colorLinear);
|
||
colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
|
||
|
||
// We don't saturate the output (To preserve HDR)
|
||
colorLinear = max(0.0, colorLinear);
|
||
}
|
||
|
||
half4 PotaToonPostProcess(float2 uv)
|
||
{
|
||
bool isCharArea = SAMPLE_TEXTURE2D_X(_PotaToonCharMask, sampler_LinearClamp, uv).r > 0.5;
|
||
#if !defined(BLOOM)
|
||
if (!isCharArea)
|
||
clip(-1);
|
||
#endif
|
||
|
||
// NOTE: Hlsl specifies missing input.a to fill 1 (0 for .rgb).
|
||
// InputColor is a "bottom" layer for alpha output.
|
||
half4 inputColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
|
||
half3 color = inputColor.rgb;
|
||
|
||
#if UNITY_COLORSPACE_GAMMA
|
||
{
|
||
color = GetSRGBToLinear(color);
|
||
inputColor = GetSRGBToLinear(inputColor); // Deadcode removal if no effect on output color
|
||
}
|
||
#endif
|
||
|
||
// Bloom
|
||
#if defined(BLOOM)
|
||
{
|
||
float2 uvBloom = uv;
|
||
#if defined(SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
|
||
UNITY_BRANCH if (_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
|
||
{
|
||
uvBloom = RemapFoveatedRenderingNonUniformToLinear(uvBloom);
|
||
}
|
||
#endif
|
||
|
||
#if _BLOOM_HQ
|
||
half3 bloom = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_Bloom_Texture, sampler_LinearClamp), SCREEN_COORD_REMOVE_SCALEBIAS(uvBloom), _Bloom_Texture_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex).xyz;
|
||
#else
|
||
half3 bloom = SAMPLE_TEXTURE2D_X(_Bloom_Texture, sampler_LinearClamp, SCREEN_COORD_REMOVE_SCALEBIAS(uvBloom)).xyz;
|
||
#endif
|
||
|
||
#if UNITY_COLORSPACE_GAMMA
|
||
bloom *= bloom; // γ to linear
|
||
#endif
|
||
|
||
bloom *= BloomIntensity;
|
||
color += bloom * BloomTint;
|
||
|
||
#if defined(BLOOM_DIRT)
|
||
{
|
||
// UVs for the dirt texture should be DistortUV(uv * DirtScale + DirtOffset) but
|
||
// considering we use a cover-style scale on the dirt texture the difference
|
||
// isn't massive so we chose to save a few ALUs here instead in case lens
|
||
// distortion is active.
|
||
half3 dirt = SAMPLE_TEXTURE2D(_LensDirt_Texture, sampler_LinearClamp, uv * LensDirtScale + LensDirtOffset).xyz;
|
||
dirt *= LensDirtIntensity;
|
||
color += dirt * bloom.xyz;
|
||
}
|
||
#endif
|
||
|
||
#if _ENABLE_ALPHA_OUTPUT
|
||
// Bloom should also spread in areas with zero alpha, so we save the image with bloom here to do the mixing at the end of the shader
|
||
inputColor.xyz = color.xyz;
|
||
#endif
|
||
|
||
if (!isCharArea)
|
||
return half4(color, 1);
|
||
}
|
||
#endif
|
||
|
||
// Apply Post Exposure
|
||
color *= _PostExposure;
|
||
|
||
// Assume the input as srgb if more contrast required.
|
||
color = lerp(color, GetSRGBToLinear(color), _CharGammaAdjust);
|
||
|
||
// Tone Mapping
|
||
color = ApplyPotaToonToneMap(color);
|
||
|
||
// Color Adjustments
|
||
ApplyColorAdjustments(color);
|
||
|
||
// When Unity is configured to use gamma color encoding, we ignore the request to convert to gamma 2.0 and instead fall back to sRGB encoding
|
||
#if _GAMMA_20 && !UNITY_COLORSPACE_GAMMA
|
||
{
|
||
color = LinearToGamma20(color);
|
||
inputColor = LinearToGamma20(inputColor);
|
||
}
|
||
// Back to sRGB
|
||
#elif UNITY_COLORSPACE_GAMMA || _LINEAR_TO_SRGB_CONVERSION
|
||
{
|
||
color = GetLinearToSRGB(color);
|
||
inputColor = LinearToSRGB(inputColor);
|
||
}
|
||
#endif
|
||
|
||
// Alpha mask
|
||
#if _ENABLE_ALPHA_OUTPUT
|
||
{
|
||
// Post processing is not applied on pixels with zero alpha
|
||
// The alpha scale and bias control how steep is the transition between the post-processed and plain regions
|
||
half alpha = inputColor.a * AlphaScale + AlphaBias;
|
||
// Saturate is necessary to avoid issues when additive blending pushes the alpha over 1.
|
||
// NOTE: in UNITY_COLORSPACE_GAMMA we alpha blend in gamma here, linear otherwise.
|
||
color.xyz = lerp(inputColor.xyz, color.xyz, saturate(alpha));
|
||
}
|
||
#endif
|
||
|
||
#if _ENABLE_ALPHA_OUTPUT
|
||
// Saturate is necessary to avoid issues when additive blending pushes the alpha over 1.
|
||
return half4(color, saturate(inputColor.a));
|
||
#else
|
||
return half4(color, 1);
|
||
#endif
|
||
}
|
||
|
||
half4 PotaToonPostProcessEnvironment(float2 uv)
|
||
{
|
||
bool isCharArea = SAMPLE_TEXTURE2D_X(_PotaToonCharMask, sampler_LinearClamp, uv).r > 0.5;
|
||
if (isCharArea)
|
||
clip(-1);
|
||
|
||
// NOTE: Hlsl specifies missing input.a to fill 1 (0 for .rgb).
|
||
// InputColor is a "bottom" layer for alpha output.
|
||
half4 inputColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
|
||
half3 color = inputColor.rgb;
|
||
|
||
#if UNITY_COLORSPACE_GAMMA
|
||
{
|
||
color = GetSRGBToLinear(color);
|
||
inputColor = GetSRGBToLinear(inputColor); // Deadcode removal if no effect on output color
|
||
}
|
||
#endif
|
||
|
||
// Bloom
|
||
#if defined(BLOOM)
|
||
{
|
||
float2 uvBloom = uv;
|
||
#if defined(SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
|
||
UNITY_BRANCH if (_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
|
||
{
|
||
uvBloom = RemapFoveatedRenderingNonUniformToLinear(uvBloom);
|
||
}
|
||
#endif
|
||
|
||
#if _BLOOM_HQ
|
||
half3 bloom = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_Bloom_Texture, sampler_LinearClamp), SCREEN_COORD_REMOVE_SCALEBIAS(uvBloom), _Bloom_Texture_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex).xyz;
|
||
#else
|
||
half3 bloom = SAMPLE_TEXTURE2D_X(_Bloom_Texture, sampler_LinearClamp, SCREEN_COORD_REMOVE_SCALEBIAS(uvBloom)).xyz;
|
||
#endif
|
||
|
||
#if UNITY_COLORSPACE_GAMMA
|
||
bloom *= bloom; // γ to linear
|
||
#endif
|
||
|
||
bloom *= BloomIntensity;
|
||
color += bloom * BloomTint;
|
||
|
||
#if defined(BLOOM_DIRT)
|
||
{
|
||
// UVs for the dirt texture should be DistortUV(uv * DirtScale + DirtOffset) but
|
||
// considering we use a cover-style scale on the dirt texture the difference
|
||
// isn't massive so we chose to save a few ALUs here instead in case lens
|
||
// distortion is active.
|
||
half3 dirt = SAMPLE_TEXTURE2D(_LensDirt_Texture, sampler_LinearClamp, uv * LensDirtScale + LensDirtOffset).xyz;
|
||
dirt *= LensDirtIntensity;
|
||
color += dirt * bloom.xyz;
|
||
}
|
||
#endif
|
||
|
||
#if _ENABLE_ALPHA_OUTPUT
|
||
// Bloom should also spread in areas with zero alpha, so we save the image with bloom here to do the mixing at the end of the shader
|
||
inputColor.xyz = color.xyz;
|
||
#endif
|
||
}
|
||
#endif
|
||
|
||
// Apply Post Exposure
|
||
color *= _PostExposure;
|
||
|
||
// Tone Mapping
|
||
color = ApplyPotaToonToneMap(color);
|
||
|
||
// Color Adjustments
|
||
ApplyColorAdjustments(color);
|
||
|
||
// When Unity is configured to use gamma color encoding, we ignore the request to convert to gamma 2.0 and instead fall back to sRGB encoding
|
||
#if _GAMMA_20 && !UNITY_COLORSPACE_GAMMA
|
||
{
|
||
color = LinearToGamma20(color);
|
||
inputColor = LinearToGamma20(inputColor);
|
||
}
|
||
// Back to sRGB
|
||
#elif UNITY_COLORSPACE_GAMMA || _LINEAR_TO_SRGB_CONVERSION
|
||
{
|
||
color = GetLinearToSRGB(color);
|
||
inputColor = LinearToSRGB(inputColor);
|
||
}
|
||
#endif
|
||
|
||
// Alpha mask
|
||
#if _ENABLE_ALPHA_OUTPUT
|
||
{
|
||
// Post processing is not applied on pixels with zero alpha
|
||
// The alpha scale and bias control how steep is the transition between the post-processed and plain regions
|
||
half alpha = inputColor.a * AlphaScale + AlphaBias;
|
||
// Saturate is necessary to avoid issues when additive blending pushes the alpha over 1.
|
||
// NOTE: in UNITY_COLORSPACE_GAMMA we alpha blend in gamma here, linear otherwise.
|
||
color.xyz = lerp(inputColor.xyz, color.xyz, saturate(alpha));
|
||
}
|
||
#endif
|
||
|
||
#if _ENABLE_ALPHA_OUTPUT
|
||
// Saturate is necessary to avoid issues when additive blending pushes the alpha over 1.
|
||
return half4(color, saturate(inputColor.a));
|
||
#else
|
||
return half4(color, 1);
|
||
#endif
|
||
}
|
||
ENDHLSL
|
||
|
||
SubShader
|
||
{
|
||
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
|
||
ZTest Always ZWrite Off Cull Off
|
||
|
||
Pass
|
||
{
|
||
Name "POTAToonUberPostCharacter"
|
||
|
||
HLSLPROGRAM
|
||
#pragma vertex Vert
|
||
#pragma fragment frag
|
||
|
||
half4 frag(Varyings input) : SV_Target
|
||
{
|
||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||
|
||
#if UNITY_VERSION >= 202230
|
||
float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.texcoord));
|
||
#else
|
||
float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.uv));
|
||
#endif
|
||
|
||
return PotaToonPostProcess(uv);
|
||
}
|
||
ENDHLSL
|
||
}
|
||
|
||
Pass
|
||
{
|
||
Name "POTAToonUberPostEnvironment"
|
||
|
||
HLSLPROGRAM
|
||
#pragma vertex Vert
|
||
#pragma fragment frag
|
||
|
||
half4 frag(Varyings input) : SV_Target
|
||
{
|
||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||
|
||
#if UNITY_VERSION >= 202230
|
||
float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.texcoord));
|
||
#else
|
||
float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.uv));
|
||
#endif
|
||
|
||
return PotaToonPostProcessEnvironment(uv);
|
||
}
|
||
ENDHLSL
|
||
}
|
||
|
||
Pass
|
||
{
|
||
Name "POTAToonScreenOutline"
|
||
Blend SrcAlpha OneMinusSrcAlpha
|
||
|
||
HLSLPROGRAM
|
||
#include "./PotaToonScreenPostPasses.hlsl"
|
||
#pragma multi_compile_local_fragment _ _EXCLUDE_INNER_SCREEN_OUTLINES
|
||
|
||
#pragma vertex Vert
|
||
#pragma fragment FragPotaToonScreenOutline
|
||
|
||
ENDHLSL
|
||
}
|
||
}
|
||
}
|