【问题标题】:WebGL Model rendering without color没有颜色的 WebGL 模型渲染
【发布时间】:2017-03-13 21:03:34
【问题描述】:

我正在尝试编写一个抽象 WebGL 函数的 javascript 程序,以便我可以使用不同的着色器绘制不同的模型。我创建了一个着色器对象,我最终将对其进行修改以将着色器程序作为参数,以及一个模型对象。我遇到的问题是我的模型当前正在屏幕上绘制,但它显示为黑色,而不是应用了预期的 phong 着色器。我不确定错误是在我的 javascript 中还是在我的着色器程序中。我只是想弄清楚被完全绘制为黑色的对象是否是一个特定问题,或者它是否可能是许多不同的事情。任何帮助表示赞赏。对不起,如果这个问题太模糊了。

这是我的 Shader 对象:

 function Shader(){
    this.program = createProgram(gl, document.getElementById('vertexShader').text,
                                 document.getElementById('fragmentShader').text);


    this.vertexPositionLocation = gl.getUniformLocation(this.program, 'vertexPosition');
    this.vertexNormalLocation = gl.getUniformLocation(this.program, 'vertexNormal')

    gl.enableVertexAttribArray(this.vertexNormalLocation);
    gl.enableVertexAttribArray(this.vertexNormalLocation);

    this.projectionMatrixLocation = gl.getUniformLocation(this.program, 'projectionMatrix');
    this.viewMatrixLocation = gl.getUniformLocation(this.program, 'viewMatrix');
    this.modelMatrixLocation = gl.getUniformLocation(this.program, 'modelMatrix');

    this.lightPositionLocation = gl.getUniformLocation(this.program, 'lightPosition');

    this.lightColorLocation = gl.getUniformLocation(this.program, 'lightColor');
    this.modelColorLocation = gl.getUniformLocation(this.program, 'modelColor');



    gl.useProgram(this.program);

}

这是我的模型对象:

function Model(model){
    this.positionArray = new Float32Array(flatten(model.positions));
    this.normalArray = new Float32Array(flatten(model.normals));
    this.triangleArray = new Uint16Array(flatten(model.triangles));

    //initialize buffer objects

    this.normalBuffer = gl.createBuffer();
    this.positionBuffer = gl.createBuffer();
    this.triangleBuffer = gl.createBuffer();

    gl.bindBuffer(gl.ARRAY_BUFFER, this.normalBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.normalArray, gl.STATIC_DRAW);

    gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.positionArray, gl.STATIC_DRAW);

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.triangleBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.triangleArray, gl.STATIC_DRAW);


    gl.enable(gl.DEPTH_TEST);

    Model.draw = function(shader){

        var modelMatrix = new Matrix4();
        var viewMatrix = new Matrix4();
        var projectionMatrix = new Matrix4();

        modelMatrix.rotate(modelRotationX, 1, 0, 0);
        modelMatrix.rotate(modelRotationY, 0, 1, 0);
        viewMatrix.translate(0, 0, -3);

        projectionMatrix.perspective(90, 1, 1, 10);

        gl.uniform3f(shader.lightColorLocation, 1.0, 1.0, 1.0);
        gl.uniform4f(shader.lightPositionLocation, 0.0, 8.0, 8.0, 1.0);    
        gl.uniform3f(shader.modelColorLocation, 0.6, 0.0, 0.0);


        gl.uniformMatrix4fv(shader.modelMatrixLocation, false, modelMatrix.elements);
        gl.uniformMatrix4fv(shader.viewMatrixLocation, false, viewMatrix.elements);
        gl.uniformMatrix4fv(shader.projectionMatrixLocation, false, projectionMatrix.elements);

        gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
        gl.vertexAttribPointer(shader.vertexNormalLocation, 3, gl.FLOAT, false, 0, 0);

        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(shader.vertexPositionLocation, 3, gl.FLOAT, false, 0, 0);


        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleBuffer);
        gl.drawElements(gl.TRIANGLES, triangleArray.length, gl.UNSIGNED_SHORT, 0);

}

}

这是我的片段着色器程序:

    <script id = "fragmentShader" type="x-shader/x-fragment">
        precision mediump float;

        varying vec3 fragmentNormal;
        varying vec3 fragmentLight;
        varying vec3 fragmentView;

        uniform vec3 modelColor;
        uniform vec3 lightColor;


        void main() {

            vec3 n = normalize(fragmentNormal);
            vec3 l = normalize(fragmentLight);
            vec3 v = normalize(fragmentView);
            vec3 h = normalize(l + v);

            float d = max(dot(l, n), 0.0);
            float s = pow(max(dot(h, n), 0.0), 10.0);

            vec3 fragmentColor = modelColor * lightColor * d + lightColor * s;

            gl_FragColor = vec4(fragmentColor, 1.0);
        }
    </script>

【问题讨论】:

  • 尝试通过你的变量,看看一切是否正确(特别是正常的颜色)。
  • 每当我发现自己处于这种情况(而且这种情况发生的频率比我愿意承认的要多)时,我都会尝试逐步定位问题:return vec4(1.,1.,0.)从着色器中,如果对象没有变黄,请仔细查看 javascript 代码;如果是,请尝试将统一颜色(modelColor 和 lightColor)分配给输出,看看它们是否有效,如果没有,请检查与制服相关的所有内容;属性等也可以这样做。如果所有输入都正常,那么问题出在您的 glsl 代码中。

标签: javascript webgl


【解决方案1】:

所以你看到了模特的剪影,但它是黑色的?

我要做的第一件事是添加

gl_FragColor = vec4(1,0,0,1);

在片段着色器的底部。你的模型变绿了吗?不?那么你没有使用那个着色器。

否则我会尝试

gl_FragColor = vec4(lightColor,1);

模型会改变灯光的颜色吗?如果不是,那么您将灯光颜色设置错误

下一个

gl_FragColor = vec4(modelColor,1);

模型会变色吗?如果不是,您将模型颜色设置错误。

接下来我会尝试

gl_FragColor = vec4(n * .5 + .5,1);

您应该将模型的法线视为颜色。它是黑色的,那么fragmentNormal 是错误的。

否则,对 lvh 等尝试相同的操作...

【讨论】:

    猜你喜欢
    • 2016-01-30
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    相关资源
    最近更新 更多