Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/skybox/Media/materials/programs/hdr.hlsl @ 883

Last change on this file since 883 was 390, checked in by landauf, 17 years ago

added materials

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.