Custom shader export + texture LODs

Hi,

I have a ShaderGraph (UnityGLTF’s Unlit graph + additional texture with some texture blending capabilities) which I export using the “Unlit WebGL2” route. Now during runtime I want to dynamically assign other textures but this breaks the LOD’ing: Only the lowest res LOD is being loaded.
Is it possible to inform the LOD manager about the texture change so it “just works”?

The automatic LOD system only inspects texture slots when the object first renders. Runtime swaps aren’t tracked, so you need to manually request the full LOD.

After assigning the texture, call NEEDLE_progressive.assignTextureLOD:

import { NEEDLE_progressive } from "@needle-tools/engine";

// Upgrade all texture slots on the material
NEEDLE_progressive.assignTextureLOD(material, 0);

// Or upgrade a single texture
NEEDLE_progressive.assignTextureLOD(yourTexture, 0).then(tex => {
    if (tex) material.uniforms._YourUniform.value = tex;
});

This forces the highest-res LOD (level 0) to load. The same works for any custom shader uniform or swapped map.

Sources: Needle Engine Docs (67%), Needle Engine Docs (63%)

1 replies left - Become PRO for more replies.
Reply to this post directly if you need further help (bottom right button)

Hi, the AI reply above should do it. Did you try that?

Coming back to this after a while, sorry for the delay. Actually I tried the AI’s suggestions but it made no difference.

Here’s the relevant snippet with the things I tried:

if(uniforms.baseColorTexture2.value != tb) {
  uniforms.baseColorTexture2.value = tb;

//  NEEDLE_progressive.assignTextureLOD(tb, 0);

//   NEEDLE_progressive.assignTextureLOD(tb, 0).then(tex => {
//     if (tex) uniforms.baseColorTexture2.value = tex;
// });
}

// NEEDLE_progressive.assignTextureLOD(this.oq.sharedMaterial, 0);

Any idea?

Hi, this is exactly how we update our textures internally too - assignTextureLOD is async, perhaps you’re missing a needsUpdate = true change? Have you tried to debug / look at it with Needle Inspector?

It works now. Nothing wrong on your end.

The giveaway was in the first line: Here the current texture is compared to the target texture (named tb). The lod-0 texture the promise handler sets gets immediately overwritten with the lod-x version of the texture again as this check happens on every update :person_facepalming: