3d-spinner 0.9.4 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animations/charged-orb.js +4 -2
- package/dist/animations/ghost-train.js +3 -1
- package/dist/animations/spin.d.ts +3 -1
- package/dist/animations/spin.js +6 -1
- package/dist/cjs/animations/charged-orb.cjs +170 -28
- package/dist/cjs/animations/grid-assembly.cjs +164 -26
- package/dist/cjs/animations/object-motion.cjs +156 -24
- package/dist/cjs/animations/particles.cjs +167 -26
- package/dist/cjs/animations/spin.cjs +169 -27
- package/dist/cjs/engines/little-3d-engine/little-3d-engine.cjs +193 -45
- package/dist/cjs/engines/little-3d-engine/loaders/obj.cjs +51 -13
- package/dist/cjs/engines/little-3d-engine/renderers/canvas2d-textured.cjs +56 -6
- package/dist/cjs/engines/little-3d-engine/renderers/webgl-textured.cjs +55 -6
- package/dist/cjs/engines/little-3d-engine/renderers/webgpu-textured.cjs +64 -11
- package/dist/cjs/prefabs/prefabs.cjs +186 -40
- package/dist/engines/little-3d-engine/core/geometry.d.ts +15 -2
- package/dist/engines/little-3d-engine/core/geometry.js +25 -3
- package/dist/engines/little-3d-engine/core/light.d.ts +28 -4
- package/dist/engines/little-3d-engine/core/light.js +48 -7
- package/dist/engines/little-3d-engine/core/mesh.d.ts +33 -0
- package/dist/engines/little-3d-engine/core/mesh.js +12 -0
- package/dist/engines/little-3d-engine/little-3d-engine.d.ts +2 -2
- package/dist/engines/little-3d-engine/little-3d-engine.js +1 -1
- package/dist/engines/little-3d-engine/loaders/obj.d.ts +8 -7
- package/dist/engines/little-3d-engine/loaders/obj.js +74 -20
- package/dist/engines/little-3d-engine/renderers/canvas2d.js +23 -1
- package/dist/engines/little-3d-engine/renderers/webgl.js +34 -5
- package/dist/engines/little-3d-engine/renderers/webgpu.js +43 -10
- package/dist/engines/little-3d-engine/shapes/complex/plane.d.ts +8 -3
- package/dist/engines/little-3d-engine/shapes/complex/plane.js +10 -4
- package/dist/engines/little-3d-engine/shapes/primitives/cube.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/cube.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/octahedron.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/octahedron.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/pyramid.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/pyramid.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/quad.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/quad.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/cube-sphere.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/cube-sphere.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/icosphere.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/icosphere.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/octa-sphere.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/octa-sphere.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/uv-sphere.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/spheres/uv-sphere.js +4 -2
- package/dist/engines/little-3d-engine/shapes/primitives/tetrahedron.d.ts +3 -2
- package/dist/engines/little-3d-engine/shapes/primitives/tetrahedron.js +4 -2
- package/dist/umd/spinner.global.js +255 -63
- package/dist/umd/spinner.global.min.js +58 -17
- package/package.json +1 -1
|
@@ -107,13 +107,42 @@ var init_geometry = __esm({
|
|
|
107
107
|
function clamp01(value) {
|
|
108
108
|
return Math.min(1, Math.max(0, value));
|
|
109
109
|
}
|
|
110
|
-
function
|
|
110
|
+
function clamp255(value) {
|
|
111
|
+
return Math.round(Math.min(255, Math.max(0, value)));
|
|
112
|
+
}
|
|
113
|
+
function shade(normal, color, light, surface) {
|
|
111
114
|
const lambert = Math.max(0, dot(normal, light.toLight));
|
|
112
115
|
const brightness = clamp01(light.ambient + light.intensity * lambert);
|
|
113
|
-
const [
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
const [baseR, baseG, baseB] = parseColor(color);
|
|
117
|
+
let r = baseR * brightness;
|
|
118
|
+
let g = baseG * brightness;
|
|
119
|
+
let b = baseB * brightness;
|
|
120
|
+
const material = surface?.material;
|
|
121
|
+
const specular = material?.specular;
|
|
122
|
+
const viewDir = surface?.viewDir;
|
|
123
|
+
if (specular && viewDir && lambert > 0) {
|
|
124
|
+
const half = normalize({
|
|
125
|
+
x: light.toLight.x + viewDir.x,
|
|
126
|
+
y: light.toLight.y + viewDir.y,
|
|
127
|
+
z: light.toLight.z + viewDir.z
|
|
128
|
+
});
|
|
129
|
+
const shininess = material?.shininess ?? 32;
|
|
130
|
+
const highlight = Math.pow(Math.max(0, dot(normal, half)), shininess) * light.intensity * 255;
|
|
131
|
+
r += highlight * specular[0];
|
|
132
|
+
g += highlight * specular[1];
|
|
133
|
+
b += highlight * specular[2];
|
|
134
|
+
}
|
|
135
|
+
const emissive = material?.emissive;
|
|
136
|
+
if (emissive) {
|
|
137
|
+
r += emissive[0] * 255;
|
|
138
|
+
g += emissive[1] * 255;
|
|
139
|
+
b += emissive[2] * 255;
|
|
140
|
+
}
|
|
141
|
+
return [clamp255(r), clamp255(g), clamp255(b)];
|
|
142
|
+
}
|
|
143
|
+
function shadeColor(normal, color, light, surface) {
|
|
144
|
+
const [r, g, b] = shade(normal, color, light, surface);
|
|
145
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
117
146
|
}
|
|
118
147
|
var init_light = __esm({
|
|
119
148
|
"src/engines/little-3d-engine/core/light.ts"() {
|
|
@@ -183,9 +212,30 @@ var init_canvas2d = __esm({
|
|
|
183
212
|
depth += dot(d, d);
|
|
184
213
|
}
|
|
185
214
|
depth /= face.indices.length;
|
|
215
|
+
let surface;
|
|
216
|
+
const material = face.material;
|
|
217
|
+
if (material) {
|
|
218
|
+
if (material.specular) {
|
|
219
|
+
let cx = 0;
|
|
220
|
+
let cy = 0;
|
|
221
|
+
let cz = 0;
|
|
222
|
+
for (const i of face.indices) {
|
|
223
|
+
cx += world[i].x;
|
|
224
|
+
cy += world[i].y;
|
|
225
|
+
cz += world[i].z;
|
|
226
|
+
}
|
|
227
|
+
const inv = 1 / face.indices.length;
|
|
228
|
+
const viewDir = normalize(
|
|
229
|
+
subtract(frame.eye, { x: cx * inv, y: cy * inv, z: cz * inv })
|
|
230
|
+
);
|
|
231
|
+
surface = { material, viewDir };
|
|
232
|
+
} else {
|
|
233
|
+
surface = { material };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
186
236
|
polygons.push({
|
|
187
237
|
points,
|
|
188
|
-
color: shadeColor(normal, face.color, frame.light),
|
|
238
|
+
color: shadeColor(normal, face.color, frame.light, surface),
|
|
189
239
|
depth,
|
|
190
240
|
opacity: faceOpacity
|
|
191
241
|
});
|
|
@@ -60,7 +60,10 @@ function expandToTriangles(mesh) {
|
|
|
60
60
|
const positions = new Float32Array(triangles * 9);
|
|
61
61
|
const normals = new Float32Array(triangles * 9);
|
|
62
62
|
const colors = new Float32Array(triangles * 9);
|
|
63
|
+
const emissives = new Float32Array(triangles * 9);
|
|
64
|
+
const speculars = new Float32Array(triangles * 12);
|
|
63
65
|
let o = 0;
|
|
66
|
+
let so = 0;
|
|
64
67
|
for (const face of mesh.faces) {
|
|
65
68
|
const v0 = mesh.vertices[face.indices[0]];
|
|
66
69
|
const v1 = mesh.vertices[face.indices[1]];
|
|
@@ -70,6 +73,15 @@ function expandToTriangles(mesh) {
|
|
|
70
73
|
const cr = r / 255;
|
|
71
74
|
const cg = g / 255;
|
|
72
75
|
const cb = b / 255;
|
|
76
|
+
const emissive = face.material?.emissive;
|
|
77
|
+
const er = emissive ? emissive[0] : 0;
|
|
78
|
+
const eg = emissive ? emissive[1] : 0;
|
|
79
|
+
const eb = emissive ? emissive[2] : 0;
|
|
80
|
+
const specular = face.material?.specular;
|
|
81
|
+
const sr = specular ? specular[0] : 0;
|
|
82
|
+
const sg = specular ? specular[1] : 0;
|
|
83
|
+
const sb = specular ? specular[2] : 0;
|
|
84
|
+
const sn = specular ? face.material?.shininess ?? 32 : 1;
|
|
73
85
|
for (let k = 1; k < face.indices.length - 1; k++) {
|
|
74
86
|
const tri = [face.indices[0], face.indices[k], face.indices[k + 1]];
|
|
75
87
|
for (const index of tri) {
|
|
@@ -83,11 +95,19 @@ function expandToTriangles(mesh) {
|
|
|
83
95
|
colors[o] = cr;
|
|
84
96
|
colors[o + 1] = cg;
|
|
85
97
|
colors[o + 2] = cb;
|
|
98
|
+
emissives[o] = er;
|
|
99
|
+
emissives[o + 1] = eg;
|
|
100
|
+
emissives[o + 2] = eb;
|
|
101
|
+
speculars[so] = sr;
|
|
102
|
+
speculars[so + 1] = sg;
|
|
103
|
+
speculars[so + 2] = sb;
|
|
104
|
+
speculars[so + 3] = sn;
|
|
86
105
|
o += 3;
|
|
106
|
+
so += 4;
|
|
87
107
|
}
|
|
88
108
|
}
|
|
89
109
|
}
|
|
90
|
-
return { positions, normals, colors, count: positions.length / 3 };
|
|
110
|
+
return { positions, normals, colors, emissives, speculars, count: positions.length / 3 };
|
|
91
111
|
}
|
|
92
112
|
var init_geometry = __esm({
|
|
93
113
|
"src/engines/little-3d-engine/core/geometry.ts"() {
|
|
@@ -151,28 +171,51 @@ var init_webgl = __esm({
|
|
|
151
171
|
in vec3 aPos;
|
|
152
172
|
in vec3 aNormal;
|
|
153
173
|
in vec3 aColor;
|
|
174
|
+
in vec3 aEmissive;
|
|
175
|
+
in vec4 aSpecular;
|
|
154
176
|
uniform mat4 uViewProj;
|
|
155
177
|
uniform mat4 uModel;
|
|
156
178
|
out vec3 vNormal;
|
|
157
179
|
out vec3 vColor;
|
|
180
|
+
out vec3 vEmissive;
|
|
181
|
+
out vec4 vSpecular;
|
|
182
|
+
out vec3 vWorldPos;
|
|
158
183
|
void main() {
|
|
159
184
|
vNormal = mat3(uModel) * aNormal;
|
|
160
185
|
vColor = aColor;
|
|
161
|
-
|
|
186
|
+
vEmissive = aEmissive;
|
|
187
|
+
vSpecular = aSpecular;
|
|
188
|
+
vec4 world = uModel * vec4(aPos, 1.0);
|
|
189
|
+
vWorldPos = world.xyz;
|
|
190
|
+
gl_Position = uViewProj * world;
|
|
162
191
|
}`;
|
|
163
192
|
FRAGMENT_SHADER = `#version 300 es
|
|
164
193
|
precision mediump float;
|
|
165
194
|
in vec3 vNormal;
|
|
166
195
|
in vec3 vColor;
|
|
196
|
+
in vec3 vEmissive;
|
|
197
|
+
in vec4 vSpecular;
|
|
198
|
+
in vec3 vWorldPos;
|
|
167
199
|
uniform vec3 uToLight;
|
|
200
|
+
uniform vec3 uEye;
|
|
168
201
|
uniform float uIntensity;
|
|
169
202
|
uniform float uAmbient;
|
|
170
203
|
uniform float uOpacity;
|
|
171
204
|
out vec4 fragColor;
|
|
172
205
|
void main() {
|
|
173
|
-
|
|
206
|
+
vec3 normal = normalize(vNormal);
|
|
207
|
+
vec3 toLight = normalize(uToLight);
|
|
208
|
+
float lambert = max(dot(normal, toLight), 0.0);
|
|
174
209
|
float brightness = clamp(uAmbient + uIntensity * lambert, 0.0, 1.0);
|
|
175
|
-
|
|
210
|
+
vec3 lit = vColor * brightness;
|
|
211
|
+
if (lambert > 0.0) {
|
|
212
|
+
vec3 viewDir = normalize(uEye - vWorldPos);
|
|
213
|
+
vec3 halfVec = normalize(toLight + viewDir);
|
|
214
|
+
float highlight = pow(max(dot(normal, halfVec), 0.0), vSpecular.w) * uIntensity;
|
|
215
|
+
lit += highlight * vSpecular.xyz;
|
|
216
|
+
}
|
|
217
|
+
lit += vEmissive;
|
|
218
|
+
fragColor = vec4(lit, uOpacity);
|
|
176
219
|
}`;
|
|
177
220
|
WebGLRenderer = class {
|
|
178
221
|
constructor(options = {}) {
|
|
@@ -193,9 +236,12 @@ void main() {
|
|
|
193
236
|
aPos: gl.getAttribLocation(this.program, "aPos"),
|
|
194
237
|
aNormal: gl.getAttribLocation(this.program, "aNormal"),
|
|
195
238
|
aColor: gl.getAttribLocation(this.program, "aColor"),
|
|
239
|
+
aEmissive: gl.getAttribLocation(this.program, "aEmissive"),
|
|
240
|
+
aSpecular: gl.getAttribLocation(this.program, "aSpecular"),
|
|
196
241
|
uViewProj: gl.getUniformLocation(this.program, "uViewProj"),
|
|
197
242
|
uModel: gl.getUniformLocation(this.program, "uModel"),
|
|
198
243
|
uToLight: gl.getUniformLocation(this.program, "uToLight"),
|
|
244
|
+
uEye: gl.getUniformLocation(this.program, "uEye"),
|
|
199
245
|
uIntensity: gl.getUniformLocation(this.program, "uIntensity"),
|
|
200
246
|
uAmbient: gl.getUniformLocation(this.program, "uAmbient"),
|
|
201
247
|
uOpacity: gl.getUniformLocation(this.program, "uOpacity")
|
|
@@ -219,17 +265,19 @@ void main() {
|
|
|
219
265
|
const data = expandToTriangles(mesh);
|
|
220
266
|
const vao = gl.createVertexArray();
|
|
221
267
|
gl.bindVertexArray(vao);
|
|
222
|
-
const attribute = (location, array) => {
|
|
268
|
+
const attribute = (location, array, size = 3) => {
|
|
223
269
|
if (location < 0) return;
|
|
224
270
|
const buffer = gl.createBuffer();
|
|
225
271
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
226
272
|
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
|
|
227
273
|
gl.enableVertexAttribArray(location);
|
|
228
|
-
gl.vertexAttribPointer(location,
|
|
274
|
+
gl.vertexAttribPointer(location, size, gl.FLOAT, false, 0, 0);
|
|
229
275
|
};
|
|
230
276
|
attribute(loc.aPos, data.positions);
|
|
231
277
|
attribute(loc.aNormal, data.normals);
|
|
232
278
|
attribute(loc.aColor, data.colors);
|
|
279
|
+
attribute(loc.aEmissive, data.emissives);
|
|
280
|
+
attribute(loc.aSpecular, data.speculars, 4);
|
|
233
281
|
gl.bindVertexArray(null);
|
|
234
282
|
const result = { vao, count: data.count };
|
|
235
283
|
this.cache.set(mesh, result);
|
|
@@ -244,6 +292,7 @@ void main() {
|
|
|
244
292
|
gl.useProgram(this.program);
|
|
245
293
|
gl.uniformMatrix4fv(loc.uViewProj, false, new Float32Array(frame.viewProjection));
|
|
246
294
|
gl.uniform3f(loc.uToLight, frame.light.toLight.x, frame.light.toLight.y, frame.light.toLight.z);
|
|
295
|
+
gl.uniform3f(loc.uEye, frame.eye.x, frame.eye.y, frame.eye.z);
|
|
247
296
|
gl.uniform1f(loc.uIntensity, frame.light.intensity);
|
|
248
297
|
gl.uniform1f(loc.uAmbient, frame.light.ambient);
|
|
249
298
|
gl.disable(gl.BLEND);
|
|
@@ -73,7 +73,10 @@ function expandToTriangles(mesh) {
|
|
|
73
73
|
const positions = new Float32Array(triangles * 9);
|
|
74
74
|
const normals = new Float32Array(triangles * 9);
|
|
75
75
|
const colors = new Float32Array(triangles * 9);
|
|
76
|
+
const emissives = new Float32Array(triangles * 9);
|
|
77
|
+
const speculars = new Float32Array(triangles * 12);
|
|
76
78
|
let o = 0;
|
|
79
|
+
let so = 0;
|
|
77
80
|
for (const face of mesh.faces) {
|
|
78
81
|
const v0 = mesh.vertices[face.indices[0]];
|
|
79
82
|
const v1 = mesh.vertices[face.indices[1]];
|
|
@@ -83,6 +86,15 @@ function expandToTriangles(mesh) {
|
|
|
83
86
|
const cr = r / 255;
|
|
84
87
|
const cg = g / 255;
|
|
85
88
|
const cb = b / 255;
|
|
89
|
+
const emissive = face.material?.emissive;
|
|
90
|
+
const er = emissive ? emissive[0] : 0;
|
|
91
|
+
const eg = emissive ? emissive[1] : 0;
|
|
92
|
+
const eb = emissive ? emissive[2] : 0;
|
|
93
|
+
const specular = face.material?.specular;
|
|
94
|
+
const sr = specular ? specular[0] : 0;
|
|
95
|
+
const sg = specular ? specular[1] : 0;
|
|
96
|
+
const sb = specular ? specular[2] : 0;
|
|
97
|
+
const sn = specular ? face.material?.shininess ?? 32 : 1;
|
|
86
98
|
for (let k = 1; k < face.indices.length - 1; k++) {
|
|
87
99
|
const tri = [face.indices[0], face.indices[k], face.indices[k + 1]];
|
|
88
100
|
for (const index of tri) {
|
|
@@ -96,11 +108,19 @@ function expandToTriangles(mesh) {
|
|
|
96
108
|
colors[o] = cr;
|
|
97
109
|
colors[o + 1] = cg;
|
|
98
110
|
colors[o + 2] = cb;
|
|
111
|
+
emissives[o] = er;
|
|
112
|
+
emissives[o + 1] = eg;
|
|
113
|
+
emissives[o + 2] = eb;
|
|
114
|
+
speculars[so] = sr;
|
|
115
|
+
speculars[so + 1] = sg;
|
|
116
|
+
speculars[so + 2] = sb;
|
|
117
|
+
speculars[so + 3] = sn;
|
|
99
118
|
o += 3;
|
|
119
|
+
so += 4;
|
|
100
120
|
}
|
|
101
121
|
}
|
|
102
122
|
}
|
|
103
|
-
return { positions, normals, colors, count: positions.length / 3 };
|
|
123
|
+
return { positions, normals, colors, emissives, speculars, count: positions.length / 3 };
|
|
104
124
|
}
|
|
105
125
|
var init_geometry = __esm({
|
|
106
126
|
"src/engines/little-3d-engine/core/geometry.ts"() {
|
|
@@ -148,6 +168,7 @@ struct Uniforms {
|
|
|
148
168
|
model: mat4x4<f32>,
|
|
149
169
|
toLight: vec4<f32>,
|
|
150
170
|
params: vec4<f32>,
|
|
171
|
+
eye: vec4<f32>,
|
|
151
172
|
};
|
|
152
173
|
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
153
174
|
|
|
@@ -155,23 +176,40 @@ struct VSOut {
|
|
|
155
176
|
@builtin(position) position: vec4<f32>,
|
|
156
177
|
@location(0) normal: vec3<f32>,
|
|
157
178
|
@location(1) color: vec3<f32>,
|
|
179
|
+
@location(2) emissive: vec3<f32>,
|
|
180
|
+
@location(3) specular: vec4<f32>,
|
|
181
|
+
@location(4) worldPos: vec3<f32>,
|
|
158
182
|
};
|
|
159
183
|
|
|
160
184
|
@vertex
|
|
161
|
-
fn vs(@location(0) pos: vec3<f32>, @location(1) normal: vec3<f32>, @location(2) color: vec3<f32>) -> VSOut {
|
|
185
|
+
fn vs(@location(0) pos: vec3<f32>, @location(1) normal: vec3<f32>, @location(2) color: vec3<f32>, @location(3) emissive: vec3<f32>, @location(4) specular: vec4<f32>) -> VSOut {
|
|
162
186
|
var out: VSOut;
|
|
163
187
|
let m = mat3x3<f32>(u.model[0].xyz, u.model[1].xyz, u.model[2].xyz);
|
|
164
188
|
out.normal = m * normal;
|
|
165
189
|
out.color = color;
|
|
166
|
-
out.
|
|
190
|
+
out.emissive = emissive;
|
|
191
|
+
out.specular = specular;
|
|
192
|
+
let world = u.model * vec4<f32>(pos, 1.0);
|
|
193
|
+
out.worldPos = world.xyz;
|
|
194
|
+
out.position = u.viewProj * world;
|
|
167
195
|
return out;
|
|
168
196
|
}
|
|
169
197
|
|
|
170
198
|
@fragment
|
|
171
199
|
fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
172
|
-
let
|
|
200
|
+
let normal = normalize(in.normal);
|
|
201
|
+
let toLight = normalize(u.toLight.xyz);
|
|
202
|
+
let lambert = max(dot(normal, toLight), 0.0);
|
|
173
203
|
let brightness = clamp(u.params.y + u.params.x * lambert, 0.0, 1.0);
|
|
174
|
-
|
|
204
|
+
var lit = in.color * brightness;
|
|
205
|
+
if (lambert > 0.0) {
|
|
206
|
+
let viewDir = normalize(u.eye.xyz - in.worldPos);
|
|
207
|
+
let halfVec = normalize(toLight + viewDir);
|
|
208
|
+
let highlight = pow(max(dot(normal, halfVec), 0.0), in.specular.w) * u.params.x;
|
|
209
|
+
lit = lit + highlight * in.specular.xyz;
|
|
210
|
+
}
|
|
211
|
+
lit = lit + in.emissive;
|
|
212
|
+
return vec4<f32>(lit, u.params.z);
|
|
175
213
|
}
|
|
176
214
|
`;
|
|
177
215
|
CLIP_Z_FIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1];
|
|
@@ -212,13 +250,15 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
212
250
|
{
|
|
213
251
|
binding: 0,
|
|
214
252
|
visibility: stage.VERTEX | stage.FRAGMENT,
|
|
215
|
-
buffer: { type: "uniform", hasDynamicOffset: true, minBindingSize:
|
|
253
|
+
buffer: { type: "uniform", hasDynamicOffset: true, minBindingSize: 176 }
|
|
216
254
|
}
|
|
217
255
|
]
|
|
218
256
|
});
|
|
219
|
-
const vertexBuffer = (location) => ({
|
|
220
|
-
arrayStride:
|
|
221
|
-
attributes: [
|
|
257
|
+
const vertexBuffer = (location, components = 3) => ({
|
|
258
|
+
arrayStride: components * 4,
|
|
259
|
+
attributes: [
|
|
260
|
+
{ shaderLocation: location, offset: 0, format: `float32x${components}` }
|
|
261
|
+
]
|
|
222
262
|
});
|
|
223
263
|
const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [layout] });
|
|
224
264
|
const blend = {
|
|
@@ -234,7 +274,13 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
234
274
|
vertex: {
|
|
235
275
|
module: module2,
|
|
236
276
|
entryPoint: "vs",
|
|
237
|
-
buffers: [
|
|
277
|
+
buffers: [
|
|
278
|
+
vertexBuffer(0),
|
|
279
|
+
vertexBuffer(1),
|
|
280
|
+
vertexBuffer(2),
|
|
281
|
+
vertexBuffer(3),
|
|
282
|
+
vertexBuffer(4, 4)
|
|
283
|
+
]
|
|
238
284
|
},
|
|
239
285
|
fragment: {
|
|
240
286
|
module: module2,
|
|
@@ -287,6 +333,8 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
287
333
|
position: upload(data.positions),
|
|
288
334
|
normal: upload(data.normals),
|
|
289
335
|
color: upload(data.colors),
|
|
336
|
+
emissive: upload(data.emissives),
|
|
337
|
+
specular: upload(data.speculars),
|
|
290
338
|
count: data.count
|
|
291
339
|
};
|
|
292
340
|
this.cache.set(mesh, result);
|
|
@@ -338,7 +386,7 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
338
386
|
const bindGroup = this.device.createBindGroup({
|
|
339
387
|
layout,
|
|
340
388
|
entries: [
|
|
341
|
-
{ binding: 0, resource: { buffer: this.uniformBuffer, offset: 0, size:
|
|
389
|
+
{ binding: 0, resource: { buffer: this.uniformBuffer, offset: 0, size: 176 } }
|
|
342
390
|
]
|
|
343
391
|
});
|
|
344
392
|
draws.forEach((draw, i) => {
|
|
@@ -347,6 +395,7 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
347
395
|
data.set(draw.item.model, 16);
|
|
348
396
|
data.set([frame.light.toLight.x, frame.light.toLight.y, frame.light.toLight.z, 0], 32);
|
|
349
397
|
data.set([frame.light.intensity, frame.light.ambient, draw.opacity, 0], 36);
|
|
398
|
+
data.set([frame.eye.x, frame.eye.y, frame.eye.z, 0], 40);
|
|
350
399
|
this.device.queue.writeBuffer(this.uniformBuffer, i * UNIFORM_STRIDE, data);
|
|
351
400
|
});
|
|
352
401
|
const encoder = this.device.createCommandEncoder();
|
|
@@ -373,6 +422,8 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
373
422
|
pass.setVertexBuffer(0, mesh.position);
|
|
374
423
|
pass.setVertexBuffer(1, mesh.normal);
|
|
375
424
|
pass.setVertexBuffer(2, mesh.color);
|
|
425
|
+
pass.setVertexBuffer(3, mesh.emissive);
|
|
426
|
+
pass.setVertexBuffer(4, mesh.specular);
|
|
376
427
|
pass.draw(mesh.count);
|
|
377
428
|
});
|
|
378
429
|
pass.end();
|
|
@@ -384,6 +435,8 @@ fn fs(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
384
435
|
mesh.position.destroy?.();
|
|
385
436
|
mesh.normal.destroy?.();
|
|
386
437
|
mesh.color.destroy?.();
|
|
438
|
+
mesh.emissive.destroy?.();
|
|
439
|
+
mesh.specular.destroy?.();
|
|
387
440
|
}
|
|
388
441
|
this.cache.clear();
|
|
389
442
|
this.uniformBuffer?.destroy?.();
|