Three.js: DirectionalLightHelper breaks when pointing down the Object3D.DefaultUp axis.

Created on 3 Jun 2017  路  8Comments  路  Source: mrdoob/three.js

Description of the problem

DirectionalLightHelper breaks when pointing down the DefaultUp axis.

This is related to:
https://github.com/mrdoob/three.js/issues/11241

I made a JSFiddle showing some of this new counterintuitive behavior, and also what seems like it might be a bug in DirectionalLightHelper as well...

First I set Object3D.DefaultUp.set(0,0,1)

Then I make a DirectionalLight, and a DirectionalLightHelper moving along the X axis, to eventually line up looking down the Z (DefaultUp) axis.

At the point that it is looking exactly down that axis, the DirectionalLightHelper breaks, and its values are full of NaNs...

Additionally when the NaN problem kicks in, I check for it, and flash the cube...

Let me know if any of this is unclear... of if I'm just using DirectionalLightHelper wrong?

Additionally, the DirectionalLightHelper, doesn't seem to be aiming down the correct axis that the light is pointing along... I animate a cube at the halfway point between light and 0,0,0, to illustrate that point...

http://jsfiddle.net/5wgjvLnz/19/

Three.js version
  • [ ] Dev
  • [x] r85
  • [ ] ...
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)

All 8 comments

Please try with this change to Matrix4.lookAt():

// eye and target are in the same vertical

if ( Math.abs( up.z ) === 1 ) {

    z.x += 0.0001;

} else {

    z.z += 0.0001;

}

Yep that fixes it. This also sorta nails down another implication of DefaultUp, namely that it can't be an arbitrary vector.. it needs to be x, y, or z exclusively.. in which case it almost seems to make more sense that it just be declared as an axis.. like DefaultUp = "z".

Thanks for checking it out @WestLangley.

This also sorta nails down another implication of DefaultUp, namely that it can't be an arbitrary vector

Why do you say that?

Additionally, the DirectionalLightHelper, doesn't seem to be aiming down the correct axis that the light is pointing along...

Commenting this line fixes that:

light.lookAt(light.target.position);

http://jsfiddle.net/5wgjvLnz/20/

@WestLangley If up.z = 1.01, would that check fail, and still yield a zero length cross product?

@mrdoob yeah. it fixes it, but doesn't explain why making a directionalLight lookAt something should break the helper. I think what you're telling me is that lookAt on a directionalLight is not intended to be used to aim the light.. which I get. Additionally, a side effect of that incorrect usage of lookAt is that any attached directionalLightHelper will be affected by the lookAt...

For instance, light.lookAt(new THREE.Vector3(0,0,0)); shows the same behavior. Like.. I wonder if lookAt on a directionLight should throw a warning or something?

up.z = 1.01

up must be unit length.

but doesn't explain why making a directionalLight lookAt something should break the helper.

Yes it does. The helper relies on the world matrix of the light.

Right. So the helper is broken for cases where one has modified the directional lights transform?

It does not make sense to modify the directional light's transform. Hence, I would not consider the helper as broken.

Was this page helpful?
0 / 5 - 0 ratings