关于使用多个顶点着色器时声明属性和矩阵的THREE.js(R75)规则

时间:2016-03-24 19:36:15

标签: three.js shader

我在使用两种着色器材料时遇到了问题,每种着色器材料都使用一对不同的顶点和顶点。片段着色器并使用不同的(自定义的)缓冲区几何体。两种几何都使用相同的属性名称,例如位置,法线,紫外线和颜色。

我可以让两个着色器自己或同时工作。 但该程序对属性和矩阵的声明很敏感。我不得不进行反复试验,以找出要保留的声明和要注释的声明。

这是我用来同时处理两个着色器材质的着色器代码(Pair1 = vertexShader01 + fragmentShader01和Pair2 = vertexShader03 + fragmentShader03)。

<script id="vertexShader01" type="x-shader/x-vertex">

// HEADER01 //
//... Not a problem for header to be inactive if the shader is not used.
//...  if two shader materials active then this header must be active.
//...  if one shader material active and one defined but not active then this header must also be active.

    precision mediump float;
    precision mediump int;
    uniform mat4 modelViewMatrix; 
    uniform mat4 projectionMatrix;              
    attribute vec3 position;
    attribute vec4 color;
    attribute vec3 normal; 
////            
    uniform float uTime;    
    varying vec3 vPosition;
    varying vec4 vColor;
    varying vec2 vUv; 
    void main() 
    {
        vPosition = position;
        vColor = color;
        vec3 NewPosition = vPosition;
        NewPosition = vPosition + 2.0 * normal * ( 1.0 + sin( uTime/10.0 ));
        gl_Position = projectionMatrix * modelViewMatrix * vec4( NewPosition, 1.0 ) ;
    }
</script>
<script id="fragmentShader01" type="x-shader/x-fragment">
    precision mediump float;
    precision mediump int;
    uniform float uTime;
    varying vec3 vPosition;
    varying vec4 vColor;            
    void main() 
    {
        vec4 color = vec4( vColor );
        color.r += sin( vPosition.x * 10.0 + uTime ) * 0.2; //... makes (position & time)dependent waves of color variation.
        gl_FragColor = color;
    }
</script>

<!-------------------------------------------------------------------------------------------------->

<script id="vertexShader03" type="x-shader/x-vertex">
// HEADER03 //
    //... Works OK without any of these active when one or two shader-pairs.

    //precision mediump float;
    //precision mediump int;            
    //uniform mat4 modelViewMatrix; // optional
    //uniform mat4 projectionMatrix; // optional                        
    // *** Enabling any of these attributes KILLS the shader!!! ?????? ***
    //... attribute values are only defined or changed in javascript

    //attribute vec3 position;  //... 3 values per vertex
    //attribute vec2 uv;        //... 2 values per vertex
    //attribute vec4 color;     //... 4 values per vertex
    //attribute vec3 normal;    //... 3 values per vertex; 

////        
    uniform float uTime;
    varying vec3 vPosition;
    varying vec4 vColor;
    varying vec2 vUv;           
    void main() 
    {
        vPosition = position; 
        vUv = uv;
        //... Sinusoidal expand and contract, amplitude is uniform
        vec3 NewPosition = vPosition + 2.0 * normal * ( 1.0 + sin( uTime/10.0 ));       
        gl_Position = projectionMatrix * modelViewMatrix * vec4( NewPosition, 1.0 );        
    } 
</script>

<script id="fragmentShader03" type="x-shader/x-fragment">
    precision mediump float;
    precision mediump int;
    uniform sampler2D baseTexture;
    varying vec2 vUv; 
    void main() {   gl_FragColor = texture2D( baseTexture, vUv );  }
</script>   

如果我激活“Header 03”声明(通过取消注释它们),则会记录以下错误: -

three.js:29438 THREE.WebGLProgram: shader error:  0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders ERROR: 0:48: 'modelViewMatrix' : redefinition 
ERROR: 0:49: 'projectionMatrix' : redefinition 
ERROR: 0:55: 'position' : redefinition 
ERROR: 0:56: 'uv' : redefinition 
ERROR: 0:58: 'normal' : redefinition 

这似乎表明“你只需要做一套声明!”

但是,如果我激活Header03声明但注释掉Header01声明,则会出现与上述相似的错误。这表明定义的顺序或使用顺序可能很重要。

所以无论如何我想知道是否存在一些已知的经验法则,关于在这样的情况下如何/何时/何时/为什么要对属性和矩阵进行声明(其中使用相同的属性名称和矩阵名称)不同的着色器材料)。

我看过relevant shader documentation,但这并不能解决我的无知。

=============================================== =======================

更新

切换到只使用RawShaderMaterial(而不是ShaderMaterial或RawShaderMaterial)。

修改所有顶点着色器以使标题声明包含: -

precision mediump float;
precision mediump int;
uniform mat4 modelViewMatrix; 
uniform mat4 projectionMatrix; 
attribute vec3 position;    //... 3 values per vertex.
attribute vec2 uv;          //... 2 values per vertex.
attribute vec4 color;       //... 4 values per vertex.
attribute vec3 normal;      //... 3 values per vertex. 

(此处要声明的属性是着色器代码中所需的属性,并作为属性存在于缓冲区中。)

此外,所有片段着色器都必须包含以下标题代码: -

precision mediump float;
precision mediump int;

然后所有着色器代码块都将编译好,使用它们的缓冲区对象将正确绘制。

源代码在此ShaderMaterial,此处RawShadermaterial。我不能说我理解为什么这个有效,除了RawShaderMaterial的文档说明

This class works just like ShaderMaterial, 
except that definitions of built-in uniforms and attributes 
are not automatically prepended to the GLSL shader code.

0 个答案:

没有答案