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

Shader material doesnt allow to enable extensions

Open Nopik opened this issue 9 years ago • 4 comments
trafficstars

I'm trying to port https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_wireframe.html / http://threejs.org/examples/#webgl_materials_wireframe to React renderer, and it seems that the shaderMaterial does accept source code for vertex and fragment shaders properly, but then doesnt allow to provide any equivalent of material.extensions.derivatives = true; (https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_wireframe.html#L92) and it fails in runtime, complaining about extensions not being enabled.

Nopik avatar May 16 '16 20:05 Nopik

Could you paste a gist and the full error please?

toxicFork avatar May 16 '16 21:05 toxicFork

Sure,

With this code:

import React from 'react';
import ReactDOM from 'react-dom';
import React3 from 'react-three-renderer';
import THREE from 'three';
import _ from 'lodash';

class Simple extends React.Component {
    constructor(props, context) {
        super(props, context);

        this.cameraPosition = new THREE.Vector3(0, 0, 5);

        this.state = {
            cubeRotation: new THREE.Euler( 1, 0, 0 )
        };
    }

    getShaderMaterial() {
        let vertexShader =
            "attribute vec3 center;" +
            " varying vec3 vCenter;" +
            " void main() {" +
            " vCenter = center;" +
            " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); " +
            "}" +
            "";

        let fragmentShader =
            "varying vec3 vCenter;" +
            " float edgeFactorTri() {" +
            " vec3 d = fwidth( vCenter.xyz );" +
            " vec3 a3 = smoothstep( vec3( 0.0 ), d * 1.5, vCenter.xyz );" +
            " return min( min( a3.x, a3.y ), a3.z );" +
            " }" +
            " void main() {" +
            " gl_FragColor.rgb = mix( vec3( 1.0 ), vec3( 0.2 ), edgeFactorTri() );" +
            " gl_FragColor.a = 1.0;" +
            " }";

        return(
            <shaderMaterial vertexShader={vertexShader} fragmentShader={fragmentShader}/>
        );
    }

    render() {
        const width = window.innerWidth;
        const height = window.innerHeight;

        let size = 1;
        let step = 0.2;

        let i = -size;
        let vertices = [];
        let z = -0.5;
        while( i <= size ) {
            vertices.push(
                new THREE.Vector3( -size, z, i ),
                new THREE.Vector3( size, z, i ),

                new THREE.Vector3( i, z, -size ),
                new THREE.Vector3( i, z, size )
            );

            i += step;
        }

        let shaderMaterial = this.getShaderMaterial();

        return (
            <div>
                <React3 mainCamera="camera" ref="react3" width={width} height={height} onAnimate={this._onAnimate}>
                    <scene>
                        <perspectiveCamera name="camera" fov={30} aspect={width / height} near={0.1} far={1000} position={this.cameraPosition} ref="mainCamera"/>

                        <mesh rotation={this.state.cubeRotation}>
                            <boxGeometry width={1} height={1} depth={1}/>
                            {this.getShaderMaterial()}
                        </mesh>
                    </scene>
                </React3>
            </div>
        );
    }
}

export default Simple;

I'm getting following errors:

THREE.WebGLShader: Shader couldn't compile.
THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:100: 'GL_OES_standard_derivatives' : extension is disabled
 1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define GAMMA_FACTOR 2
5: #define NUM_CLIPPING_PLANES 0
.... (long source code follows)

three.js:29652 THREE.WebGLProgram: shader error:  0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders  ERROR: 0:100: 'GL_OES_standard_derivatives' : extension is disabled

Changing this line:

      return new _three2.default.ShaderMaterial(materialDescription);

into this:

      var sm= new _three2.default.ShaderMaterial(materialDescription);
      sm.extensions.derivatives = true;
      return sm;

In node_modules/react-three-renderer/lib/descriptors/Material/ShaderMaterialDescriptor.js line 80 (construct of ShaderMaterialDescriptor) makes the above error go away, but instead makes the program complain about modelViewMatrix being accessed on undefined.

Nopik avatar May 17 '16 19:05 Nopik

Please try the modifications in here: https://gist.github.com/toxicFork/9dafb302cbbadf0544c11d6af4b85738/revisions

After adding the ref="shaderMaterial" and

componentDidMount() {
    this.refs.shaderMaterial.extensions.derivatives = true;
}

I am no longer getting errors. I did not get the modelViewMatrix error, which browser are you testing with? Also which version of three and react-three-renderer?

toxicFork avatar May 19 '16 17:05 toxicFork

Additionally I'm considering adding the extensions as props to shaderMaterial :) Perhaps similar to this:

<shaderMaterial 
    derivativesExtension={true}
    ...
/>

toxicFork avatar May 19 '16 17:05 toxicFork