source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg @ 3016

Revision 3016, 4.3 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "../shaderenv.h"
2
3
4struct frag
5{
6         // normalized screen position
7        float2 texCoord: TEXCOORD0;
8
9        float2 lt: TEXCOORD1; // left top
10        float2 rb: TEXCOORD2; // right bottom
11        float2 rt: TEXCOORD3; // right top
12        float2 lb: TEXCOORD4; // left bottom
13};
14
15
16struct pixel
17{
18        float4 col: COLOR0;
19};
20
21
22/*float4 DownSample(frag IN,
23                                  uniform sampler2D colors,
24                                  uniform float2 downSampleOffs[9]): COLOR
25{   
26    float4 average = .0f;
27
28        const float4 avgColor = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
29
30        float j = 0;
31        float4 color;
32
33    for (int i = 0; i < 9; ++ i)
34    {
35                color = tex2Dlod(colors, float4(IN.texCoord + downSampleOffs[i], 0, 0));
36                if (abs(color.w - avgColor.w) < 1e-3f)
37                {
38                        average += color;
39                        ++ j;
40                }
41    }
42       
43    //average *= 1.0f / 9.0f;
44    average *= 1.0f / j;
45
46    return average;
47}*/
48 
49float4 DownSample(frag IN,
50                                  uniform sampler2D colors,
51                                  uniform float2 downSampleOffs[NUM_DOWNSAMPLES]): COLOR
52{   
53        return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
54/*
55    float4 average = .0f;
56
57    for (int i = 0; i < NUM_DOWNSAMPLES; ++ i)
58    {
59                average += tex2Dlod(colors, float4(IN.texCoord + downSampleOffs[i], 0, 0));
60    }
61       
62        average *= 1.0f / (float)NUM_DOWNSAMPLES;
63
64    return average;*/
65}
66
67
68/** Does the first downsampling step and on the same time calculates the
69        intensity.
70*/
71
72float4 GreyScaleDownSample(frag IN,
73                                                   uniform sampler2D colors,
74                                                   uniform float2 downSampleOffs[4]
75                                                   ): COLOR
76{
77
78        // Compute the average of the 4 necessary samples
79        float average = .0f;
80        float maximum = .0f;
81
82        // the rgb weights
83        const float3 w = float3(0.299f, 0.587f, 0.114f);
84        //float3 w = float3(0.2125f, 0.7154f, 0.0721f);
85
86        float4 color;
87
88        for (int i = 0; i < 4; ++ i)
89        {
90                color = tex2D(colors, downSampleOffs[i]);
91
92                const float intensity = dot(cols[i].rgb, w);
93
94                maximum = max(maximum, intensity);
95                average += log(1e-5f + intensity);
96        }
97
98        average *= 0.25f;
99
100        // Output the luminance to the render target
101        return float4(average, maximum, 0.0f, 1.0f);
102}
103   
104
105/** Used for downsampling the tone map parameters (average loglum, maximum)
106        to the next lower level. This has to be applied until there is only
107        a 1x1 texture which holds the required numbers.
108*/
109float4 DownSampleForToneMapping(frag IN,
110                                                                uniform sampler2D colors,
111                                                                uniform float2 downSampleOffs[4]): COLOR
112{   
113        float average = .0f;
114        float maximum = .0f;
115       
116        float4 color;
117
118        for (int i = 0; i < 4; ++ i)
119        {
120                color = tex2D(colors, downSampleOffs[i]);
121
122                maximum = max(maximum, color.y);
123                average += color.x;
124        }
125
126        average *= 1.0f / (float)NUM_DOWNSAMPLES;
127
128        return float4(average, maximum, 0.0f, 1.0f);
129}
130
131
132
133pixel ToneMap(frag IN,
134                          uniform sampler2D colors,
135                          uniform float imageKey,
136                          uniform float whiteLum,
137                          uniform float middleGrey)
138{
139        pixel OUT;
140       
141        float4 color = tex2D(colors, IN.texCoord);
142
143        const float pixLum = 0.2125f * color.x + 0.7154f * color.y + 0.0721f * color.z;
144       
145        // obtain new image key from highest mipmap level
146        float logLumScaled = tex2Dlod(colors, float4(.5f, .5f, 0, 99)).w;
147        float logLum = logLumScaled * LOGLUM_RANGE + MINLOGLUM;
148
149        float newImageKey = exp(logLum);
150
151        // adjust to middle gray
152        const float lum = middleGrey * pixLum / newImageKey;
153         
154        // map to range and calc burnout
155        const float scaleLum = lum * (1.0f + lum / whiteLum * whiteLum) / (1.0f + lum);
156
157        OUT.col = color * scaleLum / pixLum;
158        OUT.col.w = color.w;
159
160        return OUT;
161}
162
163
164pixel CalcAvgLogLum(frag IN, uniform sampler2D colors)
165{
166        ////////////
167        //-- write out logaritmic luminance for tone mapping
168
169        pixel OUT;
170       
171        const float4 color = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0));
172
173        OUT.col = color;
174
175        // the old loglum is stored in the hightest mipmap-level
176        float oldLogLum = tex2Dlod(colors, float4(IN.texCoord.xy, 0, MAX_LOD_LEVEL)).w;
177
178        // the intensity weights
179        const float3 w = float3(0.299f, 0.587f, 0.114f);
180
181        float lum = dot(color.rgb, w);
182        float logLum = log(1e-5f + lum);
183
184        float logLumOffset = MINLOGLUM * INV_LOGLUM_RANGE;
185        float logLumScaled = logLum * INV_LOGLUM_RANGE - logLumOffset;
186
187        if (oldLogLum > 1e-5f) // too bright
188                OUT.col.w = lerp(oldLogLum, logLumScaled, 0.1f);
189        else
190                OUT.col.w = logLumScaled;
191
192        return OUT;
193}
Note: See TracBrowser for help on using the repository browser.