Occlusion culling

Everything about development and the OpenMW source code.
Post Reply
ajira2
Posts: 56
Joined: 30 Oct 2017, 14:27

Occlusion culling

Post by ajira2 »

I read OpenMW does only fustrum culling and not occlusion culling.

Image

This is not optimal. I remember years ago frustrated having the same fps looking at a plain wall at Seyda Neen and then the same fps looking at the town and landscape beyond.

I read that we can use GPU’s occlusion queries (OpenGL) to determine if an object is visible. The GPU will calculate if objects are occluded by other geometry and return visibility results.

I also read about Hierarchical Z-Buffer (HZB): you can create a low-resolution depth buffer (pyramid-like structure) to test objects for occlusion quickly.

I asked chatgpt and gave me some code:

components/occlusion/OcclusionQuery.hpp

Code: Select all

#ifndef OCCLUSIONQUERY_HPP
#define OCCLUSIONQUERY_HPP

#include <GL/glew.h>

class OcclusionQuery {
public:
    OcclusionQuery();
    ~OcclusionQuery();

    void startQuery();
    void endQuery();
    bool isVisible();

private:
    GLuint queryID;
    GLuint result;
};

#endif // OCCLUSIONQUERY_HPP

components/occlusion/OcclusionQuery.cpp

Code: Select all

#include "OcclusionQuery.hpp"

OcclusionQuery::OcclusionQuery() {
    glGenQueries(1, &queryID);
    result = 0;
}

OcclusionQuery::~OcclusionQuery() {
    glDeleteQueries(1, &queryID);
}

void OcclusionQuery::startQuery() {
    glBeginQuery(GL_ANY_SAMPLES_PASSED, queryID);
}

void OcclusionQuery::endQuery() {
    glEndQuery(GL_ANY_SAMPLES_PASSED);
}

bool OcclusionQuery::isVisible() {
    glGetQueryObjectuiv(queryID, GL_QUERY_RESULT, &result);
    return result > 0;
}

apps/openmw/mwrender/

Code: Select all

#include "OcclusionQuery.hpp"

// Create an occlusion query object per visible node.
OcclusionQuery occlusionQuery;

void renderObject(osg::Node* node) {
    // Step 1: Start Occlusion Query and Render Bounding Box
    occlusionQuery.startQuery();

    // Render a simple bounding box for occlusion testing
    osg::BoundingBox bb = node->getBound();
    renderBoundingBox(bb); // You need a helper function to render bounding volumes.

    occlusionQuery.endQuery();

    // Step 2: Check Visibility
    if(!occlusionQuery.isVisible()) {
        // Skip rendering if not visible
        return;
    }

    // Step 3: Render the actual object
    node->accept(*visitor); // Standard OSG rendering
}
renderUtils.cpp

Code: Select all

#include <osg/Geometry>
#include <osg/MatrixTransform>

void renderBoundingBox(const osg::BoundingBox& bb) {
    glPushMatrix();
    glBegin(GL_LINES);

    glVertex3f(bb._min.x(), bb._min.y(), bb._min.z());
    glVertex3f(bb._max.x(), bb._min.y(), bb._min.z());

    glVertex3f(bb._max.x(), bb._min.y(), bb._min.z());
    glVertex3f(bb._max.x(), bb._max.y(), bb._min.z());

    glVertex3f(bb._max.x(), bb._max.y(), bb._min.z());
    glVertex3f(bb._min.x(), bb._max.y(), bb._min.z());

    glVertex3f(bb._min.x(), bb._max.y(), bb._min.z());
    glVertex3f(bb._min.x(), bb._min.y(), bb._min.z());

    glEnd();
    glPopMatrix();
}
What do you think about this stuff?
Chris
Posts: 1628
Joined: 04 Sep 2011, 08:33

Re: Occlusion culling

Post by Chris »

The problem is that it can take more time to determine what to draw than to just tell the GPU to draw it anyway and let the Z-Buffer cull it for you. Occlusion testing in particular can take an additional frame or two to return whether something is visible or not, which will result in either poor framerates (if you wait for the result), or pop-in (if something that wasn't visible becomes visible, but the query doesn't report that for a few frames). Some really high-level easy culling can help, but trying to over-optimize and cull smaller segments can be a detriment; even Nintendo 64 games fell prey to this problem in the 90s.
User avatar
AnyOldName3
Posts: 2764
Joined: 26 Nov 2015, 03:25

Re: Occlusion culling

Post by AnyOldName3 »

I'd trust a random bird or frog out of my garden to implement occlusion culling before I'd trust a large language model, and the garbage it's just tricked you into thinking we might want only serves to cement that impression.

As a heads up, this post has caused the OpenMW team to realise we didn't have a rule banning AI-generated content on the forum, so there's a good chance that if you reply to this thread, the rules will have changed. I'd recommend just not posting anything else AI-generated rather than checking the rules each time you want to write something in case we've not got around to it yet.
Post Reply