source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.cpp @ 2889

Revision 2889, 26.6 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "SsaoShader.h"
2#include "FrameBufferObject.h"
3#include "RenderState.h"
4#include "SampleGenerator.h"
5#include "Vector3.h"
6#include "Camera.h"
7#include "shaderenv.h"
8#include "RndGauss.h"
9#include "Halton.h"
10
11
12using namespace std;
13
14static GLenum mymrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT};
15
16
17namespace CHCDemoEngine
18{
19
20static CGprogram sCgSsaoProgram = NULL;
21static CGprogram sCgGiProgram = NULL;
22
23static CGprogram sCgDeferredProgram = NULL;
24static CGprogram sCgAntiAliasingProgram = NULL;
25
26static CGparameter sColorsTexCombineParam;
27static CGparameter sSsaoTexCombineParam;
28
29static CGparameter sColorsTexDeferredParam;
30static CGparameter sPositionsTexDeferredParam;
31static CGparameter sNormalsTexDeferredParam;
32
33
34static CGprogram sCgCombinedSsaoProgram = NULL;
35static CGprogram sCgCombinedIllumProgram = NULL;
36
37///////////////////////////////////////7
38
39
40static CGparameter sColorsTexParam;
41static CGparameter sPositionsTexParam;
42static CGparameter sNormalsTexParam;
43
44static CGparameter sOldModelViewProjMatrixParam;
45static CGparameter sMaxDepthParam;
46static CGparameter sSamplesParam;
47static CGparameter sOldTexParam;
48static CGparameter sNoiseTexParam;
49static CGparameter sNoiseMultiplierParam;
50static CGparameter sExpFactorParam;
51
52
53
54///////////////////////////////////////
55
56
57static CGparameter sColorsTexGiParam;
58static CGparameter sPositionsTexGiParam;
59static CGparameter sNormalsTexGiParam;
60
61
62static CGparameter sOldModelViewProjMatrixGiParam;
63static CGparameter sMaxDepthGiParam;
64static CGparameter sSamplesGiParam;
65static CGparameter sOldSsaoTexGiParam;
66static CGparameter sOldIllumTexGiParam;
67static CGparameter sNoiseTexGiParam;
68static CGparameter sNoiseMultiplierGiParam;
69static CGparameter sExpFactorGiParam;
70
71
72static CGparameter sColorsTexCombinedIllumParam;
73static CGparameter sSsaoTexCombinedIllumParam;
74static CGparameter sIllumTexCombinedIllumParam;
75
76static CGparameter sColorsTexCombinedSsaoParam;
77static CGparameter sSsaoTexCombinedSsaoParam;
78
79
80////////////
81
82static CGparameter sColorsTexAntiAliasingParam;
83static CGparameter sNormalsTexAntiAliasingParam;
84
85static GLuint noiseTex = 0;
86
87// ssao random spherical samples
88static Sample2 samples[NUM_SAMPLES];
89
90
91static void PrintGLerror(char *msg)
92{
93        GLenum errCode;
94        const GLubyte *errStr;
95       
96        if ((errCode = glGetError()) != GL_NO_ERROR)
97        {
98                errStr = gluErrorString(errCode);
99                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
100        }
101}
102
103
104/** Generate poisson disc distributed sample points on the unit disc
105*/
106static void GenerateSamples(int sampling)
107{
108        switch (sampling)
109        {
110        case SsaoShader::POISSON:
111                {
112                        static PoissonDiscSampleGenerator poisson(NUM_SAMPLES, 1.0f);
113                        poisson.Generate((Sample2 *)samples);
114                }
115                break;
116        case SsaoShader::GAUSS:
117                {
118                        const float radius = 1.0f;
119                        const float sigma = 0.25f;//ComputeSigmaFromRadius(1.0f);
120
121                        static HaltonSequence halton;
122
123                        for (int i = 0; i < NUM_SAMPLES; ++ i)
124                        {
125                                Sample2 s;
126                                Vector3 input;
127
128                                halton.GetNext(3, (float *)&input.x);
129
130                                //GaussianOn2D(cinput, // input (RND in interval [0-1)x[0-1))
131                                //               sigma,            // standard deviation of gaussian distribution
132                                //                       outputVec)   // resulting vector according to gaussian distr.
133
134                                PolarGaussianOnDisk(input,  // input (RND in interval [0-1)x[0-1))
135                                        sigma,  // standard deviation of gaussian distribution
136                                        radius, // standard deviation of gaussian distribution
137                                        s);     // result
138                                samples[i] = s;
139                        }
140                }
141                break;
142        default:
143                break;
144        }
145}
146
147
148static void CreateNoiseTex2D(int w, int h)
149{
150        //GLubyte *randomNormals = new GLubyte[mWidth * mHeight * 3];
151        float *randomNormals = new float[w * h * 3];
152
153        for (int i = 0; i < w * h * 3; i += 3)
154        {
155                // create random samples on a circle
156                const float rx = RandomValue(0, 1);
157                const float theta = 2.0f * acos(sqrt(1.0f - rx));
158
159                //randomNormals[i + 0] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
160                //randomNormals[i + 1] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
161                randomNormals[i + 0] = cos(theta);
162                randomNormals[i + 1] = sin(theta);
163                randomNormals[i + 2] = 0;
164        }
165
166        glEnable(GL_TEXTURE_2D);
167        glGenTextures(1, &noiseTex);
168        glBindTexture(GL_TEXTURE_2D, noiseTex);
169               
170        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
171        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
172        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
173        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
174
175        //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
176        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGB, GL_FLOAT, randomNormals);
177
178        glBindTexture(GL_TEXTURE_2D, 0);
179        glDisable(GL_TEXTURE_2D);
180
181        delete [] randomNormals;
182
183        cout << "created noise texture" << endl;
184
185        PrintGLerror("noisetexture");
186}
187
188
189SsaoShader::SsaoShader(int w, int h, Camera *cam, float scaleFactor):
190mWidth(w), mHeight(h),
191mCamera(cam),
192mScaleFactor(scaleFactor),
193mUseTemporalCoherence(true),
194mUseGlobIllum(false),
195mSampling(POISSON)
196{
197        // create noise texture for ssao
198        CreateNoiseTex2D(w, h);
199
200        ///////////
201        //-- the flip-flop fbos
202
203        mNewFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
204       
205        mNewFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);
206        mNewFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);
207       
208
209        ///////////////////////
210
211        mOldFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
212       
213        mOldFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);
214        mOldFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);
215       
216        //mFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
217        //mFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);*/
218}
219
220
221SsaoShader::~SsaoShader()
222{
223        if (sCgSsaoProgram)     cgDestroyProgram(sCgSsaoProgram);
224        if (sCgDeferredProgram) cgDestroyProgram(sCgDeferredProgram);
225        if (sCgSsaoProgram)     cgDestroyProgram(sCgSsaoProgram);
226        if (sCgGiProgram) cgDestroyProgram(sCgGiProgram);
227        if (sCgAntiAliasingProgram) cgDestroyProgram(sCgAntiAliasingProgram);
228
229        DEL_PTR(mNewFbo);
230        DEL_PTR(mOldFbo);
231        //DEL_PTR(mFbo);
232
233        glDeleteTextures(1, &noiseTex);
234}
235
236
237void SsaoShader::SetUseGlobIllum(bool useGlobIllum)
238{
239        mUseGlobIllum = useGlobIllum;
240}
241
242
243void SsaoShader::SetUseTemporalCoherence(bool temporal)
244{
245        mUseTemporalCoherence = temporal;
246}
247
248
249void SsaoShader::Init(CGcontext context)
250{       
251        sCgDeferredProgram =
252                cgCreateProgramFromFile(context,
253                                                                CG_SOURCE,
254                                                                "src/shaders/deferred.cg",
255                                                                RenderState::sCgFragmentProfile,
256                                                                "main",
257                                                                NULL);
258
259        if (sCgDeferredProgram != NULL)
260        {
261                cgGLLoadProgram(sCgDeferredProgram);
262
263                // we need size of texture for scaling
264                sPositionsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "positions"); 
265                sColorsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "colors"); 
266                sNormalsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "normals");
267        }
268        else
269                cerr << "deferred program failed to load" << endl;
270
271
272        ///////////////
273
274        sCgSsaoProgram =
275                cgCreateProgramFromFile(context,
276                                                                CG_SOURCE,
277                                                                "src/shaders/ssao.cg",
278                                                                RenderState::sCgFragmentProfile,
279                                                                "main",
280                                                                NULL);
281
282        if (sCgSsaoProgram != NULL)
283        {
284                cgGLLoadProgram(sCgSsaoProgram);
285
286                // we need size of texture for scaling
287                sPositionsTexParam = cgGetNamedParameter(sCgSsaoProgram, "positions"); 
288                sColorsTexParam = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
289                sNormalsTexParam = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
290                sNoiseTexParam = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
291                sNoiseMultiplierParam = cgGetNamedParameter(sCgSsaoProgram, "noiseMultiplier");
292               
293                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
294                sMaxDepthParam = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
295                sExpFactorParam = cgGetNamedParameter(sCgSsaoProgram, "expFactor");
296
297                sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
298               
299                cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
300
301                // generate samples for ssao kernel
302                //GenerateSamples(mSampling);
303
304                sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
305                //cgSetArraySize(sSamplesParam, NUM_SAMPLES);
306                //cgCompileProgram(sCgSsaoProgram);
307               
308                //cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples);
309        }
310        else
311                cerr << "ssao program failed to load" << endl;
312
313        sCgGiProgram =
314                cgCreateProgramFromFile(context,
315                                                                CG_SOURCE,
316                                                                "src/shaders/globillum.cg",
317                                                                RenderState::sCgFragmentProfile,
318                                                                "main",
319                                                                NULL);
320
321        if (sCgGiProgram != NULL)
322        {
323                cgGLLoadProgram(sCgGiProgram);
324
325                // we need size of texture for scaling
326                sPositionsTexGiParam = cgGetNamedParameter(sCgGiProgram, "positions"); 
327                sColorsTexGiParam = cgGetNamedParameter(sCgGiProgram, "colors"); 
328                sNormalsTexGiParam = cgGetNamedParameter(sCgGiProgram, "normals"); 
329                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
330                sNoiseMultiplierGiParam = cgGetNamedParameter(sCgGiProgram, "noiseMultiplier");
331               
332                sOldModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "oldModelViewProj");
333                sMaxDepthGiParam = cgGetNamedParameter(sCgGiProgram, "maxDepth");
334                sExpFactorGiParam = cgGetNamedParameter(sCgGiProgram, "expFactor");
335
336                sSamplesGiParam = cgGetNamedParameter(sCgGiProgram, "samples");
337               
338                sOldSsaoTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldSsaoTex"); 
339                sOldIllumTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldIllumTex"); 
340
341                // generate samples for ssao kernel
342                //GenerateSamples();
343                //cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples);
344
345                cgGLSetParameter1f(sNoiseMultiplierGiParam, RandomValue(3.0f, 17.0f));
346        }
347        else
348                cerr << "globillum program failed to load" << endl;
349
350        sCgCombinedIllumProgram =
351                cgCreateProgramFromFile(context,
352                                                                CG_SOURCE,
353                                                                "src/shaders/globillum.cg",
354                                                                RenderState::sCgFragmentProfile,
355                                                                "combine",
356                                                                NULL);
357
358        if (sCgCombinedIllumProgram != NULL)
359        {
360                cgGLLoadProgram(sCgCombinedIllumProgram);
361
362                sColorsTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "colors"); 
363                sSsaoTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "ssaoTex");
364                sIllumTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "illumTex");
365        }
366        else
367                cerr << "combined illum program failed to load" << endl;
368
369
370        sCgCombinedSsaoProgram =
371                cgCreateProgramFromFile(context,
372                                                                CG_SOURCE,
373                                                                "src/shaders/ssao.cg",
374                                                                RenderState::sCgFragmentProfile,
375                                                                "combine",
376                                                                NULL);
377
378        if (sCgCombinedSsaoProgram != NULL)
379        {
380                cgGLLoadProgram(sCgCombinedSsaoProgram);
381
382                sColorsTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "colors"); 
383                sSsaoTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "ssaoTex");
384        }
385        else
386                cerr << "combied illum program failed to load" << endl;
387
388       
389        sCgAntiAliasingProgram =
390                cgCreateProgramFromFile(context,
391                                                                CG_SOURCE,
392                                                                "src/shaders/antialiasing.cg",
393                                                                RenderState::sCgFragmentProfile,
394                                                                "main",
395                                                                NULL);
396
397        if (sCgAntiAliasingProgram != NULL)
398        {
399                cgGLLoadProgram(sCgAntiAliasingProgram);
400
401                sColorsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "colors"); 
402                sNormalsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "normals");
403        }
404        else
405                cerr << "antialiasing program failed to load" << endl;
406
407        PrintGLerror("init");
408}
409
410
411void SsaoShader::Render(FrameBufferObject *fbo,
412                                                const Matrix4x4 &oldProjViewMatrix,
413                                                float expFactor)
414{
415       
416        // switch roles of old and new fbo
417        // the algorihm uses two input fbos, where the one
418        // contais the color buffer from the last frame,
419        // the other one will be written
420        swap(mNewFbo, mOldFbo);
421
422        FrameBufferObject::Release();
423
424        cgGLEnableProfile(RenderState::sCgFragmentProfile);
425
426        glDisable(GL_ALPHA_TEST);
427        glDisable(GL_TEXTURE_2D);
428        glDisable(GL_LIGHTING);
429
430        glPushAttrib(GL_VIEWPORT_BIT);
431        glViewport(0, 0, mWidth, mHeight);
432
433        glMatrixMode(GL_PROJECTION);
434        glPushMatrix();
435        glLoadIdentity();
436
437        glMatrixMode(GL_MODELVIEW);
438        glPushMatrix();
439        glLoadIdentity();
440
441        const float offs = 0.5f;
442        glOrtho(-offs, offs, -offs, offs, 0, 1);
443
444        FirstPass(fbo);
445       
446        if (!mUseGlobIllum)
447        {
448                ComputeSsao(fbo, expFactor, oldProjViewMatrix);
449                CombineSsao(fbo);
450        }
451        else
452        {
453                ComputeGlobIllum(fbo, expFactor, oldProjViewMatrix);
454                CombineIllum(fbo);
455        }
456
457        AntiAliasing(fbo);
458
459        glEnable(GL_LIGHTING);
460        glDisable(GL_TEXTURE_2D);
461
462        glMatrixMode(GL_PROJECTION);
463        glPopMatrix();
464
465        glMatrixMode(GL_MODELVIEW);
466        glPopMatrix();
467
468        glPopAttrib();
469
470        cgGLDisableProfile(RenderState::sCgFragmentProfile);
471}
472
473
474void SsaoShader::ComputeSsao(FrameBufferObject *fbo,
475                                                         float expFactor,
476                                                         const Matrix4x4 &oldProjViewMatrix
477                                                         )
478{
479        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
480
481        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
482        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
483        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
484
485        if (1)
486        {
487                // generate mip map levels for position texture
488                glBindTexture(GL_TEXTURE_2D, positionsTex);
489                glGenerateMipmapEXT(GL_TEXTURE_2D);
490        }
491
492
493        // read the second buffer, write to the first buffer
494        mNewFbo->Bind();
495        glDrawBuffers(1, mymrt);
496
497
498        GLuint oldTex = mOldFbo->GetColorBuffer(0)->GetTexture();
499
500        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
501
502        cgGLEnableProfile(RenderState::sCgFragmentProfile);
503        cgGLBindProgram(sCgSsaoProgram);
504
505        cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
506        cgGLEnableTextureParameter(sPositionsTexParam);
507
508        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
509        cgGLEnableTextureParameter(sColorsTexParam);
510
511        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
512        cgGLEnableTextureParameter(sNormalsTexParam);
513
514        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
515        cgGLEnableTextureParameter(sNoiseTexParam);
516
517        cgGLSetTextureParameter(sOldTexParam, oldTex);
518        cgGLEnableTextureParameter(sOldTexParam);
519       
520        cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
521       
522        if (mUseTemporalCoherence)
523        {
524                cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
525                cgGLSetParameter1f(sExpFactorParam, expFactor);
526
527
528                // q: should we generate new samples or only rotate the old ones?
529                // in the first case, the sample patterns look nicer, but the kernel
530                // needs longer to converge
531                GenerateSamples(mSampling);
532                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples);
533        }
534        else
535        {
536                        cgGLSetParameter1f(sExpFactorParam, 1.0f);
537        }
538
539        Vector3 tl, tr, bl, br;
540        ComputeViewVectors(tl, tr, bl, br);
541
542        glBegin(GL_QUADS);
543
544        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
545        //const float new_offs = 0.55f;
546        const float new_offs = 0.5f;
547        /*
548        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-new_offs, -new_offs, -0.5f);
549        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( new_offs, -new_offs, -0.5f);
550        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( new_offs,  new_offs, -0.5f);
551        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-new_offs,  new_offs, -0.5f);
552*/
553        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f(-new_offs, -new_offs, -0.5f);
554        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f( new_offs, -new_offs, -0.5f);
555        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f( new_offs,  new_offs, -0.5f);
556        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f(-new_offs,  new_offs, -0.5f);
557
558        glEnd();
559
560        cgGLDisableTextureParameter(sColorsTexParam);
561        cgGLDisableTextureParameter(sPositionsTexParam);
562        cgGLDisableTextureParameter(sNormalsTexParam);
563        cgGLDisableTextureParameter(sNoiseTexParam);
564        cgGLDisableTextureParameter(sOldTexParam);
565
566
567        FrameBufferObject::Release();
568
569        PrintGLerror("ssao first pass");
570}
571
572
573void SsaoShader::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
574{
575        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
576
577        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
578
579#if 1
580       
581        bl = Normalize(nbl - fbl);
582        br = Normalize(nbr - fbr);
583        tl = Normalize(ntl - ftl);
584        tr = Normalize(ntr - ftr);
585
586#else // just take camera direction
587       
588        bl = -Normalize(mCamera->GetDirection());
589        br = -Normalize(mCamera->GetDirection());
590        tl = -Normalize(mCamera->GetDirection());
591        tr = -Normalize(mCamera->GetDirection());
592
593#endif
594
595        // pack into 0 .. 1
596        /*bl = bl * 0.5f + 0.5f;
597        br = br * 0.5f + 0.5f;
598        tl = tl * 0.5f + 0.5f;
599        tr = tr * 0.5f + 0.5f;*/
600}
601
602
603
604static void SetVertex(float x, float y, float x_offs, float y_offs)
605{
606        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
607        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
608        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
609        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
610        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
611
612        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
613        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
614
615        glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
616}
617
618
619void SsaoShader::AntiAliasing(FrameBufferObject *fbo)
620{
621        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
622        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
623       
624        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
625
626        cgGLEnableProfile(RenderState::sCgFragmentProfile);
627        cgGLBindProgram(sCgAntiAliasingProgram);
628       
629        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
630        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
631
632        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
633        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
634
635        glColor3f(1.0f, 1.0f, 1.0f);
636
637        float offs2 = 0.5f;
638
639        glBegin(GL_QUADS);
640
641        // the neighbouring texels
642        float x_offs = 1.0f / mWidth;
643        float y_offs = 1.0f / mHeight;
644
645        SetVertex(0, 0, x_offs, y_offs);
646        SetVertex(1, 0, x_offs, y_offs);
647        SetVertex(1, 1, x_offs, y_offs);
648        SetVertex(0, 1, x_offs, y_offs);
649
650        glEnd();
651
652        cgGLDisableTextureParameter(sColorsTexAntiAliasingParam);
653        cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam);
654
655        PrintGLerror("antialiasing");
656}
657
658
659void SsaoShader::FirstPass(FrameBufferObject *fbo)
660{
661        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
662        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
663        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
664
665        fbo->Bind();
666
667        glDrawBuffers(1, mymrt + 3);
668
669        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
670       
671        cgGLEnableProfile(RenderState::sCgFragmentProfile);
672
673        cgGLBindProgram(sCgDeferredProgram);
674
675        cgGLSetTextureParameter(sColorsTexDeferredParam, colorsTex);
676        cgGLEnableTextureParameter(sColorsTexDeferredParam);
677
678        cgGLSetTextureParameter(sPositionsTexDeferredParam, positionsTex);
679        cgGLEnableTextureParameter(sPositionsTexDeferredParam);
680
681        cgGLSetTextureParameter(sNormalsTexDeferredParam, normalsTex);
682        cgGLEnableTextureParameter(sNormalsTexDeferredParam);
683       
684        glColor3f(1.0f, 1.0f, 1.0f);
685
686        const float offs = 0.5f;
687
688        glBegin(GL_QUADS);
689
690        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
691        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
692        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
693        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
694
695        glEnd();
696
697        cgGLDisableTextureParameter(sColorsTexDeferredParam);
698        cgGLDisableTextureParameter(sPositionsTexDeferredParam);
699        cgGLDisableTextureParameter(sNormalsTexDeferredParam);
700
701        cgGLDisableProfile(RenderState::sCgFragmentProfile);
702
703        FrameBufferObject::Release();
704
705        PrintGLerror("deferred shading");
706}
707
708
709void SsaoShader::ComputeGlobIllum(FrameBufferObject *fbo,
710                                                                  float expFactor,
711                                                                  const Matrix4x4 &oldProjViewMatrix
712                                                                  )
713{
714        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
715
716        //GLuint colorsTex = mFbo->GetColorBuffer(0)->GetTexture();
717        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
718        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
719        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
720
721        if (1)
722        {
723                // generate mip map levels for position texture
724                glBindTexture(GL_TEXTURE_2D, positionsTex);
725                glGenerateMipmapEXT(GL_TEXTURE_2D);
726
727                // generate mip map levels for position texture
728                glBindTexture(GL_TEXTURE_2D, colorsTex);
729                glGenerateMipmapEXT(GL_TEXTURE_2D);
730        }
731
732
733        // read the second buffer, write to the first buffer
734        mNewFbo->Bind();
735        glDrawBuffers(2, mymrt);
736
737        GLuint oldSsaoTex = mOldFbo->GetColorBuffer(0)->GetTexture();
738        GLuint oldIllumTex = mOldFbo->GetColorBuffer(1)->GetTexture();
739
740        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
741
742        cgGLEnableProfile(RenderState::sCgFragmentProfile);
743        cgGLBindProgram(sCgGiProgram);
744
745        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
746        cgGLEnableTextureParameter(sPositionsTexGiParam);
747
748        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
749        cgGLEnableTextureParameter(sColorsTexGiParam);
750
751        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
752        cgGLEnableTextureParameter(sNormalsTexGiParam);
753
754        cgGLSetTextureParameter(sNoiseTexGiParam, noiseTex);
755        cgGLEnableTextureParameter(sNoiseTexGiParam);
756
757        cgGLSetTextureParameter(sOldSsaoTexGiParam, oldSsaoTex);
758        cgGLEnableTextureParameter(sOldSsaoTexGiParam);
759
760        cgGLSetTextureParameter(sOldIllumTexGiParam, oldIllumTex);
761        cgGLEnableTextureParameter(sOldIllumTexGiParam);
762
763        cgGLSetParameter1f(sMaxDepthGiParam, mScaleFactor);
764
765
766        if (mUseTemporalCoherence)
767        {
768                cgGLSetParameter1f(sNoiseMultiplierGiParam, RandomValue(3.0f, 17.0f));
769                cgGLSetParameter1f(sExpFactorGiParam, expFactor);
770
771                // q: should we generate new samples or only rotate the old ones?
772                // in the first case, the sample patterns look nicer, but the kernel
773                // needs longer to converge
774                GenerateSamples(mSampling);
775                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples);
776        }
777        else
778        {
779                        cgGLSetParameter1f(sExpFactorGiParam, 1.0f);
780        }
781
782        Vector3 tl, tr, bl, br;
783        ComputeViewVectors(tl, tr, bl, br);
784
785        glColor3f(1.0f, 1.0f, 1.0f);
786
787        glBegin(GL_QUADS);
788
789        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
790        //const float new_offs = 0.55f;
791        const float new_offs = 0.5f;
792       
793        glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-new_offs, -new_offs, -0.5f);
794        glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( new_offs, -new_offs, -0.5f);
795        glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( new_offs,  new_offs, -0.5f);
796        glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-new_offs,  new_offs, -0.5f);
797
798        glEnd();
799
800        cgGLDisableTextureParameter(sColorsTexGiParam);
801        cgGLDisableTextureParameter(sPositionsTexGiParam);
802        cgGLDisableTextureParameter(sNormalsTexGiParam);
803        cgGLDisableTextureParameter(sNoiseTexGiParam);
804        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
805        cgGLDisableTextureParameter(sOldIllumTexGiParam);
806
807        FrameBufferObject::Release();
808
809        PrintGLerror("globillum first pass");
810}
811
812
813void SsaoShader::CombineIllum(FrameBufferObject *fbo)
814{
815        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
816
817        GLuint ssaoTex = mNewFbo->GetColorBuffer(0)->GetTexture();
818        GLuint illumTex = mNewFbo->GetColorBuffer(1)->GetTexture();
819
820        fbo->Bind();
821
822        // overwrite old color texture
823        glDrawBuffers(1, mymrt);
824
825        cgGLEnableProfile(RenderState::sCgFragmentProfile);
826
827        cgGLBindProgram(sCgCombinedIllumProgram);
828
829        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
830       
831
832        cgGLSetTextureParameter(sColorsTexCombinedIllumParam, colorsTex);
833        cgGLEnableTextureParameter(sColorsTexCombinedIllumParam);
834
835        cgGLSetTextureParameter(sSsaoTexCombinedIllumParam, ssaoTex);
836        cgGLEnableTextureParameter(sSsaoTexCombinedIllumParam);
837
838        cgGLSetTextureParameter(sIllumTexCombinedIllumParam, illumTex);
839        cgGLEnableTextureParameter(sIllumTexCombinedIllumParam);
840       
841        glColor3f(1.0f, 1.0f, 1.0f);
842
843        const float offs = 0.5f;
844
845        glBegin(GL_QUADS);
846
847        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
848        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
849        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
850        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
851
852        glEnd();
853
854        cgGLDisableTextureParameter(sColorsTexCombinedIllumParam);
855        cgGLDisableTextureParameter(sSsaoTexCombinedIllumParam);
856        cgGLDisableTextureParameter(sIllumTexCombinedIllumParam);
857
858        cgGLDisableProfile(RenderState::sCgFragmentProfile);
859
860        FrameBufferObject::Release();
861
862        PrintGLerror("combine");
863}
864
865
866void SsaoShader::CombineSsao(FrameBufferObject *fbo)
867{
868        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
869        GLuint ssaoTex = mNewFbo->GetColorBuffer(0)->GetTexture();
870
871        fbo->Bind();
872
873        // write into old color texture (not needed anymore)
874        glDrawBuffers(1, mymrt);
875
876        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
877       
878        cgGLEnableProfile(RenderState::sCgFragmentProfile);
879
880        cgGLBindProgram(sCgCombinedSsaoProgram);
881
882        cgGLSetTextureParameter(sColorsTexCombinedSsaoParam, colorsTex);
883        cgGLEnableTextureParameter(sColorsTexCombinedSsaoParam);
884
885        cgGLSetTextureParameter(sSsaoTexCombinedSsaoParam, ssaoTex);
886        cgGLEnableTextureParameter(sSsaoTexCombinedSsaoParam);
887
888       
889        glColor3f(1.0f, 1.0f, 1.0f);
890
891        const float offs = 0.5f;
892
893        glBegin(GL_QUADS);
894
895        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
896        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
897        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
898        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
899
900        glEnd();
901
902        cgGLDisableTextureParameter(sColorsTexCombinedSsaoParam);
903        cgGLDisableTextureParameter(sSsaoTexCombinedSsaoParam);
904
905        cgGLDisableProfile(RenderState::sCgFragmentProfile);
906
907        FrameBufferObject::Release();
908
909        PrintGLerror("combine ssao");
910}
911
912
913
914} // namespace
Note: See TracBrowser for help on using the repository browser.