PBR Refraction roughness (blurriness)

This might be related to KHR_materials_transmission & roughness? but I’m not sure.

I’m trying to change the blurriness of the refraction based on the PBR roughness of the material.
In the sandbox, the roughness works out of the box.
PG: https://playground.babylonjs.com/#22KZUW#261

However, I’m not able to find the values/attributes needed to create the same kind blurriness.
Any idea what I might be missing in the playground?

You can somehow use the lodGenerationOffset property of the refraction texture to simulate the roughness by using some lower mipmaps:

It will become blocky when using some higher values, however.

You could try to use some ReflectionProbe instead of refraction textures. You would need to use realtime filtering, though, which could be a bit taxing on performance… We are using a transmission helper class to handle transmission with glTF files, but this class is not exposed because we are not sure it will stay for the 5.0 release.

1 Like

Hi @Evgeni_Popov, thanks again for the quick response.

That definitely looks too blocky for my taste.
Got the reflection probe working in the playground https://playground.babylonjs.com/#22KZUW#273 (and it is indeed super heavy) but the roughness doesn’t affect the blurriness as well.

You need to enable generation of mipmaps for the probes, as well as adding a reflection texture (env map - see line 4), else the realtime filtering feature is not enabled:


I have also enabled the local cube map feature on the refraction textures (by setting the boundingBoxPosition and boundingBoxSize properties), as it is a little better.

1 Like

Hi @Evgeni_Popov , I see, thanks! So the reflectionprobe seems to work with LODoffsets to some degree. The blurry versions do look pixelated.

I do think the performance struggle is a bit to much with these three reflectionprobes. Is there a way to use some kind of BlurPostProcess on a RefractionTexture? They all seem to need a camera in the constructor.

You can try to do what the shadow generator does to blur the shadow map when using the blur exponential/blur close exponential filtering methods. It attaches to the onAfterUnbindObservable and does a direct render of the blur post process.

Relevant code:

The blur post processes are created here:

Hi @Evgeni_Popov thanks for pointing me in the right direction.
Seems just repeating the logic in the ShadowMap does not seem enough…
When disabling the textureSampler I do get a black sphere though so something must be happening.

You can’t render the blur pass into the same texture you are reading from, you get a “Feedback loop formed between Framebuffer and active Texture.” error because of that. So, you must create an additional texture T that you will render into, and bind this texture as the refraction texture of your material:


Some comments about this PG:

  • I commented the packFloat = true thing, I don’t know the purpose of this in the shadow generator code and it makes the blurring fail
  • Now that the pbr.refractionTexture property is set with the new T texture, you must add the regular refractionTexture in the scene.customRenderTargets array so that it gets generated. Indeed, RTTs (like T) assigned to some texture properties of the standard/PBR material are automatically generated each frame, but RTTs that are not are not automatically generated, you must tell the system you want them to be generated by adding them to scene.customRenderTargets
  • T is a regular RenderTargetTexture, so it gets generated each frame, meaning it is cleared and the meshes from its renderList are rendered into this texture. As this list is empty we are fine in that area, but the texture still gets cleared, something we don’t want as it happens after the blur have been generated, nullifying this processing. To avoid this clearing, we add an observer to T.onClearObservable that does nothing.