Is it not possible to set this value manually? My use case is, I am trying to create a script that can make use of existing shaders that work with LODGroup, but I want to control the LOD transition process myself. It’s for an Asset Store product which is why I am trying to make the script work with existing shaders that work with LDOGroup, to allow for maximum compatibility and not make my users have to modify their shaders.
Hey guys, I’ve managed to get it working - not sure about the unity_LODFade.y value - I got it printed using this (which helped me quite a lot for this project) and it returns the same value as unity_LODFade.x.
I’ve used your code and made it coroutine which “lerps” the tFadeOut value over time (same result as LODGroup crossFade is doing) - when lods needs to changed, call this coroutine instead.
For surface take a look at dithercrossfade
For VF shader, all you need is #pragma multi_compile _ LOD_FADE_CROSSFADE, and UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy); - at the beginning of frag shader
//Call inside Start()
rend.sharedMaterial.EnableKeyword("LOD_FADE_CROSSFADE");
// Coroutine/Lerp this
Vector4 fadeOutVec = new Vector4(tFadeOut, tFadeOut);
block.SetVector("unity_LODFade", fadeOutVec);
rend.SetPropertyBlock(block); // Blocks can be pooled
// Call this one frame after tFadeOut == 0, this will cause static batching to work again
rend.SetPropertyBlock(null);
Keep in mind, that when changing LOD0->LOD1
LOD0: unity_LODFade.x → <1, 0>
LOD1: unity_LODFade.x → <-1, 0>
Also take a look at this, I am using it for all lods which should not be rendered instead of disabling the mesh renderer. rend.forceRenderingOff = false;
EDIT: I’ve made a few updates
EnableKeyword should be called on rend.sharedMaterial, because it DOES lead to material instancing if using rend.material
Clear the property block one frame after fade == 0 to reenable static batching (otherwise it will not work due to different propertyBlock
“is sharedMaterial is used, it wil break for other object that are using it.” - can you explain this more?
"Keep in mind, that when changing LOD0->LOD1
LOD0: unity_LODFade.x → <1, 0>
LOD1: unity_LODFade.x → <-1, 0>"
You are saying for the LOD0 object which is fading out, you lerp from 1 to 0?
And for the LOD1 object which is fading in, you lerp from -1 to 0?
That does not seem correct, so I think I am misunderstanding.
Because you would be enabling Keyword for shared material (material asset), it will influence all of it usages in the scenes, so if you use the same material for X object in the scene, but you want to crossfade only one of those objects, it will crossfade all of those objects. (EDIT: it will, but that should not matter, because unity_LODFade.x will be 0 - see my first post) As I got it working only yesterday, I still have some unknowns, but will continue to watch it.
// LOD0 must use this function with ditherFactor 1..0
// LOD1 must use this function with ditherFactor -1..0
// This is what is provided by unity_LODFade
void LODDitheringTransition(uint2 fadeMaskSeed, float ditherFactor)
via trial and error (and printing the value by above mantioned function) I’ve found out, that if you have currentLOD and nextLOD, currentLOD always should be lerping from 1 to 0, and nextLOD from -1 to 0. It does not matter if you move up or down in LODs.
I stopped trying to make this work for a while, but am renewing my efforts once again.
To be honest, I don’t really understand why you need to use -1 to 0 for the stuff that is fading in. If you fade in starting at 0 and going to 1, then fade out starting at 1 and ending at 0, doesn’t that accomplish the same thing?
And how can fully faded in and fully faded out be represented by the same value (0)?
In any case, I tested using 0 → 1 for fading in and 1 → 0 for fading out and it seems to work just fine.
Another note for anyone using URP. LOD_FADE_CROSSFADE does not seem to be supported until URP 14, which requires Unity 2022.2.