2016-10-31 3 views
0

Я пытаюсь написать javascript программу, которая абстрагирует функции WebGL, чтобы я мог рисовать разные модели с разными шейдерами. Я создал объект shader, который в конечном итоге изменю, чтобы использовать шейдерные программы в качестве аргументов и объект модели. Проблема, с которой я сталкиваюсь, заключается в том, что моя модель в настоящее время рисуется на экране, но она отображается черным, вместо того, чтобы использовать намеченный phong-шейдер. Я не уверен, что ошибка в моем javascript или в моей шейдерной программе. Я просто пытаюсь выяснить, являются ли объекты черными полностью черными, это конкретная проблема, или если это может быть несколько разных вещей. Любая помощь приветствуется. Извините, если этот вопрос слишком расплывчатый.рендеринг модели WebGL без цвета

Это мой 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> 
+0

попробовать проходя через ваши varyings и посмотреть, если все выглядит правильно (нормальный и цвета, в частности). –

+0

Всякий раз, когда я нахожусь в такой ситуации (и это происходит чаще, чем я хотел бы признать), я пытаюсь найти проблему шаг за шагом: верните vec4 (1., 1., 0.) Из шейдера, если объект не станет желтым, а затем посмотрите на javascript-код; если это так, попробуйте вместо этого назначить однородные цвета (modelColor и lightColor) на выход, посмотрите, работают ли они, если нет, проверьте все, что связано с униформой; то же самое можно сделать с атрибутами и т. д. если все входы в порядке, то проблема в вашем коде glsl. – unholybear

ответ

0

Итак, вы видите силуэт модели, но это черный?

Первое, что я хотел бы сделать, это добавить

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

В нижней в пиксельный шейдер. Ваша модель зеленеет? Нет? Тогда вы не используете этот шейдер.

othewise рядом я бы попробовать

gl_FragColor = vec4(lightColor,1); 

Возбуждает ли модель цвет света? Если нет, то вы устанавливаете светлый цвет неправильный

Следующая

gl_FragColor = vec4(modelColor,1); 

Возбуждает ли модель модель цвет? Если вы не устанавливаете цвет модели неправильно.

Далее я хотел бы попробовать

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

Вы должны увидеть нормали вашей модели как цвет. Он черный, а fragmentNormal ошибочен.

В противном случае попробуйте то же самое с l, v и h и т.д. ...