| | |
| | | // |
| | | // Kino/Bloom v2 - Bloom filter for Unity |
| | | // |
| | | // Copyright (C) 2015, 2016 Keijiro Takahashi |
| | | // |
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | // of this software and associated documentation files (the "Software"), to deal |
| | | // in the Software without restriction, including without limitation the rights |
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | // copies of the Software, and to permit persons to whom the Software is |
| | | // furnished to do so, subject to the following conditions: |
| | | // |
| | | // The above copyright notice and this permission notice shall be included in |
| | | // all copies or substantial portions of the Software. |
| | | // |
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | // THE SOFTWARE. |
| | | // |
| | | Shader "Hidden/Post FX/Bloom" |
| | | { |
| | | Properties |
| | | { |
| | | _MainTex ("", 2D) = "" {} |
| | | _BaseTex ("", 2D) = "" {} |
| | | _AutoExposure ("", 2D) = "" {} |
| | | } |
| | | |
| | | CGINCLUDE |
| | | |
| | | #pragma target 3.0 |
| | | #include "UnityCG.cginc" |
| | | #include "Bloom.cginc" |
| | | #include "Common.cginc" |
| | | |
| | | sampler2D _BaseTex; |
| | | float2 _BaseTex_TexelSize; |
| | | |
| | | sampler2D _AutoExposure; |
| | | |
| | | float _PrefilterOffs; |
| | | float _Threshold; |
| | | float3 _Curve; |
| | | float _SampleScale; |
| | | |
| | | // ----------------------------------------------------------------------------- |
| | | // Vertex shaders |
| | | |
| | | struct VaryingsMultitex |
| | | { |
| | | float4 pos : SV_POSITION; |
| | | float2 uvMain : TEXCOORD0; |
| | | float2 uvBase : TEXCOORD1; |
| | | }; |
| | | |
| | | VaryingsMultitex VertMultitex(AttributesDefault v) |
| | | { |
| | | VaryingsMultitex o; |
| | | o.pos = UnityObjectToClipPos(v.vertex); |
| | | o.uvMain = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST); |
| | | o.uvBase = o.uvMain; |
| | | |
| | | #if UNITY_UV_STARTS_AT_TOP |
| | | if (_BaseTex_TexelSize.y < 0.0) |
| | | o.uvBase.y = 1.0 - o.uvBase.y; |
| | | #endif |
| | | |
| | | return o; |
| | | } |
| | | |
| | | // ----------------------------------------------------------------------------- |
| | | // Fragment shaders |
| | | |
| | | half4 FetchAutoExposed(sampler2D tex, float2 uv) |
| | | { |
| | | float autoExposure = 1.0; |
| | | uv = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST); |
| | | autoExposure = tex2D(_AutoExposure, uv).r; |
| | | return tex2D(tex, uv) * autoExposure; |
| | | } |
| | | |
| | | half4 FragPrefilter(VaryingsDefault i) : SV_Target |
| | | { |
| | | float2 uv = i.uv + _MainTex_TexelSize.xy * _PrefilterOffs; |
| | | |
| | | #if ANTI_FLICKER |
| | | float3 d = _MainTex_TexelSize.xyx * float3(1.0, 1.0, 0.0); |
| | | half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv)); |
| | | half3 s1 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.xz).rgb); |
| | | half3 s2 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.xz).rgb); |
| | | half3 s3 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.zy).rgb); |
| | | half3 s4 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.zy).rgb); |
| | | half3 m = Median(Median(s0.rgb, s1, s2), s3, s4); |
| | | #else |
| | | half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv)); |
| | | half3 m = s0.rgb; |
| | | #endif |
| | | |
| | | #if UNITY_COLORSPACE_GAMMA |
| | | m = GammaToLinearSpace(m); |
| | | #endif |
| | | |
| | | // Pixel brightness |
| | | half br = Brightness(m); |
| | | |
| | | // Under-threshold part: quadratic curve |
| | | half rq = clamp(br - _Curve.x, 0.0, _Curve.y); |
| | | rq = _Curve.z * rq * rq; |
| | | |
| | | // Combine and apply the brightness response curve. |
| | | m *= max(rq, br - _Threshold) / max(br, 1e-5); |
| | | |
| | | return EncodeHDR(m); |
| | | } |
| | | |
| | | half4 FragDownsample1(VaryingsDefault i) : SV_Target |
| | | { |
| | | #if ANTI_FLICKER |
| | | return EncodeHDR(DownsampleAntiFlickerFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy)); |
| | | #else |
| | | return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy)); |
| | | #endif |
| | | } |
| | | |
| | | half4 FragDownsample2(VaryingsDefault i) : SV_Target |
| | | { |
| | | return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy)); |
| | | } |
| | | |
| | | half4 FragUpsample(VaryingsMultitex i) : SV_Target |
| | | { |
| | | half3 base = DecodeHDR(tex2D(_BaseTex, i.uvBase)); |
| | | half3 blur = UpsampleFilter(_MainTex, i.uvMain, _MainTex_TexelSize.xy, _SampleScale); |
| | | return EncodeHDR(base + blur); |
| | | } |
| | | |
| | | ENDCG |
| | | |
| | | SubShader |
| | | { |
| | | ZTest Always Cull Off ZWrite Off |
| | | |
| | | Pass |
| | | { |
| | | CGPROGRAM |
| | | #pragma multi_compile __ ANTI_FLICKER |
| | | #pragma multi_compile __ UNITY_COLORSPACE_GAMMA |
| | | #pragma vertex VertDefault |
| | | #pragma fragment FragPrefilter |
| | | ENDCG |
| | | } |
| | | |
| | | Pass |
| | | { |
| | | CGPROGRAM |
| | | #pragma multi_compile __ ANTI_FLICKER |
| | | #pragma vertex VertDefault |
| | | #pragma fragment FragDownsample1 |
| | | ENDCG |
| | | } |
| | | |
| | | Pass |
| | | { |
| | | CGPROGRAM |
| | | #pragma vertex VertDefault |
| | | #pragma fragment FragDownsample2 |
| | | ENDCG |
| | | } |
| | | |
| | | Pass |
| | | { |
| | | CGPROGRAM |
| | | #pragma vertex VertMultitex |
| | | #pragma fragment FragUpsample |
| | | ENDCG |
| | | } |
| | | } |
| | | } |
| | | //
|
| | | // Kino/Bloom v2 - Bloom filter for Unity
|
| | | //
|
| | | // Copyright (C) 2015, 2016 Keijiro Takahashi
|
| | | //
|
| | | // Permission is hereby granted, free of charge, to any person obtaining a copy
|
| | | // of this software and associated documentation files (the "Software"), to deal
|
| | | // in the Software without restriction, including without limitation the rights
|
| | | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| | | // copies of the Software, and to permit persons to whom the Software is
|
| | | // furnished to do so, subject to the following conditions:
|
| | | //
|
| | | // The above copyright notice and this permission notice shall be included in
|
| | | // all copies or substantial portions of the Software.
|
| | | //
|
| | | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| | | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| | | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| | | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| | | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| | | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
| | | // THE SOFTWARE.
|
| | | //
|
| | | Shader "Hidden/Post FX/Bloom"
|
| | | {
|
| | | Properties
|
| | | {
|
| | | _MainTex ("", 2D) = "" {}
|
| | | _BaseTex ("", 2D) = "" {}
|
| | | _AutoExposure ("", 2D) = "" {}
|
| | | }
|
| | |
|
| | | CGINCLUDE
|
| | |
|
| | | #pragma target 3.0
|
| | | #include "UnityCG.cginc"
|
| | | #include "Bloom.cginc"
|
| | | #include "Common.cginc"
|
| | |
|
| | | sampler2D _BaseTex;
|
| | | float2 _BaseTex_TexelSize;
|
| | |
|
| | | sampler2D _AutoExposure;
|
| | |
|
| | | float _PrefilterOffs;
|
| | | float _Threshold;
|
| | | float3 _Curve;
|
| | | float _SampleScale;
|
| | |
|
| | | // -----------------------------------------------------------------------------
|
| | | // Vertex shaders
|
| | |
|
| | | struct VaryingsMultitex
|
| | | {
|
| | | float4 pos : SV_POSITION;
|
| | | float2 uvMain : TEXCOORD0;
|
| | | float2 uvBase : TEXCOORD1;
|
| | | };
|
| | |
|
| | | VaryingsMultitex VertMultitex(AttributesDefault v)
|
| | | {
|
| | | VaryingsMultitex o;
|
| | | o.pos = UnityObjectToClipPos(v.vertex);
|
| | | o.uvMain = UnityStereoScreenSpaceUVAdjust(v.texcoord.xy, _MainTex_ST);
|
| | | o.uvBase = o.uvMain;
|
| | |
|
| | | #if UNITY_UV_STARTS_AT_TOP
|
| | | if (_BaseTex_TexelSize.y < 0.0)
|
| | | o.uvBase.y = 1.0 - o.uvBase.y;
|
| | | #endif
|
| | |
|
| | | return o;
|
| | | }
|
| | |
|
| | | // -----------------------------------------------------------------------------
|
| | | // Fragment shaders
|
| | |
|
| | | half4 FetchAutoExposed(sampler2D tex, float2 uv)
|
| | | {
|
| | | float autoExposure = 1.0;
|
| | | uv = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
|
| | | autoExposure = tex2D(_AutoExposure, uv).r;
|
| | | return tex2D(tex, uv) * autoExposure;
|
| | | }
|
| | |
|
| | | half4 FragPrefilter(VaryingsDefault i) : SV_Target
|
| | | {
|
| | | float2 uv = i.uv + _MainTex_TexelSize.xy * _PrefilterOffs;
|
| | |
|
| | | #if ANTI_FLICKER
|
| | | float3 d = _MainTex_TexelSize.xyx * float3(1.0, 1.0, 0.0);
|
| | | half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv));
|
| | | half3 s1 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.xz).rgb);
|
| | | half3 s2 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.xz).rgb);
|
| | | half3 s3 = SafeHDR(FetchAutoExposed(_MainTex, uv - d.zy).rgb);
|
| | | half3 s4 = SafeHDR(FetchAutoExposed(_MainTex, uv + d.zy).rgb);
|
| | | half3 m = Median(Median(s0.rgb, s1, s2), s3, s4);
|
| | | #else
|
| | | half4 s0 = SafeHDR(FetchAutoExposed(_MainTex, uv));
|
| | | half3 m = s0.rgb;
|
| | | #endif
|
| | |
|
| | | #if UNITY_COLORSPACE_GAMMA
|
| | | m = GammaToLinearSpace(m);
|
| | | #endif
|
| | |
|
| | | // Pixel brightness
|
| | | half br = Brightness(m);
|
| | |
|
| | | // Under-threshold part: quadratic curve
|
| | | half rq = clamp(br - _Curve.x, 0.0, _Curve.y);
|
| | | rq = _Curve.z * rq * rq;
|
| | |
|
| | | // Combine and apply the brightness response curve.
|
| | | m *= max(rq, br - _Threshold) / max(br, 1e-5);
|
| | |
|
| | | return EncodeHDR(m);
|
| | | }
|
| | |
|
| | | half4 FragDownsample1(VaryingsDefault i) : SV_Target
|
| | | {
|
| | | #if ANTI_FLICKER
|
| | | return EncodeHDR(DownsampleAntiFlickerFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy));
|
| | | #else
|
| | | return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy));
|
| | | #endif
|
| | | }
|
| | |
|
| | | half4 FragDownsample2(VaryingsDefault i) : SV_Target
|
| | | {
|
| | | return EncodeHDR(DownsampleFilter(_MainTex, i.uvSPR, _MainTex_TexelSize.xy));
|
| | | }
|
| | |
|
| | | half4 FragUpsample(VaryingsMultitex i) : SV_Target
|
| | | {
|
| | | half3 base = DecodeHDR(tex2D(_BaseTex, i.uvBase));
|
| | | half3 blur = UpsampleFilter(_MainTex, i.uvMain, _MainTex_TexelSize.xy, _SampleScale);
|
| | | return EncodeHDR(base + blur);
|
| | | }
|
| | |
|
| | | ENDCG
|
| | |
|
| | | SubShader
|
| | | {
|
| | | ZTest Always Cull Off ZWrite Off
|
| | |
|
| | | Pass
|
| | | {
|
| | | CGPROGRAM
|
| | | #pragma multi_compile __ ANTI_FLICKER
|
| | | #pragma multi_compile __ UNITY_COLORSPACE_GAMMA
|
| | | #pragma vertex VertDefault
|
| | | #pragma fragment FragPrefilter
|
| | | ENDCG
|
| | | }
|
| | |
|
| | | Pass
|
| | | {
|
| | | CGPROGRAM
|
| | | #pragma multi_compile __ ANTI_FLICKER
|
| | | #pragma vertex VertDefault
|
| | | #pragma fragment FragDownsample1
|
| | | ENDCG
|
| | | }
|
| | |
|
| | | Pass
|
| | | {
|
| | | CGPROGRAM
|
| | | #pragma vertex VertDefault
|
| | | #pragma fragment FragDownsample2
|
| | | ENDCG
|
| | | }
|
| | |
|
| | | Pass
|
| | | {
|
| | | CGPROGRAM
|
| | | #pragma vertex VertMultitex
|
| | | #pragma fragment FragUpsample
|
| | | ENDCG
|
| | | }
|
| | | }
|
| | | }
|