Why does the same exact material look different in the Sandbox and my own instance?

There are subtle differences in color throughout the scene, but one material looks glaringly different.

The Sandbox Version

With default lighting (desired effect):

With studio lighting:

My Version

In Babylon:

In Blender:

What I Tried

  • I made sure to put a 0.7-intensity hemispheric light in my scene and even added a similarly-powered directional light later (which is why there are two highlights in my version).
  • I recreated the skybox, too, using the same exact .env file.
  • I went through the materials, both the skybox’s and the cone’s, to make sure they match their counterparts in the Sandbox.

The biggest thing I noticed is that, in the Sandbox, in the “Levels” section in the Inspector, the cone material receives its lighting only from the “Environment”, whereas for mine it’s only the “Specular”. However, I haven’t been able to figure out how to recreate that kind of lighting.

1 Like

I solved it by applying the skybox CubeTexture as the reflectionTexture property on the cone’s material.

It’s still unclear how the Sandbox applied the reflection texture. How did it decide which materials should receive it? Does it just apply it to all the materials in the scene?

2 Likes

To all PBR materials.

Actually materials decide this (how much reflections thay will get and where), according their metallic/roughness properties and textures.

3 Likes

Thank you. I tried to do that by iterating over every mesh in the scene, once it loaded, but since TypeScript transpiles to JavaScript and JavaScript is dynamically typed, I couldn’t figure out how to check whether the mesh’s material is of type PBRMaterial or StandardMaterial.

Checking if the reflectionTexture property is defined on the material proved pointless, since both have it.

And applying the texture to both kinds of materials regardless resulted in… interesting things :woozy_face::

1 Like

You can call getClassName() on the material to find out. :slight_smile:
https://playground.babylonjs.com/#CKQ0CR

2 Likes

After Blake’s answer, my code looked like this:

const skyboxTexture = new CubeTexture("assets/environments/environmentSpecular.env", scene);

SceneLoader.Append("assets/main_scene/", "scene.glb", scene, _ => {
  for (let mesh of scene.meshes) {
    if (mesh.material?.getClassName() == "PBRMaterial") {
        const currentMaterial = mesh.material as PBRMaterial;
        currentMaterial.reflectionTexture = skyboxTexture;
        mesh.material = currentMaterial;
    }
  }
}

However, after watching the underrated tutorial on PBR materials by Code-Small, I went with a simpler, not to mention more effective (in lighting the scene) implementation:

const skyboxTexture = new CubeTexture("assets/environments/environmentSpecular.env", scene);
const skybox = scene.createDefaultSkybox(skyboxTexture, scene);

// Set the skybox material's micro-surface to 0.7.
const skyboxMaterial = skybox?.material as PBRMaterial;
if (skyboxMaterial) {
    skyboxMaterial.microSurface = 0.7;
}

That’s it. At least, it seems to work for me. I’m still a beginner, though, so if anyone wants to correct me on that, please, go ahead.

1 Like