计算机图形学——实验三光照与材质处理实验

实验内容

        1.对实验二绘制的正三棱锥增加光照,实现点光源的光照效果,分别在顶点着色器和片元着色器中实现,观察有什么区别。把点光源改成平行光,观察有什么变化。

        2.使点光源围绕三棱锥旋转,呈现在不同位置照射三棱锥的效果。

实验设计思路

         光照处理:采用Blinn-Phong反射模型,在着色器中计算三种光的光强,将三种光相加并与物体的原色相乘得到最终的着色。

         环境光反射光强Ia由表面的环境光反射系数ka确定

                        ​​​​​​​        ​​​​​​​        ​​​​​​​     

        漫反射光的颜色Id取决于入射光光强Ld、材质反射系数kd、入射光与表面形成的入射角θ

                                                

                                            

        增加距离衰减因子后为

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

       镜面反射光的颜色Is取决于入射光光强Ls、材质反射系数ks、半角向量h与法向量n的夹角ψ、高光指数a

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​     

        增加距离衰减因子后为

                                        

        因此最终计算出的光强为

                         

        本实验中不考虑距离衰减因子

        在着色器中比实验三的程序多了①相机位置②光源位置③光色(默认白色即1.0,1.0,1.0)④法线变换矩阵

        根据Blinn-Phong模型的图示

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        归一化:向一个向量转化为对应方向的单位向量

        入射光方向I =  归一化(光源位置 - 着色点位置)

        视线方向 v= 归一化(相机位置 - 着色点位置)

        半程向量h = 归一化(入射光方向+视线方向)        

        最后利用这些数据代入公式即可算出最终反射的光强。

        

        在顶点着色器中实现光照操作,只计算了几个点的最终颜色值,最后的结果会进行插值操作,导致结果不真实

        在片段着色器中实现光照操作,对每个像素都计算的其颜色值,最终的结果会更加真实。

        平行光源的实现:将上述点光源的着色器中的光照方向改为一个固定的值即可。

        光源的旋转操作:为光源额外设置一个旋转矩阵,并传入着色器与光源位置相乘即可得到变化后的光源位置。

实验结果

点光源+旋转(顶点着色器实现)

点光源+旋转(片段着色器实现)

平行光源(片段着色器实现)

实验代码

        点光源+旋转(顶点着色器)

 // 获取WebGL上下文  
    const canvas = document.getElementById('webglCanvas');
    const gl = canvas.getContext('webgl');

    // 初始化着色器  
    const vertexShaderSource = `  
    attribute vec3 position; 
    attribute vec3 normal;
    attribute vec3 color;

    uniform mat4 modelMatrix;
    uniform mat4 visionMatrix;
    uniform mat4 perspectiveMatrix;
    uniform mat4 lightTransformMatrix;
    uniform mat4 normalMatrix;

    uniform vec3 cameraPosition;
    uniform vec3 lightColor;
    uniform vec3 lightPosition;

    varying vec3 vColor; 
    varying vec3 vNormal;

    void main() {  
        gl_Position =perspectiveMatrix* visionMatrix * modelMatrix * vec4(position, 1.0); 
        vec3 transformedPoint = (modelMatrix * vec4(position, 1.0)).xyz;
        vNormal = normalize((normalMatrix * vec4(normal,1.0)).xyz);
        vec3 transLight = (lightTransformMatrix * vec4(lightPosition, 1.0)).xyz;
        vec3 lightVec = normalize(transLight-transformedPoint);
        vec3 cameraVec = normalize(cameraPosition-transformedPoint);
        vec3 halfVec = normalize(lightVec+cameraVec);
        float lightCos = max(dot(lightVec,normal),0.0);
        float lightCosHalf = max(dot(lightVec,halfVec),0.0);

        vec3 ambientLight = lightColor*0.3;
        vec3 diffuseLight = lightColor*lightCos*1.0;
        vec3 specularLight = lightColor*pow(lightCosHalf,20.0)*0.5;


        vColor =(ambientLight + specularLight + diffuseLight)*color; 
    }  
`;

    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderSource);
    gl.compileShader(vertexShader);

    const fragmentShaderSource = `  
    precision mediump float; 
    varying vec3 vNormal; 
    varying vec3 vColor;
    void main() {  
        gl_FragColor = vec4(vColor ,1.0); 
    }  
`;

    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderSource);
    gl.compileShader(fragmentShader);

    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);
    gl.useProgram(shaderProgram);

    //初始化数据
    var transformMatrix = glMatrix.mat4.create();
    var t1, t2, t3 = null

    const vertices = new Float32Array([
      0, 0, -1,
      0, 0.942809, 0.333333,
      -0.816497, -0.471405, 0.333333,
      0.816497, -0.471405, 0.333333,

    ]);

    const indices = new Uint16Array([
      1, 2, 3,
      1, 2, 0,
      1, 3, 0,
      2, 3, 0,

    ]);

    const colors = new Float32Array([
      1, 0, 0,
      0, 1, 0,
      0, 0, 1,
      1, 1, 0,
    ])

    const normal = new Float32Array(
      [
        0, 0, -1,
        0, 0.942809, 0.333333,
        -0.816496, -0.471404, 0.333333,
        0.816496, -0.471404, 0.333333,
      ]
    )

    // 传入数据
    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
    gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionAttributeLocation);

    const indicesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

    const colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

    const colorAttributeLocation = gl.getAttribLocation(shaderProgram, 'color');
    gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(colorAttributeLocation);

    const normalBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, normal, gl.STATIC_DRAW);

    const normalAttributeLocation = gl.getAttribLocation(shaderProgram, 'normal');
    gl.vertexAttribPointer(normalAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(normalAttributeLocation);

    //传入相机位置数据
    const cameraPoint = glMatrix.vec3.fromValues(2.0, 2.0, 3.0);
    const cameraPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'cameraPosition');
    gl.uniform3fv(cameraPositionVecUniformLocation, cameraPoint);

    //传入光源颜色数据
    const lightColor = glMatrix.vec3.fromValues(1.0, 1.0, 1.0);
    const lightColorVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightColor');
    gl.uniform3fv(lightColorVecUniformLocation, lightColor);

    //传入光源位置数据
    const lightPosition = glMatrix.vec3.fromValues(0.0, 5.0, 0.0);
    const lightPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightPosition');
    gl.uniform3fv(lightPositionVecUniformLocation, lightPosition);

    //传入模型变换矩阵
    const modelMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'modelMatrix');
    var modelMatrix = glMatrix.mat4.create();
    gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);

    //传入视图变换矩阵
    const visionMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'visionMatrix');
    const eye = cameraPoint;
    const look = glMatrix.vec3.fromValues(0, 0, 0);
    const up = glMatrix.vec3.fromValues(0, 1, 0);
    const visionMatrix = glMatrix.mat4.lookAt(glMatrix.mat4.create(), eye, look, up);
    gl.uniformMatrix4fv(visionMatrixUniformLocation, false, visionMatrix);

    //传入透视矩阵
    const perspectiveMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'perspectiveMatrix');
    const perspectiveMatrix = glMatrix.mat4.perspective(glMatrix.mat4.create(), Math.PI / 2, 1 / 1, 1, -100);
    gl.uniformMatrix4fv(perspectiveMatrixUniformLocation, false, perspectiveMatrix);

    //传入光照方向变换矩阵
    const lightTransformMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'lightTransformMatrix');
    gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);

    //传入法线变换矩阵
    const normalMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'normalMatrix');
    gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));

    //绘制初始图形
    gl.clearColor(0, 0, 0, 0.5);
    gl.enable(gl.DEPTH_TEST)
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);


    //功能相关函数
    function rotate_x() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t1 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateX(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function rotate_y() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t2 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateY(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function rotate_z() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t3 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateZ(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function stopRotate() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
    }

    function drawTriangle() {
      gl.clear(gl.COLOR_BUFFER_BIT);

      gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
      gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
      gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0)
    }

    function getNormalMatrix(modelMatrix) {
      let invertMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), modelMatrix);
      return glMatrix.mat4.transpose(glMatrix.mat4.create(), invertMatrix);
    }

        点光源+旋转(片段着色器)

    // 获取WebGL上下文  
    const canvas = document.getElementById('webglCanvas');
    const gl = canvas.getContext('webgl');

    // 初始化着色器  
    const vertexShaderSource = `  
    attribute vec3 position;  
    uniform mat4 modelMatrix;
    uniform mat4 visionMatrix;
    uniform mat4 perspectiveMatrix;
    uniform mat4 normalMatrix;

    attribute vec3 normal;
    attribute vec3 color;

    varying vec3 vColor; 
    varying vec3 vNormal;
    varying vec3 vPosition;

    void main() {  
        gl_Position =perspectiveMatrix* visionMatrix * modelMatrix*  vec4(position, 1.0); 
        vColor = color;
        vPosition = position;
        vNormal = normalize((normalMatrix * vec4(normal,1.0)).xyz);
    }  
`;


    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderSource);
    gl.compileShader(vertexShader);

    const fragmentShaderSource = `  
    precision mediump float; 

    uniform vec3 lightPosition;
    uniform vec3 cameraPosition;
    uniform vec3 lightColor;
     uniform mat4 lightTransformMatrix;

    varying vec3 vNormal; 
    varying vec3 vColor;
    varying vec3 vPosition;


    void main() {  

        vec3 finalNormal = normalize(vNormal);
        vec3 transLight = (lightTransformMatrix* vec4(lightPosition, 1.0)).xyz;
        vec3 lightVec = normalize(transLight-vPosition);
        vec3 cameraVec = normalize(cameraPosition-vPosition);
        vec3 halfVec = normalize(lightVec+cameraVec);
        float lightCos = max(dot(lightVec,vNormal),0.0);
        float lightCosHalf = max(dot(lightVec,halfVec),0.0);

        vec3 ambientLight = lightColor*0.5;
        vec3 diffuseLight = lightColor*lightCos*1.0;
        vec3 specularLight = lightColor*pow(lightCosHalf,20.0)*0.5;

        vec3 finalColor =(ambientLight+diffuseLight+specularLight)*vColor; 


        gl_FragColor = vec4(finalColor ,1.0); 
    }  
`;

    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderSource);
    gl.compileShader(fragmentShader);

    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);
    gl.useProgram(shaderProgram);

    //初始化数据
    var transformMatrix = glMatrix.mat4.create();
    var t1, t2, t3 = null

    const vertices = new Float32Array([
      0, 0, -1,
      0, 0.942809, 0.333333,
      -0.816497, -0.471405, 0.333333,
      0.816497, -0.471405, 0.333333,

    ]);

    const indices = new Uint16Array([
      1, 2, 3,
      1, 2, 0,
      1, 3, 0,
      2, 3, 0,

    ]);

    const colors = new Float32Array([
      1, 0, 0,
      0, 1, 0,
      0, 0, 1,
      1, 1, 0,
    ])

    const normal = new Float32Array(
      [
        0, 0, -1,
        0, 0.942809, 0.333333,
        -0.816496, -0.471404, 0.333333,
        0.816496, -0.471404, 0.333333,
      ]
    )

    // 传入数据
    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
    gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionAttributeLocation);

    const indicesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

    const colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

    const colorAttributeLocation = gl.getAttribLocation(shaderProgram, 'color');
    gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(colorAttributeLocation);

    const normalBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, normal, gl.STATIC_DRAW);

    const normalAttributeLocation = gl.getAttribLocation(shaderProgram, 'normal');
    gl.vertexAttribPointer(normalAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(normalAttributeLocation);

    //传入相机位置数据
    const cameraPoint = glMatrix.vec3.fromValues(2.0, 2.0, 3.0);
    const cameraPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'cameraPosition');
    gl.uniform3fv(cameraPositionVecUniformLocation, cameraPoint);

    //传入光源颜色数据
    const lightColor = glMatrix.vec3.fromValues(1.0, 1.0, 1.0);
    const lightColorVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightColor');
    gl.uniform3fv(lightColorVecUniformLocation, lightColor);

    //传入光源位置数据
    const lightPosition = glMatrix.vec3.fromValues(0.0, 5.0, 0.0);
    const lightPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightPosition');
    gl.uniform3fv(lightPositionVecUniformLocation, lightPosition);

    //传入模型变换矩阵
    const modelMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'modelMatrix');
    var modelMatrix = glMatrix.mat4.create();
    gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);

    //传入视图变换矩阵
    const visionMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'visionMatrix');
    const eye = cameraPoint;
    const look = glMatrix.vec3.fromValues(0, 0, 0);
    const up = glMatrix.vec3.fromValues(0, 1, 0);
    const visionMatrix = glMatrix.mat4.lookAt(glMatrix.mat4.create(), eye, look, up);
    gl.uniformMatrix4fv(visionMatrixUniformLocation, false, visionMatrix);

    //传入透视矩阵
    const perspectiveMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'perspectiveMatrix');
    const perspectiveMatrix = glMatrix.mat4.perspective(glMatrix.mat4.create(), Math.PI / 2, 1 / 1, 1, -100);
    gl.uniformMatrix4fv(perspectiveMatrixUniformLocation, false, perspectiveMatrix);

    //传入光照方向变换矩阵
    const lightTransformMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'lightTransformMatrix');
    gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);

    //传入法线变换矩阵
    const normalMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'normalMatrix');
    gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));

    //绘制初始图形
    gl.clearColor(0, 0, 0, 0.5);
    gl.enable(gl.DEPTH_TEST)
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);


    //功能相关函数
    function rotate_x() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t1 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateX(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function rotate_y() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t2 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateY(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function rotate_z() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t3 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateZ(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function stopRotate() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
    }

    function drawTriangle() {
      gl.clear(gl.COLOR_BUFFER_BIT);

      gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
      gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
      gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0)
    }

    function getNormalMatrix(modelMatrix) {
      let invertMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), modelMatrix);
      return glMatrix.mat4.transpose(glMatrix.mat4.create(), invertMatrix);
    }

平行光(片段着色器)

    // 获取WebGL上下文  
    const canvas = document.getElementById('webglCanvas');
    const gl = canvas.getContext('webgl');

    // 初始化着色器  
    const vertexShaderSource = `  
    attribute vec3 position;  
    uniform mat4 modelMatrix;
    uniform mat4 visionMatrix;
    uniform mat4 perspectiveMatrix;
    uniform mat4 normalMatrix;

    attribute vec3 normal;
    attribute vec3 color;

    varying vec3 vColor; 
    varying vec3 vNormal;
    varying vec3 vPosition;

    void main() {  
        gl_Position =perspectiveMatrix* visionMatrix * modelMatrix*  vec4(position, 1.0); 
        vColor = color;
        vPosition = position;
        vNormal = normalize((normalMatrix * vec4(normal,1.0)).xyz);
    }  
`;


    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderSource);
    gl.compileShader(vertexShader);

    const fragmentShaderSource = `  
    precision mediump float; 

    uniform vec3 lightPosition;
    uniform vec3 cameraPosition;
    uniform vec3 lightColor;
     uniform mat4 lightTransformMatrix;

    varying vec3 vNormal; 
    varying vec3 vColor;
    varying vec3 vPosition;


    void main() {  

        vec3 finalNormal = normalize(vNormal);
        vec3 transLight = (lightTransformMatrix* vec4(lightPosition, 1.0)).xyz;
        vec3 lightVec = normalize(vec3(0.0,1.0,0.0));            //在此处直接将光源替换成固定方向即可
        vec3 cameraVec = normalize(cameraPosition-vPosition);
        vec3 halfVec = normalize(lightVec+cameraVec);
        float lightCos = max(dot(lightVec,vNormal),0.0);
        float lightCosHalf = max(dot(lightVec,halfVec),0.0);

        vec3 ambientLight = lightColor*0.5;
        vec3 diffuseLight = lightColor*lightCos*1.0;
        vec3 specularLight = lightColor*pow(lightCosHalf,20.0)*0.5;

        vec3 finalColor =(ambientLight+diffuseLight+specularLight)*vColor; 


        gl_FragColor = vec4(finalColor ,1.0); 
    }  
`;

    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderSource);
    gl.compileShader(fragmentShader);

    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);
    gl.useProgram(shaderProgram);

    //初始化数据
    var transformMatrix = glMatrix.mat4.create();
    var t1, t2, t3 = null

    const vertices = new Float32Array([
      0, 0, -1,
      0, 0.942809, 0.333333,
      -0.816497, -0.471405, 0.333333,
      0.816497, -0.471405, 0.333333,

    ]);

    const indices = new Uint16Array([
      1, 2, 3,
      1, 2, 0,
      1, 3, 0,
      2, 3, 0,

    ]);

    const colors = new Float32Array([
      1, 0, 0,
      0, 1, 0,
      0, 0, 1,
      1, 1, 0,
    ])

    const normal = new Float32Array(
      [
        0, 0, -1,
        0, 0.942809, 0.333333,
        -0.816496, -0.471404, 0.333333,
        0.816496, -0.471404, 0.333333,
      ]
    )

    // 传入数据
    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
    gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionAttributeLocation);

    const indicesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

    const colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

    const colorAttributeLocation = gl.getAttribLocation(shaderProgram, 'color');
    gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(colorAttributeLocation);

    const normalBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, normal, gl.STATIC_DRAW);

    const normalAttributeLocation = gl.getAttribLocation(shaderProgram, 'normal');
    gl.vertexAttribPointer(normalAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(normalAttributeLocation);

    //传入相机位置数据
    const cameraPoint = glMatrix.vec3.fromValues(2.0, 2.0, 3.0);
    const cameraPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'cameraPosition');
    gl.uniform3fv(cameraPositionVecUniformLocation, cameraPoint);

    //传入光源颜色数据
    const lightColor = glMatrix.vec3.fromValues(1.0, 1.0, 1.0);
    const lightColorVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightColor');
    gl.uniform3fv(lightColorVecUniformLocation, lightColor);

    //传入光源位置数据
    const lightPosition = glMatrix.vec3.fromValues(0.0, 5.0, 0.0);
    const lightPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightPosition');
    gl.uniform3fv(lightPositionVecUniformLocation, lightPosition);

    //传入模型变换矩阵
    const modelMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'modelMatrix');
    var modelMatrix = glMatrix.mat4.create();
    gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);

    //传入视图变换矩阵
    const visionMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'visionMatrix');
    const eye = cameraPoint;
    const look = glMatrix.vec3.fromValues(0, 0, 0);
    const up = glMatrix.vec3.fromValues(0, 1, 0);
    const visionMatrix = glMatrix.mat4.lookAt(glMatrix.mat4.create(), eye, look, up);
    gl.uniformMatrix4fv(visionMatrixUniformLocation, false, visionMatrix);

    //传入透视矩阵
    const perspectiveMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'perspectiveMatrix');
    const perspectiveMatrix = glMatrix.mat4.perspective(glMatrix.mat4.create(), Math.PI / 2, 1 / 1, 1, -100);
    gl.uniformMatrix4fv(perspectiveMatrixUniformLocation, false, perspectiveMatrix);

    //传入光照方向变换矩阵
    const lightTransformMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'lightTransformMatrix');
    gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);

    //传入法线变换矩阵
    const normalMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'normalMatrix');
    gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));

    //绘制初始图形
    gl.clearColor(0, 0, 0, 0.5);
    gl.enable(gl.DEPTH_TEST)
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);


    //功能相关函数
    function rotate_x() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t1 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateX(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function rotate_y() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t2 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateY(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function rotate_z() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
      t3 = setInterval(function () {
        let rotateMatrix = glMatrix.mat4.rotateZ(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
        transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
        drawTriangle();
      }, 10)
    }

    function stopRotate() {
      clearInterval(t1);
      clearInterval(t2);
      clearInterval(t3);
    }

    function drawTriangle() {
      gl.clear(gl.COLOR_BUFFER_BIT);

      gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
      gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
      gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0)
    }

    function getNormalMatrix(modelMatrix) {
      let invertMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), modelMatrix);
      return glMatrix.mat4.transpose(glMatrix.mat4.create(), invertMatrix);
    }

  • 40
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值