jdolan / quetoo

Quetoo ("Q2") is a free first person shooter based on id Tech2. GPL v2 license.

Home Page:http://quetoo.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Antiportals

SpineyPete opened this issue · comments

Since occlusion queries are such a pain in the ass I was reminded about another occlusion culling technique that’s conceptually simple.

Antiportals are basically frustum culling in reverse. An antiportal is a convex brush which is expanded into a frustum at runtime.

This isn’t free, you probably want a couple surgically placed large occluders. On the upside you don’t have latency in the visibilty tests.

The antiportal brush is convex, you then find the silhouette edges (see shadow volume algos) and for each edge you can find the plane formed by viewpoint and edge (together forming a triangle). Then you test bounding boxes against each plane to see if they are fully inside the antiportal and pull them out of the visible set.

For quake you could probably skip the silhouette finding by defining a brush face as a portal.

As an optimization you might want to actually check if one antiportal is contained in another, to avoid testing too much. This seems like some fiddly code but you could figure it out if it actually turns out to be a problem.

There seems to be very little info or implementations about it online. I think Ogre3d has some code. Unreal Engine 2 used it extensively though, it was quite popular in the mid 2000’s for mixed indoor/outdoor rendering.

@SpineyPete good to hear from you! You're right, OQ's were a massive PITA, but I'm happy to report I got them working swimmingly this past weekend.

What I didn't fully understand about them for the longest time is that they're not expensive, they're just slow. Coming up with a way for the client game to submit OQ's that would benefit subsequent frames was clutch. Suddenly we can immediately skip entire misc_dust, misc_flame, misc_light etc.. in addition to surgically culling every static light source and its corresponding shadow. My framerate actually doubled when I finally got this working and wired up, and there are probably still more things that can benefit from additional OQs.

In addition, I came up with GPU-oriented solution for supporting hundreds of lights in the scene without having to hash or sort them on the client side. I introduced a geometry shader that can test if a triangle intersects an AABB, and I use this to identify the eligible light sources for every primitive. This way, each fragment is only looking at < 8 light sources, while the scene supports 256 of them.

All in all, my framerate with full shadowmapping is actually higher now than it was in the develop branch a month ago 😂 Pretty crazy. If you have a chance to check it out, please let me know what you think. And I'm glad you're still lurking 😊