TypeScript / webGL 创建奇怪的阴影

TypeScript / webGL creates strange shadows

提问人:Sean 提问时间:11/4/2023 最后编辑:Rabbid76Sean 更新时间:11/4/2023 访问量:23

问:

我使用打字稿编写了以下代码:

const sphRayV = `

attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uNMatrix;

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);

    //Final vertex position
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}

`;


const sphRayF = `

#ifdef GL_ES
precision highp float;
#endif

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;

    gl_FragColor = finalColor;
}

`;


    var mv = new mat.matrix();
    var p  = new mat.matrix();

    var n  = new mat.matrix();

    var sphereVerticesBuffer = null;
    var sphereIndicesBuffer  = null;

    var sphereNormalsBuffer  = null;

    var vertices  = null;
    var indices   = null;

    var normals   = null;
    var prg       = null;

    var angle     = 0;


    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, sphRayF);
    gl.compileShader(fragmentShader);


    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, sphRayV);
    gl.compileShader(vertexShader);

    prg = gl.createProgram();
    gl.attachShader(prg, vertexShader);
    gl.attachShader(prg, fragmentShader);
    gl.linkProgram(prg);

    gl.useProgram(prg);
    var aVertexPosition    = gl.getAttribLocation(prg, "aVertexPosition");
    var aVertexNormal      = gl.getAttribLocation(prg, "aVertexNormal");
    var uPMatrix           = gl.getUniformLocation(prg, "uPMatrix");
    var uMVMatrix          = gl.getUniformLocation(prg, "uMVMatrix");
    var uNMatrix           = gl.getUniformLocation(prg, "uNMatrix");
    var uMaterialAmbient   = gl.getUniformLocation(prg, "uMaterialAmbient");
    var uMaterialDiffuse   = gl.getUniformLocation(prg, "uMaterialDiffuse");
    var uMaterialSpecular  = gl.getUniformLocation(prg, "uMaterialSpecular");
    var uShininess          = gl.getUniformLocation(prg, "uShininess");
    var uLightAmbient      = gl.getUniformLocation(prg, "uLightAmbient");
    var uLightDiffuse      = gl.getUniformLocation(prg, "uLightDiffuse");
    var uLightSpecular     = gl.getUniformLocation(prg, "uLightSpecular");
    var uLightDirection    = gl.getUniformLocation(prg, "uLightDirection");

    gl.uniform3f(uLightDirection,   parseFloat(localStorage.getItem("xLg")),parseFloat(localStorage.getItem("yLg")),parseFloat(localStorage.getItem("zLg")));
    gl.uniform4fv(uLightAmbient, [0.03,0.03,0.03,1.0]);
    gl.uniform4fv(uLightDiffuse,  [1.0,1.0,1.0,1.0]);
    gl.uniform4fv(uLightSpecular,  [1.0,1.0,1.0,1.0]);
    gl.uniform4fv(uMaterialAmbient, [parseFloat(localStorage.getItem("rSp")),
                        parseFloat(localStorage.getItem("gSp")),
                        parseFloat(localStorage.getItem("bSp")),1.0]);
    gl.uniform4fv(uMaterialDiffuse, [parseFloat(localStorage.getItem("rSp")),
                        parseFloat(localStorage.getItem("gSp")),
                        parseFloat(localStorage.getItem("bSp")),1.0]);
    gl.uniform4fv(uMaterialSpecular,[1.0,1.0,1.0,1.0]);
    gl.uniform1f(uShininess, 230.0);


    vertices = geom.vertices;
    indices  = geom.indices;

    normals  = geom.calculateNormals(vertices, indices);


    sphereVerticesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, sphereVerticesBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    sphereNormalsBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, sphereNormalsBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
    sphereIndicesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereIndicesBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

    // var mvT =

    var mvMatrix =  mat.translation(parseFloat(localStorage.getItem("xR")), parseFloat(localStorage.getItem("yR")),parseFloat(localStorage.getItem("zR")));// [1,0,0,0,0,1,0,0,0,0,1,0,0,0,-2,1];
    mvMatrix     =  mat.mul(mvMatrix, mat.xRotation(parseInt(localStorage.getItem("xrotRay"))/180.00 * Math.PI));
    mvMatrix     =  mat.mul(mvMatrix, mat.yRotation(parseInt(localStorage.getItem("yrotRay"))/180.00 * Math.PI));
    mvMatrix     =  mat.mul(mvMatrix, mat.zRotation(parseInt(localStorage.getItem("zrotRay"))/180.00 * Math.PI));

    gl.uniformMatrix4fv(uMVMatrix, false, mvMatrix);
    var pMatrix =  mat.perspective(45, gl.canvas.width / gl.canvas.height, 0.1, 10000.0)

    gl.uniformMatrix4fv(uPMatrix, false, pMatrix);

    var nMatrix = mat.transpose(mat.inverse(mvMatrix));

    gl.uniformMatrix4fv(uNMatrix, false, nMatrix);

    gl.enableVertexAttribArray(aVertexPosition);
    gl.enableVertexAttribArray(aVertexNormal);

    //2. bind buffers
    gl.bindBuffer(gl.ARRAY_BUFFER, sphereVerticesBuffer);
    gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0);
    gl.bindBuffer(gl.ARRAY_BUFFER, sphereNormalsBuffer);
    gl.vertexAttribPointer(aVertexNormal,3,gl.FLOAT, false, 0,0);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,sphereIndicesBuffer);
    gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

localstorage 值为 okey。它们以字符串形式返回浮点值。我检查了一下.我还尝试使用固定的硬编码浮点值运行相同的代码。这不会改变任何事情。console.log

geom 和 mat 文件可以在 pastebin 中看到:

Mat.ts : https://pastebin.com/rQTV77iJ

geom.ts : https://pastebin.com/gRa0mAFY

这应该渲染一个球体。然而,这搞砸了阴影。enter image description here

我相信这是我编写的算法中的错误,但我很难找到错误。

任何帮助将不胜感激。谢谢。

打字稿 glsl webgl

评论


答: 暂无答案