Performance improvement in the deferred lighting pipeline, utilizing hardware occlusion queries to avoid rendering objects in 3rd pass (Final Render) or loading their textures when they have been determined to be occluded in the 1st pass. (GBuffer populate)

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4094
This commit is contained in:
kearwood
2012-09-11 08:15:05 +00:00
parent b802d22dc0
commit c6417c151d
3 changed files with 27 additions and 8 deletions

View File

@@ -243,6 +243,8 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
// Render the geometry
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS);
scene.getOcclusionQueryResults(m_visibleBounds);
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
// Set render target
glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer);
@@ -310,6 +312,8 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
// Render the geometry
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE);
scene.getOcclusionQueryResults(m_visibleBounds);
}
// ----====---- Transparent Geometry, Forward Rendering ----====----
@@ -409,7 +413,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
}
}
scene.getOcclusionQueryResults(m_visibleBounds);
// scene.getOcclusionQueryResults(m_visibleBounds);
// fprintf(stderr, "visible bounds: %i\n", (int)m_visibleBounds.size());

View File

@@ -31,6 +31,7 @@ void KROctree::add(KRNode *pNode)
if(m_pRootNode == NULL) {
// First item inserted, create a node large enough to fit it
m_pRootNode = new KROctreeNode(nodeBounds);
//m_pRootNode = new KROctreeNode(KRAABB(nodeBounds.min - nodeBounds.size() * 0.25f, nodeBounds.max + nodeBounds.size() * 0.25f));
m_pRootNode->add(pNode);
} else {
// Keep encapsulating the root node until the new root contains the inserted node

View File

@@ -146,19 +146,26 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
KRAABB octreeBounds = pOctreeNode->getBounds();
//KRBoundingVolume frustrumVolumeNoNearClip = KRBoundingVolume(viewMatrix, pCamera->perspective_fov, pCamera->m_viewportSize.x / pCamera->m_viewportSize.y, 0.0, pCamera->perspective_farz);
if(true) {
//if(pOctreeNode->getBounds().visible(viewMatrix * projectionMatrix)) { // Only recurse deeper if within the view frustrum
//if(frustrumVolume.test_intersect(pOctreeNode->getBounds())) { // Only recurse deeper if within the view frustrum
//if(frustrumVolumeNoNearClip.test_intersect(pOctreeNode->getBounds())) { // Only recurse deeper if within the view frustrum
bool can_occlusion_test = renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT;
bool can_occlusion_test = renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_GBUFFER || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT;
if(true) {
//if(visibleBounds.find(octreeBounds) != visibleBounds.end()) {
bool bVisible = true;
// bool bVisible = renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE;
// if(!bVisible) {
// bVisible = visibleBounds.find(octreeBounds) != visibleBounds.end();
// }
if(bVisible) {
if(can_occlusion_test) {
pOctreeNode->beginOcclusionQuery(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
}
// Occlusion test indicates that this bounding box was visible in the last frame
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
@@ -170,8 +177,15 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
pOctreeNode->endOcclusionQuery();
}
for(int i=0; i<8; i++) {
render(pOctreeNode->getChildren()[i], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
bool bRenderChildren = renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE;
if(!bRenderChildren) {
bRenderChildren = visibleBounds.find(octreeBounds) != visibleBounds.end();
}
if(bRenderChildren) {
for(int i=0; i<8; i++) {
render(pOctreeNode->getChildren()[i], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
}
}
} else if(KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
if(pOctreeNode->getSceneNodes().empty()) {