Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/trunk/programs/hdr.hlsl @ 8532

Last change on this file since 8532 was 7708, checked in by dafrick, 14 years ago

Merging cleanup branch. You will need to update your data repository as well as your local copy of the code.

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1// RGBE mode utilities
2// RGB each carry a mantissa, A carries a shared exponent
3// The exponent is calculated based on the largest colour channel
4
5
6float3 decodeRGBE8(in float4 rgbe)
7{
8    // get exponent (-128 since it can be +ve or -ve)
9        float exp = rgbe.a * 255 - 128;
10       
11        // expand out the rgb value
12        return rgbe.rgb * exp2(exp);
13}
14
15float4 encodeRGBE8(in float3 rgb)
16{
17        float4 ret;
18
19    // What is the largest colour channel?
20        float highVal = max(rgb.r, max(rgb.g, rgb.b));
21       
22        // Take the logarithm, clamp it to a whole value
23        float exp = ceil(log2(highVal));
24
25    // Divide the components by the shared exponent
26        ret.rgb = rgb / exp2(exp);
27       
28        // Store the shared exponent in the alpha channel
29        ret.a = (exp + 128) / 255;
30
31        return ret;
32}
33
34
35static const float4 LUMINENCE_FACTOR  = float4(0.27f, 0.67f, 0.06f, 0.0f);
36static const float MIDDLE_GREY = 0.72f;
37static const float FUDGE = 0.001f;
38static const float L_WHITE = 1.5f;
39static const float4 BRIGHT_LIMITER = float4(0.6f, 0.6f, 0.6f, 0.0f);
40
41
42/** Tone mapping function
43@note Only affects rgb, not a
44@param inColour The HDR colour
45@param lum The scene lumninence
46@returns Tone mapped colour
47*/
48float4 toneMap(float4 inColour, float lum)
49{
50        // From Reinhard et al
51        // "Photographic Tone Reproduction for Digital Images"
52       
53        // Initial luminence scaling (equation 2)
54    inColour.rgb *= MIDDLE_GREY / (FUDGE + lum);
55
56        // Control white out (equation 4 nom)
57    inColour.rgb *= (1.0f + inColour / L_WHITE);
58
59        // Final mapping (equation 4 denom)
60        inColour.rgb /= (1.0f + inColour);
61       
62        return inColour;
63
64}
65
66/* Downsample a 2x2 area and convert to greyscale
67*/
68float4 downscale2x2Luminence(
69        float2 uv : TEXCOORD0,
70        uniform float2 texelSize, // depends on size of source texture
71        uniform sampler2D inRTT : register(s0)
72    ) : COLOR
73{
74       
75    float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
76
77        float2 texOffset[4] = {
78                -0.5, -0.5,
79                -0.5,  0.5,
80                 0.5, -0.5,
81                 0.5, 0.5 };
82
83        for( int i = 0; i < 4; i++ )
84    {
85        // Get colour from source
86        accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
87    }
88   
89        // Adjust the accumulated amount by lum factor
90        // Cannot use float3's here because it generates dependent texture errors because of swizzle
91        float lum = dot(accum, LUMINENCE_FACTOR);
92        // take average of 4 samples
93        lum *= 0.25;
94        return lum;
95
96}
97
98/* Downsample a 3x3 area
99 * This shader is used multiple times on different source sizes, so texel size has to be configurable
100*/
101float4 downscale3x3(
102        float2 uv : TEXCOORD0,
103        uniform float2 texelSize, // depends on size of source texture
104        uniform sampler2D inRTT : register(s0)
105    ) : COLOR
106{
107       
108    float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
109
110        float2 texOffset[9] = {
111                -1.0, -1.0,
112                 0.0, -1.0,
113                 1.0, -1.0,
114                -1.0,  0.0,
115                 0.0,  0.0,
116                 1.0,  0.0,
117                -1.0,  1.0,
118                 0.0,  1.0,
119                 1.0,  1.0
120        };
121
122        for( int i = 0; i < 9; i++ )
123    {
124        // Get colour from source
125        accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
126    }
127   
128        // take average of 9 samples
129        accum *= 0.1111111111111111;
130        return accum;
131
132}
133
134/* Downsample a 3x3 area from main RTT and perform a brightness pass
135*/
136float4 downscale3x3brightpass(
137        float2 uv : TEXCOORD0,
138        uniform float2 texelSize, // depends on size of source texture
139        uniform sampler2D inRTT : register(s0),
140        uniform sampler2D inLum : register(s1)
141    ) : COLOR
142{
143       
144    float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
145
146        float2 texOffset[9] = {
147                -1.0, -1.0,
148                 0.0, -1.0,
149                 1.0, -1.0,
150                -1.0,  0.0,
151                 0.0,  0.0,
152                 1.0,  0.0,
153                -1.0,  1.0,
154                 0.0,  1.0,
155                 1.0,  1.0
156        };
157
158        for( int i = 0; i < 9; i++ )
159    {
160        // Get colour from source
161        accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
162    }
163   
164        // take average of 9 samples
165        accum *= 0.1111111111111111;
166
167    // Reduce bright and clamp
168    accum = max(float4(0.0f, 0.0f, 0.0f, 1.0f), accum - BRIGHT_LIMITER);
169
170        // Sample the luminence texture
171        float4 lum = tex2D(inLum, float2(0.5f, 0.5f));
172       
173        // Tone map result
174        return toneMap(accum, lum.r);
175
176}
177
178/* Gaussian bloom, requires offsets and weights to be provided externally
179*/
180float4 bloom(
181                float2 uv : TEXCOORD0,
182                uniform float2 sampleOffsets[15],
183                uniform float4 sampleWeights[15],       
184                uniform sampler2D inRTT : register(s0)
185                ) : COLOR
186{
187    float4 accum = float4(0.0f, 0.0f, 0.0f, 1.0f);
188        float2 sampleUV;
189   
190    for( int i = 0; i < 15; i++ )
191    {
192        // Sample from adjacent points, 7 each side and central
193        sampleUV = uv + sampleOffsets[i];
194        accum += sampleWeights[i] * tex2D(inRTT, sampleUV);
195    }
196   
197    return accum;
198       
199}
200               
201
202/* Final scene composition, with tone mapping
203*/
204float4 finalToneMapping(
205        float2 uv : TEXCOORD0,
206        uniform sampler2D inRTT : register(s0),
207        uniform sampler2D inBloom : register(s1),
208        uniform sampler2D inLum : register(s2)
209    ) : COLOR
210{
211        // Get main scene colour
212    float4 sceneCol = tex2D(inRTT, uv);
213
214        // Get luminence value
215        float4 lum = tex2D(inLum, float2(0.5f, 0.5f));
216
217        // tone map this
218        float4 toneMappedSceneCol = toneMap(sceneCol, lum.r);
219       
220        // Get bloom colour
221    float4 bloom = tex2D(inBloom, uv);
222
223        // Add scene & bloom
224        return float4(toneMappedSceneCol.rgb + bloom.rgb, 1.0f);
225       
226}
227
228
Note: See TracBrowser for help on using the repository browser.