I have mesh with a buffer geometry with positions and normals, and translucent material. After calling computeBoundsTree() on this geometry, causes some triangles to show differently in mesh.
To Reproduce
Steps to reproduce the behavior:
Create a buffer geometry with some positions and normals.
It looks like BVH computation has reordered the vertices or indices in your geometry. In general alpha blending is sensitive to triangle order. If you want to see the interior faces of the geometry, then I think you need to keep the order stable, that might require a change/fix from the three-mesh-bvh project.
I think part of how the mesh-bvh’s implementation works is that it reorders the triangles into regions per volume, rather than storing a separate list of triangles, so this might be an optimization imposed for efficiency.
and since the triangles are sorted by centroid, its happening to split that interior face into different buckets.
So i tend to agree with the @donmccurdy 's depth prepass idea/option…
I also modded the codepen to add a 3rd option, rendering the object twice, first with material.side = BackSide (and no depthWrite) then with material.side = FrontSide, and that improves the situation a bit, but it’s still not identical.
But also from what I can tell.. relying on the ordering of the triangles will still not work with transparency in all directions.. so.. it’s kindof a wash. For instance I see z fighting with those interior triangles even in the non-bvh case.
Yet another approach would be to use separate representations for raycasting (bvh, but set to .visible=false) and your non-bvh version just for visible rendering.
I sorta doubt that this will be fixed upstream, since it would be a pretty invasive re-write of the algorithm, and impose an additional memory hit of an internal triangle index buffer, which could break other users that rely on that optimization.
My peasant approach here would be to use one mesh for raycasting, another for drawing. As a peasant, my reasoning is as follows:
If i want to draw some triangles, and raycast them i have to have a copy of them on the GPU and the CPU.
The triangles are the same, but they both want a different order.
Since i have two copies anyway, ill just draw the ones in the order i want, and compute the bvh in a different order.
Since i dont see each triangle represented uniquely (like each in a separate color) i am assuming that we only care about hitting the entire object, not individual triangles. So any triangle you hit, even though its not in the same place when drawn, would still belong to the same mesh.
If we do however cara about individual triangles, we can build a map to keep track of how the triangles got reordered.
The MeshBVH generation process modifies the geometry’s index bufferAttribute in place to save memory. … The BVH will no longer work correctly if the index buffer is modified.
So yes, the triangle order is modified. There is an “indirect” setting that will allow for keeping the “index” attribute unmodified but I don’t recommend it unless you have a really good reason. Transparency rendering will generally result in unexpected artifacts when using something like depth write due to triangle draw order dependency so I would recommend using technique like depth-prepass, depth peeling, or simply setting depthWrite to false.