forked from scriptfoundry/WebGL2-Videos-Materials
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path23.arrays.ubo.js
137 lines (109 loc) · 4.4 KB
/
23.arrays.ubo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const vertexShaderSource = `#version 300 es
#pragma vscode_glsllint_stage: vert
layout(location=0) in vec4 aPosition;
layout(location=1) in vec3 aNormal;
out vec3 vPosition;
out vec3 vNormal;
void main()
{
gl_Position = aPosition;
vPosition = gl_Position.xyz;
vNormal = aNormal;
}`;
const fragmentShaderSource = `#version 300 es
#pragma vscode_glsllint_stage: frag
precision mediump float;
uniform sampler2D sampler;
in vec3 vNormal;
in vec3 vPosition;
out vec4 fragColor;
struct Spotlight
{
vec4 location;
vec4 direction;
vec4 angles; // x = innerConeAngle, y = outerConeAngle
vec4 texCoord; // xy = texCoord UV
};
layout(std140) uniform Lighting
{
Spotlight spotlight[10];
};
void main()
{
for (int x = 0; x < 10; x++)
{
vec3 offset = spotlight[x].location.xyz - vPosition;
vec3 surfaceToLight = normalize(offset);
float distance = length(surfaceToLight);
float angleToSurface = dot(spotlight[x].direction.xyz, -surfaceToLight);
float diffuse = max(0.0, dot(surfaceToLight, normalize(vNormal)));
float attenuation = 1.0 / (distance * distance);
float spot = smoothstep(spotlight[x].angles.x, spotlight[x].angles.y, angleToSurface);
float brightness = spot * attenuation * diffuse;
vec4 color = texture(sampler, spotlight[x].texCoord.xy) * brightness;
fragColor += color;
}
fragColor.a = 1.0;
}`;
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2');
const program = gl.createProgram();
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
gl.attachShader(program, vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.log(gl.getShaderInfoLog(vertexShader));
console.log(gl.getShaderInfoLog(fragmentShader));
}
gl.useProgram(program);
// Geometry (just one quad)
const quad = new Float32Array([
// position normal
-.75, -.75, 0, 0,0,-1,
0.75, -.75, 0, 0,0,-1,
0.75, 0.75, 0, 0,0,-1,
0.75, 0.75, 0, 0,0,-1,
-.75, 0.75, 0, 0,0,-1,
-.75, -.75, 0, 0,0,-1,
]);
const quadBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
gl.bufferData(gl.ARRAY_BUFFER, quad, gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 24, 0);
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 24, 12);
gl.enableVertexAttribArray(0);
gl.enableVertexAttribArray(1);
// Light colours
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,2,0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([
255,0,0,255, 0,255,0,255, // red green
0,0,255,255, 255,255,255,255, // blue white
]));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
const _ = 0;
const lightData = new Float32Array([
// Chunk 1 Chunk 2 Chunk 3
// position direction innerCone outerCone texCoord
0.500,0.000,-.200,_, -.500,0.000,.125,_, 0.278, 0.362,_,_, .25,.25,_,_,
0.405,0.294,-.200,_, -.405,-.294,.125,_, 0.322, 0.418,_,_, .25,.75,_,_,
0.155,0.476,-.200,_, -.155,-.476,.125,_, 0.386, 0.501,_,_, .75,.75,_,_,
-.155,0.476,-.200,_, 0.155,-.476,.125,_, 0.273, 0.355,_,_, .75,.25,_,_,
-.405,0.294,-.200,_, 0.405,-.294,.125,_, 0.276, 0.359,_,_, .25,.25,_,_,
-.500,0.000,-.200,_, 0.500,-.000,.125,_, 0.345, 0.448,_,_, .25,.75,_,_,
-.405,-.294,-.200,_, 0.405,0.294,.125,_, 0.295, 0.383,_,_, .75,.75,_,_,
-.155,-.476,-.200,_, 0.155,0.476,.125,_, 0.300, 0.390,_,_, .75,.25,_,_,
0.155,-.476,-.200,_, -.155,0.476,.125,_, 0.242, 0.315,_,_, .25,.25,_,_,
0.405,-.294,-.200,_, -.405,0.294,.125,_, 0.365, 0.475,_,_, .25,.75,_,_,
]);
const buffer = gl.createBuffer();
gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, buffer);
gl.bufferData(gl.UNIFORM_BUFFER, lightData, gl.STATIC_DRAW);
gl.uniformBlockBinding(program, gl.getUniformBlockIndex(program, 'Lighting'), 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);