reze-engine 0.1.6 → 0.1.7

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/engine.js CHANGED
@@ -72,226 +72,226 @@ export class Engine {
72
72
  });
73
73
  const shaderModule = this.device.createShaderModule({
74
74
  label: "model shaders",
75
- code: /* wgsl */ `
76
- struct CameraUniforms {
77
- view: mat4x4f,
78
- projection: mat4x4f,
79
- viewPos: vec3f,
80
- _padding: f32,
81
- };
82
-
83
- struct Light {
84
- direction: vec3f,
85
- _padding1: f32,
86
- color: vec3f,
87
- intensity: f32,
88
- };
89
-
90
- struct LightUniforms {
91
- ambient: f32,
92
- lightCount: f32,
93
- _padding1: f32,
94
- _padding2: f32,
95
- lights: array<Light, 4>,
96
- };
97
-
98
- struct MaterialUniforms {
99
- alpha: f32,
100
- _padding1: f32,
101
- _padding2: f32,
102
- _padding3: f32,
103
- };
104
-
105
- struct VertexOutput {
106
- @builtin(position) position: vec4f,
107
- @location(0) normal: vec3f,
108
- @location(1) uv: vec2f,
109
- @location(2) worldPos: vec3f,
110
- };
111
-
112
- @group(0) @binding(0) var<uniform> camera: CameraUniforms;
113
- @group(0) @binding(1) var<uniform> light: LightUniforms;
114
- @group(0) @binding(2) var diffuseTexture: texture_2d<f32>;
115
- @group(0) @binding(3) var diffuseSampler: sampler;
116
- @group(0) @binding(4) var<storage, read> skinMats: array<mat4x4f>;
117
- @group(0) @binding(5) var toonTexture: texture_2d<f32>;
118
- @group(0) @binding(6) var toonSampler: sampler;
119
- @group(0) @binding(7) var<uniform> material: MaterialUniforms;
120
-
121
- @vertex fn vs(
122
- @location(0) position: vec3f,
123
- @location(1) normal: vec3f,
124
- @location(2) uv: vec2f,
125
- @location(3) joints0: vec4<u32>,
126
- @location(4) weights0: vec4<f32>
127
- ) -> VertexOutput {
128
- var output: VertexOutput;
129
- let pos4 = vec4f(position, 1.0);
130
-
131
- // Normalize weights to ensure they sum to 1.0 (handles floating-point precision issues)
132
- let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
133
- var normalizedWeights: vec4f;
134
- if (weightSum > 0.0001) {
135
- normalizedWeights = weights0 / weightSum;
136
- } else {
137
- normalizedWeights = vec4f(1.0, 0.0, 0.0, 0.0);
138
- }
139
-
140
- var skinnedPos = vec4f(0.0, 0.0, 0.0, 0.0);
141
- var skinnedNrm = vec3f(0.0, 0.0, 0.0);
142
- for (var i = 0u; i < 4u; i++) {
143
- let j = joints0[i];
144
- let w = normalizedWeights[i];
145
- let m = skinMats[j];
146
- skinnedPos += (m * pos4) * w;
147
- let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
148
- skinnedNrm += (r3 * normal) * w;
149
- }
150
- let worldPos = skinnedPos.xyz;
151
- output.position = camera.projection * camera.view * vec4f(worldPos, 1.0);
152
- output.normal = normalize(skinnedNrm);
153
- output.uv = uv;
154
- output.worldPos = worldPos;
155
- return output;
156
- }
157
-
158
- @fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
159
- let n = normalize(input.normal);
160
- let albedo = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
161
-
162
- var lightAccum = vec3f(light.ambient);
163
- let numLights = u32(light.lightCount);
164
- for (var i = 0u; i < numLights; i++) {
165
- let l = -light.lights[i].direction;
166
- let nDotL = max(dot(n, l), 0.0);
167
- let toonUV = vec2f(nDotL, 0.5);
168
- let toonFactor = textureSample(toonTexture, toonSampler, toonUV).rgb;
169
- let radiance = light.lights[i].color * light.lights[i].intensity;
170
- lightAccum += toonFactor * radiance * nDotL;
171
- }
172
-
173
- let color = albedo * lightAccum;
174
- let finalAlpha = material.alpha;
175
- if (finalAlpha < 0.001) {
176
- discard;
177
- }
178
-
179
- return vec4f(clamp(color, vec3f(0.0), vec3f(1.0)), finalAlpha);
180
- }
75
+ code: /* wgsl */ `
76
+ struct CameraUniforms {
77
+ view: mat4x4f,
78
+ projection: mat4x4f,
79
+ viewPos: vec3f,
80
+ _padding: f32,
81
+ };
82
+
83
+ struct Light {
84
+ direction: vec3f,
85
+ _padding1: f32,
86
+ color: vec3f,
87
+ intensity: f32,
88
+ };
89
+
90
+ struct LightUniforms {
91
+ ambient: f32,
92
+ lightCount: f32,
93
+ _padding1: f32,
94
+ _padding2: f32,
95
+ lights: array<Light, 4>,
96
+ };
97
+
98
+ struct MaterialUniforms {
99
+ alpha: f32,
100
+ _padding1: f32,
101
+ _padding2: f32,
102
+ _padding3: f32,
103
+ };
104
+
105
+ struct VertexOutput {
106
+ @builtin(position) position: vec4f,
107
+ @location(0) normal: vec3f,
108
+ @location(1) uv: vec2f,
109
+ @location(2) worldPos: vec3f,
110
+ };
111
+
112
+ @group(0) @binding(0) var<uniform> camera: CameraUniforms;
113
+ @group(0) @binding(1) var<uniform> light: LightUniforms;
114
+ @group(0) @binding(2) var diffuseTexture: texture_2d<f32>;
115
+ @group(0) @binding(3) var diffuseSampler: sampler;
116
+ @group(0) @binding(4) var<storage, read> skinMats: array<mat4x4f>;
117
+ @group(0) @binding(5) var toonTexture: texture_2d<f32>;
118
+ @group(0) @binding(6) var toonSampler: sampler;
119
+ @group(0) @binding(7) var<uniform> material: MaterialUniforms;
120
+
121
+ @vertex fn vs(
122
+ @location(0) position: vec3f,
123
+ @location(1) normal: vec3f,
124
+ @location(2) uv: vec2f,
125
+ @location(3) joints0: vec4<u32>,
126
+ @location(4) weights0: vec4<f32>
127
+ ) -> VertexOutput {
128
+ var output: VertexOutput;
129
+ let pos4 = vec4f(position, 1.0);
130
+
131
+ // Normalize weights to ensure they sum to 1.0 (handles floating-point precision issues)
132
+ let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
133
+ var normalizedWeights: vec4f;
134
+ if (weightSum > 0.0001) {
135
+ normalizedWeights = weights0 / weightSum;
136
+ } else {
137
+ normalizedWeights = vec4f(1.0, 0.0, 0.0, 0.0);
138
+ }
139
+
140
+ var skinnedPos = vec4f(0.0, 0.0, 0.0, 0.0);
141
+ var skinnedNrm = vec3f(0.0, 0.0, 0.0);
142
+ for (var i = 0u; i < 4u; i++) {
143
+ let j = joints0[i];
144
+ let w = normalizedWeights[i];
145
+ let m = skinMats[j];
146
+ skinnedPos += (m * pos4) * w;
147
+ let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
148
+ skinnedNrm += (r3 * normal) * w;
149
+ }
150
+ let worldPos = skinnedPos.xyz;
151
+ output.position = camera.projection * camera.view * vec4f(worldPos, 1.0);
152
+ output.normal = normalize(skinnedNrm);
153
+ output.uv = uv;
154
+ output.worldPos = worldPos;
155
+ return output;
156
+ }
157
+
158
+ @fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
159
+ let n = normalize(input.normal);
160
+ let albedo = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
161
+
162
+ var lightAccum = vec3f(light.ambient);
163
+ let numLights = u32(light.lightCount);
164
+ for (var i = 0u; i < numLights; i++) {
165
+ let l = -light.lights[i].direction;
166
+ let nDotL = max(dot(n, l), 0.0);
167
+ let toonUV = vec2f(nDotL, 0.5);
168
+ let toonFactor = textureSample(toonTexture, toonSampler, toonUV).rgb;
169
+ let radiance = light.lights[i].color * light.lights[i].intensity;
170
+ lightAccum += toonFactor * radiance * nDotL;
171
+ }
172
+
173
+ let color = albedo * lightAccum;
174
+ let finalAlpha = material.alpha;
175
+ if (finalAlpha < 0.001) {
176
+ discard;
177
+ }
178
+
179
+ return vec4f(clamp(color, vec3f(0.0), vec3f(1.0)), finalAlpha);
180
+ }
181
181
  `,
182
182
  });
183
183
  // Create a separate shader for hair-over-eyes that outputs pre-multiplied color for darkening effect
184
184
  const hairMultiplyShaderModule = this.device.createShaderModule({
185
185
  label: "hair multiply shaders",
186
- code: /* wgsl */ `
187
- struct CameraUniforms {
188
- view: mat4x4f,
189
- projection: mat4x4f,
190
- viewPos: vec3f,
191
- _padding: f32,
192
- };
193
-
194
- struct Light {
195
- direction: vec3f,
196
- _padding1: f32,
197
- color: vec3f,
198
- intensity: f32,
199
- };
200
-
201
- struct LightUniforms {
202
- ambient: f32,
203
- lightCount: f32,
204
- _padding1: f32,
205
- _padding2: f32,
206
- lights: array<Light, 4>,
207
- };
208
-
209
- struct MaterialUniforms {
210
- alpha: f32,
211
- _padding1: f32,
212
- _padding2: f32,
213
- _padding3: f32,
214
- };
215
-
216
- struct VertexOutput {
217
- @builtin(position) position: vec4f,
218
- @location(0) normal: vec3f,
219
- @location(1) uv: vec2f,
220
- @location(2) worldPos: vec3f,
221
- };
222
-
223
- @group(0) @binding(0) var<uniform> camera: CameraUniforms;
224
- @group(0) @binding(1) var<uniform> light: LightUniforms;
225
- @group(0) @binding(2) var diffuseTexture: texture_2d<f32>;
226
- @group(0) @binding(3) var diffuseSampler: sampler;
227
- @group(0) @binding(4) var<storage, read> skinMats: array<mat4x4f>;
228
- @group(0) @binding(5) var toonTexture: texture_2d<f32>;
229
- @group(0) @binding(6) var toonSampler: sampler;
230
- @group(0) @binding(7) var<uniform> material: MaterialUniforms;
231
-
232
- @vertex fn vs(
233
- @location(0) position: vec3f,
234
- @location(1) normal: vec3f,
235
- @location(2) uv: vec2f,
236
- @location(3) joints0: vec4<u32>,
237
- @location(4) weights0: vec4<f32>
238
- ) -> VertexOutput {
239
- var output: VertexOutput;
240
- let pos4 = vec4f(position, 1.0);
241
-
242
- let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
243
- var normalizedWeights: vec4f;
244
- if (weightSum > 0.0001) {
245
- normalizedWeights = weights0 / weightSum;
246
- } else {
247
- normalizedWeights = vec4f(1.0, 0.0, 0.0, 0.0);
248
- }
249
-
250
- var skinnedPos = vec4f(0.0, 0.0, 0.0, 0.0);
251
- var skinnedNrm = vec3f(0.0, 0.0, 0.0);
252
- for (var i = 0u; i < 4u; i++) {
253
- let j = joints0[i];
254
- let w = normalizedWeights[i];
255
- let m = skinMats[j];
256
- skinnedPos += (m * pos4) * w;
257
- let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
258
- skinnedNrm += (r3 * normal) * w;
259
- }
260
- let worldPos = skinnedPos.xyz;
261
- output.position = camera.projection * camera.view * vec4f(worldPos, 1.0);
262
- output.normal = normalize(skinnedNrm);
263
- output.uv = uv;
264
- output.worldPos = worldPos;
265
- return output;
266
- }
267
-
268
- @fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
269
- let n = normalize(input.normal);
270
- let albedo = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
271
-
272
- var lightAccum = vec3f(light.ambient);
273
- let numLights = u32(light.lightCount);
274
- for (var i = 0u; i < numLights; i++) {
275
- let l = -light.lights[i].direction;
276
- let nDotL = max(dot(n, l), 0.0);
277
- let toonUV = vec2f(nDotL, 0.5);
278
- let toonFactor = textureSample(toonTexture, toonSampler, toonUV).rgb;
279
- let radiance = light.lights[i].color * light.lights[i].intensity;
280
- lightAccum += toonFactor * radiance * nDotL;
281
- }
282
-
283
- let color = albedo * lightAccum;
284
- let finalAlpha = material.alpha;
285
- if (finalAlpha < 0.001) {
286
- discard;
287
- }
288
-
289
- // For hair-over-eyes effect: simple half-transparent overlay
290
- // Use 60% opacity to create a semi-transparent hair color overlay
291
- let overlayAlpha = finalAlpha * 0.6;
292
-
293
- return vec4f(clamp(color, vec3f(0.0), vec3f(1.0)), overlayAlpha);
294
- }
186
+ code: /* wgsl */ `
187
+ struct CameraUniforms {
188
+ view: mat4x4f,
189
+ projection: mat4x4f,
190
+ viewPos: vec3f,
191
+ _padding: f32,
192
+ };
193
+
194
+ struct Light {
195
+ direction: vec3f,
196
+ _padding1: f32,
197
+ color: vec3f,
198
+ intensity: f32,
199
+ };
200
+
201
+ struct LightUniforms {
202
+ ambient: f32,
203
+ lightCount: f32,
204
+ _padding1: f32,
205
+ _padding2: f32,
206
+ lights: array<Light, 4>,
207
+ };
208
+
209
+ struct MaterialUniforms {
210
+ alpha: f32,
211
+ _padding1: f32,
212
+ _padding2: f32,
213
+ _padding3: f32,
214
+ };
215
+
216
+ struct VertexOutput {
217
+ @builtin(position) position: vec4f,
218
+ @location(0) normal: vec3f,
219
+ @location(1) uv: vec2f,
220
+ @location(2) worldPos: vec3f,
221
+ };
222
+
223
+ @group(0) @binding(0) var<uniform> camera: CameraUniforms;
224
+ @group(0) @binding(1) var<uniform> light: LightUniforms;
225
+ @group(0) @binding(2) var diffuseTexture: texture_2d<f32>;
226
+ @group(0) @binding(3) var diffuseSampler: sampler;
227
+ @group(0) @binding(4) var<storage, read> skinMats: array<mat4x4f>;
228
+ @group(0) @binding(5) var toonTexture: texture_2d<f32>;
229
+ @group(0) @binding(6) var toonSampler: sampler;
230
+ @group(0) @binding(7) var<uniform> material: MaterialUniforms;
231
+
232
+ @vertex fn vs(
233
+ @location(0) position: vec3f,
234
+ @location(1) normal: vec3f,
235
+ @location(2) uv: vec2f,
236
+ @location(3) joints0: vec4<u32>,
237
+ @location(4) weights0: vec4<f32>
238
+ ) -> VertexOutput {
239
+ var output: VertexOutput;
240
+ let pos4 = vec4f(position, 1.0);
241
+
242
+ let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
243
+ var normalizedWeights: vec4f;
244
+ if (weightSum > 0.0001) {
245
+ normalizedWeights = weights0 / weightSum;
246
+ } else {
247
+ normalizedWeights = vec4f(1.0, 0.0, 0.0, 0.0);
248
+ }
249
+
250
+ var skinnedPos = vec4f(0.0, 0.0, 0.0, 0.0);
251
+ var skinnedNrm = vec3f(0.0, 0.0, 0.0);
252
+ for (var i = 0u; i < 4u; i++) {
253
+ let j = joints0[i];
254
+ let w = normalizedWeights[i];
255
+ let m = skinMats[j];
256
+ skinnedPos += (m * pos4) * w;
257
+ let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
258
+ skinnedNrm += (r3 * normal) * w;
259
+ }
260
+ let worldPos = skinnedPos.xyz;
261
+ output.position = camera.projection * camera.view * vec4f(worldPos, 1.0);
262
+ output.normal = normalize(skinnedNrm);
263
+ output.uv = uv;
264
+ output.worldPos = worldPos;
265
+ return output;
266
+ }
267
+
268
+ @fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
269
+ let n = normalize(input.normal);
270
+ let albedo = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
271
+
272
+ var lightAccum = vec3f(light.ambient);
273
+ let numLights = u32(light.lightCount);
274
+ for (var i = 0u; i < numLights; i++) {
275
+ let l = -light.lights[i].direction;
276
+ let nDotL = max(dot(n, l), 0.0);
277
+ let toonUV = vec2f(nDotL, 0.5);
278
+ let toonFactor = textureSample(toonTexture, toonSampler, toonUV).rgb;
279
+ let radiance = light.lights[i].color * light.lights[i].intensity;
280
+ lightAccum += toonFactor * radiance * nDotL;
281
+ }
282
+
283
+ let color = albedo * lightAccum;
284
+ let finalAlpha = material.alpha;
285
+ if (finalAlpha < 0.001) {
286
+ discard;
287
+ }
288
+
289
+ // For hair-over-eyes effect: simple half-transparent overlay
290
+ // Use 50% opacity to create a semi-transparent hair color overlay
291
+ let overlayAlpha = finalAlpha * 0.5;
292
+
293
+ return vec4f(clamp(color, vec3f(0.0), vec3f(1.0)), overlayAlpha);
294
+ }
295
295
  `,
296
296
  });
297
297
  // Create explicit bind group layout for all pipelines using the main shader
@@ -383,72 +383,72 @@ export class Engine {
383
383
  });
384
384
  const outlineShaderModule = this.device.createShaderModule({
385
385
  label: "outline shaders",
386
- code: /* wgsl */ `
387
- struct CameraUniforms {
388
- view: mat4x4f,
389
- projection: mat4x4f,
390
- viewPos: vec3f,
391
- _padding: f32,
392
- };
393
-
394
- struct MaterialUniforms {
395
- edgeColor: vec4f,
396
- edgeSize: f32,
397
- _padding1: f32,
398
- _padding2: f32,
399
- _padding3: f32,
400
- };
401
-
402
- @group(0) @binding(0) var<uniform> camera: CameraUniforms;
403
- @group(0) @binding(1) var<uniform> material: MaterialUniforms;
404
- @group(0) @binding(2) var<storage, read> skinMats: array<mat4x4f>;
405
-
406
- struct VertexOutput {
407
- @builtin(position) position: vec4f,
408
- };
409
-
410
- @vertex fn vs(
411
- @location(0) position: vec3f,
412
- @location(1) normal: vec3f,
413
- @location(2) uv: vec2f,
414
- @location(3) joints0: vec4<u32>,
415
- @location(4) weights0: vec4<f32>
416
- ) -> VertexOutput {
417
- var output: VertexOutput;
418
- let pos4 = vec4f(position, 1.0);
419
-
420
- // Normalize weights to ensure they sum to 1.0 (handles floating-point precision issues)
421
- let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
422
- var normalizedWeights: vec4f;
423
- if (weightSum > 0.0001) {
424
- normalizedWeights = weights0 / weightSum;
425
- } else {
426
- normalizedWeights = vec4f(1.0, 0.0, 0.0, 0.0);
427
- }
428
-
429
- var skinnedPos = vec4f(0.0, 0.0, 0.0, 0.0);
430
- var skinnedNrm = vec3f(0.0, 0.0, 0.0);
431
- for (var i = 0u; i < 4u; i++) {
432
- let j = joints0[i];
433
- let w = normalizedWeights[i];
434
- let m = skinMats[j];
435
- skinnedPos += (m * pos4) * w;
436
- let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
437
- skinnedNrm += (r3 * normal) * w;
438
- }
439
- let worldPos = skinnedPos.xyz;
440
- let worldNormal = normalize(skinnedNrm);
441
-
442
- // MMD invert hull: expand vertices outward along normals
443
- let scaleFactor = 0.01;
444
- let expandedPos = worldPos + worldNormal * material.edgeSize * scaleFactor;
445
- output.position = camera.projection * camera.view * vec4f(expandedPos, 1.0);
446
- return output;
447
- }
448
-
449
- @fragment fn fs() -> @location(0) vec4f {
450
- return material.edgeColor;
451
- }
386
+ code: /* wgsl */ `
387
+ struct CameraUniforms {
388
+ view: mat4x4f,
389
+ projection: mat4x4f,
390
+ viewPos: vec3f,
391
+ _padding: f32,
392
+ };
393
+
394
+ struct MaterialUniforms {
395
+ edgeColor: vec4f,
396
+ edgeSize: f32,
397
+ _padding1: f32,
398
+ _padding2: f32,
399
+ _padding3: f32,
400
+ };
401
+
402
+ @group(0) @binding(0) var<uniform> camera: CameraUniforms;
403
+ @group(0) @binding(1) var<uniform> material: MaterialUniforms;
404
+ @group(0) @binding(2) var<storage, read> skinMats: array<mat4x4f>;
405
+
406
+ struct VertexOutput {
407
+ @builtin(position) position: vec4f,
408
+ };
409
+
410
+ @vertex fn vs(
411
+ @location(0) position: vec3f,
412
+ @location(1) normal: vec3f,
413
+ @location(2) uv: vec2f,
414
+ @location(3) joints0: vec4<u32>,
415
+ @location(4) weights0: vec4<f32>
416
+ ) -> VertexOutput {
417
+ var output: VertexOutput;
418
+ let pos4 = vec4f(position, 1.0);
419
+
420
+ // Normalize weights to ensure they sum to 1.0 (handles floating-point precision issues)
421
+ let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
422
+ var normalizedWeights: vec4f;
423
+ if (weightSum > 0.0001) {
424
+ normalizedWeights = weights0 / weightSum;
425
+ } else {
426
+ normalizedWeights = vec4f(1.0, 0.0, 0.0, 0.0);
427
+ }
428
+
429
+ var skinnedPos = vec4f(0.0, 0.0, 0.0, 0.0);
430
+ var skinnedNrm = vec3f(0.0, 0.0, 0.0);
431
+ for (var i = 0u; i < 4u; i++) {
432
+ let j = joints0[i];
433
+ let w = normalizedWeights[i];
434
+ let m = skinMats[j];
435
+ skinnedPos += (m * pos4) * w;
436
+ let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
437
+ skinnedNrm += (r3 * normal) * w;
438
+ }
439
+ let worldPos = skinnedPos.xyz;
440
+ let worldNormal = normalize(skinnedNrm);
441
+
442
+ // MMD invert hull: expand vertices outward along normals
443
+ let scaleFactor = 0.01;
444
+ let expandedPos = worldPos + worldNormal * material.edgeSize * scaleFactor;
445
+ output.position = camera.projection * camera.view * vec4f(expandedPos, 1.0);
446
+ return output;
447
+ }
448
+
449
+ @fragment fn fs() -> @location(0) vec4f {
450
+ return material.edgeColor;
451
+ }
452
452
  `,
453
453
  });
454
454
  this.outlinePipeline = this.device.createRenderPipeline({
@@ -888,31 +888,31 @@ export class Engine {
888
888
  createSkinMatrixComputePipeline() {
889
889
  const computeShader = this.device.createShaderModule({
890
890
  label: "skin matrix compute",
891
- code: /* wgsl */ `
892
- struct BoneCountUniform {
893
- count: u32,
894
- _padding1: u32,
895
- _padding2: u32,
896
- _padding3: u32,
897
- _padding4: vec4<u32>,
898
- };
899
-
900
- @group(0) @binding(0) var<uniform> boneCount: BoneCountUniform;
901
- @group(0) @binding(1) var<storage, read> worldMatrices: array<mat4x4f>;
902
- @group(0) @binding(2) var<storage, read> inverseBindMatrices: array<mat4x4f>;
903
- @group(0) @binding(3) var<storage, read_write> skinMatrices: array<mat4x4f>;
904
-
905
- @compute @workgroup_size(64)
906
- fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
907
- let boneIndex = globalId.x;
908
- // Bounds check: we dispatch workgroups (64 threads each), so some threads may be out of range
909
- if (boneIndex >= boneCount.count) {
910
- return;
911
- }
912
- let worldMat = worldMatrices[boneIndex];
913
- let invBindMat = inverseBindMatrices[boneIndex];
914
- skinMatrices[boneIndex] = worldMat * invBindMat;
915
- }
891
+ code: /* wgsl */ `
892
+ struct BoneCountUniform {
893
+ count: u32,
894
+ _padding1: u32,
895
+ _padding2: u32,
896
+ _padding3: u32,
897
+ _padding4: vec4<u32>,
898
+ };
899
+
900
+ @group(0) @binding(0) var<uniform> boneCount: BoneCountUniform;
901
+ @group(0) @binding(1) var<storage, read> worldMatrices: array<mat4x4f>;
902
+ @group(0) @binding(2) var<storage, read> inverseBindMatrices: array<mat4x4f>;
903
+ @group(0) @binding(3) var<storage, read_write> skinMatrices: array<mat4x4f>;
904
+
905
+ @compute @workgroup_size(64)
906
+ fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
907
+ let boneIndex = globalId.x;
908
+ // Bounds check: we dispatch workgroups (64 threads each), so some threads may be out of range
909
+ if (boneIndex >= boneCount.count) {
910
+ return;
911
+ }
912
+ let worldMat = worldMatrices[boneIndex];
913
+ let invBindMat = inverseBindMatrices[boneIndex];
914
+ skinMatrices[boneIndex] = worldMat * invBindMat;
915
+ }
916
916
  `,
917
917
  });
918
918
  this.skinMatrixComputePipeline = this.device.createComputePipeline({
@@ -1389,7 +1389,7 @@ export class Engine {
1389
1389
  pass.setIndexBuffer(this.indexBuffer, "uint32");
1390
1390
  this.drawCallCount = 0;
1391
1391
  // === PASS 1: Opaque non-eye, non-hair (face, body, etc) ===
1392
- this.drawOutlines(pass, false); // Opaque outlines
1392
+ // this.drawOutlines(pass, false) // Opaque outlines
1393
1393
  pass.setPipeline(this.pipeline);
1394
1394
  for (const draw of this.opaqueNonEyeNonHairDraws) {
1395
1395
  if (draw.count > 0) {
@@ -1450,6 +1450,7 @@ export class Engine {
1450
1450
  pass.drawIndexed(draw.count, 1, draw.firstIndex, 0, 0);
1451
1451
  }
1452
1452
  }
1453
+ this.drawOutlines(pass, false); // Opaque outlines
1453
1454
  // === PASS 4: Transparent non-eye, non-hair ===
1454
1455
  pass.setPipeline(this.pipeline);
1455
1456
  for (const draw of this.transparentNonEyeNonHairDraws) {
@@ -1 +1 @@
1
- {"version":3,"file":"pmx-loader.d.ts","sourceRoot":"","sources":["../src/pmx-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA+C,MAAM,SAAS,CAAA;AAI5E,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO;WAIM,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAK9C,OAAO,CAAC,KAAK;IAgBb,OAAO,CAAC,WAAW;IA+CnB,OAAO,CAAC,aAAa;IA+FrB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IA+FtB,OAAO,CAAC,UAAU;IA2IlB,OAAO,CAAC,UAAU;IAyGlB,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,gBAAgB;IAyFxB,OAAO,CAAC,WAAW;IAmGnB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,OAAO;IA2If,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,QAAQ;CAIjB"}
1
+ {"version":3,"file":"pmx-loader.d.ts","sourceRoot":"","sources":["../src/pmx-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA+C,MAAM,SAAS,CAAA;AAI5E,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO;WAIM,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAK9C,OAAO,CAAC,KAAK;IAgBb,OAAO,CAAC,WAAW;IA+CnB,OAAO,CAAC,aAAa;IA+FrB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAyFtB,OAAO,CAAC,UAAU;IA2IlB,OAAO,CAAC,UAAU;IAyGlB,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,gBAAgB;IAyFxB,OAAO,CAAC,WAAW;IAmGnB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,OAAO;IA2If,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,QAAQ;CAIjB"}