You can also think about doing it with the CPU. Checking which meshes are in the camera frustum is easy to do
The system is actually doing it for you: scene.activeMeshes is exactly what you need
Occlusion will not be taken in account with that approach but at least it will be super fast
Actually I would like to go further than that, and directly check if which parts of the vertices are visible or not
For example, I want to know whether vertex 0, 100 or 1000 is visible in camera view, is there a way to do this?
E.g.
vertices = mesh.getPositionData(true, true)
for(let i = 0; i < vertices.length / 3; i++) {
if (isVertexVisible(i, activeCamera)) { // looking for ideas on how to do this
// if vertex is in camera view BUT occluded by another vertex/face, return false
}
}
If you only have a few vertices to check, you can try to do scene picking
with a ray going from the camera position to the vertex position you want to check. if the result is the same position, then it’s visible. if not, it’s hidden behind another mesh.
I think with webgpu + a compute shader it’s possible to do it quite fast. Compute clip-space position in the CS, sample depth buffer and fill a texture with the check value.
I guess it’s possible to sample depth buffer on CPU but it will be slower for a huge number of vertices.
Yes, it can be a tedious work.
Line 52, the depth buffer is retrieved from the GPU ram to the CPU ram. This has a cost. It’s better to keep infos in GPU ram and do the work exclusively on the GPU for better performance.
This said, if you want to keep using the datas CPU, you will have to compute an object bounding box, project it in clip space, read all values corresponding to its pixels and deduce if it’s behind geometry or not.
Another solution is to compute a mipmap chain using a shader. Each value is the depth the most far away instead of the average. Then, depending on the size on screen of the object, pick the mipmap chain corresponding.
If all depth value of the object pixels are > than the mipmap value, then it’s hidden. Otherwise, it’s, at least, partially visible.