Skip to content

Commit 4d3e144

Browse files
author
Andrew Adamson
committed
Adding episode 18 (directional diffuse lighting)
1 parent 5213cbb commit 4d3e144

6 files changed

+557
-0
lines changed

18.diffuselighting1.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* Added features in this version over previous version (HelloWorld.js):
2+
1. adding very basic brightness calculation
3+
2. ambient + diffuse shading
4+
3. animation of light source direction
5+
*/
6+
7+
import { glMatrix, mat3, mat4, vec3 } from 'gl-matrix';
8+
9+
const vertexShaderSrc = `#version 300 es
10+
#pragma vscode_glsllint_stage: vert
11+
12+
uniform vec3 uLightDirection;
13+
14+
out float vBrightness;
15+
16+
vec3 normal = vec3(0.0, 0.0, -1.0);
17+
18+
void main()
19+
{
20+
vBrightness = max(dot(uLightDirection, normal), 0.0);
21+
gl_PointSize = 200.0;
22+
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
23+
}`;
24+
25+
const fragmentShaderSrc = `#version 300 es
26+
#pragma vscode_glsllint_stage: frag
27+
28+
precision mediump float;
29+
30+
in float vBrightness;
31+
32+
out vec4 fragColor;
33+
34+
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
35+
36+
void main()
37+
{
38+
fragColor = (color * .4) + (color * vBrightness * .6);
39+
fragColor.a = 1.0;
40+
}`;
41+
42+
const gl = document.querySelector('canvas').getContext('webgl2');
43+
44+
const program = gl.createProgram();
45+
46+
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
47+
gl.shaderSource(vertexShader, vertexShaderSrc);
48+
gl.compileShader(vertexShader);
49+
gl.attachShader(program, vertexShader);
50+
51+
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
52+
gl.shaderSource(fragmentShader, fragmentShaderSrc);
53+
gl.compileShader(fragmentShader);
54+
gl.attachShader(program, fragmentShader);
55+
56+
gl.linkProgram(program);
57+
58+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
59+
// tslint:disable: no-console
60+
console.log(gl.getShaderInfoLog(vertexShader));
61+
console.log(gl.getShaderInfoLog(fragmentShader));
62+
// tslint:enable: no-console
63+
}
64+
gl.useProgram(program);
65+
66+
const lightDirectionLoc = gl.getUniformLocation(program, 'uLightDirection');
67+
const lightDirection = vec3.fromValues(1, 1, 1);
68+
vec3.normalize(lightDirection, lightDirection);
69+
70+
const draw = () => {
71+
// Rotate the light:
72+
vec3.rotateY(lightDirection, lightDirection, [0,0,0], 0.02);
73+
74+
gl.uniform3fv(lightDirectionLoc, lightDirection);
75+
76+
gl.drawArrays(gl.POINTS, 0, 1);
77+
78+
requestAnimationFrame(draw);
79+
};
80+
81+
draw();

18.diffuselighting2.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* Added features in this version over version 1:
2+
1. add async main function
3+
2. loading icosphere object
4+
3. loading vertex buffer data
5+
4. adding vertex buffer attributes (position + normal)
6+
5. adding back face culling
7+
*/
8+
9+
import { glMatrix, mat3, mat4, vec3 } from 'gl-matrix';
10+
11+
const vertexShaderSrc = `#version 300 es
12+
#pragma vscode_glsllint_stage: vert
13+
14+
uniform vec3 uLightDirection;
15+
16+
layout(location=0) in vec4 aPosition;
17+
layout(location=1) in vec3 aNormal;
18+
19+
out float vBrightness;
20+
21+
void main()
22+
{
23+
vBrightness = max(dot(uLightDirection, aNormal), 0.0);
24+
gl_Position = aPosition;
25+
}`;
26+
27+
const fragmentShaderSrc = `#version 300 es
28+
#pragma vscode_glsllint_stage: frag
29+
30+
precision mediump float;
31+
32+
in float vBrightness;
33+
34+
out vec4 fragColor;
35+
36+
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
37+
38+
void main()
39+
{
40+
fragColor = (color * .4) + (color * vBrightness * .6);
41+
fragColor.a = 1.0;
42+
}`;
43+
44+
const gl = document.querySelector('canvas').getContext('webgl2');
45+
46+
const program = gl.createProgram();
47+
48+
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
49+
gl.shaderSource(vertexShader, vertexShaderSrc);
50+
gl.compileShader(vertexShader);
51+
gl.attachShader(program, vertexShader);
52+
53+
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
54+
gl.shaderSource(fragmentShader, fragmentShaderSrc);
55+
gl.compileShader(fragmentShader);
56+
gl.attachShader(program, fragmentShader);
57+
58+
gl.linkProgram(program);
59+
60+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
61+
// tslint:disable: no-console
62+
console.log(gl.getShaderInfoLog(vertexShader));
63+
console.log(gl.getShaderInfoLog(fragmentShader));
64+
// tslint:enable: no-console
65+
}
66+
gl.useProgram(program);
67+
68+
// Prevent back surfaces from covering forward surfaces
69+
gl.enable(gl.CULL_FACE);
70+
gl.cullFace(gl.BACK);
71+
72+
const loadObject = async () => {
73+
const file = await fetch('./icosphere.PNT.bin');
74+
const arrayBuffer = await file.arrayBuffer();
75+
return arrayBuffer;
76+
};
77+
78+
const main = async () => {
79+
const object = await loadObject();
80+
81+
const buffer = gl.createBuffer();
82+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
83+
gl.bufferData(gl.ARRAY_BUFFER, object, gl.STATIC_DRAW);
84+
85+
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 32, 0);
86+
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 32, 12);
87+
88+
gl.enableVertexAttribArray(0);
89+
gl.enableVertexAttribArray(1);
90+
91+
const lightDirectionLoc = gl.getUniformLocation(program, 'uLightDirection');
92+
const lightDirection = vec3.fromValues(1, 1, 1);
93+
vec3.normalize(lightDirection, lightDirection);
94+
95+
const draw = () => {
96+
// Rotate the light:
97+
vec3.rotateY(lightDirection, lightDirection, [0,0,0], 0.02);
98+
99+
gl.uniform3fv(lightDirectionLoc, lightDirection);
100+
101+
gl.drawArrays(gl.TRIANGLES, 0, object.byteLength / 32);
102+
103+
requestAnimationFrame(draw);
104+
};
105+
106+
draw();
107+
};
108+
main();

18.diffuselighting3.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/* Added features in this version over version 2:
2+
1. adding model transformations
3+
2. fixing post-transform normal values (simple)
4+
*/
5+
6+
import { glMatrix, mat3, mat4, vec3 } from 'gl-matrix';
7+
8+
const vertexShaderSrc = `#version 300 es
9+
#pragma vscode_glsllint_stage: vert
10+
11+
uniform mat4 uModelMatrix;
12+
uniform vec3 uLightDirection;
13+
14+
layout(location=0) in vec4 aPosition;
15+
layout(location=1) in vec3 aNormal;
16+
17+
out float vBrightness;
18+
19+
void main()
20+
{
21+
vBrightness = max(dot(uLightDirection, normalize(mat3(uModelMatrix) * aNormal)), 0.0);
22+
gl_Position = uModelMatrix * aPosition;
23+
}`;
24+
25+
const fragmentShaderSrc = `#version 300 es
26+
#pragma vscode_glsllint_stage: frag
27+
28+
precision mediump float;
29+
30+
in float vBrightness;
31+
32+
out vec4 fragColor;
33+
34+
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
35+
36+
void main()
37+
{
38+
fragColor = (color * .4) + (color * vBrightness * .6);
39+
fragColor.a = 1.0;
40+
}`;
41+
42+
const gl = document.querySelector('canvas').getContext('webgl2');
43+
44+
const program = gl.createProgram();
45+
46+
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
47+
gl.shaderSource(vertexShader, vertexShaderSrc);
48+
gl.compileShader(vertexShader);
49+
gl.attachShader(program, vertexShader);
50+
51+
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
52+
gl.shaderSource(fragmentShader, fragmentShaderSrc);
53+
gl.compileShader(fragmentShader);
54+
gl.attachShader(program, fragmentShader);
55+
56+
gl.linkProgram(program);
57+
58+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
59+
// tslint:disable: no-console
60+
console.log(gl.getShaderInfoLog(vertexShader));
61+
console.log(gl.getShaderInfoLog(fragmentShader));
62+
// tslint:enable: no-console
63+
}
64+
gl.useProgram(program);
65+
66+
// Prevent back surfaces from covering forward surfaces
67+
gl.enable(gl.CULL_FACE);
68+
gl.cullFace(gl.BACK);
69+
70+
const loadObject = async () => {
71+
const file = await fetch('./icosphere.PNT.bin');
72+
const arrayBuffer = await file.arrayBuffer();
73+
return arrayBuffer;
74+
};
75+
76+
const main = async () => {
77+
const object = await loadObject();
78+
79+
const buffer = gl.createBuffer();
80+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
81+
gl.bufferData(gl.ARRAY_BUFFER, object, gl.STATIC_DRAW);
82+
83+
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 32, 0);
84+
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 32, 12);
85+
86+
gl.enableVertexAttribArray(0);
87+
gl.enableVertexAttribArray(1);
88+
89+
const lightDirectionLoc = gl.getUniformLocation(program, 'uLightDirection');
90+
const lightDirection = vec3.fromValues(1, 1, 1);
91+
vec3.normalize(lightDirection, lightDirection);
92+
93+
const modelMatrixLoc = gl.getUniformLocation(program, 'uModelMatrix');
94+
const modelMatrix = mat4.create();
95+
96+
const draw = () => {
97+
// Rotate the light:
98+
// vec3.rotateY(lightDirection, lightDirection, [0,0,0], 0.02);
99+
100+
// Rotate the model:
101+
mat4.rotateY(modelMatrix, modelMatrix, 0.02);
102+
103+
// Squash the model:
104+
// mat4.scale(modelMatrix, modelMatrix, [1, 1, .99]);
105+
106+
gl.uniform3fv(lightDirectionLoc, lightDirection);
107+
gl.uniformMatrix4fv(modelMatrixLoc, false, modelMatrix);
108+
109+
gl.drawArrays(gl.TRIANGLES, 0, object.byteLength / 32);
110+
111+
requestAnimationFrame(draw);
112+
};
113+
114+
draw();
115+
};
116+
main();

0 commit comments

Comments
 (0)