在我的着色器中实现 phong 着色(过度纹理)的错误

Posted

技术标签:

【中文标题】在我的着色器中实现 phong 着色(过度纹理)的错误【英文标题】:Errors on phong shading (over texture) implementation in my shaders 【发布时间】:2015-10-18 15:14:28 【问题描述】:

我正在尝试学习 webGL,尝试按照链接 http://voxelent.com/html/beginners-guide/chapter_3/ch3_Sphere_Phong.html 上的此示例代码实现 phong 着色

我在着色器编译时遇到两个错误,因此没有显示月亮,这应该是显示的,因为我正在关注 Github 的第 11 课,他们从矩形制作球体,我得到的错误是:

ERROR: 0:49: '*' :  wrong operand types  no operation '*' exists that takes a left-hand operand of type 'mediump 3-component vector of float' and a right operand of type 'mediump 4-component vector of float' (or there is no acceptable conversion)

我的完整代码是:

<script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;
        varying vec2 vTextureCoord;
        varying vec3 vLightWeighting;
        uniform sampler2D uSampler;
        uniform float uShininess;        //shininess
        uniform vec3 uLightDirection;  //light direction

        uniform vec4 uLightAmbient;      //light ambient property
        uniform vec4 uLightDiffuse;      //light diffuse property
        uniform vec4 uLightSpecular;     //light specular property

        uniform vec4 uMaterialAmbient;  //object ambient property
        uniform vec4 uMaterialDiffuse;   //object diffuse property
        uniform vec4 uMaterialSpecular;  //object specular property

        varying vec3 vNormal;
        varying vec3 vEyeVec;

        void main(void) 
        
          vec3 L = normalize(uLightDirection);
        vec3 N = normalize(vNormal);

        //Lambert's cosine law
        float lambertTerm = dot(N,-L);

        //Ambient Term
        vec4 Ia = uLightAmbient * uMaterialAmbient;

        //Diffuse Term
        vec4 Id = vec4(0.0,0.0,0.0,1.0);

        //Specular Term
        vec4 Is = vec4(0.0,0.0,0.0,1.0);

        if(lambertTerm > 0.0) //only if lambertTerm is positive
        
              Id = uLightDiffuse * uMaterialDiffuse * lambertTerm; //add diffuse term
              vec3 E = normalize(vEyeVec);
              vec3 R = reflect(L, N);
              float specular = pow( max(dot(R, E), 0.0), uShininess);
              Is = uLightSpecular * uMaterialSpecular * specular; //add specular term
        
        //Final color
           vec4 finalColor =Ia + Id + Is;
           finalColor.a = 1.0;
           vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
           gl_FragColor = vec4(textureColor.rgb * finalColor, textureColor.a);
        
    </script>

    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec3 aVertexPosition;
        attribute vec3 aVertexNormal;
        attribute vec2 aTextureCoord;
        uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;
        uniform mat3 uNMatrix;
        uniform vec3 uAmbientColor;
        uniform vec3 uLightingDirection;
        uniform vec3 uDirectionalColor;
        uniform bool uUseLighting;
        varying vec2 vTextureCoord;
        varying vec3 vLightWeighting;

        varying vec3 vNormal;
        varying vec3 vEyeVec;

        void main(void) 
        
        //Transformed vertex position
        vec4 vertex= uMVMatrix * vec4(aVertexPosition, 1.0);

        //Transformed normal position
        vNormal   = vec3(uNMatrix * vec4(aVertexNormal, 1.0));

        //Vector Eye
        vEyeVec = -vec3(vertex.xyz);
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;       
        
    </script>   

EDIT2:

  <script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;
        varying vec2 vTextureCoord;
        varying vec3 vLightWeighting;
        uniform sampler2D uSampler;
        uniform float uShininess;        //shininess
        uniform vec3 uLightDirection;  //light direction

        uniform vec4 uLightAmbient;      //light ambient property
        uniform vec4 uLightDiffuse;      //light diffuse property
        uniform vec4 uLightSpecular;     //light specular property

        uniform vec4 uMaterialAmbient;  //object ambient property
        uniform vec4 uMaterialDiffuse;   //object diffuse property
        uniform vec4 uMaterialSpecular;  //object specular property

        varying vec3 vNormal;
        varying vec3 vEyeVec;

        void main(void)
        
        vec3 L = normalize(uLightDirection);
        vec3 N = normalize(vNormal);

        //Lambert's cosine law
        float lambertTerm = dot(N,-L);

        //Ambient Term
        vec4 Ia = uLightAmbient * uMaterialAmbient;

        //Diffuse Term
        vec4 Id = vec4(0.0,0.0,0.0,1.0);

        //Specular Term
        vec4 Is = vec4(0.0,0.0,0.0,1.0);

        if(lambertTerm > 0.0) //only if lambertTerm is positive
        
        Id = uLightDiffuse * uMaterialDiffuse * lambertTerm; //add diffuse term
        vec3 E = normalize(vEyeVec);
        vec3 R = reflect(L, N);
        float specular = pow( max(dot(R, E), 0.0), uShininess);
        Is = uLightSpecular * uMaterialSpecular * specular; //add specular term
        
        //Final color
        vec4 finalColor =Ia + Id + Is;
        finalColor.a = 1.0;
        vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
        gl_FragColor = vec4(textureColor.rgb, textureColor.a)+finalColor;
        
    </script>

    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec3 aVertexPosition;
        attribute vec3 aVertexNormal;
        attribute vec2 aTextureCoord;
        uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;
        uniform mat3 uNMatrix;
        uniform vec3 uAmbientColor;
        uniform vec3 uLightingDirection;
        uniform vec3 uDirectionalColor;
        uniform bool uUseLighting;
        varying vec2 vTextureCoord;
        varying vec3 vLightWeighting;

        varying vec3 vNormal;
        varying vec3 vEyeVec;

        void main(void)
        
        //Transformed vertex position
        vec4 vertex= uMVMatrix * vec4(aVertexPosition, 1.0);

        //Transformed normal position
        vNormal   = vec3(uNMatrix * vec3(aVertexNormal));

        //Vector Eye
        vEyeVec = -vec3(vertex.xyz);
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;
        
    </script>   

如何使用 phong 阴影效果显示月亮。有人可以帮我吗?

【问题讨论】:

【参考方案1】:

错误信息很明确:您尝试将vec3vec4 相乘,这显然毫无意义。它还告诉你错误在着色器的第 49 行:

gl_FragColor = vec4(textureColor.rgb * finalColor, textureColor.a);
//                                     ^ finalColor is a vec4!

您可能想在这里使用finalColor.rgb

【讨论】:

我已经解决了这个问题,但感谢您尝试帮助我。 我做了一些类似的事情 "" vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); gl_FragColor = vec4(textureColor.rgb, textureColor.a)+finalColor; , 另外你能检查一下我的代码中 phong shading 的逻辑吗?我的 edit2 部分现在没有错误,但它的亮度不是很好。

以上是关于在我的着色器中实现 phong 着色(过度纹理)的错误的主要内容,如果未能解决你的问题,请参考以下文章

Phong 着色器不起作用

顶点着色器中的 Phong 光照

顶点纹理获取(在顶点着色器中读取纹理)

OpenGL着色器没有传递正确的纹理坐标

使用 GLSL 的多个着色器加载多个纹理时出现问题

使用 FBO 和着色器 OpenGL 渲染到纹理