Nanite Voxelization Bias

Hello!

I am experimenting a bit with Nanite Voxelization.

In most cases, it seems that the sooner voxels appear (i.e. closer to camera), the faster it renders.

I have couple related questions:

  1. Is there any mesh authoring guidelines to favor voxels appearing sooner? I have noticed that for example, flat surfaces prefer sticking to triangles instead of voxels, does this make any sense? Any intuition of what “voxels prefer”?
  2. I was trying to modify NaniteBuilder.cpp and ClusterDAG.cpp to force the cluster hierarchy to voxelize sooner for some models: some sort of a “Voxel Bias” setting. The bigger this “Voxel Bias” is set for a model, the sooner voxels would show up. Maybe kind of analogous to a “MaxPixelsPerEdge”, but on a per-model basis, built offline into the Nanite ClusterDAG, somehow. This would be an experiment just for performance, regardless of if it looks a bit worse (useful for scalability). I have tried to bias LODErrors, SimplifyErrors, EdgeLengths, etc. based on this invented “Voxel Bias” parameter, but nothing seems to be fully working. Do you see any way to make this “Voxel Bias” work in any way? (if it makes any sense whatsoever)

Thank you very much! :smiley:

[Attachment Removed]

Hi Victor,

Thanks for reaching out. Let me try to answer your questions as best as I can:

Is there any mesh authoring guidelines to favor voxels appearing sooner? I have noticed that for example, flat surfaces prefer sticking to triangles instead of voxels, does this make any sense? Any intuition of what “voxels prefer”?

We do not have much guidance on Nanite foliage at this point, as the feature is still in an experimental state. We did have a talk at Unreal Fest Stockholm last year by CDPR that highlights a few tips and tricks, but I wouldn’t take that as definitive advice. You are correct in your intuition that flat surfaces follow the triangle rasterization path. That is done by design to reduce pixel overdraw as much as possible. We added a voxel path to handle the case where dense foliage, such as leaves on trees, does not form a continuous surface as the geometry recedes into the distance. If you use the old triangle rasterization path, you will see that tree tops begin to lose their shape significantly at a distance, since Nanite’s cluster culling cannot preserve foliage shape. We have a “Preserve Surface Area” option to help with that case, but it is more of a workaround, and voxels are better at handling foliage. I hope that helps you gain a better intuition for what we want people to use the voxelization path for.

As for your second question, could you provide more details about this request? The MaxPixelsPerEdge heuristic is global, and we never considered applying it on a per-mesh basis, so I wouldn’t know what advice to give you to make it work with voxels.

[Attachment Removed]

Hello Tim,

Thank you for your answer!

We have managed to do it in two ways.

  1. In FClusterDAG::ReduceGroup, you can multiply the SimplifyError by some large number ( after SimplifyError = Merged.Simplify( *this, TargetNumTris ); )
  2. Then we discovered there’s an already exposed Nanite Setting in the asset called “Voxel Level”, and if you set that to -1, it does something quite similar to the change mentioned in 1., bringing the voxels closer

So I’d say, best option for us is 2.: Setting Voxel Level setting to -1.

Some holes show up after doing this, for now using the Separable flag helps fixing it at the expense of a slight performance reduction.

Thank you for you help!

[Attachment Removed]

Ah, I see! Then I assume your questions have been answered. Unless you have any outstanding questions, I will go ahead and close out the ticket. Please let me know if that works for you.

[Attachment Removed]

Yes, thanks!

[Attachment Removed]