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

Revision 3103, 4.4 KB checked in by mattausch, 16 years ago (diff)

still some error with ssao on edges
bilateral filter slow

RevLine 
[2972]1#include "../shaderenv.h"
2
3
[2974]4struct frag
[2972]5{
6         // normalized screen position
[2974]7        float2 texCoord: TEXCOORD0;
[2973]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
[2972]13};
14
15
[2973]16struct pixel
[2972]17{
[2973]18        float4 col: COLOR0;
19};
[2972]20
21
[3010]22/*float4 DownSample(frag IN,
[2972]23                                  uniform sampler2D colors,
[3010]24                                  uniform float2 downSampleOffs[9]): COLOR
[2972]25{   
26    float4 average = .0f;
27
[3010]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)
[2972]34    {
[3010]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                }
[2972]41    }
42       
[3010]43    //average *= 1.0f / 9.0f;
44    average *= 1.0f / j;
[2972]45
[3006]46    return average;
[3010]47}*/
[3017]48 
49
50// let bilinear filtering do its work
[3010]51float4 DownSample(frag IN,
52                                  uniform sampler2D colors,
53                                  uniform float2 downSampleOffs[NUM_DOWNSAMPLES]): COLOR
54{   
[3016]55        return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
56/*
[3010]57    float4 average = .0f;
58
59    for (int i = 0; i < NUM_DOWNSAMPLES; ++ i)
60    {
61                average += tex2Dlod(colors, float4(IN.texCoord + downSampleOffs[i], 0, 0));
62    }
63       
64        average *= 1.0f / (float)NUM_DOWNSAMPLES;
65
[3016]66    return average;*/
[2972]67}
68
[3010]69
70/** Does the first downsampling step and on the same time calculates the
71        intensity.
72*/
73
[2974]74float4 GreyScaleDownSample(frag IN,
[3010]75                                                   uniform sampler2D colors,
76                                                   uniform float2 downSampleOffs[4]
[2974]77                                                   ): COLOR
[2972]78{
79
80        // Compute the average of the 4 necessary samples
[2974]81        float average = .0f;
82        float maximum = .0f;
[2972]83
84        // the rgb weights
85        const float3 w = float3(0.299f, 0.587f, 0.114f);
86        //float3 w = float3(0.2125f, 0.7154f, 0.0721f);
87
[3010]88        float4 color;
[2973]89
[2972]90        for (int i = 0; i < 4; ++ i)
91        {
[3010]92                color = tex2D(colors, downSampleOffs[i]);
[2973]93                const float intensity = dot(cols[i].rgb, w);
[2972]94
[2973]95                maximum = max(maximum, intensity);
[2974]96                average += log(1e-5f + intensity);
[2972]97        }
98
[3010]99        average *= 0.25f;
[2972]100
101        // Output the luminance to the render target
[3010]102        return float4(average, maximum, 0.0f, 1.0f);
[2972]103}
[2973]104   
[2972]105
[3010]106/** Used for downsampling the tone map parameters (average loglum, maximum)
107        to the next lower level. This has to be applied until there is only
108        a 1x1 texture which holds the required numbers.
109*/
110float4 DownSampleForToneMapping(frag IN,
111                                                                uniform sampler2D colors,
112                                                                uniform float2 downSampleOffs[4]): COLOR
113{   
114        float average = .0f;
115        float maximum = .0f;
116       
117        float4 color;
118
119        for (int i = 0; i < 4; ++ i)
120        {
121                color = tex2D(colors, downSampleOffs[i]);
122
123                maximum = max(maximum, color.y);
124                average += color.x;
125        }
126
127        average *= 1.0f / (float)NUM_DOWNSAMPLES;
128
129        return float4(average, maximum, 0.0f, 1.0f);
130}
131
132
133
[2974]134pixel ToneMap(frag IN,
[2973]135                          uniform sampler2D colors,
136                          uniform float imageKey,
137                          uniform float whiteLum,
138                          uniform float middleGrey)
139{
140        pixel OUT;
[3008]141       
[2974]142        float4 color = tex2D(colors, IN.texCoord);
[2973]143
144        const float pixLum = 0.2125f * color.x + 0.7154f * color.y + 0.0721f * color.z;
145       
[2974]146        // obtain new image key from highest mipmap level
[3103]147        float logLumScaled = tex2Dlod(colors, float4(.5f, .5f, 0, MAX_LOD_LEVEL)).w;
[2975]148        float logLum = logLumScaled * LOGLUM_RANGE + MINLOGLUM;
[2974]149
150        float newImageKey = exp(logLum);
151
[2973]152        // adjust to middle gray
[2974]153        const float lum = middleGrey * pixLum / newImageKey;
[2973]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;
[2991]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
[3103]171        const float4 color = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0));
[2992]172        OUT.col = color;
173
[2991]174        // the old loglum is stored in the hightest mipmap-level
175        float oldLogLum = tex2Dlod(colors, float4(IN.texCoord.xy, 0, MAX_LOD_LEVEL)).w;
176
177        // the intensity weights
178        const float3 w = float3(0.299f, 0.587f, 0.114f);
179
180        float lum = dot(color.rgb, w);
181        float logLum = log(1e-5f + lum);
182
183        float logLumOffset = MINLOGLUM * INV_LOGLUM_RANGE;
184        float logLumScaled = logLum * INV_LOGLUM_RANGE - logLumOffset;
185
[3103]186        // exponential smoothing of tone mapping over time
187        if (oldLogLum > 1e-5f) // loglum from last frame too bright
[2992]188                OUT.col.w = lerp(oldLogLum, logLumScaled, 0.1f);
[2991]189        else
[2992]190                OUT.col.w = logLumScaled;
191
[3008]192        return OUT;
[3103]193}
Note: See TracBrowser for help on using the repository browser.