Update SkyMaterial shader?

I just wanted to resurrect this discussion from the old forum:

I changed the filtering of the input texture to LINEAR_NEAREST and that resolved the original poster’s reported “line artifacts”. See https://www.babylonjs-playground.com/#11GAIH#93

But I notice that since that discussion there’s a new sky shader on Shadertoy which is even better:
https://www.shadertoy.com/view/tdSXzD

I started playing around trying to port this to Babylon.js but I’m still quite a newbie with shaders, so I’m not sure how to proceed. https://www.babylonjs-playground.com/#11GAIH#95

I’m also curious why that first sky shader seems to run slower after porting to Babylon.js than it does in Shadertoy. Compare @BitOfGold’s Shadertoy version Shader - Shadertoy BETA with the equivalent Babylon.js PG https://www.babylonjs-playground.com/#11GAIH#93

It’d be so cool to have dynamic, blended clouds in the SkyMaterial.

Any help or advice appreciated.

1 Like

Regarding your fix for the first PG, I could not understand why changing the sampling mode for the mip levels would change anything, because in the code the sampling is done like this:

vec2 rg = texture( iChannel0, (uv+ 0.5)/256.0, -100.0).yx;

The -100 here is a bias applied when the gpu chooses the mip levels to sample from, so in effect the level chosen is always 0 because of this big offset. That means the GPU never blends between mip levels, it always sample the level 0 (meaning, the full regular texture). So, your change should have no effect…

However, we can find this code in ThinEngine._setAnisotropicLevel:

var anisotropicFilterExtension = this._caps.textureAnisotropicFilterExtension;
if (internalTexture.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST
    && internalTexture.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR
    && internalTexture.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR) {
    anisotropicFilteringLevel = 1; // Forcing the anisotropic to 1 because else webgl will force filters to linear
}

As LINEAR_NEAREST (the value you set) is different from the values we see in the if, anisotropic level is reset to 1 => anisotropic level > 1 is indeed responsible for the banding you can see in the PG, if you don’t perform your change but simply add mainTexture.anisotropicFilteringLevel = 1; the banding disappears:

https://www.babylonjs-playground.com/#11GAIH#100

Regarding the new shader you try to convert to Babylon, the problem is that it is not an equirectangular texture that is generated, so you won’t be able to use it on a skydome, it will appear deformed.

As for the perf problem, maybe it’s a problem of cache coherency on the GPU. Instead of using the shader as a material applied to the sphere, I think the perf would be better if the sky was generated as a texture (maybe in a procedural texture) and this texture used as a diffuse texture on the sphere.

3 Likes

Thanks for your input @Evgeni_Popov

Yes I just cycled through the different filtering modes and LINEAR_NEAREST worked but I didn’t know why it worked. Thanks for investigating deeper.

Forgive my shader ignorance, but I’m not clear on the difference between (or how to) create a procedural texture vs a shader material or why that should make a difference to performance, so I’ll read up on the docs.