is there a proper way to fade out meshes in the distance?
for example in PCG we’re spawning grass in giant rectangular square blocks and the player can’t be allowed to see these giant blocks appearing and disappearing as the player walks forward, so our hack solution was to put a dithered distance into their alphatest to get them to fade out.
that’s a terrible way to do it though, so it can’t be right. that means you then have to change all the meshes’ shaders to be alphatest, which should never be done. The other problem is that if you spawn one of these meshes outside of PCG, they still have the fade out effect on them when they shouldn’t. it should only exist for the PCG meshes.
so i was wondering if there’s a proper way to fade out meshes that would skip all of this alphatest craziness? i would think there is because before nanite, you’d have a distinct pop as a mesh switches between LOD states and so unreal has a fade in and out feature to help hide that pop. so i was wondering if that same feature is available for this type of issue? And i was curious how that fade worked, as it somehow worked on meshes without alphatest.
thanks so much!
[Attachment Removed]
Steps to Reproduce
no repro steps needed. we’re just trying to figure out the proper way to fade out PCG meshes so the user doesn’t see the giant blocks of meshes popping in and out of existence in the distance as you walk forward.
[Attachment Removed]
Hi,
it’s not possible to fade out an entire PCG volume at once, but you can use a combination of using the Instance Start/End Cull Distance on the Static Mesh Spawner node (to fully cull distant instanced meshes and save performance) and a material that is applied to each instance and is set to Masked with a DitherTemporalAA node (with a distance based alpha threshold) plugged into its Opacity Mask input. It should be possible to restrict the fading effect to only PCG instances by using per instance custom data via the Instance Data Packer on the Static Mesh Spawner Node (set the “Instance Data Packer Type” to “PCGInstanceDataPackerByAttribute” and add an attribute, in the instanced mesh material the “PerInstanceCustomData3Vector” node can be used to access this data).
This article provides some other ways to enable smooth transitions, such as a distance dependent scaling effect which uses world position offset.
Hopefully this helps, but let me know if you have more questions.
Thanks,
Sam
[Attachment Removed]
thanks i didn’t know about the start/end cull vars. that would enable us to fade out a specific mesh in PCG but not have it fade if it wasn’t spawned in PCG.
it still doesn’t sound “right” to have to use alphatest in the material though. they say we should try our hardest to not use alphatest anymore on nanite meshes.
so i was curious exactly HOW non-nanite meshes fade in and out as they swap LODs? it could be that they’re all forced to use an alphatest material as well but that just doesn’t sound right.
thanks in advance.
-seneca
[Attachment Removed]
Hi,
>> i was curious exactly HOW non-nanite meshes fade in and out as they swap LODs?
The LODs of non-Nanite meshes can be blended by enabling “Dithered LOD Transition” in the material details. The engine renders both LODs simultaneously during the transition. The material uses a dithered pattern (dots) to mask pixels, effectively blending them in screen space. The LOD fading is implemented by changing the dither threshold over time. Both tiles use the same threshold value and as a result get the same screen-space dither value. The fading-in tile however, inverts the dither value before plugging it into the opacity mask.
When combined with TAA, the dither pattern changes every frame, which through temporal accumulation, creates a smooth semi-transparent blend effect rather than a sharp cutout. This mimics true transparency (which is expensive) using only one rendering pass with an opacity mask, allowing it to work well for objects like foliage.
Dithered opacity masking is significantly more performant than the translucency approach as it has essentially no overdraw (when compared to translucency), no depth sorting cost, no extra lighting cost, and no negative effect on occlusion culling. However, the implicit cost of LOD blending remains - both LODs have to be drawn at the same time during the transition period.
If you have LODs in your scene, you can visualize how this dithered LOD transition works by enabling Level of Detail Coloration > Mesh LOD Coloration.
Let me know if you have more questions.
Best,
Sam
[Attachment Removed]
thanks. so we did some testing and the max draw distance did work and so the PCG meshes stopped drawing after a distance.
but that’s only half way.. we need the meshes to alphatest fade out before they stop drawing. we tried both the DISTANCE CULL FADE and PERINSTANCEFADEAMOUNT shader nodes in the shader’s alphatest output and neither access the max draw distance setting from the PCG spawner -if- the meshes are using nanite… which doesn’t make any sense as all geo is supposed to be nanite these days..
if the meshes are not nanite, they get the fade distance properly. if they’re not, they do get something, but it’s a boolean on/off value and it’s at about 1/3rd the true cull distance somehow.
i kinda can’t imagine this bug existing because i’d think all other companies with open world games should be using this feature and nanite…?
[Attachment Removed]
Hi,
there is a way to have fading with dithered opacity masking on Nanite meshes. Can you try the following material (to avoid clipping of shadows near the camera, make sure to select Excluding Material Shader Offsets on the Absolute World Position node):
[Image Removed]
That material gives me the following result on a PCG scene with a bunch of Nanite enabled spheres, where the instances start fading out from a certain distance:
[Image Removed]
For reference, this is the same scene without fading, just using the cull distance:
[Image Removed]
Please let me know if this works for you.
Sam
[Attachment Removed]
correct. that’s a hardcoded shader distance fading, which we didn’t want to use because it would be applying to ALL meshes, not just the ones spawned by PCG. and it’s distance wouldn’t be tied to the PCG’s cull distance variables, thus if that was changed, the shader’s distance would then be out of synch.
what we were curious about is why the DISTANCE CULL FADE and PERINSTANCEFADEAMOUNT shader nodes appear to not be usable on nanite meshes, as nanite is now the default mesh type?
if we have no choice, we have no choice and we’ll do what you did which is hardcode the fade out distance and also have two material instances with and without the fading so the non PCG meshes can skip it, but that’s just an ugly way of doing it for a bunch of reasons. 
[Attachment Removed]
Hi,
I see. The DistanceCullFade and PerInstanceFadeAmount not working with Nanite is a known issue, these cases might be relevant:
[Content removed]
[Content removed]
[Content removed]
There is however a way to obtain the cull distance in a shader via a custom HLSL node as explained in this case: [Content removed]
It’s possible to visualise the instance’s draw distance with this node setup, which displays the value as a texture:
[Image Removed]Changing the Instance End Cull Distance on the PCG’s Static Mesh Spawner node will result in a different value. There is a quadratic relationship between the Instance End Cull Distance and the result from GetPrimitiveData().InstanceDrawDistanceMinMaxSquared.y, (e.g. 1000 maps to 640000, 2000 maps to 2560000 etc).
If you have further questions, please let me know,
Sam
[Attachment Removed]
Glad that helped. I will close the case now, but feel free to re-open if you have further questions.
Regards,
Sam
[Attachment Removed]