Skip to main content
GameDev.net gamedev.net
🔒 Locked

Average luminance slowdown

Started by rozz666 Mar 2, 2009 at 3:07 PM 0 replies 1k views
Original Post
rozz666
rozz666
During HDR rendering I have to calculate the average luminance. I iteratively downscale the scene to 2x2 pixels and call GetTexImage to read the values from framebuffere image. Now, the problem is it takes about 10 ms (which is 90% of CPU time of rendering). I thought it's because all previous GL commands have to be finished before reading the texture. So I moved reading before HDR pass, which is the same as skipping 1 frame. But it still takes about 10 ms. If I remove GetTexImage, it takes about 1 ms. Any ideas? Here's the relevant code:

        void Renderer::renderHDR()
        {
            GPUTimerQuery::Scope tc(hdrTQ_);
            CPUTimerQuery::Scope cc(hdrCQ_);


            GLfloat lumValues[4];

            {
                PixelPackBuffer<GLfloat>::Unbind u(pbb2_);

                pbb2_.bind();

                logLBuffer2_.bindTexture();

                glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, 0);

                const GLfloat *p = pbb2_.map(GL_READ_ONLY_ARB);

                std::copy(p, p + 4, lumValues);

                pbb2_.unmap();

            }


            glDisable(GL_DEPTH_TEST);
            glDepthMask(GL_FALSE);
            glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
            glDisable(GL_BLEND);

            const Shader& logLShader = shaderManager_[ShaderManager::LUMINANCE_LOG];

            logLBuffer512_.bind();

            setOrthoMatrices();

            logLShader.use();
            
            glContext_.glUniform1iARB(logLShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1fARB(logLShader.uniformLocation("ds_Sigma"), 0.001f);

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            stencilBuffer_.bindTexture();

            drawQuad(0, 0, 1, 1);

            logLBuffer512_.unbind();

            const Shader& downsampleShader = shaderManager_[ShaderManager::DOWNSAMPLE4x4];

            logLBuffer128_.bind();

            setOrthoMatrices();

            downsampleShader.use();

            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Size"), 512);

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            logLBuffer512_.bindTexture();

            drawQuad(0, 0, 1, 1);

            logLBuffer128_.unbind();

            logLBuffer32_.bind();

            setOrthoMatrices();

            downsampleShader.use();

            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Size"), 128);

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            logLBuffer128_.bindTexture();

            drawQuad(0, 0, 1, 1);

            logLBuffer32_.unbind();

            logLBuffer8_.bind();

            setOrthoMatrices();

            downsampleShader.use();

            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Size"), 32);

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            logLBuffer32_.bindTexture();

            drawQuad(0, 0, 1, 1);

            logLBuffer8_.unbind();

            logLBuffer2_.bind();

            setOrthoMatrices();

            downsampleShader.use();

            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1iARB(downsampleShader.uniformLocation("ds_Size"), 8);

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            logLBuffer8_.bindTexture();

            drawQuad(0, 0, 1, 1);

            logLBuffer2_.unbind();



            GLfloat avLum = 0;

            for (std::size_t i = 0; i < 4; ++i) avLum += lumValues;

            avLum = std::exp(avLum / 4);

            // tone mapping

            const Shader& toneMappingShader = shaderManager_[ShaderManager::DEFERRED_TONE_MAP];

            hdrBuffer_.bind();

            setOrthoMatrices();

            toneMappingShader.use();

            glContext_.glUniform1iARB(toneMappingShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1fARB(toneMappingShader.uniformLocation("ds_WhitePoint2"), 5.0f);

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            stencilBuffer_.bindTexture();

            float delta = 0.04f / (0.04f + avLum);
            float t = delta * 0.4f + (1.0f - delta) * 0.1f;
            double eyeTime = eyeTimer_.time();

            luminance_ += (avLum - luminance_) * (1.0f - std::exp(float(lastEyeTime_ - eyeTime) / t));

            lastEyeTime_ = eyeTime;

            float key = std::max(0.0f, 1.5f - 1.5f / (luminance_ * 3.0f + 1.0f)) + 0.01f;

            glContext_.glUniform1fARB(toneMappingShader.uniformLocation("ds_Exposure"), key / luminance_);

            drawQuad(0, 0, 1, 1);

            hdrBuffer_.unbind();
            
            const Shader& lightPass = shaderManager_[ShaderManager::LIGHT_PASS];

            highlightBuffer_.bind();

            lightPass.use();
            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            hdrBuffer_.bindTexture();

            glContext_.glUniform1iARB(lightPass.uniformLocation("ds_Image"), 0);

            drawQuad(0, 0, 1, 1);

            highlightBuffer_.unbind();

            const Shader& horzBlurShader = shaderManager_[ShaderManager::DEFERRED_HORIZONTAL_BLUR];
            const Shader& vertBlurShader = shaderManager_[ShaderManager::DEFERRED_VERTICAL_BLUR];

            blurBuffer0_.bind();

            horzBlurShader.use();

            glContext_.glUniform1iARB(horzBlurShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1fARB(horzBlurShader.uniformLocation("ds_Size"), GLfloat(window_.width()));

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            highlightBuffer_.bindTexture();

            drawQuad(0, 0, 1, 1);

            blurBuffer0_.unbind();

            hdrBuffer_.bind();

            glEnable(GL_BLEND);
            glBlendFunc(GL_ONE, GL_ONE);

            vertBlurShader.use();
            glContext_.glUniform1iARB(vertBlurShader.uniformLocation("ds_Image"), 0);
            glContext_.glUniform1fARB(horzBlurShader.uniformLocation("ds_Size"), GLfloat(window_.height()));

            glContext_.glActiveTextureARB(GL_TEXTURE0_ARB);
            blurBuffer0_.bindTexture();

            drawQuad(0, 0, 1, 1);

            hdrBuffer_.unbind();
        }



Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.