Moved occlusion test expiry code from KRScene::render to a dedicated function, KRViewport::expireOcclusionResults

This commit is contained in:
2024-09-21 21:21:48 -07:00
parent 8bee10c768
commit 3b9a5d6f81
6 changed files with 34 additions and 33 deletions

View File

@@ -34,6 +34,8 @@
#include "KRViewport.h" #include "KRViewport.h"
const long KRENGINE_OCCLUSION_TEST_EXPIRY = 10;
using namespace hydra; using namespace hydra;
KRViewport::KRViewport() KRViewport::KRViewport()
@@ -283,7 +285,19 @@ bool KRViewport::visible(const AABB& b) const
return is_visible; return is_visible;
} }
void KRViewport::expireOcclusionResults(long frame)
{
// Expire cached occlusion test results.
// Cached "failed" results are expired on the next frame (marked with .second of -1)
// Cached "success" results are expired after KRENGINE_OCCLUSION_TEST_EXPIRY frames (marked with .second of the last frame
std::set<AABB> expired_visible_bounds;
for (unordered_map<AABB, int>::iterator visible_bounds_itr = m_visibleBounds.begin(); visible_bounds_itr != m_visibleBounds.end(); visible_bounds_itr++) {
if ((*visible_bounds_itr).second == -1 || (*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < frame) {
expired_visible_bounds.insert((*visible_bounds_itr).first);
}
}
for (std::set<AABB>::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) {
m_visibleBounds.erase(*expired_visible_bounds_itr);
}
}

View File

@@ -70,6 +70,7 @@ public:
bool visible(const hydra::AABB& b) const; bool visible(const hydra::AABB& b) const;
float coverage(const hydra::AABB& b) const; float coverage(const hydra::AABB& b) const;
void expireOcclusionResults(long frame);
private: private:
hydra::Vector2 m_size; hydra::Vector2 m_size;

View File

@@ -180,6 +180,8 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
scene.updateOctree(m_viewport); scene.updateOctree(m_viewport);
m_viewport.expireOcclusionResults(getContext().getCurrentFrame());
// ----====---- Pre-stream resources ----====---- // ----====---- Pre-stream resources ----====----
KRNode::RenderInfo ri(commandBuffer); KRNode::RenderInfo ri(commandBuffer);
ri.camera = this; ri.camera = this;
@@ -187,13 +189,13 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_PRESTREAM); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_PRESTREAM);
ri.surface = &compositeSurface; ri.surface = &compositeSurface;
scene.render(ri, true); scene.render(ri);
// ----====---- Generate Shadowmaps for Lights ----====---- // ----====---- Generate Shadowmaps for Lights ----====----
if (settings.m_cShadowBuffers > 0) { if (settings.m_cShadowBuffers > 0) {
GL_PUSH_GROUP_MARKER("Generate Shadowmaps"); GL_PUSH_GROUP_MARKER("Generate Shadowmaps");
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_SHADOWMAP); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_SHADOWMAP);
scene.render(ri, false /*settings.bEnableDeferredLighting*/); scene.render(ri);
GL_POP_GROUP_MARKER; GL_POP_GROUP_MARKER;
} }
@@ -208,7 +210,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
// Render the geometry // Render the geometry
scene.render(ri, false); scene.render(ri);
// End render pass // End render pass
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
@@ -234,7 +236,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
// Render the geometry // Render the geometry
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_DEFERRED_LIGHTS); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_DEFERRED_LIGHTS);
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri, false); scene.render(ri);
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
GL_POP_GROUP_MARKER; GL_POP_GROUP_MARKER;
@@ -252,7 +254,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
// Render the geometry // Render the geometry
// TODO: At this point, we only want to 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(ri, false); scene.render(ri);
// End render pass // End render pass
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
@@ -267,7 +269,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
// Render the geometry // Render the geometry
scene.render(ri, false); scene.render(ri);
GL_POP_GROUP_MARKER; GL_POP_GROUP_MARKER;
@@ -334,7 +336,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
// Render all transparent geometry // Render all transparent geometry
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT);
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri, false); scene.render(ri);
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
GL_POP_GROUP_MARKER; GL_POP_GROUP_MARKER;
@@ -346,7 +348,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION);
if (ri.renderPass) { if (ri.renderPass) {
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri, false); scene.render(ri);
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
} }
@@ -360,7 +362,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES);
if (ri.renderPass) { if (ri.renderPass) {
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri, false); scene.render(ri);
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
} }
@@ -395,7 +397,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE); ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE);
ri.viewport = &volumetricLightingViewport; ri.viewport = &volumetricLightingViewport;
ri.renderPass->begin(commandBuffer, compositeSurface); ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri, false); scene.render(ri);
ri.renderPass->end(commandBuffer); ri.renderPass->end(commandBuffer);
ri.viewport = &m_viewport; ri.viewport = &m_viewport;
GL_POP_GROUP_MARKER; GL_POP_GROUP_MARKER;

View File

@@ -544,7 +544,8 @@ void KRLight::renderShadowBuffers(RenderInfo& ri)
ri.viewport = &m_shadowViewports[iShadow]; ri.viewport = &m_shadowViewports[iShadow];
shadowShader->bind(ri, Matrix4()); shadowShader->bind(ri, Matrix4());
getScene().render(ri, true); m_shadowViewports[iShadow].expireOcclusionResults(m_pContext->getCurrentFrame());
getScene().render(ri);
} }
} }
ri.viewport = prevViewport; ri.viewport = prevViewport;

View File

@@ -44,8 +44,6 @@
using namespace mimir; using namespace mimir;
using namespace hydra; using namespace hydra;
const long KRENGINE_OCCLUSION_TEST_EXPIRY = 10;
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;
@@ -103,23 +101,8 @@ std::set<KRLight*>& KRScene::getLights()
return m_lights; return m_lights;
} }
void KRScene::render(KRNode::RenderInfo& ri, bool new_frame) void KRScene::render(KRNode::RenderInfo& ri)
{ {
unordered_map<AABB, int>& visibleBounds = ri.viewport->getVisibleBounds();
if (new_frame) {
// Expire cached occlusion test results.
// Cached "failed" results are expired on the next frame (marked with .second of -1)
// Cached "success" results are expired after KRENGINE_OCCLUSION_TEST_EXPIRY frames (marked with .second of the last frame
std::set<AABB> expired_visible_bounds;
for (unordered_map<AABB, int>::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) {
if ((*visible_bounds_itr).second == -1 || (*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) {
expired_visible_bounds.insert((*visible_bounds_itr).first);
}
}
for (std::set<AABB>::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);
}
}
if (getFirstLight() == NULL) { if (getFirstLight() == NULL) {
addDefaultLights(); addDefaultLights();

View File

@@ -71,7 +71,7 @@ public:
bool sphereCast(const hydra::Vector3& v0, const hydra::Vector3& v1, float radius, hydra::HitInfo& hitinfo, unsigned int layer_mask); bool sphereCast(const hydra::Vector3& v0, const hydra::Vector3& v1, float radius, hydra::HitInfo& hitinfo, unsigned int layer_mask);
void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, float deltaTime); void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, float deltaTime);
void render(KRNode::RenderInfo& ri, bool new_frame); void render(KRNode::RenderInfo& ri);
void updateOctree(const KRViewport& viewport); void updateOctree(const KRViewport& viewport);
void buildOctreeForTheFirstTime(); void buildOctreeForTheFirstTime();