Exemplo n.º 1
0
void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
{
    //RH
    if (UserConfigParams::m_gi && UserConfigParams::m_shadows && hasShadow)
    {
        ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
        glDisable(GL_BLEND);
        m_rtts->getRH().Bind();
        glBindVertexArray(SharedObject::FullScreenQuadVAO);
        if (irr_driver->needRHWorkaround())
        {
            glUseProgram(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->Program);
            FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->SetTextureUnits(
                m_rtts->getRSM().getRTT()[0], m_rtts->getRSM().getRTT()[1], m_rtts->getRSM().getDepthTexture());
            for (unsigned i = 0; i < 32; i++)
            {
                FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, i, irr_driver->getSunColor());
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
            }
        }
        else
        {
            glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program);
            FullScreenShader::RadianceHintsConstructionShader::getInstance()->SetTextureUnits(
                    m_rtts->getRSM().getRTT()[0],
                    m_rtts->getRSM().getRTT()[1],
                    m_rtts->getRSM().getDepthTexture()
            );
            FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, irr_driver->getSunColor());
            glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
        }
    }

    for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
        sun_ortho_matrix[i] *= getInvViewMatrix();
    m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind();
    glClear(GL_COLOR_BUFFER_BIT);

    m_rtts->getFBO(FBO_DIFFUSE).Bind();
    if (irr_driver->usesGI() && hasShadow)
    {
        ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
        m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
    }

    m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind();

    {
        ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
        m_post_processing->renderEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff, SkyboxSpecularProbe);
    }

    // Render sunlight if and only if track supports shadow
    if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows())
    {
        ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_SUN));
        if (World::getWorld() && irr_driver->usesShadows() && hasShadow)
            m_post_processing->renderShadowedSunlight(irr_driver->getSunDirection(), irr_driver->getSunColor(), sun_ortho_matrix, m_rtts->getShadowFBO().getRTT()[0]);
        else
            m_post_processing->renderSunlight(irr_driver->getSunDirection(), irr_driver->getSunColor());
    }
    {
        ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS));
        renderPointLights(MIN2(pointlightcount, MAXLIGHT));
    }
}
Exemplo n.º 2
0
void IrrDriver::renderLights(const core::aabbox3df& cambox,
                             scene::ICameraSceneNode * const camnode,
                             video::SOverrideMaterial &overridemat,
                             int cam, float dt)
{
    for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
        sun_ortho_matrix[i] *= getInvViewMatrix();
    core::array<video::IRenderTarget> rtts;
    // Diffuse
    rtts.push_back(m_rtts->getRTT(RTT_TMP1));
    // Specular
    rtts.push_back(m_rtts->getRTT(RTT_TMP2));

    m_video_driver->setRenderTarget(rtts, true, false,
                                        video::SColor(0, 0, 0, 0));

    const u32 lightcount = m_lights.size();
    const core::vector3df &campos =
        irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
    std::vector<float> accumulatedLightPos;
    std::vector<float> accumulatedLightColor;
    std::vector<float> accumulatedLightEnergy;
    std::vector<LightNode *> BucketedLN[15];
    for (unsigned int i = 0; i < lightcount; i++)
    {
        if (!m_lights[i]->isPointLight())
        {
          m_lights[i]->render();
          if (UserConfigParams::m_shadows)
              m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
          else
              m_post_processing->renderSunlight();
          continue;
        }
        const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
        unsigned idx = (unsigned)(lightpos.getLength() / 10);
        if (idx > 14)
          continue;
        BucketedLN[idx].push_back(m_lights[i]);
    }

    unsigned lightnum = 0;

    for (unsigned i = 0; i < 15; i++)
    {
        for (unsigned j = 0; j < BucketedLN[i].size(); j++)
        {
            if (++lightnum > MAXLIGHT)
            {
                LightNode* light_node = BucketedLN[i].at(j);
                light_node->setEnergyMultiplier(0.0f);
            }
            else
            {
                LightNode* light_node = BucketedLN[i].at(j);

                float em = light_node->getEnergyMultiplier();
                if (em < 1.0f)
                {
                    light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
                }

                const core::vector3df &pos = light_node->getAbsolutePosition();
                accumulatedLightPos.push_back(pos.X);
                accumulatedLightPos.push_back(pos.Y);
                accumulatedLightPos.push_back(pos.Z);
                accumulatedLightPos.push_back(0.);
                const core::vector3df &col = light_node->getColor();

                accumulatedLightColor.push_back(col.X);
                accumulatedLightColor.push_back(col.Y);
                accumulatedLightColor.push_back(col.Z);
                accumulatedLightColor.push_back(0.);
                accumulatedLightEnergy.push_back(light_node->getEffectiveEnergy());
            }
        }
        if (lightnum > MAXLIGHT)
        {
          irr_driver->setLastLightBucketDistance(i * 10);
          break;
        }
    }
	// Fill lights
	for (; lightnum < MAXLIGHT; lightnum++) {
		accumulatedLightPos.push_back(0.);
		accumulatedLightPos.push_back(0.);
		accumulatedLightPos.push_back(0.);
		accumulatedLightPos.push_back(0.);
		accumulatedLightColor.push_back(0.);
		accumulatedLightColor.push_back(0.);
		accumulatedLightColor.push_back(0.);
		accumulatedLightColor.push_back(0.);
		accumulatedLightEnergy.push_back(0.);
	}
	m_post_processing->renderPointlight(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
    // Handle SSAO
    m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false,
                         SColor(255, 255, 255, 255));

    if(UserConfigParams::m_ssao)
        m_post_processing->renderSSAO(irr_driver->getInvProjMatrix(), irr_driver->getProjMatrix());

    // Blur it to reduce noise.
    if(UserConfigParams::m_ssao == 1)
		m_post_processing->renderGaussian3Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_QUARTER4), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height);
    else if (UserConfigParams::m_ssao == 2)
		m_post_processing->renderGaussian6Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_TMP4), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height);

    m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
}