reze-engine 0.25.0 → 0.25.2
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 +5 -1
- package/dist/engine.d.ts +95 -16
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +205 -72
- package/dist/graph/slots.d.ts.map +1 -1
- package/dist/graph/slots.js +10 -2
- package/dist/shaders/materials/common.d.ts +1 -1
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +143 -141
- package/dist/shaders/passes/composite.d.ts.map +1 -1
- package/dist/shaders/passes/composite.js +18 -3
- package/dist/shaders/passes/depth-prepass.d.ts +2 -0
- package/dist/shaders/passes/depth-prepass.d.ts.map +1 -0
- package/dist/shaders/passes/depth-prepass.js +56 -0
- package/dist/shaders/passes/outline.d.ts +1 -1
- package/dist/shaders/passes/outline.d.ts.map +1 -1
- package/dist/shaders/passes/outline.js +50 -23
- package/package.json +1 -1
- package/src/engine.ts +220 -75
- package/src/graph/slots.ts +11 -2
- package/src/shaders/materials/common.ts +207 -205
- package/src/shaders/passes/composite.ts +23 -3
- package/src/shaders/passes/depth-prepass.ts +57 -0
- package/src/shaders/passes/outline.ts +50 -23
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
// MMD-style
|
|
2
|
-
//
|
|
1
|
+
// MMD-style inverted-hull outline, ported from babylon-mmd's mmdOutline shader
|
|
2
|
+
// (the reference implementation whose output matches MMD):
|
|
3
|
+
// 1. Extrude along the VIEW-SPACE normal's XY, normalized — a pure screen
|
|
4
|
+
// direction, so rims never smear toward the camera at grazing angles.
|
|
5
|
+
// 2. Offset in clip space by edgeSize · 4/viewport · w. The ×w cancels the
|
|
6
|
+
// perspective divide → CONSTANT screen thickness of exactly
|
|
7
|
+
// 2·edgeSize device pixels (babylon: `screenNormal / (viewport*0.25) *
|
|
8
|
+
// offset * projectedPosition.w`). PMX edgeSize ~0.3–1.0 ⇒ fine 0.6–2px
|
|
9
|
+
// rims, matching MMD instead of our former chunky constants.
|
|
10
|
+
// 3. The FRAGMENT stage samples the material's own diffuse texture and
|
|
11
|
+
// MODULATES the rim's alpha by it (discarding only near-zero cut-out
|
|
12
|
+
// margins) — sheer fabric gets a proportional rim, never a solid black
|
|
13
|
+
// hull, without dropping the author's edge flag.
|
|
3
14
|
|
|
4
15
|
export const OUTLINE_SHADER_WGSL = /* wgsl */ `
|
|
5
16
|
struct CameraUniforms {
|
|
6
17
|
view: mat4x4f,
|
|
7
18
|
projection: mat4x4f,
|
|
8
19
|
viewPos: vec3f,
|
|
9
|
-
|
|
20
|
+
// Render-target height in device pixels (engine writes it each frame);
|
|
21
|
+
// width is recovered via the projection matrix's aspect.
|
|
22
|
+
viewportHeight: f32,
|
|
10
23
|
};
|
|
11
24
|
|
|
12
25
|
struct MaterialUniforms {
|
|
@@ -18,16 +31,20 @@ struct MaterialUniforms {
|
|
|
18
31
|
};
|
|
19
32
|
|
|
20
33
|
@group(0) @binding(0) var<uniform> camera: CameraUniforms;
|
|
34
|
+
@group(0) @binding(1) var edgeSampler: sampler;
|
|
21
35
|
@group(1) @binding(0) var<storage, read> skinMats: array<mat4x4f>;
|
|
22
36
|
@group(2) @binding(0) var<uniform> material: MaterialUniforms;
|
|
37
|
+
@group(2) @binding(1) var diffuseTexture: texture_2d<f32>;
|
|
23
38
|
|
|
24
39
|
struct VertexOutput {
|
|
25
40
|
@builtin(position) position: vec4f,
|
|
41
|
+
@location(0) uv: vec2f,
|
|
26
42
|
};
|
|
27
43
|
|
|
28
44
|
@vertex fn vs(
|
|
29
45
|
@location(0) position: vec3f,
|
|
30
46
|
@location(1) normal: vec3f,
|
|
47
|
+
@location(2) uv: vec2f,
|
|
31
48
|
@location(3) joints0: vec4<u32>,
|
|
32
49
|
@location(4) weights0: vec4<f32>
|
|
33
50
|
) -> VertexOutput {
|
|
@@ -51,33 +68,43 @@ struct VertexOutput {
|
|
|
51
68
|
let worldPos = skinnedPos.xyz;
|
|
52
69
|
let worldNormal = normalize(skinnedNrm);
|
|
53
70
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// projection is column-major: proj[0][0] = 1/(aspect·tan(fov/2)), proj[1][1] = 1/tan(fov/2).
|
|
67
|
-
// Ratio proj[1][1]/proj[0][0] recovers the viewport aspect (width/height).
|
|
71
|
+
let clipPos = camera.projection * camera.view * vec4f(worldPos, 1.0);
|
|
72
|
+
|
|
73
|
+
// babylon-mmd: screenNormal = normalize((view * worldNormal).xy)
|
|
74
|
+
let viewNormal = (camera.view * vec4f(worldNormal, 0.0)).xyz;
|
|
75
|
+
let snLen = length(viewNormal.xy);
|
|
76
|
+
let screenNormal = select(vec2f(0.0, 0.0), viewNormal.xy / snLen, snLen > 1e-5);
|
|
77
|
+
|
|
78
|
+
// Reference-height normalization (babylon-mmd ships this variant commented
|
|
79
|
+
// out as \`renderHeight = 1080\`): thickness is a constant FRACTION of the
|
|
80
|
+
// frame — 2·edgeSize px at 1080p — so retina DPR and 4K export don't thin
|
|
81
|
+
// the rims to sub-pixel. Width follows the projection aspect.
|
|
82
|
+
// projection[1][1]/projection[0][0] = width/height for a symmetric frustum.
|
|
68
83
|
let aspect = camera.projection[1][1] / camera.projection[0][0];
|
|
69
|
-
let
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
84
|
+
let viewport = vec2f(1080.0 * aspect, 1080.0);
|
|
85
|
+
|
|
86
|
+
// NDC offset = edgeSize · 4/viewport, ×w so the perspective divide cancels:
|
|
87
|
+
// constant screen thickness at any distance (babylon-mmd parity).
|
|
88
|
+
let offset = screenNormal * (material.edgeSize * 4.0 / viewport) * clipPos.w;
|
|
73
89
|
output.position = vec4f(clipPos.xy + offset, clipPos.z, clipPos.w);
|
|
90
|
+
output.uv = uv;
|
|
74
91
|
return output;
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
struct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };
|
|
78
|
-
@fragment fn fs() -> FSOut {
|
|
95
|
+
@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
96
|
+
// Rim alpha FOLLOWS the fabric's texture alpha instead of a hard alpha test:
|
|
97
|
+
// MMD draws blend-material edges solid (only cutout materials alpha-test), so
|
|
98
|
+
// a 0.4 discard erased the whole hull on semi-transparent cloth — stockinged
|
|
99
|
+
// legs crossing lost their outline entirely. Modulating instead keeps a
|
|
100
|
+
// proportional rim on sheer weave (never a solid black hull) and still
|
|
101
|
+
// discards true cut-out margins like hair-card borders.
|
|
102
|
+
let texA = textureSample(diffuseTexture, edgeSampler, input.uv).a;
|
|
103
|
+
if (texA < 0.05) {
|
|
104
|
+
discard;
|
|
105
|
+
}
|
|
79
106
|
var out: FSOut;
|
|
80
|
-
out.color = material.edgeColor;
|
|
107
|
+
out.color = vec4f(material.edgeColor.rgb, material.edgeColor.a * texA);
|
|
81
108
|
out.mask = vec4f(1.0, 1.0, 0.0, out.color.a);
|
|
82
109
|
return out;
|
|
83
110
|
}
|