reze-engine 0.1.10 → 0.1.12
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/README.md +104 -99
- package/dist/engine.d.ts +3 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +73 -13
- package/package.json +2 -2
- package/src/camera.ts +358 -358
- package/src/engine.ts +76 -13
- package/src/math.ts +546 -546
- package/src/model.ts +421 -421
- package/src/physics.ts +680 -680
- package/src/pmx-loader.ts +1054 -1054
package/README.md
CHANGED
|
@@ -1,99 +1,104 @@
|
|
|
1
|
-
# Reze Engine
|
|
2
|
-
|
|
3
|
-
A lightweight engine built with WebGPU and TypeScript for real-time 3D anime character MMD model rendering.
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const [
|
|
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
|
-
<div className="absolute inset-0
|
|
92
|
-
|
|
93
|
-
</div>
|
|
94
|
-
)}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
# Reze Engine
|
|
2
|
+
|
|
3
|
+
A lightweight engine built with WebGPU and TypeScript for real-time 3D anime character MMD model rendering.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Physics
|
|
8
|
+
- Alpha blending
|
|
9
|
+
- Post alpha eye rendering
|
|
10
|
+
- Rim lighting
|
|
11
|
+
- Bloom
|
|
12
|
+
- Outlines
|
|
13
|
+
- Toon shading with directional lights
|
|
14
|
+
- MSAA 4x anti-aliasing
|
|
15
|
+
- GPU-accelerated skinning
|
|
16
|
+
- Bone rotation api
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
export default function Home() {
|
|
22
|
+
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
23
|
+
const engineRef = useRef<Engine | null>(null)
|
|
24
|
+
const [engineError, setEngineError] = useState<string | null>(null)
|
|
25
|
+
const [loading, setLoading] = useState(true)
|
|
26
|
+
const [stats, setStats] = useState<EngineStats>({
|
|
27
|
+
fps: 0,
|
|
28
|
+
frameTime: 0,
|
|
29
|
+
gpuMemory: 0,
|
|
30
|
+
})
|
|
31
|
+
const [progress, setProgress] = useState(0)
|
|
32
|
+
|
|
33
|
+
const initEngine = useCallback(async () => {
|
|
34
|
+
if (canvasRef.current) {
|
|
35
|
+
// Initialize engine
|
|
36
|
+
try {
|
|
37
|
+
const engine = new Engine(canvasRef.current)
|
|
38
|
+
engineRef.current = engine
|
|
39
|
+
await engine.init()
|
|
40
|
+
await engine.loadModel("/models/塞尔凯特/塞尔凯特.pmx")
|
|
41
|
+
setLoading(false)
|
|
42
|
+
|
|
43
|
+
engine.runRenderLoop(() => {
|
|
44
|
+
setStats(engine.getStats())
|
|
45
|
+
})
|
|
46
|
+
} catch (error) {
|
|
47
|
+
setEngineError(error instanceof Error ? error.message : "Unknown error")
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, [])
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
void (async () => {
|
|
54
|
+
initEngine()
|
|
55
|
+
})()
|
|
56
|
+
|
|
57
|
+
// Cleanup on unmount
|
|
58
|
+
return () => {
|
|
59
|
+
if (engineRef.current) {
|
|
60
|
+
engineRef.current.dispose()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}, [initEngine])
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (loading) {
|
|
67
|
+
const interval = setInterval(() => {
|
|
68
|
+
setProgress((prev) => {
|
|
69
|
+
if (prev >= 100) {
|
|
70
|
+
return 0
|
|
71
|
+
}
|
|
72
|
+
return prev + 1
|
|
73
|
+
})
|
|
74
|
+
}, 50)
|
|
75
|
+
|
|
76
|
+
return () => clearInterval(interval)
|
|
77
|
+
}
|
|
78
|
+
}, [loading])
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div
|
|
82
|
+
className="fixed inset-0 w-full h-full overflow-hidden touch-none"
|
|
83
|
+
style={{
|
|
84
|
+
background:
|
|
85
|
+
"radial-gradient(ellipse at center, rgba(35, 35, 45, 0.8) 0%, rgba(35, 35, 45, 0.8) 8%, rgba(8, 8, 12, 0.95) 65%, rgba(0, 0, 0, 1) 100%)",
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<Header stats={stats} />
|
|
89
|
+
|
|
90
|
+
{engineError && (
|
|
91
|
+
<div className="absolute inset-0 w-full h-full flex items-center justify-center text-white p-6">
|
|
92
|
+
Engine Error: {engineError}
|
|
93
|
+
</div>
|
|
94
|
+
)}
|
|
95
|
+
{loading && !engineError && (
|
|
96
|
+
<div className="absolute inset-0 max-w-xs mx-auto w-full h-full flex items-center justify-center text-white p-6">
|
|
97
|
+
<Progress value={progress} className="rounded-none" />
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
<canvas ref={canvasRef} className="absolute inset-0 w-full h-full touch-none z-1" />
|
|
101
|
+
</div>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
```
|
package/dist/engine.d.ts
CHANGED
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAKnC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,kBAAkB,CAAmB;IACtC,MAAM,EAAG,MAAM,CAAA;IACtB,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,WAAW,CAAC,CAAW;IAC/B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,mBAAmB,CAAoB;IAC/C,OAAO,CAAC,2BAA2B,CAAoB;IACvD,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,sBAAsB,CAAqB;IACnD,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,gBAAgB,CAAC,CAAW;IACpC,OAAO,CAAC,iBAAiB,CAAC,CAAW;IACrC,OAAO,CAAC,uBAAuB,CAAC,CAAW;IAC3C,OAAO,CAAC,yBAAyB,CAAC,CAAoB;IACtD,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAI;IAChC,OAAO,CAAC,oBAAoB,CAA0B;IAEtD,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,sBAAsB,CAAiB;IAC/C,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,iBAAiB,CAAa;IAEtC,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,oBAAoB,CAAoB;IAEhD,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,aAAa,CAAa;IAE3B,cAAc,EAAE,MAAM,CAAM;IAC5B,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -11,7 +11,11 @@ export class Engine {
|
|
|
11
11
|
this.sampleCount = 4; // MSAA 4x
|
|
12
12
|
// Bloom settings
|
|
13
13
|
this.bloomThreshold = 0.3;
|
|
14
|
-
this.bloomIntensity = 0.
|
|
14
|
+
this.bloomIntensity = 0.1;
|
|
15
|
+
// Rim light settings
|
|
16
|
+
this.rimLightIntensity = 0.35;
|
|
17
|
+
this.rimLightPower = 2.0;
|
|
18
|
+
this.rimLightColor = [1.0, 1.0, 1.0];
|
|
15
19
|
this.currentModel = null;
|
|
16
20
|
this.modelDir = "";
|
|
17
21
|
this.physics = null;
|
|
@@ -102,9 +106,11 @@ export class Engine {
|
|
|
102
106
|
|
|
103
107
|
struct MaterialUniforms {
|
|
104
108
|
alpha: f32,
|
|
109
|
+
rimIntensity: f32,
|
|
110
|
+
rimPower: f32,
|
|
105
111
|
_padding1: f32,
|
|
112
|
+
rimColor: vec3f,
|
|
106
113
|
_padding2: f32,
|
|
107
|
-
_padding3: f32,
|
|
108
114
|
};
|
|
109
115
|
|
|
110
116
|
struct VertexOutput {
|
|
@@ -175,7 +181,13 @@ export class Engine {
|
|
|
175
181
|
lightAccum += toonFactor * radiance * nDotL;
|
|
176
182
|
}
|
|
177
183
|
|
|
178
|
-
|
|
184
|
+
// Rim light calculation
|
|
185
|
+
let viewDir = normalize(camera.viewPos - input.worldPos);
|
|
186
|
+
var rimFactor = 1.0 - max(dot(n, viewDir), 0.0);
|
|
187
|
+
rimFactor = pow(rimFactor, material.rimPower);
|
|
188
|
+
let rimLight = material.rimColor * material.rimIntensity * rimFactor;
|
|
189
|
+
|
|
190
|
+
let color = albedo * lightAccum + rimLight;
|
|
179
191
|
let finalAlpha = material.alpha;
|
|
180
192
|
if (finalAlpha < 0.001) {
|
|
181
193
|
discard;
|
|
@@ -215,8 +227,10 @@ export class Engine {
|
|
|
215
227
|
struct MaterialUniforms {
|
|
216
228
|
alpha: f32,
|
|
217
229
|
alphaMultiplier: f32, // New: multiplier for alpha (0.5 for over-eyes, 1.0 for over-non-eyes)
|
|
230
|
+
rimIntensity: f32,
|
|
231
|
+
rimPower: f32,
|
|
232
|
+
rimColor: vec3f,
|
|
218
233
|
_padding1: f32,
|
|
219
|
-
_padding2: f32,
|
|
220
234
|
};
|
|
221
235
|
|
|
222
236
|
struct VertexOutput {
|
|
@@ -286,7 +300,13 @@ export class Engine {
|
|
|
286
300
|
lightAccum += toonFactor * radiance * nDotL;
|
|
287
301
|
}
|
|
288
302
|
|
|
289
|
-
|
|
303
|
+
// Rim light calculation
|
|
304
|
+
let viewDir = normalize(camera.viewPos - input.worldPos);
|
|
305
|
+
var rimFactor = 1.0 - max(dot(n, viewDir), 0.0);
|
|
306
|
+
rimFactor = pow(rimFactor, material.rimPower);
|
|
307
|
+
let rimLight = material.rimColor * material.rimIntensity * rimFactor;
|
|
308
|
+
|
|
309
|
+
let color = albedo * lightAccum + rimLight;
|
|
290
310
|
let finalAlpha = material.alpha * material.alphaMultiplier;
|
|
291
311
|
if (finalAlpha < 0.001) {
|
|
292
312
|
discard;
|
|
@@ -1501,11 +1521,16 @@ export class Engine {
|
|
|
1501
1521
|
const EPSILON = 0.001;
|
|
1502
1522
|
const isTransparent = materialAlpha < 1.0 - EPSILON;
|
|
1503
1523
|
// Create material uniform data - for hair materials, we'll create two versions
|
|
1504
|
-
|
|
1524
|
+
// MaterialUniforms struct: alpha, rimIntensity, rimPower, _padding1, rimColor (vec3), _padding2
|
|
1525
|
+
const materialUniformData = new Float32Array(8);
|
|
1505
1526
|
materialUniformData[0] = materialAlpha;
|
|
1506
|
-
materialUniformData[1] =
|
|
1507
|
-
materialUniformData[2] =
|
|
1508
|
-
materialUniformData[3] = 0.0;
|
|
1527
|
+
materialUniformData[1] = this.rimLightIntensity;
|
|
1528
|
+
materialUniformData[2] = this.rimLightPower;
|
|
1529
|
+
materialUniformData[3] = 0.0; // _padding1
|
|
1530
|
+
materialUniformData[4] = this.rimLightColor[0]; // rimColor.r
|
|
1531
|
+
materialUniformData[5] = this.rimLightColor[1]; // rimColor.g
|
|
1532
|
+
materialUniformData[6] = this.rimLightColor[2]; // rimColor.b
|
|
1533
|
+
materialUniformData[7] = 0.0; // _padding2
|
|
1509
1534
|
const materialUniformBuffer = this.device.createBuffer({
|
|
1510
1535
|
label: `material uniform: ${mat.name}`,
|
|
1511
1536
|
size: materialUniformData.byteLength,
|
|
@@ -1538,11 +1563,16 @@ export class Engine {
|
|
|
1538
1563
|
}
|
|
1539
1564
|
else if (mat.isHair) {
|
|
1540
1565
|
// For hair materials, create two bind groups: one for over-eyes (alphaMultiplier = 0.5) and one for over-non-eyes (alphaMultiplier = 1.0)
|
|
1541
|
-
|
|
1566
|
+
// Hair MaterialUniforms struct: alpha, alphaMultiplier, rimIntensity, rimPower, rimColor (vec3), _padding1
|
|
1567
|
+
const materialUniformDataOverEyes = new Float32Array(8);
|
|
1542
1568
|
materialUniformDataOverEyes[0] = materialAlpha;
|
|
1543
1569
|
materialUniformDataOverEyes[1] = 0.5; // alphaMultiplier: 0.5 for over-eyes
|
|
1544
|
-
materialUniformDataOverEyes[2] =
|
|
1545
|
-
materialUniformDataOverEyes[3] =
|
|
1570
|
+
materialUniformDataOverEyes[2] = this.rimLightIntensity;
|
|
1571
|
+
materialUniformDataOverEyes[3] = this.rimLightPower;
|
|
1572
|
+
materialUniformDataOverEyes[4] = this.rimLightColor[0]; // rimColor.r
|
|
1573
|
+
materialUniformDataOverEyes[5] = this.rimLightColor[1]; // rimColor.g
|
|
1574
|
+
materialUniformDataOverEyes[6] = this.rimLightColor[2]; // rimColor.b
|
|
1575
|
+
materialUniformDataOverEyes[7] = 0.0; // _padding1
|
|
1546
1576
|
const materialUniformBufferOverEyes = this.device.createBuffer({
|
|
1547
1577
|
label: `material uniform (over eyes): ${mat.name}`,
|
|
1548
1578
|
size: materialUniformDataOverEyes.byteLength,
|
|
@@ -1569,10 +1599,40 @@ export class Engine {
|
|
|
1569
1599
|
bindGroup: bindGroupOverEyes,
|
|
1570
1600
|
isTransparent,
|
|
1571
1601
|
});
|
|
1602
|
+
// Create material uniform for hair over non-eyes (alphaMultiplier = 1.0)
|
|
1603
|
+
const materialUniformDataOverNonEyes = new Float32Array(8);
|
|
1604
|
+
materialUniformDataOverNonEyes[0] = materialAlpha;
|
|
1605
|
+
materialUniformDataOverNonEyes[1] = 1.0; // alphaMultiplier: 1.0 for over-non-eyes
|
|
1606
|
+
materialUniformDataOverNonEyes[2] = this.rimLightIntensity;
|
|
1607
|
+
materialUniformDataOverNonEyes[3] = this.rimLightPower;
|
|
1608
|
+
materialUniformDataOverNonEyes[4] = this.rimLightColor[0]; // rimColor.r
|
|
1609
|
+
materialUniformDataOverNonEyes[5] = this.rimLightColor[1]; // rimColor.g
|
|
1610
|
+
materialUniformDataOverNonEyes[6] = this.rimLightColor[2]; // rimColor.b
|
|
1611
|
+
materialUniformDataOverNonEyes[7] = 0.0; // _padding1
|
|
1612
|
+
const materialUniformBufferOverNonEyes = this.device.createBuffer({
|
|
1613
|
+
label: `material uniform (over non-eyes): ${mat.name}`,
|
|
1614
|
+
size: materialUniformDataOverNonEyes.byteLength,
|
|
1615
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
1616
|
+
});
|
|
1617
|
+
this.device.queue.writeBuffer(materialUniformBufferOverNonEyes, 0, materialUniformDataOverNonEyes);
|
|
1618
|
+
const bindGroupOverNonEyes = this.device.createBindGroup({
|
|
1619
|
+
label: `material bind group (over non-eyes): ${mat.name}`,
|
|
1620
|
+
layout: this.hairBindGroupLayout,
|
|
1621
|
+
entries: [
|
|
1622
|
+
{ binding: 0, resource: { buffer: this.cameraUniformBuffer } },
|
|
1623
|
+
{ binding: 1, resource: { buffer: this.lightUniformBuffer } },
|
|
1624
|
+
{ binding: 2, resource: diffuseTexture.createView() },
|
|
1625
|
+
{ binding: 3, resource: this.textureSampler },
|
|
1626
|
+
{ binding: 4, resource: { buffer: this.skinMatrixBuffer } },
|
|
1627
|
+
{ binding: 5, resource: toonTexture.createView() },
|
|
1628
|
+
{ binding: 6, resource: this.textureSampler },
|
|
1629
|
+
{ binding: 7, resource: { buffer: materialUniformBufferOverNonEyes } },
|
|
1630
|
+
],
|
|
1631
|
+
});
|
|
1572
1632
|
this.hairDrawsOverNonEyes.push({
|
|
1573
1633
|
count: matCount,
|
|
1574
1634
|
firstIndex: runningFirstIndex,
|
|
1575
|
-
bindGroup,
|
|
1635
|
+
bindGroup: bindGroupOverNonEyes,
|
|
1576
1636
|
isTransparent,
|
|
1577
1637
|
});
|
|
1578
1638
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reze-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "A WebGPU-based MMD model renderer",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/
|
|
10
|
+
"url": "https://github.com/AmyangXYZ/reze-engine"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|