GLTF model shadows not receiving with GLTFMeshStandardSGMaterial

Minecraft Education edition has a tool for exporting .GLB files directly from the game, but I can’t get the resulting GLB file to receive shadows in Three.js.

Here’s the demo - https://2cf782ea.minecraft-website.pages.dev/
The source repository - GitHub - aufyx/minecraft-website

I’ve set cast and recieve shadows on the mesh elements, adjusted the orthographic camera to cover the scene, etc. The other 3D objects I’ve added to the scene cast shadows correctly, and the GLTF model successfully casts shadows - but it doesn’t recieve them.

When I import the model into Blender, then export it as a GLTF, the shadows work, but the textures break. :confused:

The key difference between the two GLB models is that the original file loads in with GLTFMeshStandardSGMaterial, whereas the re-exported file loads in with MeshStandardMaterial. Loading the original file in https://gltf-viewer.donmccurdy.com/, it says that the file has a GLTF extension:
KHR_materials_pbrSpecularGlossiness

Any thoughts?

Hm, if glTF models using the KHR_materials_pbrSpecularGlossiness do not support shadows then that sounds like a bug. Trying to narrow it down, what happens if you run this command on the model?

npx gltf-transform metalrough input.glb output.glb

(documentation)

If just doing that fixes the shadows, I’d suggest filing a bug on the three.js github repo.

Performing the gltf-transform, the model materials have been updated to MeshStandardMaterial, and the textures of the model still load correctly, but this sadly doesn’t fix the shadows.

When I load the converted model in the gltf-viewer, I get the following two warnings:

UNSUPPORTED_EXTENSION - Cannot validate an extension as it is not supported by the validator: 'KHR_materials_ior'. - /extensionsUsed/0

UNSUPPORTED_EXTENSION - Cannot validate an extension as it is not supported by the validator: 'KHR_materials_specular'. - /extensionsUsed/1

Checking the docs, I see that these extensions are still experimental. Here is how the model uses these extension parameters to render a solid stone brick.

KHR_materials_ior: {
  ior: 1000
}
KHR_materials_specular: {
  specularColorFactor:
  [ 0: 0.03999999910593033
    1: 0.03999999910593033
    2: 0.03999999910593033 ],
​  specularFactor: 1
}

Changing / deleting these values when I loaded the model didn’t have any effect, so I don’t think this is relevant. IOR and Specular are related to lighting however… Perhaps another part of the model is missing?

That is fine, as long as the material still looks the way you expect it to look (other than the already missing shadows) you can ignore this warning.

When I run your demo (locally or in the link) I do seem to be seeing shadows. Are you expecting something different? Or perhaps have caching enabled in your browser?

That’s odd, because when I view the demo site it in my browser, I don’t see the shadows - see image below.

I’ve tested this in Firefox, Chrome and Edge using Windows 10. I have disabled my cache in the DevTools Network tab and reloaded the page, but nothing changes. I also don’t see the shadows on my phone when I open the site using the mobile Chrome browser.

I similarly don’t have any luck testing this locally. Disabling all my browser extensions also didn’t have any effect.

Hm, that is definitely weird. I’m seeing the shadows in Chrome, Firefox, and Safari on macOS.

Do you have any errors in the JS console on this demo? I see only ".gammaOutput has been removed", which is probably not related.

I see the following extra log messages,

THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(73,25-100): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them  [three.module-91c9237f.js:17075:12]

THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(260,25-100): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them  [three.module-91c9237f.js:17075:12]

8.810757470241375% loaded
100% loaded

THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(268,23-154): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
C:\fakepath(272,25-100): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them  [three.module-91c9237f.js:17075:12]

THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(267,23-154): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
C:\fakepath(271,25-100): warning X3571: pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them

I’ve seen these logs in previous projects and they didn’t mean anything. I don’t usually see four of the these logs at a time though; normally I just see two. The last two logs occur after the model is loaded in, which might not be a coincidence.

Googling the error, I found this relevant GitHub issue: Errors in the threejs.org editor · Issue #18553 · mrdoob/three.js · GitHub, Murgen87 commenting “This is a DirectX warning since you are on Windows. It does not appear e.g. on macOS or Linux.”

I’m not sure what to make of that. It may be worth filing an issue on the three.js repository since something is not working consistently across devices here.

After a bit of digging, Mugen87 found the fix:

const loader = new GLTFLoader();

loader.load( 'models/example.glb',
  function ( gltf ) {
    gltf.scene.traverse( function ( child ) {

      if ( child.isMesh ) {
        child.castShadow = true;
        child.receiveShadow = true;
        child.geometry.computeVertexNormals(); // FIX
      }

  ...

The Minecraft model exported from Education Edition doesn’t have precomputed vertex normals, so we get Three.js to calculate them for us.

Alternative solutions for model exporting exist for Minecraft Java Edition, consider using Mineways in combination with MCPrep and Blender. Blender supports exporting .gltf files and MCPrep does a good job of sharpening model textures and changing blend modes. Note that the file size of the model when using Mineways + Blender instead of the Education Edition structure block is considerably smaller.

A GitHub issue related to this thread can be found here:

2 Likes

Amazing, that Fix solved it for me as well.