Izzimach / react-three-legacy

React bindings to create and control a 3D scene using three.js
Other
1.52k stars 127 forks source link

Component for THREE.ShaderMaterial #71

Open oveddan opened 8 years ago

oveddan commented 8 years ago

Per the example using shaders: https://github.com/oveddan/react-three/blob/three-shader-example/examples/shader/shader.jsx#L22

It would be great if there was a react component for a THREE.ShaderMaterial

Currently this is done like:

cass Wavey extends React.Component {
  constructor(props) {
    super(props)

    this.uniforms = {
      time: { type: "f", value: props.time },
      resolution: { type: "v2", value: new THREE.Vector2(props.width, props.height) }
    }; 

    this.material = new THREE.ShaderMaterial({
      uniforms: this.uniforms,
      vertexShader: vertexShader,
      fragmentShader: fragmentShader
    });
  }
  componentWillReceiveProps(nextProps) {
    this.uniforms.time.value = nextProps.time

    if(nextProps.width !== this.props.width)
      this.uniforms.resolution.value.x = nextProps.width;

    if(nextProps.height !== this.props.height)
      this.uniforms.resolution.value.y = nextProps.height;
  }
  render() {
    return <Mesh geometry={geometry} material={this.material} />
  }
}

It would be great if there was some way to have a ShaderMaterial as a child element of the mesh, and there was an easy way to pass new values to the uniforms.

Izzimach commented 8 years ago

The problem here is that things like ShaderMaterial and Geometry are not instances of Object3D and the underlying scene graph is built using Object3D nodes. I mean it's certainly possible but would require a lot of work and/or hackery. Especially problematic is that the behavior is undefined when people do odd things like have multiple Geometry child or other strange things.

I usually recommend doing something like you've shown above - write a component to do all the nasty work and then use that component everywhere. #34 lists a few other components I wanted to write that would be similar.

Izzimach commented 8 years ago

Also you might want to look at react-three-renderer which takes a different approach and betters supports embedding geometry/material as React components.