WebGL寫入光照

1.Buffer中每個頂點的法向量數據

cubeNormalVertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,cubeNormalVertexBuffer);
        var normalVertices = [
            // Front face
            0.0,  0.0,  1.0,
            0.0,  0.0,  1.0,
            0.0,  0.0,  1.0,
            0.0,  0.0,  1.0,

            // Back face
            0.0,  0.0, -1.0,
            0.0,  0.0, -1.0,
            0.0,  0.0, -1.0,
            0.0,  0.0, -1.0,

            // Top face
            0.0,  1.0,  0.0,
            0.0,  1.0,  0.0,
            0.0,  1.0,  0.0,
            0.0,  1.0,  0.0,

            // Bottom face
            0.0, -1.0,  0.0,
            0.0, -1.0,  0.0,
            0.0, -1.0,  0.0,
            0.0, -1.0,  0.0,

            // Right face
            1.0,  0.0,  0.0,
            1.0,  0.0,  0.0,
            1.0,  0.0,  0.0,
            1.0,  0.0,  0.0,

            // Left face
            -1.0,  0.0,  0.0,
            -1.0,  0.0,  0.0,
            -1.0,  0.0,  0.0,
            -1.0,  0.0,  0.0
        ]
        gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(normalVertices),gl.STATIC_DRAW);
        cubeNormalVertexBuffer.itemSize = 3;
        cubeNormalVertexBuffer.numItems = cubeNormalVertexBuffer.length/3;

2.drawScene中綁定法向量buffer

gl.bindBuffer(gl.ARRAY_BUFFER,cubeNormalVertexBuffer);
        gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,cubeNormalVertexBuffer.itemSize,gl.FLOAT,false,0,0);

聲明環境光ambient RGB 和定向光的方向和RGB

       //設置light
        var lighting = document.getElementById("lighting").checked;
        gl.uniform1i(shaderProgram.useLightingUniform,lighting);
        if (lighting){
            // ambient lighting RGB
            gl.uniform3f(
                shaderProgram.ambientColorUniform,
                parseFloat(document.getElementById("ambientR").value),
                parseFloat(document.getElementById("ambientG").value),
                parseFloat(document.getElementById("ambientB").value)
            );
            //設置direction lighting的方向向量
            var lightingDirection = [
                parseFloat(document.getElementById("lightDirectionX").value),
                parseFloat(document.getElementById("lightDirectionY").value),
                parseFloat(document.getElementById("lightDirectionZ").value)
            ];
            //以下三句定義了direction lighting的法線向量
            //定義一個vec3向量
            var adjustedLD = vec3.create();
            //使adjustedLD與lightingDirection單位法線
            //vec3.normalize=function(a,b)
            // {b||(b=a);
            // var c=a[0],d=a[1],e=a[2],
            // g=Math.sqrt(c*c+d*d+e*e);i
            // f(g){if(g==1){b[0]=c;b[1]=d;b[2]=e;return b}}else{b[0]=0;b[1]=0;b[2]=0;return b}
            // g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b}
            vec3.normalize(lightingDirection, adjustedLD);
            //改變adjustedLD方向
            vec3.scale(adjustedLD, -1);
            gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD);

            gl.uniform3f(
                shaderProgram.directionalColorUniform,
                parseFloat(document.getElementById("directionalR").value),
                parseFloat(document.getElementById("directionalG").value),
                parseFloat(document.getElementById("directionalB").value)
            );
        }

3.setMatrixUniforms()中聲明

function setMatrixUniforms() {
        gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
        gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);

        //法線矩陣不能像頂點vertex那樣直接translate平移
        //可以藉助model-view矩陣???
        //eg:mvTranslate (00,-5) nomorMatrix 將從(0,0,1)移到(0,0,-4)
        //inverse 逆矩陣
        //tarnspose  轉置矩陣?
        var normalMatrix = mat3.create();
        //mat4.toInverseMat3=function(a,b)
        // {var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],
        // l=k*f-h*j,o=-k*g+h*i,m=j*g-f*i,n=c*l+d*o+e*m;if(!n)return null;n=1/n;b||(b=mat3.create());
        // b[0]=l*n;b[1]=(-k*d+e*j)*n;b[2]=(h*d-e*f)*n;b[3]=o*n;b[4]=(k*c-e*i)*n;b[5]=(-h*c+e*g)*n;b[6]=m*n;b[7]=(-j*c+d*i)*n;
        // b[8]=(f*c-d*g)*n;
        // return b};
        mat4.toInverseMat3(mvMatrix,normalMatrix);
        mat3.transpose(normalMatrix);
        gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);
    }

4.在vertex shader中聲明

<script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;
    attribute vec2 aTextureCoord;
    attribute vec3 aVertexNormal;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;
    //法線矩陣  3*3
    uniform mat3 uNMatrix;
    //環境光源
    uniform vec3 uAmbientColor;
    //平行光源的方向
    uniform vec3 uLightingDirection;
    //平行光源的顏色
    uniform vec3 uDirectionalColor;
    //chebox 是否使用光源
    uniform bool uUseLighting;

    varying vec2 vTextureCoord;
    //傳給fragment的光源
    varying vec3 vLightWeighting;

    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;

        if(!uUseLighting){
            vLightWeighting = vec3(1.0, 1.0, 1.0);
        }else{
        //定義transformedNormal = 法線矩陣*頂點法線向量
            vec3 transformedNormal = uNMatrix * aVertexNormal;

            float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
        //傳給fragment的light強度 由環境RGB 定向光RGB*光照強度
            vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
        }
    }
</script>

5.fragment shader

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

    varying vec2 vTextureCoord;
    varying vec3 vLightWeighting;

    uniform sampler2D uSampler;
    //設置透明度(depth buffer)
    // uniform float uAlpha;

    void main(void) {
       // gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
        vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
       // gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a*uAlpha);
        gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
    }
</script>

6.shaderProgram添加語句

 shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
        shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
        shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
        shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
        shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");
發佈了47 篇原創文章 · 獲贊 24 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章