reze-engine 0.62.1 → 0.64.0
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.d.ts +95 -57
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +466 -162
- package/dist/graph/compile.d.ts.map +1 -1
- package/dist/graph/compile.js +4 -1
- package/dist/graph/registry.d.ts +3 -0
- package/dist/graph/registry.d.ts.map +1 -1
- package/dist/graph/registry.js +133 -0
- package/dist/graph/schema.d.ts +12 -0
- package/dist/graph/schema.d.ts.map +1 -1
- package/dist/graph/slots.d.ts.map +1 -1
- package/dist/graph/slots.js +11 -20
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/shaders/lights.d.ts +3 -2
- package/dist/shaders/lights.d.ts.map +1 -1
- package/dist/shaders/lights.js +16 -3
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +63 -56
- package/dist/shaders/materials/nodes.d.ts +1 -1
- package/dist/shaders/materials/nodes.d.ts.map +1 -1
- package/dist/shaders/materials/nodes.js +210 -0
- package/dist/shaders/passes/composite.d.ts.map +1 -1
- package/dist/shaders/passes/composite.js +13 -1
- package/dist/shaders/passes/cull.d.ts +1 -1
- package/dist/shaders/passes/cull.d.ts.map +1 -1
- package/dist/shaders/passes/cull.js +7 -3
- package/dist/shaders/passes/ground.d.ts.map +1 -1
- package/dist/shaders/passes/ground.js +32 -55
- package/dist/shaders/passes/particles.d.ts +11 -1
- package/dist/shaders/passes/particles.d.ts.map +1 -1
- package/dist/shaders/passes/particles.js +9 -4
- package/dist/shaders/scene-light-api.d.ts +18 -10
- package/dist/shaders/scene-light-api.d.ts.map +1 -1
- package/dist/shaders/scene-light-api.js +58 -46
- package/dist/shadow-cascades.d.ts +47 -20
- package/dist/shadow-cascades.d.ts.map +1 -1
- package/dist/shadow-cascades.js +36 -13
- package/dist/unity/character.d.ts +59 -0
- package/dist/unity/character.d.ts.map +1 -0
- package/dist/unity/character.js +120 -0
- package/dist/unity/globals.d.ts +93 -0
- package/dist/unity/globals.d.ts.map +1 -0
- package/dist/unity/globals.js +340 -0
- package/dist/unity/host.d.ts +137 -0
- package/dist/unity/host.d.ts.map +1 -0
- package/dist/unity/host.js +489 -0
- package/dist/unity/looks.d.ts +88 -0
- package/dist/unity/looks.d.ts.map +1 -0
- package/dist/unity/looks.js +295 -0
- package/dist/unity/skin.d.ts +9 -0
- package/dist/unity/skin.d.ts.map +1 -0
- package/dist/unity/skin.js +117 -0
- package/dist/unity/stage.d.ts +148 -0
- package/dist/unity/stage.d.ts.map +1 -0
- package/dist/unity/stage.js +375 -0
- package/dist/unity/state.d.ts +22 -0
- package/dist/unity/state.d.ts.map +1 -0
- package/dist/unity/state.js +170 -0
- package/package.json +1 -1
- package/src/engine.ts +504 -176
- package/src/graph/compile.ts +3 -1
- package/src/graph/registry.ts +142 -0
- package/src/graph/schema.ts +9 -0
- package/src/graph/slots.ts +11 -20
- package/src/index.ts +11 -0
- package/src/shaders/lights.ts +16 -3
- package/src/shaders/materials/common.ts +63 -57
- package/src/shaders/materials/nodes.ts +210 -0
- package/src/shaders/passes/composite.ts +13 -1
- package/src/shaders/passes/cull.ts +7 -3
- package/src/shaders/passes/ground.ts +32 -55
- package/src/shaders/passes/particles.ts +19 -5
- package/src/shaders/scene-light-api.ts +59 -46
- package/src/shadow-cascades.ts +61 -32
- package/src/unity/character.ts +169 -0
- package/src/unity/globals.ts +443 -0
- package/src/unity/host.ts +587 -0
- package/src/unity/looks.ts +372 -0
- package/src/unity/skin.ts +128 -0
- package/src/unity/stage.ts +568 -0
- package/src/unity/state.ts +172 -0
package/dist/shadow-cascades.js
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
import { Mat4, Vec3 } from "./math";
|
|
2
|
-
export const SHADOW_CASCADES = [{ mapSize: 4096 }, { mapSize: 2048 }];
|
|
3
|
-
/** How far past the camera's point of interest the near cascade reaches, in
|
|
4
|
-
* world units: the dancer and the floor around her, at the near map's texel. */
|
|
5
|
-
export const NEAR_REACH = 40;
|
|
6
2
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
3
|
+
* ONE ATLAS, FOUR TILES, as the game's pipeline (and URP) lays its sun shadow
|
|
4
|
+
* out: one depth texture, cascade i in tile (i mod 2, i div 2). One texture
|
|
5
|
+
* means one binding for every reader — materials, ground, effects, particles —
|
|
6
|
+
* and room in the same scheme for the local lights' shadows later.
|
|
11
7
|
*/
|
|
8
|
+
export const SHADOW_ATLAS_SIZE = 4096;
|
|
9
|
+
const TILE = SHADOW_ATLAS_SIZE / 2;
|
|
10
|
+
export const SHADOW_CASCADES = [0, 1, 2, 3].map((i) => ({
|
|
11
|
+
mapSize: TILE,
|
|
12
|
+
origin: [(i % 2) * TILE, Math.floor(i / 2) * TILE],
|
|
13
|
+
}));
|
|
14
|
+
/** How far past the camera's point of interest the inner cascade reaches, in
|
|
15
|
+
* world units: the dancer and the floor around her. Half the old two-map
|
|
16
|
+
* reach, which keeps her texel where it was at half the tile; the three
|
|
17
|
+
* outer cascades carry the rest of the room. */
|
|
18
|
+
export const NEAR_REACH = 20;
|
|
12
19
|
/** The deepest a cascade reaches along the view, in world units — the far
|
|
13
20
|
* plane's old cap, which is where every stage's shadows were fitted before. */
|
|
14
21
|
const SHADOW_FAR = 8000;
|
|
22
|
+
/**
|
|
23
|
+
* Where each cascade's slice of the view starts and ends, as distances along
|
|
24
|
+
* the view, inner to outer: every slice starts at the near plane and they
|
|
25
|
+
* nest, the innermost ending just past the point of interest and the
|
|
26
|
+
* outermost where the scene ends, the two between spaced evenly in ratio.
|
|
27
|
+
* Nested rather than abutting so the invariant above holds: the outermost
|
|
28
|
+
* box contains all of them, and the sampler takes the first that holds a point.
|
|
29
|
+
*/
|
|
15
30
|
export function cascadeSlices(view, bounds) {
|
|
16
31
|
let farFit = view.near + 200;
|
|
17
32
|
if (bounds) {
|
|
@@ -28,11 +43,14 @@ export function cascadeSlices(view, bounds) {
|
|
|
28
43
|
// a kilometre out is in the scene's bounds, and fitting the far cascade to it
|
|
29
44
|
// would spread the stage's shadow map across the sky.
|
|
30
45
|
farFit = Math.min(view.far, SHADOW_FAR, Math.max(view.near + 1, farFit));
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
const first = Math.min(farFit, Math.max(view.near + 8, view.focus + NEAR_REACH));
|
|
47
|
+
const n = SHADOW_CASCADES.length;
|
|
48
|
+
const out = [];
|
|
49
|
+
for (let i = 0; i < n; i++) {
|
|
50
|
+
const end = i === n - 1 ? farFit : first * Math.pow(farFit / first, i / (n - 1));
|
|
51
|
+
out.push([view.near, end]);
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
36
54
|
}
|
|
37
55
|
/** The bounding sphere of a frustum slice: on the view axis, at the depth that
|
|
38
56
|
* balances the near and far rectangles' corners. */
|
|
@@ -113,6 +131,11 @@ export function fitShadowVP(view, slice, sunDirection, bounds, cascade, out, off
|
|
|
113
131
|
out.set(proj.multiply(viewM).values, offset);
|
|
114
132
|
return out;
|
|
115
133
|
}
|
|
134
|
+
/** Every cascade's bounding sphere (centre, radius), inner to outer — the
|
|
135
|
+
* split spheres a game shader picks its cascade by (_CascadeShadowSplitSpheres). */
|
|
136
|
+
export function cascadeSpheres(view, bounds) {
|
|
137
|
+
return cascadeSlices(view, bounds).map(([n, f]) => sliceSphere(view, n, f));
|
|
138
|
+
}
|
|
116
139
|
/** Every cascade's view-projection in a row, inner to outer. */
|
|
117
140
|
export function buildShadowCascades(view, sunDirection, bounds, out) {
|
|
118
141
|
const slices = cascadeSlices(view, bounds);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { NativeValue } from "./host";
|
|
2
|
+
/** A game character's CharacterEffect values, as its prefab serialises them. */
|
|
3
|
+
export type CharacterRig = {
|
|
4
|
+
localLightInclination: number;
|
|
5
|
+
localLightAzimuth: number;
|
|
6
|
+
localLightIntensity: number;
|
|
7
|
+
localLightColor: [number, number, number, number];
|
|
8
|
+
faceReceiveShadow: boolean;
|
|
9
|
+
disableFaceSDFShadow: boolean;
|
|
10
|
+
emissionColor: [number, number, number, number];
|
|
11
|
+
fillOuter: [number, number, number, number];
|
|
12
|
+
fillInner: [number, number, number, number];
|
|
13
|
+
fillColor: [number, number, number, number];
|
|
14
|
+
fillRatio: number;
|
|
15
|
+
rimlightColor: [number, number, number, number];
|
|
16
|
+
rimlightThreshold: number;
|
|
17
|
+
rimlightFade: number;
|
|
18
|
+
rimlightRange: number;
|
|
19
|
+
rimlightInclination: number;
|
|
20
|
+
rimlightAzimuth1: number;
|
|
21
|
+
rimlightAzimuth2: number;
|
|
22
|
+
characterLayer: number;
|
|
23
|
+
/** EnvironmentEffect's trilight, sRGB as serialised. */
|
|
24
|
+
skyColor: [number, number, number];
|
|
25
|
+
equatorColor: [number, number, number];
|
|
26
|
+
groundColor: [number, number, number];
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Unity's ambient probe of a trilight (RenderSettings.ambientProbe in Trilight
|
|
30
|
+
* mode), measured in Unity 6 rather than derived: the colours are taken to
|
|
31
|
+
* linear, then
|
|
32
|
+
* c0 = (S + 4E + G) / 6 c1 = (√6 / 9)(S − G)
|
|
33
|
+
* c6 = (5/192)(2E − S − G) c8 = (5/64)(2E − S − G)
|
|
34
|
+
* and every other coefficient is zero — Unity's raw coefficients, which its
|
|
35
|
+
* shader constants pack as SHA = (c3, c1, c2, c0 − c6), SHB = (c4, c5, 3c6, c7),
|
|
36
|
+
* SHC = c8. Checked against the game's recorded block for (0.8, 0.5, 0.3).
|
|
37
|
+
*/
|
|
38
|
+
export declare function trilightProbe(sky: [number, number, number], equator: [number, number, number], ground: [number, number, number]): number[][];
|
|
39
|
+
/** Unity's shader constants from raw coefficients (channel, index). */
|
|
40
|
+
export declare function probeConstants(c: number[][]): Record<string, number[]>;
|
|
41
|
+
/**
|
|
42
|
+
* sim_TowardMatrix (LightingFeatures.SetupTowardMatrix): the frame the
|
|
43
|
+
* character light is expressed in — the camera's backward direction flattened
|
|
44
|
+
* to the ground, as columns (up × d, up, d). Taken immediately, as the DLC
|
|
45
|
+
* poster sets CameraExtension.shadowRotationImmediately.
|
|
46
|
+
*/
|
|
47
|
+
export declare function towardMatrix(cameraForward: [number, number, number]): Float32Array;
|
|
48
|
+
/** CharacterGlobalParams.Execute: the outline's resolution allowance. */
|
|
49
|
+
export declare function outlineMaxOffsetMultiplier(pixelWidth: number): number;
|
|
50
|
+
/**
|
|
51
|
+
* The character's property block (CharacterEffect.LateUpdate with the default
|
|
52
|
+
* look: no dissolve, dither, interference), by name.
|
|
53
|
+
*
|
|
54
|
+
* `head` is the head bone's skinning matrix (its pose relative to the bind
|
|
55
|
+
* pose, engine units) and `headRest` its rest position; `scale` engine units
|
|
56
|
+
* per game unit.
|
|
57
|
+
*/
|
|
58
|
+
export declare function characterBlock(rig: CharacterRig, head: ArrayLike<number> | null, headRest: [number, number, number], scale: number): Record<string, NativeValue>;
|
|
59
|
+
//# sourceMappingURL=character.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"character.d.ts","sourceRoot":"","sources":["../../src/unity/character.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAGzC,gFAAgF;AAChF,MAAM,MAAM,YAAY,GAAG;IACzB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;IACzB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACjD,iBAAiB,EAAE,OAAO,CAAA;IAC1B,oBAAoB,EAAE,OAAO,CAAA;IAC7B,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,wDAAwD;IACxD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CACtC,CAAA;AAID;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACjC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAC/B,MAAM,EAAE,EAAE,CAUZ;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAUtE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAMlF;AAED,yEAAyE;AACzE,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA+C7B"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// The game's per-character shading inputs, for a model wearing its character
|
|
2
|
+
// shaders.
|
|
3
|
+
//
|
|
4
|
+
// In the game a CharacterEffect component (P08.RenderPipeline, ported in
|
|
5
|
+
// ag-rip's charfx/CharacterEffect.cs from the decompiled GameAssembly.dll)
|
|
6
|
+
// writes one property block shared by all of a character's renderers: its own
|
|
7
|
+
// key light, expressed in a camera-facing frame (_LocalLightDir in
|
|
8
|
+
// sim_TowardMatrix, LightingFeatures.SetupTowardMatrix); its face frame for the
|
|
9
|
+
// SDF face shadow (_World2Face); its rim lights; its fills; and an ambient of
|
|
10
|
+
// its own from three colours (EnvironmentEffect). Nothing here is per scene:
|
|
11
|
+
// it is the character's look, carried by the character.
|
|
12
|
+
//
|
|
13
|
+
// An MMD model has no CharacterEffect. It takes a CharacterRig — the values a
|
|
14
|
+
// game character's prefab carries, exported with the look — and the frames
|
|
15
|
+
// come from its own bones: the face is the head bone turned to face the way
|
|
16
|
+
// the game's faces do (the game's face node rests aligned with the world,
|
|
17
|
+
// looking +Z; a PMX model looks −Z, so a half turn about Y).
|
|
18
|
+
import { gameToEngine, invert4, mul4 } from "./globals";
|
|
19
|
+
const srgbToLinear = (c) => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));
|
|
20
|
+
/**
|
|
21
|
+
* Unity's ambient probe of a trilight (RenderSettings.ambientProbe in Trilight
|
|
22
|
+
* mode), measured in Unity 6 rather than derived: the colours are taken to
|
|
23
|
+
* linear, then
|
|
24
|
+
* c0 = (S + 4E + G) / 6 c1 = (√6 / 9)(S − G)
|
|
25
|
+
* c6 = (5/192)(2E − S − G) c8 = (5/64)(2E − S − G)
|
|
26
|
+
* and every other coefficient is zero — Unity's raw coefficients, which its
|
|
27
|
+
* shader constants pack as SHA = (c3, c1, c2, c0 − c6), SHB = (c4, c5, 3c6, c7),
|
|
28
|
+
* SHC = c8. Checked against the game's recorded block for (0.8, 0.5, 0.3).
|
|
29
|
+
*/
|
|
30
|
+
export function trilightProbe(sky, equator, ground) {
|
|
31
|
+
const out = [];
|
|
32
|
+
for (let k = 0; k < 3; k++) {
|
|
33
|
+
const S = srgbToLinear(sky[k]), E = srgbToLinear(equator[k]), G = srgbToLinear(ground[k]);
|
|
34
|
+
const ring = 2 * E - S - G;
|
|
35
|
+
out.push([(S + 4 * E + G) / 6, (Math.sqrt(6) / 9) * (S - G), 0, 0, 0, 0, (5 / 192) * ring, 0, (5 / 64) * ring]);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
/** Unity's shader constants from raw coefficients (channel, index). */
|
|
40
|
+
export function probeConstants(c) {
|
|
41
|
+
const ch = ["r", "g", "b"];
|
|
42
|
+
const o = {};
|
|
43
|
+
for (let k = 0; k < 3; k++) {
|
|
44
|
+
const s = c[k];
|
|
45
|
+
o[`SHA${ch[k]}`] = [s[3], s[1], s[2], s[0] - s[6]];
|
|
46
|
+
o[`SHB${ch[k]}`] = [s[4], s[5], s[6] * 3, s[7]];
|
|
47
|
+
}
|
|
48
|
+
o.SHC = [c[0][8], c[1][8], c[2][8], 1];
|
|
49
|
+
return o;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* sim_TowardMatrix (LightingFeatures.SetupTowardMatrix): the frame the
|
|
53
|
+
* character light is expressed in — the camera's backward direction flattened
|
|
54
|
+
* to the ground, as columns (up × d, up, d). Taken immediately, as the DLC
|
|
55
|
+
* poster sets CameraExtension.shadowRotationImmediately.
|
|
56
|
+
*/
|
|
57
|
+
export function towardMatrix(cameraForward) {
|
|
58
|
+
const x = -cameraForward[0], z = -cameraForward[2];
|
|
59
|
+
const len = Math.hypot(x, z);
|
|
60
|
+
const d = len > 1e-5 ? [x / len, 0, z / len] : [0, 0, 0];
|
|
61
|
+
return Float32Array.from([d[2], 0, -d[0], 0, 0, 1, 0, 0, d[0], d[1], d[2], 0, 0, 0, 0, 1]);
|
|
62
|
+
}
|
|
63
|
+
/** CharacterGlobalParams.Execute: the outline's resolution allowance. */
|
|
64
|
+
export function outlineMaxOffsetMultiplier(pixelWidth) {
|
|
65
|
+
return Math.max(pixelWidth / 768 - 1, 0);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The character's property block (CharacterEffect.LateUpdate with the default
|
|
69
|
+
* look: no dissolve, dither, interference), by name.
|
|
70
|
+
*
|
|
71
|
+
* `head` is the head bone's skinning matrix (its pose relative to the bind
|
|
72
|
+
* pose, engine units) and `headRest` its rest position; `scale` engine units
|
|
73
|
+
* per game unit.
|
|
74
|
+
*/
|
|
75
|
+
export function characterBlock(rig, head, headRest, scale) {
|
|
76
|
+
const o = {};
|
|
77
|
+
// _World2Face: the face frame's world-to-local, in game units. The face is
|
|
78
|
+
// the head's pose applied to a frame at the head's rest position looking −Z.
|
|
79
|
+
const faceRest = Float32Array.from([-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, headRest[0], headRest[1], headRest[2], 1]);
|
|
80
|
+
const face = head ? mul4(head, faceRest) : faceRest;
|
|
81
|
+
o._World2Face = mul4(invert4(face), gameToEngine(scale));
|
|
82
|
+
o._ExtralEmissionColor = rig.emissionColor;
|
|
83
|
+
let inner = rig.fillInner, outer = rig.fillOuter;
|
|
84
|
+
inner = [inner[0], inner[1], inner[2], inner[3] * rig.fillRatio];
|
|
85
|
+
outer = [outer[0], outer[1], outer[2], outer[3] * rig.fillRatio];
|
|
86
|
+
o._FillOuter = outer;
|
|
87
|
+
o._FillInner = inner;
|
|
88
|
+
o._FillClamp = 0;
|
|
89
|
+
o._FillSoft = 0;
|
|
90
|
+
o._DissolveFactor = 0;
|
|
91
|
+
// inclination about the horizon, azimuth negated — float math as the game's
|
|
92
|
+
const incl = (rig.localLightInclination * Math.PI) / 180;
|
|
93
|
+
const az = (-rig.localLightAzimuth * Math.PI) / 180;
|
|
94
|
+
const c = Math.cos(incl);
|
|
95
|
+
o._LocalLightDir = [Math.sin(az) * -c, Math.sin(incl), Math.cos(az) * c, 0];
|
|
96
|
+
const k = rig.localLightIntensity;
|
|
97
|
+
o._LocalLightColor = [rig.localLightColor[0] * k, rig.localLightColor[1] * k, rig.localLightColor[2] * k, rig.localLightColor[3] * k];
|
|
98
|
+
o._UseFaceReceiveShadow = rig.faceReceiveShadow ? 1 : 0;
|
|
99
|
+
o._DisableFaceSDFShadow = rig.disableFaceSDFShadow ? 1 : 0;
|
|
100
|
+
o._RimlightColor = rig.rimlightColor;
|
|
101
|
+
o._RimlightThreshold = rig.rimlightThreshold;
|
|
102
|
+
o._RimlightFade = rig.rimlightFade;
|
|
103
|
+
o._RimlightRange = rig.rimlightRange;
|
|
104
|
+
const zr = rig.rimlightInclination;
|
|
105
|
+
const sr = Math.sqrt(1 - zr * zr);
|
|
106
|
+
const a1 = rig.rimlightAzimuth1 * Math.PI, a2 = rig.rimlightAzimuth2 * Math.PI;
|
|
107
|
+
o._RimlightDir1 = [Math.cos(a1) * sr, Math.sin(a1) * sr, zr, 0];
|
|
108
|
+
o._RimlightDir2 = [Math.cos(a2) * sr, Math.sin(a2) * sr, zr, 0];
|
|
109
|
+
o._ZOffset_Unit = rig.characterLayer;
|
|
110
|
+
o._DitherAlpha = 1;
|
|
111
|
+
// EnvironmentEffect: the character's own ambient, in both names it is read by
|
|
112
|
+
const sh = probeConstants(trilightProbe(rig.skyColor, rig.equatorColor, rig.groundColor));
|
|
113
|
+
for (const [n, v] of Object.entries(sh)) {
|
|
114
|
+
o[`unity_${n}`] = v;
|
|
115
|
+
o[`_Replica_${n}`] = v;
|
|
116
|
+
}
|
|
117
|
+
// CharacterEffect.OnEnable: every character renderer on rendering layer 0x40000001
|
|
118
|
+
o.unity_RenderingLayer = new Uint32Array([0x40000001, 0, 0, 0]);
|
|
119
|
+
return o;
|
|
120
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { NativeValue } from "./host";
|
|
2
|
+
export type Mat4Like = ArrayLike<number>;
|
|
3
|
+
export type UnityLight = {
|
|
4
|
+
/** World position, engine units. */
|
|
5
|
+
position: [number, number, number];
|
|
6
|
+
/** Reach, engine units. */
|
|
7
|
+
radius: number;
|
|
8
|
+
/** Linear colour times intensity. */
|
|
9
|
+
color: [number, number, number];
|
|
10
|
+
/** Unit aim, away from the light; zero for a point light. */
|
|
11
|
+
aim: [number, number, number];
|
|
12
|
+
cosOuter: number;
|
|
13
|
+
cosInner: number;
|
|
14
|
+
/** Rendering-layer bits it reaches. */
|
|
15
|
+
layers: number;
|
|
16
|
+
/** What the game's pipeline packs beside a light it lit with, when the light
|
|
17
|
+
* came from a game stage (stage_native.py): spot direction with w = 1 /
|
|
18
|
+
* its sphere's radius (the area term reads it), colour alpha, Extra,
|
|
19
|
+
* WorldToLight and type — all in the game's world, used as they are. */
|
|
20
|
+
unity?: {
|
|
21
|
+
spotDir: number[];
|
|
22
|
+
colorW: number;
|
|
23
|
+
extra: number[];
|
|
24
|
+
worldToLight: number[] | null;
|
|
25
|
+
lightType: number;
|
|
26
|
+
simSpotDir?: number[] | null;
|
|
27
|
+
simColorW?: number;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export type UnityFrameInput = {
|
|
31
|
+
/** Engine units per game unit. */
|
|
32
|
+
scale: number;
|
|
33
|
+
view: Mat4Like;
|
|
34
|
+
proj: Mat4Like;
|
|
35
|
+
eye: [number, number, number];
|
|
36
|
+
near: number;
|
|
37
|
+
far: number;
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
/** Scene clock and its step, seconds. */
|
|
41
|
+
time: number;
|
|
42
|
+
dt: number;
|
|
43
|
+
/** The direction the main light travels, unit; null for none. */
|
|
44
|
+
sunDirection: [number, number, number] | null;
|
|
45
|
+
sunColor: [number, number, number];
|
|
46
|
+
sunShadow: number;
|
|
47
|
+
lights: UnityLight[];
|
|
48
|
+
/** Ambient as the engine's folded SH9 (27 floats, ibl.ts), or null for flat. */
|
|
49
|
+
ambientSH: ArrayLike<number> | null;
|
|
50
|
+
ambientFlat: [number, number, number];
|
|
51
|
+
/** The cascades as the engine drew them: render view-projections (engine
|
|
52
|
+
* units, the atlas's own depth convention), their tiles, and the spheres
|
|
53
|
+
* they were fitted to. */
|
|
54
|
+
shadow: {
|
|
55
|
+
viewProj: Mat4Like[];
|
|
56
|
+
tiles: [number, number][];
|
|
57
|
+
tileSize: number;
|
|
58
|
+
atlasSize: number;
|
|
59
|
+
spheres: {
|
|
60
|
+
center: [number, number, number];
|
|
61
|
+
radius: number;
|
|
62
|
+
}[];
|
|
63
|
+
} | null;
|
|
64
|
+
/** What a loaded game stage sets for its scene (stage.ts): fog, tint, ambient
|
|
65
|
+
* SH, the environment cube's numbers — the pipeline's per-scene globals, in
|
|
66
|
+
* place of the defaults below. Never camera, time, lights or shadows. */
|
|
67
|
+
settings?: Record<string, NativeValue> | null;
|
|
68
|
+
};
|
|
69
|
+
/** Column-major 4x4 multiply. */
|
|
70
|
+
export declare function mul4(a: Mat4Like, b: Mat4Like): Float32Array;
|
|
71
|
+
export declare function invert4(m: Mat4Like): Float32Array;
|
|
72
|
+
/** Game world -> engine world: `s` PMX per unit, half a turn about Y. */
|
|
73
|
+
export declare function gameToEngine(s: number): Float32Array;
|
|
74
|
+
/** Engine world -> game world. */
|
|
75
|
+
export declare function engineToGame(s: number): Float32Array;
|
|
76
|
+
/** An engine point in the game's world. */
|
|
77
|
+
export declare function gamePoint(p: ArrayLike<number>, s: number): [number, number, number];
|
|
78
|
+
/** An engine direction in the game's world. */
|
|
79
|
+
export declare function gameDir(d: ArrayLike<number>): [number, number, number];
|
|
80
|
+
/** Uniform scale, as a column-major matrix. */
|
|
81
|
+
export declare function scale4(s: number): Float32Array;
|
|
82
|
+
/** The projection with clip y negated — undone by naga's own negation. */
|
|
83
|
+
export declare function flipY(p: Mat4Like): Float32Array;
|
|
84
|
+
/**
|
|
85
|
+
* The engine's folded SH9 (ibl.ts: c0 + c1·y + c2·z + c3·x + c4·xy + c5·yz +
|
|
86
|
+
* c6·(3z²−1) + c7·xz + c8·(x²−y²)) as Unity's seven shader constants —
|
|
87
|
+
* SHA = (x, y, z, constant), SHB = (xy, yz, z², zx), SHC = (x²−y²) — the same
|
|
88
|
+
* polynomial, regrouped.
|
|
89
|
+
*/
|
|
90
|
+
export declare function unitySH(sh: ArrayLike<number> | null, flat: [number, number, number]): Record<string, number[]>;
|
|
91
|
+
/** Everything the frame sets, by name. */
|
|
92
|
+
export declare function unityFrameGlobals(f: UnityFrameInput): Record<string, NativeValue>;
|
|
93
|
+
//# sourceMappingURL=globals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/unity/globals.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;AAExC,MAAM,MAAM,UAAU,GAAG;IACvB,oCAAoC;IACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,qCAAqC;IACrC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,6DAA6D;IAC7D,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAA;IACd;;;6EAGyE;IACzE,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAC7B,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,iEAAiE;IACjE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IAC7C,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,gFAAgF;IAChF,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IACnC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC;;+BAE2B;IAC3B,MAAM,EAAE;QACN,QAAQ,EAAE,QAAQ,EAAE,CAAA;QACpB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;QACzB,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE;YAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAChE,GAAG,IAAI,CAAA;IACR;;8EAE0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,IAAI,CAAA;CAC9C,CAAA;AAID,iCAAiC;AACjC,wBAAgB,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAS3D;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAmDjD;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAEpD;AAED,kCAAkC;AAClC,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAEpD;AAED,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAEnF;AAED,+CAA+C;AAC/C,wBAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAEtE;AAED,+CAA+C;AAC/C,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAE9C;AAED,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAI/C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAU9G;AAED,0CAA0C;AAC1C,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAsOjF"}
|