Shadow Shader Chunks返回错误

时间:2016-08-07 06:42:22

标签: typescript three.js glsl

我试图将一个基本的香椿阴影ShaderMaterial与三个'内置在影子系统中(某些代码是从here获取和修改的)。从我在网上找到的内容中,我发现我在宣布制服,顶点和片段部分时应该使用ShaderChunks。我这样做了,每当我将Mesh的recieveShadow属性设置为true时,我都会收到错误。以下是我遇到的错误:

顶点错误

THREE.WebGLShader: gl.getShaderInfoLog() vertex ERROR: 0:72: 'worldPosition' : undeclared identifier 
ERROR: 0:72: 'assign' :  cannot convert from 'mediump 4X4 matrix of float' to 'mediump 4-component vector of float'

碎片错误

THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:356: 'shadowMask' : undeclared identifier
ERROR: 0:356: 'assign' :  cannot convert from 'mediump 3-component vector float' to 'float'

我正在使用超级大国游戏引擎,它使用的是打字稿。它的threejs插件目前在r73上。这是我的代码(仍然有点凌乱,我只是想在抛光之前完成所有工作):

着色

const IslandVertexShader = `
    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    ${ THREE.ShaderChunk[ "shadowmap_pars_vertex" ] }

    void main() {

        vNormal = normalize( normalMatrix * normal );
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vViewPosition = -mvPosition.xyz;
        vUv = uv;

        ${ THREE.ShaderChunk[ "shadowmap_vertex" ] }

        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

     }
`

const IslandFragmentShader = `
    uniform vec3 uMaterialColor;

    uniform vec3 uDirLightPos;
    uniform vec3 uDirLightColor;

    uniform float uKd;
    uniform float uBorder;

    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    ${ THREE.ShaderChunk[ "shadowmap_pars_fragment" ] }

    void main() {

        // compute direction to light
        vec4 lDirection = viewMatrix * vec4( uDirLightPos, 0.0 );
        vec3 lVector = normalize( lDirection.xyz );

        // diffuse: N * L. Normal must be normalized, since it's interpolated.
        vec3 normal = normalize( vNormal );
        //was: "float diffuse = max( dot( normal, lVector ), 0.0);",
        // solution
        float diffuse = dot( normal, lVector );
        if ( diffuse > 0.5 ) { diffuse = 1.0; }
        //else { diffuse = 0.5; };
        else if ( diffuse > -0.2 ) { diffuse = 0.7; }
        else { diffuse = 0.6; }

        //gl_FragColor = vec4( uMaterialColor.rgb, 1.0 );
        gl_FragColor = vec4( uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );

        ${ THREE.ShaderChunk[ "shadowmap_fragment" ] }

    }
`

声明

var sphere = new THREE.TorusKnotGeometry( 5, 1, 100, 16 );

var shader = new THREE.ShaderMaterial();
shader.uniforms = THREE.UniformsUtils.merge( [ THREE.UniformsLib[ "shadowmap" ], {

    uDirLightPos: { type: "v3", value: new THREE.Vector3( 0, 10, 0 ) },
    uDirLightColor: { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) },
    uMaterialColor: { type: "v3", value: new THREE.Vector3( 0.5, 1, 1 ) },
    uKd: { type: "f", value: 1 }

} ] );

shader.vertexShader = IslandVertexShader;
shader.fragmentShader = IslandFragmentShader;
shader.lights = true; // Probably not needed
shader.needsUpdate = true; // Probably not needed either

var mesh = new THREE.Mesh( sphere, shader );
mesh.castShadow = true;
mesh.receiveShadow = true; // The culprit
( <any>this.actor ).__inner.threeObject.add( mesh ); // Ignore this

1 个答案:

答案 0 :(得分:1)

好的,我经过一番挖掘后得到了它。如果您使用的是更新版本,那么很多内容都无关紧要,但这里是现在更正的代码:

const IslandVertexShader = `
    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    ${ THREE.ShaderChunk[ "shadowmap_pars_vertex" ] }

    void main() {

        ${ THREE.ShaderChunk[ "begin_vertex" ] }

        vNormal = normalize( normalMatrix * normal );
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vViewPosition = -mvPosition.xyz;
        vUv = uv;

        ${ THREE.ShaderChunk[ "worldpos_vertex" ] }
        ${ THREE.ShaderChunk[ "shadowmap_vertex" ] }

        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

    }
`

const IslandFragmentShader = `
    uniform vec3 uMaterialColor;

    uniform vec3 uDirLightPos;
    uniform vec3 uDirLightColor;

    uniform float uKd;
    uniform float uBorder;

    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    vec3 shadowMask = vec3( 1.0 );

    ${ THREE.ShaderChunk[ "shadowmap_pars_fragment" ] }


    void main() {

        // compute direction to light
        vec4 lDirection = viewMatrix * vec4( uDirLightPos, 0.0 );
        vec3 lVector = normalize( lDirection.xyz );

        // diffuse: N * L. Normal must be normalized, since it's interpolated.
        vec3 normal = normalize( vNormal );
        //was: "float diffuse = max( dot( normal, lVector ), 0.0);",
        // solution
        float diffuse = dot( normal, lVector );
        if ( diffuse > 0.5 ) { diffuse = 1.0; }
        //else { diffuse = 0.5; };
        else if ( diffuse > -0.2 ) { diffuse = 0.7; }
        else { diffuse = 0.6; }

        ${ THREE.ShaderChunk[ "shadowmap_fragment" ] }
        //gl_FragColor = vec4( shadowMask, 1.0 );
        gl_FragColor = vec4( shadowMask * uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );


    }
`

我需要添加begin_vertexworldpos_vertex块并在片段着色器中定义vec3 shadowMask,并在计算最终gl_FragColor时使用它。我通过检查BasicMaterial着色器在threejs r73提交(link here)中的工作原理来获取此信息。