wangguan
2020-10-29 6502aa82fef41313e1062ed119e56c141be3e2a1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#ifndef __BLOOM__
#define __BLOOM__
 
#include "Common.cginc"
 
// Brightness function
half Brightness(half3 c)
{
    return Max3(c);
}
 
// 3-tap median filter
half3 Median(half3 a, half3 b, half3 c)
{
    return a + b + c - min(min(a, b), c) - max(max(a, b), c);
}
 
// Downsample with a 4x4 box filter
half3 DownsampleFilter(sampler2D tex, float2 uv, float2 texelSize)
{
    float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0);
 
    half3 s;
    s = DecodeHDR(tex2D(tex, uv + d.xy));
    s += DecodeHDR(tex2D(tex, uv + d.zy));
    s += DecodeHDR(tex2D(tex, uv + d.xw));
    s += DecodeHDR(tex2D(tex, uv + d.zw));
 
    return s * (1.0 / 4.0);
}
 
// Downsample with a 4x4 box filter + anti-flicker filter
half3 DownsampleAntiFlickerFilter(sampler2D tex, float2 uv, float2 texelSize)
{
    float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0);
 
    half3 s1 = DecodeHDR(tex2D(tex, uv + d.xy));
    half3 s2 = DecodeHDR(tex2D(tex, uv + d.zy));
    half3 s3 = DecodeHDR(tex2D(tex, uv + d.xw));
    half3 s4 = DecodeHDR(tex2D(tex, uv + d.zw));
 
    // Karis's luma weighted average (using brightness instead of luma)
    half s1w = 1.0 / (Brightness(s1) + 1.0);
    half s2w = 1.0 / (Brightness(s2) + 1.0);
    half s3w = 1.0 / (Brightness(s3) + 1.0);
    half s4w = 1.0 / (Brightness(s4) + 1.0);
    half one_div_wsum = 1.0 / (s1w + s2w + s3w + s4w);
 
    return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div_wsum;
}
 
half3 UpsampleFilter(sampler2D tex, float2 uv, float2 texelSize, float sampleScale)
{
#if MOBILE_OR_CONSOLE
    // 4-tap bilinear upsampler
    float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0) * (sampleScale * 0.5);
 
    half3 s;
    s =  DecodeHDR(tex2D(tex, uv + d.xy));
    s += DecodeHDR(tex2D(tex, uv + d.zy));
    s += DecodeHDR(tex2D(tex, uv + d.xw));
    s += DecodeHDR(tex2D(tex, uv + d.zw));
 
    return s * (1.0 / 4.0);
#else
    // 9-tap bilinear upsampler (tent filter)
    float4 d = texelSize.xyxy * float4(1.0, 1.0, -1.0, 0.0) * sampleScale;
 
    half3 s;
    s =  DecodeHDR(tex2D(tex, uv - d.xy));
    s += DecodeHDR(tex2D(tex, uv - d.wy)) * 2.0;
    s += DecodeHDR(tex2D(tex, uv - d.zy));
 
    s += DecodeHDR(tex2D(tex, uv + d.zw)) * 2.0;
    s += DecodeHDR(tex2D(tex, uv))        * 4.0;
    s += DecodeHDR(tex2D(tex, uv + d.xw)) * 2.0;
 
    s += DecodeHDR(tex2D(tex, uv + d.zy));
    s += DecodeHDR(tex2D(tex, uv + d.wy)) * 2.0;
    s += DecodeHDR(tex2D(tex, uv + d.xy));
 
    return s * (1.0 / 16.0);
#endif
}
 
#endif // __BLOOM__