framework2

Форк
0
255 строк · 9.7 Кб
1
/*
2
 *  SSAOPass.h
3
 *
4
 *  Copyright (c) 2013, satcy, http://satcy.net
5
 *  All rights reserved. 
6
 *  
7
 *  Redistribution and use in source and binary forms, with or without 
8
 *  modification, are permitted provided that the following conditions are met: 
9
 *  
10
 *  * Redistributions of source code must retain the above copyright notice, 
11
 *    this list of conditions and the following disclaimer. 
12
 *  * Redistributions in binary form must reproduce the above copyright 
13
 *    notice, this list of conditions and the following disclaimer in the 
14
 *    documentation and/or other materials provided with the distribution. 
15
 *  * Neither the name of Neil Mendoza nor the names of its contributors may be used 
16
 *    to endorse or promote products derived from this software without 
17
 *    specific prior written permission. 
18
 *  
19
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
20
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
21
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
22
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
23
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
24
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
25
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
26
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
27
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
28
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
29
 *  POSSIBILITY OF SUCH DAMAGE. 
30
 *
31
 */
32
#include "SSAOPass.h"
33
#include "ofMain.h"
34

35
namespace itg
36
{
37
    SSAOPass::SSAOPass(const ofVec2f& aspect, bool arb, const char * customVertexShader, const char * customFragmentShader, float cameraNear, float cameraFar, float fogNear, float fogFar, bool fogEnabled, bool onlyAO, float aoClamp, float lumInfluence) :
38
        cameraNear(cameraNear), cameraFar(cameraFar), fogNear(fogNear), fogFar(fogFar), fogEnabled(fogEnabled), onlyAO(onlyAO), aoClamp(aoClamp), lumInfluence(lumInfluence), RenderPass(aspect, arb, "SSAO")
39
    {
40
        string fragShaderSrc = "";
41
        
42
        if (customFragmentShader == NULL) {
43
          fragShaderSrc = STRINGIFY(
44
            uniform float cameraNear;
45
            uniform float cameraFar;
46

47
            uniform float fogNear;
48
            uniform float fogFar;
49

50
            uniform bool fogEnabled;		// attenuate AO with linear fog
51
            uniform bool onlyAO; 		// use only ambient occlusion pass?
52

53
            uniform vec2 size;			// texture width, height
54
            uniform float aoClamp; 		// depth clamp - reduces haloing at screen edges
55

56
            uniform float lumInfluence;  // how much luminance affects occlusion
57

58
            uniform sampler2D tDiffuse;
59
            uniform sampler2D tDepth;
60

61
            //const float PI = 3.14159265;
62
            const float DL = 2.399963229728653; // PI * ( 3.0 - sqrt( 5.0 ) )
63
            const float EULER = 2.718281828459045;
64

65
            // helpers
66

67
            float width = size.x; 	// texture width
68
            float height = size.y; 	// texture height
69

70
            float cameraFarPlusNear = cameraFar + cameraNear;
71
            float cameraFarMinusNear = cameraFar - cameraNear;
72
            float cameraCoef = 2.0 * cameraNear;
73

74
            // user variables
75

76
            const int samples = 8; 		// ao sample count
77
            const float radius = 5.0; 	// ao radius
78

79
            const bool useNoise = true; 		 // use noise instead of pattern for sample dithering
80
            const float noiseAmount = 0.0003; // dithering amount
81

82
            const float diffArea = 0.4; 		// self-shadowing reduction
83
            const float gDisplace = 0.4; 	// gauss bell center
84

85
            const vec3 onlyAOColor = vec3( 1.0, 0.7, 0.5 );
86
            //const vec3 onlyAOColor = vec3( 1.0, 1.0, 1.0 );,
87

88

89
            // RGBA depth
90

91
            float unpackDepth( const in vec4 rgba_depth ) {
92
                const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
93
                float depth = dot( rgba_depth, bit_shift );
94
                return depth;
95
            }
96

97
            // generating noise / pattern texture for dithering
98

99
            vec2 rand( const vec2 coord ) {
100

101
                vec2 noise;
102

103
                if ( useNoise ) {
104
                 
105
                 float nx = dot ( coord, vec2( 12.9898, 78.233 ) );
106
                 float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );
107
                 
108
                 noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );
109
                 
110
                } else {
111
                 
112
                 float ff = fract( 1.0 - coord.s * ( width / 2.0 ) );
113
                 float gg = fract( coord.t * ( height / 2.0 ) );
114
                 
115
                 noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;
116
                 
117
                }
118

119
                return ( noise * 2.0  - 1.0 ) * noiseAmount;
120

121
            }
122

123
            float doFog() {
124
                vec2 vUv = gl_TexCoord[0].st;
125
                float zdepth = unpackDepth( texture2D( tDepth, vUv ) );
126
                float depth = -cameraFar * cameraNear / ( zdepth * cameraFarMinusNear - cameraFar );
127

128
                return smoothstep( fogNear, fogFar, depth );
129

130
            }
131

132
            float readDepth( const in vec2 coord ) {
133

134
                //return ( 2.0 * cameraNear ) / ( cameraFar + cameraNear - unpackDepth( texture2D( tDepth, coord ) ) * ( cameraFar - cameraNear ) );,
135
                return cameraCoef / ( cameraFarPlusNear - unpackDepth( texture2D( tDepth, coord ) ) * cameraFarMinusNear );
136

137

138
            }
139

140
            float compareDepths( const in float depth1, const in float depth2, inout int far ) {
141

142
                float garea = 2.0; 						 // gauss bell width
143
                float diff = ( depth1 - depth2 ) * 100.0; // depth difference (0-100)
144

145
                // reduce left bell width to avoid self-shadowing
146

147
                if ( diff < gDisplace ) {
148
                 
149
                 garea = diffArea;
150
                 
151
                } else {
152
                 
153
                 far = 1;
154
                 
155
                }
156

157
                float dd = diff - gDisplace;
158
                float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );
159
                return gauss;
160

161
            }
162

163
            float calcAO( float depth, float dw, float dh ) {
164
                vec2 vUv = gl_TexCoord[0].st;
165
                float dd = radius - depth * radius;
166
                vec2 vv = vec2( dw, dh );
167
                vec2 coord1 = vUv + dd * vv;
168
                vec2 coord2 = vUv - dd * vv;
169

170
                float temp1 = 0.0;
171
                float temp2 = 0.0;
172
                int far = 0;
173
                temp1 = compareDepths( depth, readDepth( coord1 ), far );
174

175
                // DEPTH EXTRAPOLATION
176

177
                if ( far > 0 ) {
178
                 temp2 = compareDepths( readDepth( coord2 ), depth, far );
179
                 temp1 += ( 1.0 - temp1 ) * temp2;
180
                }
181
                return temp1;
182
            }
183
            void main() {
184
                vec2 vUv = gl_TexCoord[0].st;
185
                vec2 noise = rand( vUv );
186
                float depth = readDepth( vUv );
187
                float tt = clamp( depth, aoClamp, 1.0 );
188
                float w = ( 1.0 / width )  / tt + ( noise.x * ( 1.0 - noise.x ) );
189
                float h = ( 1.0 / height ) / tt + ( noise.y * ( 1.0 - noise.y ) );
190
                float pw;
191
                float ph;
192
                float ao;
193
                float dz = 1.0 / float( samples );
194
                float z = 1.0 - dz / 2.0;
195
                float l = 0.0;
196
                for ( int i = 0; i <= samples; i ++ ) {
197
                 float r = sqrt( 1.0 - z );
198
                 pw = cos( l ) * r;
199
                 ph = sin( l ) * r;
200
                 ao += calcAO( depth, pw * w, ph * h );
201
                 z = z - dz;
202
                 l = l + DL;
203
                }
204
                ao /= float( samples );
205
                ao = 1.0 - ao;
206
                if ( fogEnabled ) {
207
                 ao = mix( ao, 1.0, doFog() );
208
                }
209
                vec3 color = texture2D( tDiffuse, vUv ).rgb;
210
                vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );
211
                float lum = dot( color.rgb, lumcoeff );
212
                vec3 luminance = vec3( lum );
213
                vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );
214
                if ( onlyAO ) {
215
                    final = onlyAOColor * vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );
216
                }
217
                gl_FragColor = vec4( final, 1.0 );
218
            }
219
          );
220
        } else {
221
          fragShaderSrc = customFragmentShader;
222
        }
223
        
224
    
225
        shader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragShaderSrc);
226
        shader.linkProgram();
227
        
228
    }
229
    
230

231
    void SSAOPass::render(ofFbo& readFbo, ofFbo& writeFbo, ofTexture& depthTex)
232
    {
233
        writeFbo.begin();
234
        
235
        
236
        shader.begin();
237
        
238
        shader.setUniformTexture("tDiffuse", readFbo.getTexture(), 0);
239
        shader.setUniformTexture("tDepth", depthTex, 1);
240
        shader.setUniform2f("size", writeFbo.getWidth(), writeFbo.getHeight());
241
        shader.setUniform1f("cameraNear", cameraNear);
242
        shader.setUniform1f("cameraFar", cameraFar);
243
        shader.setUniform1f("fogNear", fogNear);
244
        shader.setUniform1f("fogFar", fogFar);
245
        shader.setUniform1i("fogEnabled", fogEnabled ? 1 : 0 );
246
        shader.setUniform1i("onlyAO", onlyAO ? 1 : 0);
247
        shader.setUniform1f("aoClamp", aoClamp);
248
        shader.setUniform1f("lumInfluence", lumInfluence);
249
        
250
        texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight());
251
        
252
        shader.end();
253
        writeFbo.end();
254
    }
255
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.