0
\$\begingroup\$

I am trying to implement shadow mapping, and currently I have 2 point lights and 1 global ambient light source and my rendering loop looks roughly like this (the details are not relevant):

void OpenGLRenderer::DrawRenderables(const uint32_t windowWidth, const uint32_t windowHeight, const RenderQueue& renderQueue, const RenderableLighting& lighting)
{
    GLCALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

    for (uint32_t lightIndex = 0; lightIndex < lighting.mUsedLights; lightIndex++)
    {
        if (lighting.mLights[lightIndex].mLightType == LightType::LIGHT_TYPE_POINT)
        {
            GLCALL(glUseProgram(mShadowMapProgram.mProgramHandle));
            GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, mFrameBuffer));
            GLCALL(glViewport(0, 0, mShadowTextureWidth, mShadowTextureHeight));
            for (uint32_t faceNum = 0; faceNum < CUBEMAP_NUM_FACES; faceNum++)
            {
                GLCALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceNum, mShadowMapTexture, 0));
                GLCALL(glClear(GL_DEPTH_BUFFER_BIT));

                ShadowPass();
            }
            GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));

        }

        // final pass
        GLCALL(glUseProgram(mDefaultProgram.mProgramHandle));
        GLCALL(glViewport(0, 0, (GLsizei)windowWidth, (GLsizei)windowHeight));

        // enable blending, how?

        ShadingPass();
    }

    GLCALL(glUseProgram(0));
}

The problem is the screen will only be shown with last light in the light list, for example the ambient light and therefore ignoring the effects of the point lights. I assume I somehow needs to do blending but I was wondering how and where is this done?

Thanks

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You enable or disable blending with:

glEnable (GL_BLEND); // disable blending
// objects that you want blended go here
glDisable (GL_BLEND); // disable blending

The type of blend you want to do is controlled with glBlendFunc; for accumulating multiple lights you generally lay down the scene objects all-black to start with, then use additive blending, i.e:

glBlendFunc (GL_ONE, GL_ONE);

In some cases this may give an end result greater than 1, in which case it will be clamped and your lighting might look duller than you'd like. One solution here might be to dim your lights a little during the additive passes, then perform one final fullscreen pass to brighten them back up again. That loses some bits of precision and is a little old-fashioned, a more modern approach might be to use a floating point FBO (64-bit should suffice for most cases).

\$\endgroup\$
5
  • \$\begingroup\$ Do I need to enable/disable blending in the loop? or just enable blending once outside the main loop? \$\endgroup\$ Commented Nov 26, 2013 at 8:17
  • \$\begingroup\$ Also, when trying to use the blend, my objects become transparent and the accumulated lighting makes nearly everything white \$\endgroup\$ Commented Nov 26, 2013 at 11:16
  • \$\begingroup\$ I did this, and it didn't work. It's like the lighting pass for the final light overwrites the data in the buffer. \$\endgroup\$
    – Ian Young
    Commented Apr 14, 2017 at 19:01
  • \$\begingroup\$ @IanYoung - then you're doing something wrong. This is the method Doom 3 uses, for example (and the Doom 3 source code is available if you need confirmation) and Doom 3 certainly does work. \$\endgroup\$ Commented Apr 14, 2017 at 20:09
  • \$\begingroup\$ @LeComteduMerde-fou Indeed I was. I was clearing the framebuffer inbetween lighting calls... \$\endgroup\$
    – Ian Young
    Commented Apr 14, 2017 at 20:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .