SkinnedMesh culling is wrong and PointLightShadow gets clipped for SkinnedMesh

Description of the problem

Not sure if this is the same bug or two different.

  1. Whenever SkinnedMesh origin is out of camera frustum, the mesh gets culled even if its actual transformed geometry must be visible on the screen.
    Seems like the bounding box used for clipping is not updated with animation.

  2. Same happens for shadows.
    When the SkinnedMesh moves away from its origin in light space, its shadow gets clipped/partially clipped by pointlight’s perspectivecamera (I guess).

Here’s an example in jsfiddle:
Sorry for inline json. The example was dependent of viewport dimensions. Fixed.

And its not, light.shadow.radius bug.
Actually the use case for this was to make a complete animation in any 3d editor (blender in my case) just to play it as is in three.js. So the character isn’t moved by mesh.position, there is no need to sync movement/animation and hardcode movement positions.
It just plays baked animation!

Update: yes, making frustumCulled = false does fix both problems (which is enough for me to continue),
but most engines update object bbox with root motion/transforms.
Update2: actual temporary fix #11991 (comment)

Three.js version
  • r87
  • r85
  • Firefox
  • Windows
Hardware Requirements (graphics card, VR Device, …)

Author: Fantashit

1 thought on “SkinnedMesh culling is wrong and PointLightShadow gets clipped for SkinnedMesh

  1. Usnul, the horse case is a bit more close to updating boundings problem than to in-clip movement of character I’m talking about. In my case the boundings not only change in dimensions, but move around animation scene.
    But… oh, well, I got it. Instead of making changes in frustum.js, alll I need is to update the geometry.boundingSphere on the user side:

    function animate() {
    	scene.children.forEach((o) => {
    		if(o.isSkinnedMesh) {
    			var sphere = new THREE.Sphere();
    			sphere.copy( o.geometry.boundingSphere );
    			sphere.applyMatrix4( o.skeleton.bones[0].matrix );
    			o.geometry.boundingSphere = sphere; // easy
    	renderer.render(scene, camera);

    This solves my problem (actually I solved it in the first post by turning off culling at all), but I think I’ll leave the issue as probably the engine should be handling both cases somehow on its side.

Comments are closed.