Shader "Hidden/EffectiveBloom" { Properties { _MainTex ("EffectiveBloom", 2D) = "black" {} } SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } ZTest Always Cull Off ZWrite Off HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 struct Attributes { float4 positionOS : POSITION; half2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; half2 uv : TEXCOORD0; }; struct VaryingsBlur { float4 positionCS : SV_POSITION; half2 uv : TEXCOORD0; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_SourceTex); SAMPLER(sampler_SourceTex); CBUFFER_START(UnityPerMaterial) half2 _TexelSize; half _Intensity; half _Threshold; half3 _Curve; half4 _Tint; CBUFFER_END half4 BoxFilterOptimized(half2 uv) { return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv); } half4 BoxFilter(half2 uv, half2 texelSize) { half4 sum; sum = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv); sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + half2(texelSize.x, 0.0h)); sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv - half2(texelSize.x, 0.0h)); sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + half2(0.0h, texelSize.y)); return sum * 0.25h; } half4 BoxFilter2Tap(half2 uv, half2 texelSize) { half4 sum; sum = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + half2(0.5h, 0.5h) * texelSize); sum += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv - half2(0.5h, 0.5h) * texelSize); return sum * 0.5h; } Varyings vert_base(Attributes input) { Varyings output; VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); output.positionCS = vertexInput.positionCS; output.uv = input.uv; return output; } VaryingsBlur vert_blur(Attributes input) { VaryingsBlur output; VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); output.positionCS = vertexInput.positionCS; output.uv = input.uv; return output; } half4 frag_prefilter(Varyings input) : SV_Target { half4 c = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv); half contribution = _Threshold; return half4(c.rgb * contribution, c.a); } half4 frag_blur_downsample(VaryingsBlur input) : SV_Target { return BoxFilterOptimized(input.uv); } half4 frag_blur_upsample(VaryingsBlur input) : SV_Target { return BoxFilter2Tap(input.uv, _TexelSize); } half4 frag_final(VaryingsBlur input) : SV_Target { half4 bloom = BoxFilterOptimized(input.uv) * _Intensity; bloom.rgb *= _Tint.rgb; return bloom; } half4 frag_combine(VaryingsBlur input) : SV_Target { half3 bloom = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv).rgb; bloom = LinearToSRGB(bloom); bloom *= _Tint.rgb; half4 source = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, input.uv); return half4(source.rgb + bloom, source.a); } ENDHLSL Pass { NAME "Prefilter" HLSLPROGRAM #pragma vertex vert_base #pragma fragment frag_prefilter ENDHLSL } Pass { NAME "Downsample" HLSLPROGRAM #pragma vertex vert_blur #pragma fragment frag_blur_downsample ENDHLSL } Pass { NAME "Upsample" Blend One One HLSLPROGRAM #pragma vertex vert_blur #pragma fragment frag_blur_upsample ENDHLSL } Pass { NAME "Final" HLSLPROGRAM #pragma vertex vert_blur #pragma fragment frag_final ENDHLSL } Pass { NAME "Combine" HLSLPROGRAM #pragma vertex vert_blur #pragma fragment frag_combine ENDHLSL } } }