Open jhancock532 opened 3 years ago
I can reproduce this on a Windows 10 laptop with Chrome.
I'm a Mac user and I don't see the shadow 😁
That is strange 🤔 . It works fine on my iMac...
@jhancock532 Do you mind providing a second version of your app (via a second URL) with the following changes:
WebGL1Renderer
gammaOutput
and use: renderer.outputEncoding = THREE.sRGBEncoding;
.@Mugen87 Here's the new link with the updates made as requested.
https://426d15f3.minecraft-website.pages.dev/
Nothing has changed on my end, no new errors or logs.
@jhancock532 I've investigated the issue closer and could fix it on my Windows laptop by adding vertex normals. Can you please add the following line into your onLoad()
callback where you enable shadows for the child objects?
child.castShadow = true;
child.receiveShadow = true;
child.geometry.computeVertexNormals(); // FIX
It would be great if you can update https://426d15f3.minecraft-website.pages.dev/ with that fix.
@mrdoob The OP's asset has no vertex normals and it seems this behavior is somewhat undefined since the normal
attribute in the shader might have different default values depending on the platform. To me, this is an issue in the exporter since they should always export vertex normals. At least when lit materials are going to be used.
We could try to detect this issue and generate vertex normals if not present however they will not be required for all use cases.
Thank you, this has fixed my issue. I'm afraid I can't update the old URL due to how Cloudflare Pages works, but I have deployed the fixed example to https://61c69ff5.minecraft-website.pages.dev/.
... this behavior is somewhat undefined since the normal attribute in the shader might have different default values depending on the platform. To me, this is an issue in the exporter since they should always export vertex normals. At least when lit materials are going to be used.
GLTFLoader will automatically set material.flatShading = true
when vertex normals are not included, since that's the behavior glTF specifies. Does this effectively mean that we don't intend to support shadows with material.flatShading = true
? I'm not sure I understand why this setting would have platform-specific effects.
GLTFLoader will automatically set material.flatShading = true when vertex normals are not included,
I've missed that bit. Then this issue needs further investigation. I wonder why the existence of vertex normals makes a difference although flat shading is used 🤔 .
Okay, I think I have found the problematic line. It is:
When no vertex normals are present, normal
has an undefined value and thus objectNormal
and transformedNormal
. Using an undefined value in the above line breaks shadowWorldNormal
and thus vDirectionalShadowCoord
can't be computed.
So it seems vertex normals are required for receiving shadows even when flat shading is used. This is also true for other features like displacement maps.
However, I'm not aware of an approach to compute vertex normals in the vertex shader. It seems the only way of fixing this is the usage of toNonIndexed()
and computeVertexNormals()
(instead of setting flatShading
to true
).
Couldn't we just generate flat vertex normals in GLTFLoader
instead of setting flatShading
to true
?
I'd generally prefer not to add O(n) per-vertex costs for all users as solutions to avoid less common issues for specific use cases. If WebGLRenderer requires vertex normals for an object to receive shadows, perhaps it can print a warning when those conditions aren't met?
I expect the solution is to fix #18915 to handle the case when flatShading
is true
and normals are not present.
/ping @Oletus.
(Setting flatShading
to false
when normals are not present is a user error. GLTFLoader
silently handles that case.)
From #22056 we've been running into this issue as of r118 and I'm trying to think of a way to fix it. Some our geometry does not have normals and we'd prefer not to regenerate them because the mesh changes frequently and vertex normal generation is expensive.
One (temporary?) solution would be to set shadowWorldNormal
to 0 0 0
on this line if the FLAT_SHADED
define is set though of course that means normal bias won't work on materials that do have normals and are flat shaded but that would be the simplest solution to at least get something working more as expected. Perhaps another define could be added to indicate if the geometry does have vertex normals so shadowWorldNormal
is only set to 0 0 0
if the geometry is flat shaded and has no vertex normals.
However, I'm not aware of an approach to compute vertex normals in the vertex shader.
I think the true fix for this would be to compute the normal bias offset in the fragment shader if flat shading is enabled but that's clearly a more complicated and expensive change. Another option might be to apply the normal offset when rendering the shadow map rather than when sampling the shadow map but I'd have to look into the implementation a bit more to see if the same result could be achieved.
Minecraft Education edition has a tool for exporting .GLB files directly from the game, but the resulting GLB file won't receive shadows when displayed using three.js on Windows devices.
This issue occurs when using Windows browsers (Firefox, Chrome, Edge), but not when using MacOS browsers (Chrome, Firefox, and Safari). See the original thread on discourse.threejs.org for more information.
Steps to reproduce the behavior:
Live example https://2cf782ea.minecraft-website.pages.dev/ Source code can be found in this GitHub repository.
Expected behavior The red sphere should cast a shadow onto the 3D model.
Screenshots Windows users don't see the sphere shadow, its absence circled in red.
Mac users see the shadow as expected, as well as the model casting shadows on itself.
Platform: