react-three-renderer icon indicating copy to clipboard operation
react-three-renderer copied to clipboard

Directional light too dark / not hitting object?

Open mdwint opened this issue 8 years ago • 4 comments
trafficstars

I've taken the three.js OBJLoader example and converted it to a React component.

As you can see in the screenshots below, something is off with the lighting. Even after increasing the intensity to 5, the directional light looks very dark, as if only the object's edges are illuminated.

Any idea what I might be doing wrong? Does your library set any defaults that I'm not taking into account? (I have no prior experience with three.js)

Original (source):

screen shot 2017-09-07 at 22 23 25

My result (source below):

screen shot 2017-09-07 at 22 23 14
import React from 'react';
import React3 from 'react-three-renderer';
import * as THREE from 'three';
import * as OBJLoader from 'three-obj-loader';
import uvGrid from '../../src/assets/images/uv-grid.jpg';
import male from '../../src/assets/objects/male.obj';

OBJLoader(THREE);

class Example extends React.Component {

  constructor(props, context) {
    super(props, context);
    this.state = {
      objectRotation: new THREE.Euler(),
    };
    this.lightPosition = new THREE.Vector3(0, 0, 1);
    this.objectPosition = new THREE.Vector3(0, -95, 0);
    this.cameraPosition = new THREE.Vector3(0, 0, 300);
    this.loadObject();
  }

  componentWillUnmount() {
    if (this.state.object) {
      this.group.remove(this.state.object);
    }
  }

  setGroup = (ref) => {
    this.group = ref;
  }

  loadObject() {
    const manager = new THREE.LoadingManager();
    manager.onProgress = (item, loaded, total) => {
      console.log(item, loaded, total);
    };

    const onProgress = (xhr) => {
      if (xhr.lengthComputable) {
        const percentComplete = (xhr.loaded / xhr.total) * 100;
        console.log(`${Math.round(percentComplete, 2)}% downloaded`);
      }
    };

    const texture = new THREE.Texture();

    const imgLoader = new THREE.ImageLoader(manager);
    imgLoader.load(uvGrid, (image) => {
      texture.image = image;
      texture.needsUpdate = true;
    });

    const objLoader = new THREE.OBJLoader(manager);
    objLoader.load(male, (object) => {
      object.traverse((child) => {
        if (child instanceof THREE.Mesh) {
          child.material.map = texture;
        }
      });
      this.group.add(object);
      this.setState({ object });
    }, onProgress);
  }

  animate = () => {
    this.setState({
      objectRotation: new THREE.Euler(
        0, this.state.objectRotation.y + 0.05, 0,
      ),
    });
  };

  render() {
    const width = 600;
    const height = 600;

    return (
      <React3
        mainCamera="camera"
        width={width}
        height={height}
        pixelRatio={window.devicePixelRatio}
        onAnimate={this.animate}
      >
        <scene>
          <perspectiveCamera
            name="camera"
            fov={45}
            aspect={width / height}
            near={1}
            far={2000}
            position={this.cameraPosition}
          />
          <ambientLight
            color={0x101030}
          />
          <directionalLight
            color={0xffeedd}
            position={this.lightPosition}
            intensity={5}
          />
          <group
            ref={this.setGroup}
            position={this.objectPosition}
            rotation={this.state.objectRotation}
          />
        </scene>
      </React3>
    );
  }
}

export default Example;

mdwint avatar Sep 07 '17 20:09 mdwint

Ah yes, this is because Three does directional light rotation in a strange way...

See https://github.com/toxicFork/react-three-renderer/issues/65#issuecomment-219002299

I think this should make it work the same as vanilla threejs:


// anywhere in the file, e.g. before the class
const origin = new THREE.Vector3(0, 0, 0);

// in the render
          <directionalLight
            // other props
            lookAt={origin}
          />

I will need to add a note to directional light properties to explain this.

toxicFork avatar Sep 09 '17 09:09 toxicFork

I guess it's "kind of a bug" that it behaves different than Three, but I'll still find a way to fix it without having inconsisterncies in behaviour with other components... (e.g. require one of the rotation properties?)

toxicFork avatar Sep 09 '17 09:09 toxicFork

Nice, that fixed it. Thanks a lot!

mdwint avatar Sep 10 '17 15:09 mdwint

Happy to hear :)

toxicFork avatar Sep 10 '17 15:09 toxicFork