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

Revision 3132, 3.9 KB checked in by mattausch, 16 years ago (diff)

reordered functions: antialiasing comes after initial shading pass and before ssao.cgadded final output pass which does nothing but stream everything out

now ssao much nicer but slower!!

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
23float4 DownSample(frag IN,
24                                  uniform sampler2D colors,
25                                  uniform float2 downSampleOffs[NUM_DOWNSAMPLES]): COLOR
26{   
27        // let bilinear filtering do its work
28        return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
29/*
30    float4 average = .0f;
31    for (int i = 0; i < NUM_DOWNSAMPLES; ++ i)
32    {
33                average += tex2Dlod(colors, float4(IN.texCoord + downSampleOffs[i], 0, 0));
34    } 
35        average *= 1.0f / (float)NUM_DOWNSAMPLES;
36
37    return average;*/
38}
39
40
41/** Does the first downsampling step and on the same time calculates the
42        intensity.
43*/
44float4 GreyScaleDownSample(frag IN,
45                                                   uniform sampler2D colors,
46                                                   uniform float2 downSampleOffs[4]
47                                                   ): COLOR
48{
49
50        // Compute the average of the 4 necessary samples
51        float average = .0f;
52        float maximum = .0f;
53
54        // the rgb weights
55        const float3 w = float3(0.299f, 0.587f, 0.114f);
56        //float3 w = float3(0.2125f, 0.7154f, 0.0721f);
57
58        float4 color;
59
60        for (int i = 0; i < 4; ++ i)
61        {
62                color = tex2D(colors, downSampleOffs[i]);
63                const float intensity = dot(cols[i].rgb, w);
64
65                maximum = max(maximum, intensity);
66                average += log(1e-5f + intensity);
67        }
68
69        average *= 0.25f;
70
71        // Output the luminance to the render target
72        return float4(average, maximum, 0.0f, 1.0f);
73}
74   
75
76/** Used for downsampling the tone map parameters (average loglum, maximum)
77        to the next lower level. This has to be applied until there is only
78        a 1x1 texture which holds the required numbers.
79*/
80float4 DownSampleForToneMapping(frag IN,
81                                                                uniform sampler2D colors,
82                                                                uniform float2 downSampleOffs[4]): COLOR
83{   
84        float average = .0f;
85        float maximum = .0f;
86       
87        float4 color;
88
89        for (int i = 0; i < 4; ++ i)
90        {
91                color = tex2D(colors, downSampleOffs[i]);
92
93                maximum = max(maximum, color.y);
94                average += color.x;
95        }
96
97        average *= 1.0f / (float)NUM_DOWNSAMPLES;
98
99        return float4(average, maximum, 0.0f, 1.0f);
100}
101
102
103
104pixel ToneMap(frag IN,
105                          uniform sampler2D colors,
106                          uniform float imageKey,
107                          uniform float whiteLum,
108                          uniform float middleGrey)
109{
110        pixel OUT;
111       
112        float4 color = tex2D(colors, IN.texCoord);
113
114        const float pixLum = 0.2125f * color.x + 0.7154f * color.y + 0.0721f * color.z;
115       
116        // obtain new image key from highest mipmap level
117        float logLumScaled = tex2Dlod(colors, float4(.5f, .5f, 0, MAX_LOD_LEVEL)).w;
118        float logLum = logLumScaled * LOGLUM_RANGE + MINLOGLUM;
119
120        float newImageKey = max(exp(logLum), 1e-6f);
121
122        // adjust to middle gray
123        const float lum = middleGrey * pixLum / newImageKey;
124        // map to range and calc burnout
125        const float scaleLum = lum * (1.0f + lum / whiteLum * whiteLum) / (1.0f + lum);
126
127        OUT.col = color * scaleLum / pixLum;
128        OUT.col.w = color.w;
129
130        return OUT;
131}
132
133
134pixel CalcAvgLogLum(frag IN, uniform sampler2D colors)
135{
136        ////////////
137        //-- write out logaritmic luminance for tone mapping
138
139        pixel OUT;
140
141        const float4 color = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0));
142        OUT.col = color;
143
144        // the old loglum is stored in the hightest mipmap-level
145        float oldLogLum = tex2Dlod(colors, float4(IN.texCoord.xy, 0, MAX_LOD_LEVEL)).w;
146
147        // the intensity weights
148        const float3 w = float3(0.299f, 0.587f, 0.114f);
149
150        float lum = dot(color.rgb, w);
151        float logLum = log(max(1e-3f, lum));
152
153        float logLumOffset = MINLOGLUM * INV_LOGLUM_RANGE;
154        float logLumScaled = logLum * INV_LOGLUM_RANGE - logLumOffset;
155
156        const float expFactor = 0.1f;
157        // exponential smoothing of tone mapping over time
158        if (oldLogLum > 1e-3f) // check if loglum from last frame too small (=> tm too bright)
159                OUT.col.w = lerp(oldLogLum, logLumScaled, expFactor);
160        else
161                OUT.col.w = logLumScaled;
162
163        return OUT;
164}
Note: See TracBrowser for help on using the repository browser.