gkjohnson / three-mesh-bvh

A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes.
https://gkjohnson.github.io/three-mesh-bvh/example/bundle/raycast.html
MIT License
2.5k stars 260 forks source link

Example: Add per-triangle frustum culling, z sorting demo #236

Open gkjohnson opened 3 years ago

gkjohnson commented 3 years ago

With a really complex mesh there may be benefit in performing per-triangle frustum culling or approximate per-triangle sorting to avoid overdraw. In the case of a transparent mesh you may be able to sort per-triangle to avoid transparency overdraw artifacts.

MeshBVH can be used to frustum cull by filtering the triangles using the "triangleRange" callback when doing a "shapecast" (v0.4.0) and adjusting another index buffer to only draw the triangles that are in that frustum.

Likewise while doing that filtering the triangle bounds closest to the camera can be traversed first in order to ensure that the triangles closest to the camera are drawn first. In both of these cases it's likely good enough to not have to do any kind of more granular per-triangle sorting within the leaf bounds.

When sorting for transparency, though, every triangle needs to be sorted in order to get the best look. The "best" way to sort triangles is probably by the vertex closest to the camera but because of how bounds can overlap we can't guarantee that triangles will be sorted correctly at those bounds causing possible incorrect overlap. Maybe it common cases it will look good enough, though? And maybe sorting by triangle centroid is good enough, as well.

Relevant paper here: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.83.572&rep=rep1&type=pdf

Example

Models

gkjohnson commented 3 years ago

As expected this doesn't work all that great when really long triangles are involved but cases where objects have relatively evenly sized triangles (like photogrammetry models) the incorrect triangles from the overlap are not so noticeable.

This is the type of thing that's probably best preprocessed and baked into the geometry rather than sorted in real time.

NOTE: additional parameters are required for ordering the bounds -- specifically the side, split axis, and split axis position.

gkjohnson commented 3 years ago

Demo here:

https://raw.githack.com/gkjohnson/three-mesh-bvh/overdraw-demo/example/bundle/overdraw.html

Probably not worthwile adding in to the demo list but a fun use case. Depth prepass, depth peeling, and / or geometry preprocessing would be a better solution for these issues. Frustum culling may be valuable but rarely.

gkjohnson commented 2 years ago

With BatchedMesh this kind of fast frustum culling might be more viable. Leaf node "chunks" can be added as batch meshes and individual chunks can be disabled when they're outside the frustum with the multi draw functionality.