Most optimized way to use a 4k environment map? Skybox is giving jagged results

I’m using the code below to set up a SkyBox with an HDRCubeTexture:

        var skybox = BABYLON.MeshBuilder.CreateBox("SkyBox", { size: 1000.0 }, newScene);
        skyboxMaterial = new BABYLON.StandardMaterial("skyBox", newScene);

        var textureSource = new BABYLON.HDRCubeTexture(hdrUrl, newScene, 4096);

The loading time is over a minute for the texture to load, and it still doesn’t look like the original HDR map. Is there a more optimized way to import HDR maps while keeping the quality close to the original? I need this HDR to be visible at all times, and not just for the reflections.

I also tried using a CubeTexture with 6 images instead, but I get the same quality and loading times.

can you share a repro? loading during a minute seems catastrophic

in the hdrCubeTexture use generateHarmonics set to false, this will speed up loading a lot
image

If you also use it for Create a much smaller version as an env texture to be as efficient as possible.

I can’t with this client until the project is public :frowning_face: is there anything else I can provide that would help?

Thank you for the suggestion. I’m setting the size to 2048 for testing, and with or without generateHarmonics set to true I get the same loading time of 20 seconds.

Is there anything else I can try?

Can you make sure it is not the network?

Yes I tried from two different locations already. Basically I just need the diffuse information for the HDR. I don’t need it to cast light on anything and I don’t need it to be visible in reflections. I just need it to be displayed in the scene. I tried using an .env texture instead, but the quality is really bad. The only way I get get decent quality is using an HDRCubeTexture with the resolution set to 4096.

My questions is are there any other methods of getting the same quality as the 4k HDR texture, while removing the reflections and lighting data so the load times are faster?

Can you try after load without harmonics to set the sphericalPolynomial flag to a new SphericalPolynomial empty object ? this way it would prevent if you use it with pbr which you should not to force the creation for it.

Sorry I’m still learning JS and Babylon, I come from a 3D artist background. Can you please elaborate? It would be really helpful if you include the code for the function you described.

I added this after the HDR is imported, but the loading time is still at 20 seconds using 2k resolution.

            skyboxMaterial.reflectionTexture.sphericalPolynomial = new BABYLON.SphericalPolynomial();

Is this what you were referring to?

1 Like

That’s why we need a repro
we are shooting in the dark else.

Ok I created a similar scene without any client assets:

https://playground.babylonjs.com/#U3Y5IB

My set up is the same except I’m using another high resolution HDRCubeTexture. I’ve tested the source texture from the client in Blender and it looks great without any aliasing or blurriness. However, in the playground the same texture looks low quality with a lot of aliasing. Even at 4096 resolution it doesn’t look the same as the source HDR image.

Even in the example above using the room.hdr texture from Babylon assets, you can see that the quality is not acceptable for a deliverable to the client. Keep in mind that they want the HDR to be visible in the scene, and not just be used for reflections. I don’t need any lighting data from the HDR, just for it to be visible in the background and have the same quality as the source texture.

This is the HDR in photoshop: as you can see the original data is not HR

Regarding speed to load, you need to prefilter your data using Lys or a similar tool:
Using An HDR Environment For PBR | Babylon.js Documentation (babylonjs.com)

Yes I see that, but in my case the source texture from the client has really good quality. It’s a 63MB hdr texture that I tested in Blender and it looks great.

Thank you for the recommendation, are there any alternatives to Lys that are free to use? or any other methods to prefilter the texture?

Here is the example with 4K texture from HDRI Haven - https://playground.babylonjs.com/#U3Y5IB#1
2K - https://playground.babylonjs.com/#U3Y5IB#2 (much faster)

Thanks for this, this is a great example that shows the issue I’m having. You can see that even at 4k resolution, which takes a really long time to load, the texture still doesn’t look identical to the source image, which is also at 4k resolution.

Here is the comparison with the same HDR opened in Blender (left is Babylon and right side is Blender). I marked some of the areas where you can really notice the difference.

The load times for the 4k version wouldn’t be acceptable for the client, as some of their customers may not have access to high speed internet, so the highest I can go is 2k which looks even more jagged. This issue is more pronounced in my scene because the HDR is from a space a lot smaller than the airport HDR you used, so everything is more up-close and the aliasing looks even more intense.

Are there any anti-aliasing filters I can apply to the HDRCubeTexture that would help?

Again for speed you should use a .env as stated in the doc I shared.

Adding @sebavan to see if he has an idea on the quality aspect

I did try converting the HDR to an .env and the loading times improved significantly, but the quality was even worse.

Can you please share the hdr you are using cause the size in the texture is the size of the edge of each square in the cube texture meaning your source needs to be at least 4 times bigger so if you load 2048 in babylon, your hdr needs to be 8192 width to keep the resolution in sync.

It would make my life a lot easier but unfortunately I can’t share anything from this client :frowning:

I can request a higher res HDR from them and test it out, but that will also increase the loading times correct? so if they provide me a texture with 2x resolution, the 2048 resolution in Babylon would have the same loading time as previous HDR set to 4096.