HDRBloom(光晕)
取亮光部分,进行降采样,在升采样的过程中,叠加降采样对应尺寸的图片,合并效果图和源图片
初处理
如果放入的是HDR图片,可以在shader里面加float4 _MainTex_HDR; col.rgb = DecodeHDR(col,_MainTex_HDR);进行解码。
取光亮部分
先进行均值模糊,取亮色部分。
1 2 3 4 5 6 7
| float intensity = Mathf.Exp(_Intensity / 10.0f * 0.693f) - 1.0f;
mat.SetFloat("_Threshold", _Threshold); mat.SetFloat("_Intensity", intensity);
Graphics.Blit(source, RT_Down[0], mat, 0);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| half4 frag_PreFilter(v2f_img i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); half4 d=_MainTex_TexelSize.xyxy*half4(1,1,-1,-1); col.rgb+=tex2D(_MainTex,i.uv+d.xy).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.zy).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.xw).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.zw).rgb; col.rgb*=0.25; float br = max(max(col.r,col.g),col.b); br = max(0,(br - _Threshold))/max(0.00001,br); col.rgb*=br; return col; }
|
降采样
用双重盒状模糊的降采样方式
1 2 3 4 5
| for(int i=0;i<_Iteration;i++) { Graphics.Blit(RT_Down[i], RT_Down[i + 1], mat, 1); }
|
1 2 3 4 5 6 7 8 9 10 11
| half4 frag_DownsampleBox(v2f_img i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); half4 d=_MainTex_TexelSize.xyxy*half4(1,1,-1,-1); col.rgb+=tex2D(_MainTex,i.uv+d.xy).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.zy).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.xw).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.zw).rgb; col.rgb*=0.25; return col; }
|
升采样
升采样过程中加同尺寸的降采样贴图
1 2 3 4 5 6 7
| Graphics.Blit(RT_Down[_Iteration], RT_Up[_Iteration]); for(int i=_Iteration;i>0;i--) { mat.SetTexture("_BloomTex", RT_Down[i-1]); Graphics.Blit(RT_Up[i], RT_Up[i-1], mat, 2);
}
|
1 2 3 4 5 6 7 8 9 10 11 12
| half4 frag_UpsampleBox(v2f_img i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); half4 d=_MainTex_TexelSize.xyxy*half4(1,1,-1,-1); col.rgb+=tex2D(_MainTex,i.uv+d.xy).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.zy).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.xw).rgb; col.rgb+=tex2D(_MainTex,i.uv+d.zw).rgb; col.rgb*=0.25; half4 color2 = tex2D(_BloomTex, i.uv); return col + color2; }
|
合并
把升采样的最后一张图和原图合并,和释放贴图。
1 2 3 4 5 6 7 8 9 10
| mat.SetTexture("_BloomTex", RT_Up[0]); Graphics.Blit(source, destination, mat, 3);
for (int i = 0; i < _Iteration+1; i++) {
RenderTexture.ReleaseTemporary(RT_Down[i]); RenderTexture.ReleaseTemporary(RT_Up[i]); }
|
1 2 3 4 5 6 7
| half4 frag_Combine(v2f_img i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); half3 color1 = tex2D(_BloomTex, i.uv).rgb; col.rgb+= color1.rgb*_Intensity; return col ; }
|
最后小瑕疵
在光晕的周围还有点不自然。可用如下解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| float3 ACES_Tonemapping(float3 x) { float a = 2.51f; float b = 0.03f; float c = 2.43f; float d = 0.59f; float e = 0.14f; float3 encode_color = saturate((x*(a*x + b)) / (x*(c*x + d) + e)); return encode_color; };
half4 frag (v2f_img i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); half3 linear_color = pow(col.rgb, 2.2); half3 encode_color = ACES_Tonemapping(linear_color); half3 final_color = pow(encode_color, 1.0 / 2.2); return float4(final_color,col.a); }
|
后处理的顺序

调整顺序:Bloom->Vignette->Tonemapping->ColorGrading