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)); } }
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); }