firtoz / react-three-renderer

Render into a three.js canvas using React.
https://toxicfork.github.com/react-three-renderer-example/
MIT License
1.49k stars 155 forks source link

Directional light too dark / not hitting object? #195

Open mdwint opened 7 years ago

mdwint commented 7 years ago

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;
toxicFork commented 7 years ago

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 commented 7 years ago

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?)

mdwint commented 7 years ago

Nice, that fixed it. Thanks a lot!

toxicFork commented 7 years ago

Happy to hear :)