#ifndef BEAUTIFY_PPSLUM_FX #define BEAUTIFY_PPSLUM_FX // Copyright 2020-2021 Kronnect - All Rights Reserved. #include "BeautifyCommon.hlsl" TEXTURE2D_X(_MainTex); TEXTURE2D_X(_BloomTex); float4 _BloomTex_TexelSize; TEXTURE2D_X(_CombineTex); TEXTURE2D_X(_BloomTex1); TEXTURE2D_X(_BloomTex2); TEXTURE2D_X(_BloomTex3); TEXTURE2D_X(_BloomTex4); float4 _MainTex_TexelSize; float4 _MainTex_ST; float4 _Bloom; float4 _BloomWeights; float4 _BloomWeights2; float4 _BloomTint; float3 _BloomTint0, _BloomTint1, _BloomTint2, _BloomTint3, _BloomTint4, _BloomTint5; float _BloomSpread; float4 _AFTint; float _BlurScale; float4 _AFData; #if defined(USE_AF_THRESHOLD) #define MAX_BRIGHTNESS _AFData.w #else #define MAX_BRIGHTNESS _BloomWeights2.z #endif #if BEAUTIFY_BLOOM_USE_DEPTH || BEAUTIFY_ANAMORPHIC_FLARES_USE_DEPTH float _BloomDepthThreshold; float _BloomNearThreshold; float _AFDepthThreshold; float _AFNearThreshold; #endif TEXTURE2D_X(_BloomSourceDepth); TEXTURE2D_X(_AFSourceDepth); struct VaryingsCross { float4 positionCS : SV_POSITION; float2 uv: TEXCOORD0; BEAUTIFY_VERTEX_CROSS_UV_DATA UNITY_VERTEX_OUTPUT_STEREO }; struct VaryingsLum { float4 positionCS : SV_POSITION; float2 uv: TEXCOORD0; UNITY_VERTEX_OUTPUT_STEREO }; struct VaryingsCrossLum { float4 positionCS : SV_POSITION; float2 uv: TEXCOORD0; BEAUTIFY_VERTEX_CROSS_UV_DATA UNITY_VERTEX_OUTPUT_STEREO }; VaryingsLum VertLum(AttributesSimple input) { VaryingsLum output; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); output.positionCS = input.positionOS; output.positionCS.y *= _ProjectionParams.x * _FlipY; output.uv = input.uv; return output; } half Brightness(half3 c) { return max(c.r, max(c.g, c.b)); } half Included(half4 c) { #if BEAUTIFY_BLOOM_USE_LAYER_INCLUSION || BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION return Brightness(c.rgb) >= 0.01; #else return Brightness(c.rgb) < 0.01; #endif } half3 ColorAboveThreshold(half3 c, half brightness) { #if defined(USE_AF_THRESHOLD) half threshold = _AFData.y; #else half threshold = _Bloom.w; #endif #if BEAUTIFY_ANAMORPHIC_PROP_THRESHOLDING || BEAUTIFY_BLOOM_PROP_THRESHOLDING half cs = clamp(brightness - 0.5 * threshold, 0.0, threshold); cs = 0.5 * cs * cs / (threshold + 0.0001); c *= max(brightness - threshold, cs) / max(brightness, 0.0001); #else c = max(c - threshold, 0); #endif return c; } half4 FragLum (VaryingsLum i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); half4 c = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv); c = clamp(c, 0.0.xxxx, MAX_BRIGHTNESS.xxxx); #if UNITY_COLORSPACE_GAMMA c.rgb = GAMMA_TO_LINEAR(c.rgb); #endif #if BEAUTIFY_BLOOM_USE_DEPTH || BEAUTIFY_ANAMORPHIC_FLARES_USE_DEPTH float depth01 = BEAUTIFY_GET_SCENE_DEPTH_01(i.uv); #endif #if BEAUTIFY_BLOOM_USE_DEPTH c.rgb *= max(0, 1.0 - depth01 * _BloomDepthThreshold); c.rgb *= min(1.0, depth01 / _BloomNearThreshold); #endif #if BEAUTIFY_ANAMORPHIC_FLARES_USE_DEPTH c.rgb *= max(0, 1.0 - depth01 * _AFDepthThreshold); c.rgb *= min(1.0, depth01 / _AFNearThreshold); #endif #if BEAUTIFY_BLOOM_USE_LAYER || BEAUTIFY_BLOOM_USE_LAYER_INCLUSION half included = Included(SAMPLE_TEXTURE2D_X(_BloomSourceDepth, sampler_LinearClamp, i.uv)); c.rgb *= included; #endif #if BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER || BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION half included = Included(SAMPLE_TEXTURE2D_X(_AFSourceDepth, sampler_LinearClamp, i.uv)); c.rgb *= included; #endif c.a = Brightness(c.rgb); #if !defined(USE_AF_THRESHOLD) c.rgb = lerp(c.rgb, c.a * _BloomTint.rgb, _BloomTint.a); #endif c.rgb = ColorAboveThreshold(c.rgb, c.a); return c; } VaryingsCross VertCross(AttributesSimple v) { VaryingsCross o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.positionCS = v.positionOS; o.positionCS.y *= _ProjectionParams.x * _FlipY; o.uv = v.uv; BEAUTIFY_VERTEX_OUTPUT_CROSS_UV(o) return o; } VaryingsCrossLum VertCrossLum(AttributesSimple v) { VaryingsCrossLum o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.positionCS = v.positionOS; o.positionCS.y *= _ProjectionParams.x * _FlipY; o.uv = v.uv; BEAUTIFY_VERTEX_OUTPUT_CROSS_UV(o) return o; } half4 FragLumAntiflicker(VaryingsCrossLum i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); BEAUTIFY_FRAG_SETUP_CROSS_UV(i) half4 c1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1); half4 c2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2); half4 c3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3); half4 c4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4); c1 = clamp(c1, 0.0.xxxx, MAX_BRIGHTNESS.xxxx); c2 = clamp(c2, 0.0.xxxx, MAX_BRIGHTNESS.xxxx); c3 = clamp(c3, 0.0.xxxx, MAX_BRIGHTNESS.xxxx); c4 = clamp(c4, 0.0.xxxx, MAX_BRIGHTNESS.xxxx); #if BEAUTIFY_BLOOM_USE_DEPTH || BEAUTIFY_ANAMORPHIC_FLARES_USE_DEPTH float depth01 = BEAUTIFY_GET_SCENE_DEPTH_01(i.uv); #endif #if BEAUTIFY_BLOOM_USE_DEPTH float depthAtten = max(0, 1.0 - depth01 * _BloomDepthThreshold); c1.rgb *= depthAtten; c2.rgb *= depthAtten; c3.rgb *= depthAtten; c4.rgb *= depthAtten; float nearAtten = min(1.0, depth01 / _BloomNearThreshold); c1.rgb *= nearAtten; c2.rgb *= nearAtten; c3.rgb *= nearAtten; c4.rgb *= nearAtten; #endif #if BEAUTIFY_ANAMORPHIC_FLARES_USE_DEPTH float depthAtten = max(0, 1.0 - depth01 * _AFDepthThreshold); c1.rgb *= depthAtten; c2.rgb *= depthAtten; c3.rgb *= depthAtten; c4.rgb *= depthAtten; float nearAtten = min(1.0, depth01 / _AFNearThreshold); c1.rgb *= nearAtten; c2.rgb *= nearAtten; c3.rgb *= nearAtten; c4.rgb *= nearAtten; #endif #if BEAUTIFY_BLOOM_USE_LAYER || BEAUTIFY_BLOOM_USE_LAYER_INCLUSION half included = Included(SAMPLE_TEXTURE2D_X(_BloomSourceDepth, sampler_LinearClamp, i.uv)); c1.rgb *= included; c2.rgb *= included; c3.rgb *= included; c4.rgb *= included; #endif #if BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER || BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION half included = Included(SAMPLE_TEXTURE2D_X(_AFSourceDepth, sampler_LinearClamp, i.uv)); c1.rgb *= included; c2.rgb *= included; c3.rgb *= included; c4.rgb *= included; #endif c1.a = Brightness(c1.rgb); c2.a = Brightness(c2.rgb); c3.a = Brightness(c3.rgb); c4.a = Brightness(c4.rgb); half w1 = 1.0 / (c1.a + 1.0); half w2 = 1.0 / (c2.a + 1.0); half w3 = 1.0 / (c3.a + 1.0); half w4 = 1.0 / (c4.a + 1.0); half dd = 1.0 / (w1 + w2 + w3 + w4); c1 = (c1 * w1 + c2 * w2 + c3 * w3 + c4 * w4) * dd; #if UNITY_COLORSPACE_GAMMA c1.rgb = GAMMA_TO_LINEAR(c1.rgb); #endif #if !defined(USE_AF_THRESHOLD) c1.rgb = lerp(c1.rgb, c1.a * _BloomTint.rgb, _BloomTint.a); #endif c1.rgb = ColorAboveThreshold(c1.rgb, c1.a); return c1; } float4 FragBloomCompose (VaryingsSimple i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); float4 b0 = SAMPLE_TEXTURE2D_X( _BloomTex , sampler_LinearClamp, i.uv ); float4 b1 = SAMPLE_TEXTURE2D_X( _BloomTex1 , sampler_LinearClamp, i.uv ); float4 b2 = SAMPLE_TEXTURE2D_X( _BloomTex2 , sampler_LinearClamp, i.uv ); float4 b3 = SAMPLE_TEXTURE2D_X( _BloomTex3 , sampler_LinearClamp, i.uv ); float4 b4 = SAMPLE_TEXTURE2D_X( _BloomTex4 , sampler_LinearClamp, i.uv ); float4 b5 = SAMPLE_TEXTURE2D_X( _MainTex , sampler_LinearClamp, i.uv ); b0.rgb *= _BloomTint0; b1.rgb *= _BloomTint1; b2.rgb *= _BloomTint2; b3.rgb *= _BloomTint3; b4.rgb *= _BloomTint4; b5.rgb *= _BloomTint5; float4 pixel = b0 * _BloomWeights.x + b1 * _BloomWeights.y + b2 * _BloomWeights.z + b3 * _BloomWeights.w + b4 * _BloomWeights2.x + b5 * _BloomWeights2.y; //pixel.rgb = lerp(pixel.rgb, Brightness(pixel.rgb) * _BloomTint.rgb, _BloomTint.a); return pixel; } inline float4 Lerp3(float4 a, float4 b, float4 c, float t) { if (t <= 0.5) { return lerp(a, b, t * 2.0); } else { return lerp(b, c, t * 2.0 - 1.0); } } float4 FragResample(VaryingsCross i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); BEAUTIFY_FRAG_SETUP_CROSS_UV(i) float4 c1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1); float4 c2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2); float4 c3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3); float4 c4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4); float w1 = 1.0 / (c1.a + 1.0); float w2 = 1.0 / (c2.a + 1.0); float w3 = 1.0 / (c3.a + 1.0); float w4 = 1.0 / (c4.a + 1.0); float dd = 1.0 / (w1 + w2 + w3 + w4); float4 v = (c1 * w1 + c2 * w2 + c3 * w3 + c4 * w4) * dd; #if defined(COMBINE_BLOOM) float4 o = SAMPLE_TEXTURE2D_X(_BloomTex, sampler_LinearClamp, i.uv); v = Lerp3(o, o+v, v, _BloomSpread); #endif return v; } float4 FragResampleAF(VaryingsCross i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); BEAUTIFY_FRAG_SETUP_CROSS_UV(i) float4 c1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1); float4 c2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2); float4 c3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3); float4 c4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4); float w1 = 1.0 / (c1.a + 1.0); float w2 = 1.0 / (c2.a + 1.0); float w3 = 1.0 / (c3.a + 1.0); float w4 = 1.0 / (c4.a + 1.0); float dd = 1.0 / (w1 + w2 + w3 + w4); float4 v = (c1 * w1 + c2 * w2 + c3 * w3 + c4 * w4) * dd; v.rgb = lerp(v.rgb, Brightness(c1.rgb) * _AFTint.rgb, _AFTint.a); v.rgb *= _AFData.xxx; #if defined(COMBINE_BLOOM) float4 o = SAMPLE_TEXTURE2D_X(_BloomTex, sampler_LinearClamp, i.uv); v += o; #endif return v; } float4 FragCombine(VaryingsSimple i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); float4 c1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv); float4 c2 = SAMPLE_TEXTURE2D_X(_CombineTex, sampler_LinearClamp, i.uv); return c1 + c2; } float4 FragDebugBloom (VaryingsSimple i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); return SAMPLE_TEXTURE2D_X(_BloomTex, sampler_LinearClamp, i.uv) * _Bloom.xxxx; } float4 FragDebugBloomExclusionLayer (VaryingsSimple i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); float depth = BEAUTIFY_GET_CUSTOM_DEPTH_01(_BloomSourceDepth, i.uv); return float4(depth.xxx, 1.0); } float4 FragDebugAnamorphicFlaresExclusionLayer (VaryingsSimple i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); float depth = BEAUTIFY_GET_CUSTOM_DEPTH_01(_AFSourceDepth, i.uv); return float4(depth.xxx, 1.0); } float4 FragResampleFastAF(VaryingsSimple i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); float4 c = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv); c.rgb = lerp(c.rgb, Brightness(c.rgb) * _AFTint.rgb, _AFTint.a); c.rgb *= _AFData.xxx; return c; } VaryingsCross VertBlur(AttributesSimple v) { VaryingsCross o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.positionCS = v.positionOS; o.positionCS.y *= _ProjectionParams.x * _FlipY; o.uv = v.uv; BEAUTIFY_VERTEX_OUTPUT_GAUSSIAN_UV(o) return o; } float4 FragBlur (VaryingsCross i): SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); i.uv = UnityStereoTransformScreenSpaceTex(i.uv); BEAUTIFY_FRAG_SETUP_GAUSSIAN_UV(i) float4 pixel = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv) * 0.2270270270 + (SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1) + SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2)) * 0.3162162162 + (SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3) + SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4)) * 0.0702702703; return pixel; } #endif