A Related Concept

Light: Direction + color (intensity included)

The light source

    1. Parallel light: same direction + color
    1. Point light source: Direction (light source position to illumination position) + color
    1. Ambient light: color

Incident Angle: The Angle between the opposite direction of incident light and the plane normal

Reflection:

    1. Diffuse reflection: the reflected light is uniform in all directions. The color of the reflected light is the color of the incident light X, the base color X cos(a), and a is the incident Angle
    1. Ambient reflection: Reflected light color = ambient light color X base color
    1. Diffuse + Ambient: Reflected light color = Diffuse light color + ambient light color

Draw a cube with the same surface color

/** * same color cube ** /

var gl_SrcVS = ` attribute vec4 a_Position; attribute vec4 a_Color; uniform mat4 u_MvpMatrix; varying vec4 v_Color; void main(){ gl_Position = u_MvpMatrix * a_Position; v_Color = a_Color; } `;

var gl_SrcFS = ` precision lowp float; varying vec4 v_Color; void main(){ gl_FragColor = v_Color; } `;

function main() {
    var gl = getGL();
    var sp = initShader(gl, gl_SrcVS, gl_SrcFS);

    var projMat = getPerspectiveProjection(30.1.1.100);
    var viewMat = lookAt(3.3.7.0.0.0.0.1.0);
    var mvpMat = multiMatrix44(projMat, viewMat);

    var u_MvpMatrix = gl.getUniformLocation(sp, "u_MvpMatrix");
    gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMat);

    var n = initVertexBuffers(gl, sp);
    draw(gl, n)
}

function getGL() {
    var cavans = document.getElementById("container");
    return cavans.getContext("webgl") || cavans.getContext("experimental-webgl");
}

function initShader(gl, srcVS, srcFS) {
    var sp = createProgram(gl, srcVS, srcFS);
    gl.useProgram(sp);
    return sp;
}

function createProgram(gl, srcVS, srcFS) {
    var vs = loadShader(gl, gl.VERTEX_SHADER, srcVS);
    var fs = loadShader(gl, gl.FRAGMENT_SHADER, srcFS);

    var sp = gl.createProgram();
    gl.attachShader(sp, vs);
    gl.attachShader(sp, fs);

    The variable varying in VS and FS must be assigned a value. 3 The same uniform variables in VS and FS must be shared
    gl.linkProgram(sp);
    if(! gl.getProgramParameter(sp, gl.LINK_STATUS)) {console.log(gl.getProgramInfoLog(sp));
        return;
    }
    return sp;
}

function loadShader(gl, type, shaderSrc) {
    var shader = gl.createShader(type);
    gl.shaderSource(shader, shaderSrc);
    gl.compileShader(shader);
    if(! gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {console.log(gl.getShaderInfoLog(shader));
        return;
    }
    return shader;
}

function initVertexBuffers(gl, sp) {
    // The six sides of the cube and the two triangles on each side
    var vertices = new Float32Array([
        1.0.1.0.1.0, -1.0.1.0.1.0, -1.0, -1.0.1.0.1.0, -1.0.1.0.1.0.1.0.1.0.1.0, -1.0.1.0.1.0, -1.0, -1.0.1.0.1.0, -1.0.1.0.1.0.1.0.1.0.1.0, -1.0, -1.0.1.0, -1.0, -1.0.1.0.1.0,
        -1.0.1.0.1.0, -1.0.1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0.1.0,
        -1.0, -1.0, -1.0.1.0, -1.0, -1.0.1.0, -1.0.1.0, -1.0, -1.0.1.0.1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0.1.0, -1.0.1.0.1.0, -1.0
    ]);
    var FSIZE = vertices.BYTES_PER_ELEMENT;

    // The color of each vertex
    var colors = new Float32Array([
        1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0
    ]);

    // The six sides of the cube are made up of two triangles each
    var indices = new Uint8Array([
        0.1.2.0.2.3.4.5.6.4.6.7.8.9.10.8.10.11.12.13.14.12.14.15.16.17.18.16.18.19.20.21.22.20.22.23
    ]);

    var vbo = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    var a_Position = gl.getAttribLocation(sp, "a_Position");
    gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false.0.0);
    gl.enableVertexAttribArray(a_Position);

    var cbo = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, cbo);
    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

    var a_Color = gl.getAttribLocation(sp, "a_Color");
    gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false.0.0);
    gl.enableVertexAttribArray(a_Color);

    var ibo = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

    return indices.length;
}

function draw(gl, n) {
    gl.clearColor(0.0.0.0.0.0.1.0);
    gl.enable(gl.DEPTH_TEST);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, 0);

    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
}


Copy the code

Cubic under the diffuse reflection of three parallel light

/** * Directional light Diffuse Reflection ** /

var gl_SrcVS = ` attribute vec4 a_Position; attribute vec4 a_Color; attribute vec4 a_Normal; // Vertex normal vector uniform mat4u_mvpmatrix; uniform vec3 u_LightColor; // Incident light color uniform vec3 u_LightDir; // The direction of the incident light varying VEC4 v_Color; void main(){ gl_Position = u_MvpMatrix * a_Position; vec3 normal = normalize(vec3(a_Normal)); Float cos = Max (dot(u_LightDir, normal), 0.0); Vec3 Diffuse = u_LightColor * vec3(a_Color) * cos; V_Color = vec4(diffuse, a_color.a); } `;

var gl_SrcFS = ` precision lowp float; varying vec4 v_Color; void main(){ gl_FragColor = v_Color; } `;

function main() {
    var gl = getGL();
    var sp = initShader(gl, gl_SrcVS, gl_SrcFS);

    / / set the MVP
    var projMat = getPerspectiveProjection(30.16/9.1.100);
    var viewMat = lookAt(3.3.7.0.0.0.0.1.0);
    var mvpMat = multiMatrix44(projMat, viewMat);
    var u_MvpMatrix = gl.getUniformLocation(sp, "u_MvpMatrix");
    gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMat);

    // Set the incident light
    var u_LightColor = gl.getUniformLocation(sp, "u_LightColor");
    gl.uniform3f(u_LightColor, 1.0.1.0.1.0);

    var dir = normalizeVector([0.5.3.0.4.0]);
    var u_LightDir = gl.getUniformLocation(sp, "u_LightDir");
    gl.uniform3f(u_LightDir, dir[0], dir[1], dir[2]);

    var n = initVertexBuffers(gl, sp);
    draw(gl, n)
}

function getGL() {
    var cavans = document.getElementById("container");
    return cavans.getContext("webgl") || cavans.getContext("experimental-webgl");
}

function initShader(gl, srcVS, srcFS) {
    var sp = createProgram(gl, srcVS, srcFS);
    gl.useProgram(sp);
    return sp;
}

function createProgram(gl, srcVS, srcFS) {
    var vs = loadShader(gl, gl.VERTEX_SHADER, srcVS);
    var fs = loadShader(gl, gl.FRAGMENT_SHADER, srcFS);

    var sp = gl.createProgram();
    gl.attachShader(sp, vs);
    gl.attachShader(sp, fs);

    The variable varying in VS and FS must be assigned a value. 3 The same uniform variables in VS and FS must be shared
    gl.linkProgram(sp);
    if(! gl.getProgramParameter(sp, gl.LINK_STATUS)) {console.log(gl.getProgramInfoLog(sp));
        return;
    }
    return sp;
}

function loadShader(gl, type, shaderSrc) {
    var shader = gl.createShader(type);
    gl.shaderSource(shader, shaderSrc);
    gl.compileShader(shader);
    if(! gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {console.log(gl.getShaderInfoLog(shader));
        return;
    }
    return shader;
}

function initVertexBuffers(gl, sp) {
    // The six sides of the cube and the two triangles on each side
    var vertices = new Float32Array([
        1.0.1.0.1.0, -1.0.1.0.1.0, -1.0, -1.0.1.0.1.0, -1.0.1.0.1.0.1.0.1.0.1.0, -1.0.1.0.1.0, -1.0, -1.0.1.0.1.0, -1.0.1.0.1.0.1.0.1.0.1.0, -1.0, -1.0.1.0, -1.0, -1.0.1.0.1.0,
        -1.0.1.0.1.0, -1.0.1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0.1.0,
        -1.0, -1.0, -1.0.1.0, -1.0, -1.0.1.0, -1.0.1.0, -1.0, -1.0.1.0.1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0.1.0, -1.0.1.0.1.0, -1.0
    ]);

    // The normal vector for each vertex
    var normals = new Float32Array([
        0.0.0.0.1.0.0.0.0.0.1.0.0.0.0.0.1.0.0.0.0.0.1.0.1.0.0.0.0.0.1.0.0.0.0.0.1.0.0.0.0.0.1.0.0.0.0.0.0.0.1.0.0.0.0.0.1.0.0.0.0.0.1.0.0.0.0.0.1.0.0.0,
        -1.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0, -1.0.0.0.0.0, -1.0
    ]);

    // The color of each vertex
    var colors = new Float32Array([
        1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0.1.0.0
    ]);

    // The six sides of the cube are made up of two triangles each
    var indices = new Uint8Array([
        0.1.2.0.2.3.4.5.6.4.6.7.8.9.10.8.10.11.12.13.14.12.14.15.16.17.18.16.18.19.20.21.22.20.22.23
    ]);

    initArrayBuffer(gl, sp, vertices, 3, gl.FLOAT, "a_Position");
    initArrayBuffer(gl, sp, normals, 3, gl.FLOAT, "a_Normal");
    initArrayBuffer(gl, sp, colors, 3, gl.FLOAT, "a_Color");

    var ibo = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

    return indices.length;
}

function initArrayBuffer(gl, sp, data, num, type, attribute) {
    var buff = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buff);
    gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

    var attr = gl.getAttribLocation(sp, attribute);
    gl.vertexAttribPointer(attr, num, type, false.0.0);
    gl.enableVertexAttribArray(attr);

    gl.bindBuffer(gl.ARRAY_BUFFER, null);
}

function draw(gl, n) {
    gl.clearColor(0.0.0.0.0.0.1.0);
    gl.enable(gl.DEPTH_TEST);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, 0);

    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
}

Copy the code

The cube under ambient light diffuse reflection

Modify the above code to add ambient light.

var gl_SrcVS = ` attribute vec4 a_Position; attribute vec4 a_Color; attribute vec4 a_Normal; // Vertex normal vector uniform mat4u_mvpmatrix; uniform vec3 u_LightColor; // Incident light color uniform vec3 u_LightDir; // Uniform vec3 u_LightColorAmbient; // The color of the ambient light varying VEC4 v_Color; void main(){ gl_Position = u_MvpMatrix * a_Position; vec3 normal = normalize(vec3(a_Normal)); Float cos = Max (dot(u_LightDir, normal), 0.0); Vec3 Diffuse = u_LightColor * vec3(a_Color) * cos; Vec3 ambient = u_LightColorAmbient * a_color.rgb; V_Color = vec4(Diffuse + ambient, a_color.a); } `;

function main() {
    var gl = getGL();
    var sp = initShader(gl, gl_SrcVS, gl_SrcFS);

    / / set the MVP
    var projMat = getPerspectiveProjection(30.16/9.1.100);
    var viewMat = lookAt(3.3.7.0.0.0.0.1.0);
    var mvpMat = multiMatrix44(projMat, viewMat);
    var u_MvpMatrix = gl.getUniformLocation(sp, "u_MvpMatrix");
    gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMat);

    // Set the incident light
    var u_LightColor = gl.getUniformLocation(sp, "u_LightColor");
    gl.uniform3f(u_LightColor, 1.0.1.0.1.0);

    var dir = normalizeVector([0.5.3.0.4.0]);
    var u_LightDir = gl.getUniformLocation(sp, "u_LightDir");
    gl.uniform3f(u_LightDir, dir[0], dir[1], dir[2]);

    // Set the ambient light
    var u_LightColorAmbient = gl.getUniformLocation(sp, "u_LightColorAmbient");
    gl.uniform3f(u_LightColorAmbient, 0.2.0.2.0.2);

    var n = initVertexBuffers(gl, sp);
    draw(gl, n)
}

Copy the code