Updated realtime occlusion culling algorithm to reduce the number of occlusion tests.
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40160
This commit is contained in:
@@ -179,8 +179,6 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
|
|
||||||
KRVector3 vecCameraDirection = m_viewport.getCameraDirection();
|
KRVector3 vecCameraDirection = m_viewport.getCameraDirection();
|
||||||
|
|
||||||
std::set<KRAABB> newVisibleBounds;
|
|
||||||
|
|
||||||
// GLuint shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
|
// GLuint shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||||
// KRViewport shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
|
// KRViewport shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||||
// int cShadows = 0;
|
// int cShadows = 0;
|
||||||
@@ -209,10 +207,10 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
GLDEBUG(glDisable(GL_BLEND));
|
GLDEBUG(glDisable(GL_BLEND));
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER);
|
||||||
|
|
||||||
// ----====---- Generate Shadowmaps for Lights ----====----
|
// ----====---- Generate Shadowmaps for Lights ----====----
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
|
||||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||||
|
|
||||||
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
||||||
@@ -239,7 +237,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
|
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
|
||||||
|
|
||||||
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
||||||
// Set render target
|
// Set render target
|
||||||
@@ -270,8 +268,8 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
GLDEBUG(glDepthMask(GL_TRUE));
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
std::set<KRAABB> emptyBoundsSet; // At this point, we only render octree nodes that produced fragments during the 1st pass into the GBuffer
|
// TODO: At this point, we only want to render octree nodes that produced fragments during the 1st pass into the GBuffer
|
||||||
scene.render(this, emptyBoundsSet, m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE);
|
||||||
|
|
||||||
// Deactivate source buffer texture units
|
// Deactivate source buffer texture units
|
||||||
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
||||||
@@ -282,7 +280,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||||
} else {
|
} else {
|
||||||
// ----====---- Generate Shadowmaps for Lights ----====----
|
// ----====---- Generate Shadowmaps for Lights ----====----
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
|
||||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||||
|
|
||||||
// ----====---- Opaque Geometry, Forward Rendering ----====----
|
// ----====---- Opaque Geometry, Forward Rendering ----====----
|
||||||
@@ -313,7 +311,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
|
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----====---- Sky Box ----====----
|
// ----====---- Sky Box ----====----
|
||||||
@@ -372,7 +370,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
|
|
||||||
// Render all transparent geometry
|
// Render all transparent geometry
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||||
|
|
||||||
|
|
||||||
// ----====---- Flares ----====----
|
// ----====---- Flares ----====----
|
||||||
@@ -396,7 +394,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||||
|
|
||||||
// Render all flares
|
// Render all flares
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
|
||||||
|
|
||||||
// ----====---- Volumetric Lighting ----====----
|
// ----====---- Volumetric Lighting ----====----
|
||||||
|
|
||||||
@@ -424,7 +422,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, newVisibleBounds);
|
scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE);
|
||||||
|
|
||||||
if(volumetric_environment_downsample != 0) {
|
if(volumetric_environment_downsample != 0) {
|
||||||
// Set render target
|
// Set render target
|
||||||
@@ -459,10 +457,10 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
KRMat4 projectionMatrix = getProjectionMatrix();
|
KRMat4 projectionMatrix = getProjectionMatrix();
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
|
||||||
for(std::set<KRAABB>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
|
for(std::map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
|
||||||
KRMat4 matModel = KRMat4();
|
KRMat4 matModel = KRMat4();
|
||||||
matModel.scale((*itr).size() / 2.0f);
|
matModel.scale((*itr).first.size() / 2.0f);
|
||||||
matModel.translate((*itr).center());
|
matModel.translate((*itr).first.center());
|
||||||
|
|
||||||
if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
|
||||||
@@ -470,8 +468,6 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_viewport.setVisibleBounds(newVisibleBounds);
|
|
||||||
|
|
||||||
// Re-enable z-buffer write
|
// Re-enable z-buffer write
|
||||||
GLDEBUG(glDepthMask(GL_TRUE));
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
|
||||||
|
|||||||
@@ -300,9 +300,7 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera)
|
|||||||
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
|
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
|
||||||
|
|
||||||
|
|
||||||
std::set<KRAABB> newVisibleBounds;
|
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP);
|
||||||
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
|
|
||||||
m_shadowViewports[iShadow].setVisibleBounds(newVisibleBounds);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
#import "KRPointLight.h"
|
#import "KRPointLight.h"
|
||||||
#import "KRQuaternion.h"
|
#import "KRQuaternion.h"
|
||||||
|
|
||||||
|
const long KRENGINE_OCCLUSION_TEST_EXPIRY = 60;
|
||||||
|
|
||||||
KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
|
KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
|
||||||
m_pFirstLight = NULL;
|
m_pFirstLight = NULL;
|
||||||
m_pRootNode = new KRNode(*this, "scene_root");
|
m_pRootNode = new KRNode(*this, "scene_root");
|
||||||
@@ -58,7 +60,7 @@ KRScene::~KRScene() {
|
|||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
|
void KRScene::render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass) {
|
||||||
|
|
||||||
std::vector<KRLight *> lights;
|
std::vector<KRLight *> lights;
|
||||||
|
|
||||||
@@ -96,10 +98,10 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, c
|
|||||||
newRemainingOctrees.clear();
|
newRemainingOctrees.clear();
|
||||||
newRemainingOctreesTestResults.clear();
|
newRemainingOctreesTestResults.clear();
|
||||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
|
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
|
||||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
|
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
|
||||||
}
|
}
|
||||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
|
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
|
||||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false);
|
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, false);
|
||||||
}
|
}
|
||||||
remainingOctrees = newRemainingOctrees;
|
remainingOctrees = newRemainingOctrees;
|
||||||
remainingOctreesTestResults = newRemainingOctreesTestResults;
|
remainingOctreesTestResults = newRemainingOctreesTestResults;
|
||||||
@@ -108,11 +110,23 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, c
|
|||||||
newRemainingOctrees.clear();
|
newRemainingOctrees.clear();
|
||||||
newRemainingOctreesTestResults.clear();
|
newRemainingOctreesTestResults.clear();
|
||||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
|
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
|
||||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true);
|
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Expire cached occlusion test results
|
||||||
|
std::set<KRAABB> expired_visible_bounds;
|
||||||
|
for(std::map<KRAABB, int>::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) {
|
||||||
|
if((*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) {
|
||||||
|
expired_visible_bounds.insert((*visible_bounds_itr).first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(std::set<KRAABB>::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) {
|
||||||
|
visibleBounds.erase(*expired_visible_bounds_itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
||||||
{
|
{
|
||||||
if(pOctreeNode) {
|
if(pOctreeNode) {
|
||||||
|
|
||||||
@@ -124,8 +138,9 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
|||||||
GLuint params = 0;
|
GLuint params = 0;
|
||||||
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
||||||
if(params) {
|
if(params) {
|
||||||
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
|
// Record the frame number that the test has passed on
|
||||||
// visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
|
visibleBounds[octreeBounds] = getContext().getCurrentFrame();
|
||||||
|
|
||||||
if(!bOcclusionTestResultsOnly) {
|
if(!bOcclusionTestResultsOnly) {
|
||||||
// Schedule a pass to perform the rendering
|
// Schedule a pass to perform the rendering
|
||||||
remainingOctrees.push_back(pOctreeNode);
|
remainingOctrees.push_back(pOctreeNode);
|
||||||
@@ -140,8 +155,8 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
|||||||
|
|
||||||
float min_coverage = 0.0f;
|
float min_coverage = 0.0f;
|
||||||
|
|
||||||
float lod_coverage = pOctreeNode->getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
|
float lod_coverage = pOctreeNode->getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // Cull against the view frustrum
|
||||||
if(lod_coverage > min_coverage) {
|
if(lod_coverage > min_coverage) {
|
||||||
|
|
||||||
// ----====---- Rendering and occlusion test pass ----====----
|
// ----====---- Rendering and occlusion test pass ----====----
|
||||||
bool bVisible = false;
|
bool bVisible = false;
|
||||||
@@ -153,25 +168,24 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
|||||||
KRAABB cameraExtents = KRAABB(viewport.getCameraPosition() - KRVector3(pCamera->getPerspectiveNearZ()), viewport.getCameraPosition() + KRVector3(pCamera->getPerspectiveNearZ()));
|
KRAABB cameraExtents = KRAABB(viewport.getCameraPosition() - KRVector3(pCamera->getPerspectiveNearZ()), viewport.getCameraPosition() + KRVector3(pCamera->getPerspectiveNearZ()));
|
||||||
bVisible = octreeBounds.intersects(cameraExtents);
|
bVisible = octreeBounds.intersects(cameraExtents);
|
||||||
if(bVisible) {
|
if(bVisible) {
|
||||||
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
|
// Record the frame number in which the camera was within the bounds
|
||||||
// visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
|
visibleBounds[octreeBounds] = getContext().getCurrentFrame();
|
||||||
bNeedOcclusionTest = false;
|
bNeedOcclusionTest = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!bVisible) {
|
|
||||||
// Check if an occlusion query from the prior pass has returned true
|
|
||||||
bVisible = newVisibleBounds.find(octreeBounds) != newVisibleBounds.end();
|
|
||||||
if(bVisible) {
|
|
||||||
bNeedOcclusionTest = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bVisible) {
|
if(!bVisible) {
|
||||||
// Take advantage of temporal consistency of visible elements from frame to frame
|
// Check if a previous occlusion query has returned true, taking advantage of temporal consistency of visible elements from frame to frame
|
||||||
// If the previous frame rendered this octree, then attempt to render it in this frame without performing a pre-occlusion test
|
// If the previous frame rendered this octree, then attempt to render it in this frame without performing a pre-occlusion test
|
||||||
bVisible = visibleBounds.find(octreeBounds) != visibleBounds.end();
|
std::map<KRAABB, int>::iterator match_itr = visibleBounds.find(octreeBounds);
|
||||||
// We don't set bNeedOcclusionTest to false here, as we need to perform an occlusion test to record if this octree node was visible for the next frame
|
if(match_itr != visibleBounds.end()) {
|
||||||
|
bVisible = true;
|
||||||
|
|
||||||
|
// We set bNeedOcclusionTest to false only when the previous occlusion test is old and we need to perform an occlusion test to record if this octree node was visible for the next frame
|
||||||
|
bNeedOcclusionTest = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!bVisible) {
|
if(!bVisible) {
|
||||||
@@ -270,7 +284,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
|||||||
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
|
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
|
||||||
|
|
||||||
for(int i=0; i<8; i++) {
|
for(int i=0; i<8; i++) {
|
||||||
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, lights, viewport, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
|
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, lights, viewport, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove lights added at this octree level from the stack
|
// Remove lights added at this octree level from the stack
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ public:
|
|||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
void render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
|
void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||||
|
|
||||||
void render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
void render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -154,14 +154,7 @@ void KRViewport::calculateDerivedValues()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::set<KRAABB> &KRViewport::getVisibleBounds()
|
std::map<KRAABB, int> &KRViewport::getVisibleBounds()
|
||||||
{
|
{
|
||||||
return m_visibleBounds;
|
return m_visibleBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRViewport::setVisibleBounds(const std::set<KRAABB> visibleBounds)
|
|
||||||
{
|
|
||||||
m_visibleBounds = visibleBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "KRVector2.h"
|
#include "KRVector2.h"
|
||||||
#include "KRMat4.h"
|
#include "KRMat4.h"
|
||||||
#include "KRAABB.h"
|
#include "KRAABB.h"
|
||||||
|
#include <map.h>
|
||||||
|
|
||||||
class KRLight;
|
class KRLight;
|
||||||
|
|
||||||
@@ -38,8 +39,7 @@ public:
|
|||||||
// Overload assignment operator
|
// Overload assignment operator
|
||||||
KRViewport& operator=(const KRViewport &v);
|
KRViewport& operator=(const KRViewport &v);
|
||||||
|
|
||||||
const std::set<KRAABB> &getVisibleBounds();
|
std::map<KRAABB, int> &getVisibleBounds();
|
||||||
void setVisibleBounds(const std::set<KRAABB> visibleBounds);
|
|
||||||
|
|
||||||
const std::set<KRLight *> &getVisibleLights();
|
const std::set<KRLight *> &getVisibleLights();
|
||||||
void setVisibleLights(const std::set<KRLight *> visibleLights);
|
void setVisibleLights(const std::set<KRLight *> visibleLights);
|
||||||
@@ -62,7 +62,7 @@ private:
|
|||||||
|
|
||||||
void calculateDerivedValues();
|
void calculateDerivedValues();
|
||||||
|
|
||||||
std::set<KRAABB> m_visibleBounds; // AABB's that output fragments in the last frame
|
std::map<KRAABB, int> m_visibleBounds; // AABB's that output fragments in the last frame
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user