0

我不明白如何解决这个错误。我能够在两个角上制作一个带有两个球体的 xz 平面。球体带有阴影(一个 goroud,一个 phong),平面为平面颜色。但是,当我尝试以棋盘格图案对飞机进行纹理化时,我开始收到此错误。

这是我的 HTML:

<html>
<script id="BsphereV" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vNormal;
varying vec3 N;
varying vec3 L;
varying vec3 E;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec4 lightPosition;
uniform mat3 normalMatrix;

void main() {
    //----- Color Code
    // vPos in eye coords
    vec3 pos = (modelViewMatrix * vPosition).xyz;

    // directional light check
    if(lightPosition.w == 0.0) L = normalize(lightPosition.xyz);
    else L = normalize(lightPosition.xyz - pos);

    // vPos to eye vector
    E = -normalize(pos);

    // transform vNorm to eye coords
    N = normalize(normalMatrix * vNormal.xyz);

    //----- Postion code
    mat4 SnT = mat4(0.3, 0.0, 0.0, 0.0,
                    0.0, 0.3, 0.0, 0.0,
                    0.0, 0.0, 0.3, 0.0,
                    0.7, 0.0,-0.7, 1.0);

    gl_Position = projectionMatrix * modelViewMatrix * SnT * vPosition;
}
</script>

<script id="SphereCB" type="x-shader/x-fragment">
precision mediump float;
varying vec3 N;
varying vec3 L;
varying vec3 E;
uniform vec4 ambientProduct;
uniform vec4 diffuseProduct;
uniform vec4 specularProduct;
uniform float shininess;

void main() {
    vec4 fColor;

    // halfway vector
    vec3 H = normalize(L + E);

    // Light calcs
    vec4 ambient = ambientProduct;

    float Kd = max(dot(L, N), 0.0);
    vec4 diffuse = Kd * diffuseProduct;

    float Ks = pow(max(dot(N, H), 0.0), shininess);
    vec4 specular = Ks * specularProduct;

    if(dot(L, N) < 0.0) specular = vec4(0.0, 0.0, 0.0, 1.0);

    // set color
    //fColor = ambient + diffuse + specular;
    fColor = ambient + specular;
    fColor.a = 1.0;

    gl_FragColor = fColor;
}
</script>

<script id="RsphereV" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vNormal;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec4 ambientProduct;
uniform vec4 diffuseProduct;
uniform vec4 specularProduct;
uniform vec4 lightPosition;
uniform float shininess;
uniform mat3 normalMatrix;

void main() {
    //----- Color code
    // vPos in eye coords
    vec3 pos = (modelViewMatrix * vPosition).xyz;

    // vec from vPos to light source
    vec3 L;

    // directional light check
    if(lightPosition.w == 0.0) L = normalize(lightPosition.xyz);
    else L = normalize(lightPosition.xyz - pos);

    // vPos to eye vector
    vec3 E = -normalize(pos);

    // halfway vector
    vec3 H = normalize(L + E);

    // transform vNorm to eye coords
    vec3 N = normalize(normalMatrix * vNormal.xyz);

    // Light calcs
    vec4 ambient = ambientProduct;

    float Kd = max(dot(L, N), 0.0);
    vec4 diffuse = Kd * diffuseProduct;

    float Ks = pow(max(dot(N, H), 0.0), shininess);
    vec4 specular = Ks * specularProduct;

    if(dot(L, N) < 0.0) specular = vec4(0.0, 0.0, 0.0, 1.0);

    // set color
    //fColor = ambient + diffuse + specular;
    fColor = ambient + diffuse;
    fColor.a = 1.0;

    //----- Position code    
    mat4 SnT = mat4(0.3, 0.0, 0.0, 0.0,
                    0.0, 0.3, 0.0, 0.0,
                    0.0, 0.0, 0.3, 0.0,
                   -0.7, 0.0,-0.7, 1.0);

    gl_Position = projectionMatrix * modelViewMatrix * SnT * vPosition;
}
</script>

<script id="SphereCR" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;

void main() {
    gl_FragColor = fColor;
}
</script>

<script id="floorV" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

void main() {
    mat4 SnT = mat4(1.0, 0.0, 0.0, 0.0,
                    0.0, 1.0, 0.0, 0.0,
                    0.0, 0.0, 1.0, 0.0,
                    0.0, 0.7, 0.0, 1.0);

    gl_Position = projectionMatrix * modelViewMatrix * SnT * vPosition;
    fTexCoord = vTexCoord;
}
</script>

<script id="floorC" type="x-shader/x-fragment">
precision mediump float;
varying vec2 fTexCoord;
uniform sampler2D texture;

void main() {
    vec4 fColor = vec4(0, 1, 0, 1);
    gl_FragColor = fColor * texture2D(texture, fTexCoord);
}
</script>

<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="assign4snt.js"></script>

<body>
<canvas id="gl-canvas" width="600" height="600">
Oops... your browser doesn't support the HTML5 canvas element.
</canvas>
</body>
</html>

这是我的javascript:

//----- General variables
var gl;
var canvas;
var pointsArray = [];

//----- Sphere variables
var pSphereB;
var pSphereR;
var index = 0;
var indexRedStart;
var numTimesToSubdivide = 4;
var va = vec4( 0.0,  0.0, -1.0, 1);
var vb = vec4( 0.0,  0.9,  0.3, 1);
var vc = vec4(-0.8, -0.5,  0.3, 1);
var vd = vec4( 0.8, -0.5,  0.3, 1);
var normalsArray = [];

//----- Light variables
var lightPosition = vec4(5.0, 5.0, 5.0, 0.0);
var lightAmbient = vec4(0.2, 0.2, 0.2, 1.0);
var lightDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
var lightSpecular = vec4(1.0, 1.0, 1.0, 1.0);
var pointLight = true;

//----- Red Sphere Coloring (goroud)
var redMatAmbient = vec4(1.0, 0.0, 0.0, 1.0);
var redMatDiffuse = vec4(1.0, 0.0, 0.0, 1.0);
var redMatSpecular = vec4(1.0, 1.0, 1.0, 1.0);
var redMatShininess = 150.0;
var normalMatrixR;
var normalMatrixLocR;

//----- Blue Sphere Coloring (phong)
var blueMatAmbient = vec4(0.0, 0.0, 1.0, 1.0);
var blueMatDiffuse = vec4(0.0, 0.0, 1.0, 1.0);
var blueMatSpecular = vec4(1.0, 1.0, 1.0, 1.0);
var blueMatShininess = 8.0;
var normalMatrixB;
var normalMatrixLocB;

//----- Plane variables
var pFloor;
var texCoordsArray = [];
var texSize = 64;
var texture;

//----- Camera variables
var modelViewMatrix;
var projectionMatrix;
var bMVLoc;
var bPVLoc;
var rMVLoc;
var rPVLoc;
var fMVLoc;
var fPVLoc;
var fov = 45;
var near = 0.5;
var far = 1000;
var x;
var y = 3;
var z;
var eye;
var at = vec3(0, 0, 0);
var up = vec3(0, 1, 0);
var degrees = 90;
var angles;
var RADIUS = 3;

//----- Checkerboard Texture
// create using floats
var image1 = new Array();
    for(var i = 0; i < texSize; i++) image1[i] = new Array();
    for(var i = 0; i < texSize; i++)
        for(var j = 0; j < texSize; j++)
            image1[i][j] = new Float32Array(4);
    for(var i = 0; i < texSize; i++)
        for(var j = 0; j < texSize; j++) {
            var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0));
            image1[i][j] = [c, c, c, 1];
        }
// convert floats to ubytes
var image2 = new Uint8Array(4 * texSize * texSize);
    for(var i = 0; i < texSize; i++)
        for(var j = 0; j < texSize; j++)
            for(var k = 0; k < 4; k++)
                image2[4 * texSize * i + 4 * j + k] = 255 * image1[i][j][k];

//==============================================================================
window.onload = function init() {
    //----- Initialize WebGL
    canvas = document.getElementById("gl-canvas");
    gl = WebGLUtils.setupWebGL(canvas);
    if (!gl) alert("WebGL isn't available");
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(0.9, 0.9, 0.9, 1);
    gl.enable(gl.DEPTH_TEST);

    //----- Initialize Shaders
    pSphereB = initShaders(gl, "BsphereV", "SphereCB");
    pSphereR = initShaders(gl, "RsphereV", "SphereCR");
    pFloor = initShaders(gl, "floorV", "floorC");

    //----- Create Spheres
    sphere(va, vb, vc, vd, numTimesToSubdivide);

    indexRedStart = index;
    sphere(va, vb, vc, vd, numTimesToSubdivide);

    //----- Create Plane
    plane();

    //----- Light Calcs (Red Sphere)
    var redAmbientProd = mult(lightAmbient, redMatAmbient);
    var redDiffuseProd = mult(lightDiffuse, redMatDiffuse);
    var redSpecularProd = mult(lightSpecular, redMatSpecular);
    var blueAmbientProd = mult(lightAmbient, blueMatAmbient);
    var blueDiffuseProd = mult(lightDiffuse, blueMatDiffuse);
    var blueSpecularProd = mult(lightSpecular, blueMatSpecular);

    //----- Vertex Buffer Code
    var vBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW);

    var vPosBlue = gl.getAttribLocation(pSphereB, "vPosition");
    gl.vertexAttribPointer(vPosBlue, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPosBlue);

    var vPosRed = gl.getAttribLocation(pSphereR, "vPosition");
    gl.vertexAttribPointer(vPosRed, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPosRed);

    var vPlane = gl.getAttribLocation(pFloor, "vPosition");
    gl.vertexAttribPointer(vPlane, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPlane);

    //----- Texture Buffer Code
    var tBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, tBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW);

    var vTexCoord = gl.getAttribLocation(pFloor, "vTexCoord");
    gl.vertexAttribPointer(vTexCoord, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vTexCoord);

    //----- Normals Buffer Code
    var nBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, nBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW);

    var nBlue = gl.getAttribLocation(pSphereB, "vNormal");
    gl.vertexAttribPointer(nBlue, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(nBlue);

    var nRed = gl.getAttribLocation(pSphereR, "vNormal");
    gl.vertexAttribPointer(nRed, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(nRed);

    //----- Process Texture
    configureTexture(image2);

    //----- Link Camera
    bMVLoc = gl.getUniformLocation(pSphereB, "modelViewMatrix");
    bPVLoc = gl.getUniformLocation(pSphereB, "projectionMatrix");
    rMVLoc = gl.getUniformLocation(pSphereR, "modelViewMatrix");
    rPVLoc = gl.getUniformLocation(pSphereR, "projectionMatrix");
    fMVLoc = gl.getUniformLocation(pFloor, "modelViewMatrix");
    fPVLoc = gl.getUniformLocation(pFloor, "projectionMatrix");

    //----- Link Nomrmals
    normalMatrixLocR = gl.getUniformLocation(pSphereR, "normalMatrix");
    normalMatrixLocB = gl.getUniformLocation(pSphereB, "normalMatrix");

    //----- Link Blue Lights
    gl.useProgram(pSphereB);
    gl.uniform4fv(gl.getUniformLocation(pSphereB, "ambientProduct"),
            flatten(blueAmbientProd));
    gl.uniform4fv(gl.getUniformLocation(pSphereB, "diffuseProduct"),
            flatten(blueDiffuseProd));
    gl.uniform4fv(gl.getUniformLocation(pSphereB, "specularProduct"),
            flatten(blueSpecularProd));
    gl.uniform4fv(gl.getUniformLocation(pSphereB, "lightPosition"),
            flatten(lightPosition));
    gl.uniform1f(gl.getUniformLocation(pSphereB, "shininess"),
            blueMatShininess);

    //----- Link Red Lights
    gl.useProgram(pSphereR);
    gl.uniform4fv(gl.getUniformLocation(pSphereR, "ambientProduct"),
            flatten(redAmbientProd));
    gl.uniform4fv(gl.getUniformLocation(pSphereR, "diffuseProduct"),
            flatten(redDiffuseProd));
    gl.uniform4fv(gl.getUniformLocation(pSphereR, "specularProduct"),
            flatten(redSpecularProd));
    gl.uniform4fv(gl.getUniformLocation(pSphereR, "lightPosition"),
            flatten(lightPosition));
    gl.uniform1f(gl.getUniformLocation(pSphereR, "shininess"),
            redMatShininess);

    //----- Initialize camera location    
    setInitialXZ();

    //----- Navigation Control
    window.addEventListener("keydown", function() {
       if(event.keyCode == 65 || event.keyCode == 37) {    // A (left)
           degrees -= 5;
           angles = radians(degrees);
           x = RADIUS * Math.cos(angles);
           z = RADIUS * Math.sin(angles);
       }
       if(event.keyCode == 68 || event.keyCode == 39) {    // D (right)
           degrees += 5;
           angles = radians(degrees);
           x = RADIUS * Math.cos(angles);
           z = RADIUS * Math.sin(angles);
       }
    });

    //----- Draw Screen
    render();
}

//==============================================================================
function render() {
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    //----- Set Camera
    projectionMatrix = perspective(fov, canvas.width/canvas.height, near, far);
    eye = vec3(x, y, z);
    modelViewMatrix = lookAt(eye, at, up);
    normalMatrix = [
        vec3(modelViewMatrix[0][0], modelViewMatrix[0][1],
                modelViewMatrix[0][2]),
        vec3(modelViewMatrix[1][0], modelViewMatrix[1][1],
                modelViewMatrix[1][2]),
        vec3(modelViewMatrix[2][0], modelViewMatrix[2][1],
                modelViewMatrix[2][2]),
    ];

    //----- Draw Blue Sphere
    gl.useProgram(pSphereB);
    gl.uniformMatrix4fv(bMVLoc, false, flatten(modelViewMatrix));
    gl.uniformMatrix4fv(bPVLoc, false, flatten(projectionMatrix));
    gl.uniformMatrix3fv(normalMatrixLocB, false, flatten(normalMatrix));
    for(var i = 0; i < indexRedStart; i += 3)
        gl.drawArrays(gl.TRIANGLES, i, 3);

    //----- Draw Red Sphere
    gl.useProgram(pSphereR);
    gl.uniformMatrix4fv(rMVLoc, false, flatten(modelViewMatrix));
    gl.uniformMatrix4fv(rPVLoc, false, flatten(projectionMatrix));
    gl.uniformMatrix3fv(normalMatrixLocR, false, flatten(normalMatrix));
    for(var i = indexRedStart; i < index; i += 3)
        gl.drawArrays(gl.TRIANGLES, i, 3);

    //----- Draw Plane
    gl.useProgram(pFloor);
    gl.uniformMatrix4fv(fMVLoc, false, flatten(modelViewMatrix));
    gl.uniformMatrix4fv(fPVLoc, false, flatten(projectionMatrix));
    gl.drawArrays(gl.TRIANGLES, index, 6);

    //----- Draw Again
    requestAnimFrame(render);
}

//==============================================================================
function configureTexture(image) {
    texture = gl.createTexture();
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA,
            gl.UNSIGNED_BYTE, image);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
            gl.NEAREST_MIPMAP_LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}

//==============================================================================
function setInitialXZ() {
    angles = radians(degrees);
    x = RADIUS * Math.cos(angles);
    z = RADIUS * Math.sin(angles);
}

//==============================================================================
function plane() {
    var vertices = [
        vec4( 1,-1, 1, 1),  // 0 #4 upper right
        vec4(-1,-1, 1, 1),  // 1 #3 upper left
        vec4(-1,-1,-1, 1),  // 2 #1 lower left
        vec4( 1,-1,-1, 1)   // 3 #2 lower right
    ];

    var texCoord = [
        vec2(0, 0),
        vec2(0, 1),
        vec2(1, 1),
        vec2(1, 0)
    ];

    pointsArray.push(vertices[0]);
    pointsArray.push(vertices[1]);
    pointsArray.push(vertices[2]);
    pointsArray.push(vertices[0]);
    pointsArray.push(vertices[2]);
    pointsArray.push(vertices[3]);

    texCoordsArray.push(texCoord[0]);
    texCoordsArray.push(texCoord[1]);
    texCoordsArray.push(texCoord[2]);
    texCoordsArray.push(texCoord[0]);
    texCoordsArray.push(texCoord[2]);
    texCoordsArray.push(texCoord[3]);
}

//==============================================================================
function sphere(a, b, c, d, n) {
    divideTriangle(a, b, c, n);
    divideTriangle(d, c, b, n);
    divideTriangle(a, d, b, n);
    divideTriangle(a, c, d, n);
}

//==============================================================================
function divideTriangle(a, b, c, count) {
    if (count > 0) {
        //----- Find midpoint
        var ab = mix(a, b, 0.5);
        var ac = mix(a, c, 0.5);
        var bc = mix(b, c, 0.5);

        //----- Find Normal Vector
        ab = normalize(ab, true);
        ac = normalize(ac, true);
        bc = normalize(bc, true);

        //----- Repeat
        divideTriangle(a, ab, ac, count-1);
        divideTriangle(ab, b, bc, count-1);
        divideTriangle(bc, c, ac, count-1);
        divideTriangle(ab, bc, ac, count-1);
    } else {
        triangle(a, b, c);
    }
}

//==============================================================================
function triangle(a, b, c) {
    pointsArray.push(a);
    pointsArray.push(b);
    pointsArray.push(c);

    normalsArray.push(a[0], a[1], a[2], 0);
    normalsArray.push(b[0], b[1], b[2], 0);
    normalsArray.push(c[0], c[1], c[2], 0);

    index += 3;
} 

任何帮助,将不胜感激。

4

1 回答 1

0

属性是全局状态。这意味着您必须在每次绘制调用(或每次更改顶点)之前设置它们,而不是在初始化时。

代码似乎认为属性是每个程序的。

例如这部分

var vPosBlue = gl.getAttribLocation(pSphereB, "vPosition");
gl.vertexAttribPointer(vPosBlue, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosBlue);

var vPosRed = gl.getAttribLocation(pSphereR, "vPosition");
gl.vertexAttribPointer(vPosRed, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosRed);

var vPlane = gl.getAttribLocation(pFloor, "vPosition");
gl.vertexAttribPointer(vPlane, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPlane);

上面的代码可能将相同的属性设置了 3 次,这意味着只有最后一个有任何影响,因为如果它们是相同的属性位置,则该位置的全局属性已被最后 2 行覆盖。

制服是着色器程序状态。所有其他州都是全球性的。例如属性、纹理单元和其他所有内容。

你可能会发现这篇文章很有用

于 2016-04-10T11:07:57.370 回答