This check-if-intersecting-and-exiting-any-closest-triangle algorithm produces streaks of incorrect voxels in some meshes.
I reduced the issue by checking for multiple ray directions and && them.
It misses some voxels inside the mesh now but at least it doesn't produce incorrect streaks outside the mesh.
Also i had to increase AABB extents in shell generator kernel a bit because it was missing some plane-aligned triangles sometimes.
Now the voxelizer is much more stable. Hopefully this can help somebody else out:
float3 rayDirection0 = float3(0, 0, 1);
float3 rayDirection1 = float3(0, 0, -1);
float minDistance0 = 10000000.0;
float minDistance1 = 10000000.0;
float3 minDistanceNormal0;
float3 minDistanceNormal1;
bool didIntersect0 = false;
bool didIntersect1 = false;
for (int i = 0; i < _TriangleCount; i += 3)
{
Triangle tri;
tri.a = _MeshVertices[_MeshTriangleIndices[i]];
tri.b = _MeshVertices[_MeshTriangleIndices[i + 1]];
tri.c = _MeshVertices[_MeshTriangleIndices[i + 2]];
float3 outNormal0;
float distance0;
if (IntersectsRayTriangle(rayOrigin, rayDirection0, tri, distance0, outNormal0))
{
if (distance0 < minDistance0)
{
minDistance0 = distance0;
minDistanceNormal0 = outNormal0;
didIntersect0 = true;
}
}
float3 outNormal1;
float distance1;
if (IntersectsRayTriangle(rayOrigin, rayDirection1, tri, distance1, outNormal1))
{
if (distance1 < minDistance1)
{
minDistance1 = distance1;
minDistanceNormal1 = outNormal1;
didIntersect1 = true;
}
}
}
if ((didIntersect0 && dot(minDistanceNormal0, rayDirection0) > 0.0) && (didIntersect1 && dot(minDistanceNormal1, rayDirection1) > 0.0))
{
_Voxels[voxelIndex].isSolid = 1.0; //or whatever
}