【问题标题】:Shadow Shader Chunks return errors阴影着色器块返回错误
【发布时间】:2016-12-13 04:36:22
【问题描述】:

我正在尝试将带有 ShaderMaterial 的基本卡通阴影与 threejs 的内置阴影系统相结合(一些代码取自 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'

我正在使用使用 typescript 的 superpowers-game 引擎。它的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

【问题讨论】:

  • 您确定像您正在做的那样将 ShaderChunks 直接添加到着色器字符串中会起作用吗?创建一个小提琴,以便更容易为您提供帮助
  • 是的,着色器似乎已检出。它只会失败,我将收到Shadow 设置为true。我不确定模板字符串是否只是打字稿,但 ${} 只是连接一个变量。
  • 再深入一点,这似乎是threejs版本的问题。我实际上在r68上。从那时起,关于shaderChunk 阴影的事情发生了变化。但是,问题是我需要添加一些其他块才能使其正常工作。
  • 哦,如果您使用的是旧版本,那么示例 HERE 可能会有所帮助
  • 对不起,我的错。我在寻找错误的文件。我在 r73,我发现出了什么问题。现在写一个答案。

标签: typescript three.js glsl


【解决方案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) 中的工作方式获得了这些信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多