SkyBox vs. PhotoDome (How to improve image resolution and reflections)

Hi,
I’m trying to define the right workflow for having an environment-image visible in the background as well as in the reflections with an acceptable quality of the environment-image. When using “cubeMaps” the result isn’t sufficient or I’m missing something. I raised the quality of the cubeMap (BJS Texture Tools) to 512px, but it didn’t make a huge difference, also not when using 8k hdr-files as input (tool doesn’t support more than 512px?!).

Playground (skyBox 512px)

  • background-image: looking ‘pixelated’ (resolution not high enough for visible background)
  • sphere: reflection looks good (as the whole image is being used for reflection - enough resolution, 6x 512px)
  • plane: reflection looks ‘pixelated’ (resolution not high enough for visible area in reflection)

Is there a way to use ‘cubeMaps’ with higher resolutions or set the settings in a way that it looks better?

Alternative to skyBox (PhotoDome)
Instead of using a skyBox with cubeMaps I tried setting up a ‘Photo-Dome’ (equirectangular/spherical texture) with a .jpg file of 2k/4k as input additionally. Concept: the Photo-Dome is used for the background and reflection-texture and the skyBox stays for the image-based-illumination (resolution 256px). Using this method the background image and reflection on the plane looks a lot sharper and cleaner.

Playground (PhotoDome - 4k)

  • is there a way to re-use the diffuse texture of the dome as reflection-map (couldn’t make it work)
  • for now I have to set up a ‘mirror-texture’ or ‘reflection-probe’ for having the dome-texture (diffuse) visible in the reflections

Perhaps someone can help me out in clarifying the right way, how to set it up having a high quality for the background as well as the reflections (mainly planes).
Is there a different way in setting up the skybox with cubeMaps or other alternatives like the photo-dome? Can a spherical (equirectangular) texture be used for IBL, without having it re-calculated as cubeMap? Would appreciate any kind of advise… Thanks!

cc @PatrickRyan

@anonymouse let me think about this question a bit and I will get an answer to you asap.

1 Like

@anonymouse, after considering a couple of different methods, I think the best method is simply to create a second PBR spec/gloss material and pass a custom reflectionTexture. What I did here was to grab another hdr image that I could get a large version of at polyhaven. The reason is that you will need both a 2k version and a 4k image. The 2k version is passed as the IBL for the scene, and the 4K version is converted to a cube map and passed in as a second reflection texture.

I took the 4k texture to 360Toolkit - Convert equirectangular to cubemap to create my six cube images. Note there are a few things I needed to do to get the cube images correct. The first was to take the hdr file into an image editor and convert to 8-bit color and save as a png since I don’t need the HDR data. Then once I got the images from the conversion using 360Toolkit, I needed to bring them back into the image editor to make sure I had them aligned and in the right order for naming. I dropped them into the cube and found the exported images were not named correctly in a few instances and that the Y axis images needed to be rotated by 180 degrees. It looks like this:

Then I exported each image with the correct rotation and name as noted in the image above so that we get the correct cube in the scene.

In this way, you can get a cubemap that has a higher than 512x512 per face resolution. In this case I am using a 1k x 1k per face resolution (note that this will increase loading time, but you could use a more compressed jpg to cut down on the download a bit. But creating this reflection texture from a cube that is larger is going to give you a better resolution in your plane reflections:

The thing to remember here is that if you are passing a reflection texture to PBRMaterial, you are working with a spec/gloss lighting model not a metallic/rough. Since you want this to be a mirror reflection, this is a simple way to accomplish this. The rest of the materials in the scene can use metallic rough and simply use the scene environment. However, if you want reflections other than pure mirror reflection you will have to also pass a reflectivityTexture to break up the reflections like in this PG which uses the reflectivityTexture to break up the reflectionTexture.

I also considered cameras with render textures, but that would not work well with geometry other than planes and you would significantly increase the number of cameras and rendering to texture if you have many planes that need to reflect. So making a separate PBR-SG texture with a custom reflection texture would probably be the best result for you. Hope this helps and let me know if you have more questions.

1 Like

@PatrickRyan thank you so much for digging into the topic and giving a detailed approach how to achieve the “mirror-reflections” with a 1k per face resolution.

The workflow for creating the 1k cubic-texture is quite complex, but having your instructions, everything works well - thanks for figuring it out!

For now I’m thinking about how to additionally increase the quality of the image in the background. I see two different journeys for us and would appreciate it, when you can confirm it.

  1. "Mirror-Plane-Reflection" needed with 1k CubeMap (as your described) and a “High-Res Background” image (re-use of the 1k-cubeTexture)

    • first skybox - for lighting and reflections (256/512 hdr or env file cubic)
    • second skybox - background and custom-reflection for ‘mirror-plane-reflection’ (1024 jpg file cubic)
    • example: https://playground.babylonjs.com/#CGA05F#504
  2. No “Mirror-Plane-Reflection”, only “High-Res Background” as environment needed

    • in this case I would avoid the process of manual generating the 1k-cubeTexture and go for a photoDome with a 4k-spherical (equirectangular) jpg-file instead
    • lighting & reflection comes from the skybox (256/512 env cubic), visibility gets turned of
    • PhotoDome gets adjusted in rotation (same position as skybox) and used for the background

Thanks for the quick support and appreciation for the work you guys are doing…!

3 Likes