reze-engine 0.50.11 → 0.51.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 +81 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +316 -46
- package/dist/graph/presets/unlit.d.ts +3 -0
- package/dist/graph/presets/unlit.d.ts.map +1 -0
- package/dist/graph/presets/unlit.js +34 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/physics/autofit.d.ts +147 -0
- package/dist/physics/autofit.d.ts.map +1 -0
- package/dist/physics/autofit.js +501 -0
- package/dist/shaders/anchor-table.d.ts.map +1 -1
- package/dist/shaders/anchor-table.js +17 -0
- package/dist/shaders/lyrics-api.d.ts +11 -2
- package/dist/shaders/lyrics-api.d.ts.map +1 -1
- package/dist/shaders/lyrics-api.js +11 -2
- package/dist/shaders/passes/field-blit.d.ts +26 -0
- package/dist/shaders/passes/field-blit.d.ts.map +1 -0
- package/dist/shaders/passes/field-blit.js +65 -0
- package/dist/shaders/passes/ground-noise.d.ts +7 -0
- package/dist/shaders/passes/ground-noise.d.ts.map +1 -0
- package/dist/shaders/passes/ground-noise.js +88 -0
- package/dist/shaders/passes/sim.d.ts +34 -0
- package/dist/shaders/passes/sim.d.ts.map +1 -0
- package/dist/shaders/passes/sim.js +169 -0
- package/dist/shaders/score-api.d.ts +10 -0
- package/dist/shaders/score-api.d.ts.map +1 -0
- package/dist/shaders/score-api.js +114 -0
- package/package.json +1 -1
- package/src/engine.ts +336 -11
- package/src/graph/presets/unlit.ts +37 -0
- package/src/index.ts +1 -0
- package/src/shaders/anchor-table.ts +17 -0
- package/src/shaders/lyrics-api.ts +11 -2
- package/dist/_dbg-loader.mjs +0 -1100
- package/dist/physics-debug.d.ts +0 -30
- package/dist/physics-debug.d.ts.map +0 -1
- package/dist/physics-debug.js +0 -526
- package/dist/shaders/materials/body.d.ts +0 -2
- package/dist/shaders/materials/body.d.ts.map +0 -1
- package/dist/shaders/materials/body.js +0 -95
- package/dist/shaders/materials/cloth_rough.d.ts +0 -2
- package/dist/shaders/materials/cloth_rough.d.ts.map +0 -1
- package/dist/shaders/materials/cloth_rough.js +0 -69
- package/dist/shaders/materials/cloth_smooth.d.ts +0 -2
- package/dist/shaders/materials/cloth_smooth.d.ts.map +0 -1
- package/dist/shaders/materials/cloth_smooth.js +0 -61
- package/dist/shaders/materials/default.d.ts +0 -2
- package/dist/shaders/materials/default.d.ts.map +0 -1
- package/dist/shaders/materials/default.js +0 -43
- package/dist/shaders/materials/eye.d.ts +0 -2
- package/dist/shaders/materials/eye.d.ts.map +0 -1
- package/dist/shaders/materials/eye.js +0 -60
- package/dist/shaders/materials/face.d.ts +0 -2
- package/dist/shaders/materials/face.d.ts.map +0 -1
- package/dist/shaders/materials/face.js +0 -95
- package/dist/shaders/materials/hair.d.ts +0 -2
- package/dist/shaders/materials/hair.d.ts.map +0 -1
- package/dist/shaders/materials/hair.js +0 -90
- package/dist/shaders/materials/metal.d.ts +0 -2
- package/dist/shaders/materials/metal.d.ts.map +0 -1
- package/dist/shaders/materials/metal.js +0 -77
- package/dist/shaders/materials/mmd_classic.d.ts +0 -2
- package/dist/shaders/materials/mmd_classic.d.ts.map +0 -1
- package/dist/shaders/materials/mmd_classic.js +0 -66
- package/dist/shaders/materials/stockings.d.ts +0 -2
- package/dist/shaders/materials/stockings.d.ts.map +0 -1
- package/dist/shaders/materials/stockings.js +0 -122
- package/dist/shaders/passes/physics-debug.d.ts +0 -2
- package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
- package/dist/shaders/passes/physics-debug.js +0 -69
package/dist/engine.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Camera } from "./camera";
|
|
|
2
2
|
import { decodeDds, isDds } from "./dds-loader";
|
|
3
3
|
import { Mat4, Quat, Vec3 } from "./math";
|
|
4
4
|
import { decodePsd, isPsd } from "./psd-loader";
|
|
5
|
-
import { MATERIAL_MORPH_MULTIPLY } from "./model";
|
|
5
|
+
import { Model, MATERIAL_MORPH_MULTIPLY } from "./model";
|
|
6
6
|
import { MORPH_COMPUTE_WGSL } from "./shaders/passes/morph";
|
|
7
7
|
import { CULL_COMPUTE_WGSL } from "./shaders/passes/cull";
|
|
8
8
|
import { buildAnchorTable, anchorAliasWgsl, EMPTY_ANCHOR_TABLE } from "./shaders/anchor-table";
|
|
@@ -41,6 +41,7 @@ import { PICK_SHADER_WGSL } from "./shaders/passes/pick";
|
|
|
41
41
|
import { MIPMAP_BLIT_SHADER_WGSL } from "./shaders/passes/mipmap";
|
|
42
42
|
import { compileGraph } from "./graph/compile";
|
|
43
43
|
import { DEFAULT_GRAPH } from "./graph/presets/default";
|
|
44
|
+
import { UNLIT_GRAPH } from "./graph/presets/unlit";
|
|
44
45
|
import { FACE_GRAPH } from "./graph/presets/face";
|
|
45
46
|
import { HAIR_GRAPH } from "./graph/presets/hair";
|
|
46
47
|
import { BODY_GRAPH } from "./graph/presets/body";
|
|
@@ -983,6 +984,8 @@ export class Engine {
|
|
|
983
984
|
this.framePhysicsMsRaw = 0;
|
|
984
985
|
/** Every shadow caster in one sphere: (x, y, z, radius). radius 0 = nothing
|
|
985
986
|
* casts, -1 = do not use (a rigid caster has no sphere). See updateCasterSphere. */
|
|
987
|
+
/** A card's own texture, by model key — see setPlaneFrame. */
|
|
988
|
+
this.planeTextures = new Map();
|
|
986
989
|
this.casterSphere = new Float32Array(4);
|
|
987
990
|
/** The ground's uniform block, kept so the caster sphere can be refreshed in
|
|
988
991
|
* it every frame rather than rebuilding the buffer (addGround allocates). */
|
|
@@ -2040,41 +2043,6 @@ export class Engine {
|
|
|
2040
2043
|
primitive: { topology: "triangle-list" },
|
|
2041
2044
|
});
|
|
2042
2045
|
}
|
|
2043
|
-
/**
|
|
2044
|
-
* Install the scene's WGSL effect (shadertoy-style), rendered per-pixel in the
|
|
2045
|
-
* composite pass. ONE effect per scene, and the code says where it mounts by
|
|
2046
|
-
* which of these it defines — either, or both in one file:
|
|
2047
|
-
*
|
|
2048
|
-
* fn background(ray: vec3f, uv: vec2f, time: f32) -> vec4f
|
|
2049
|
-
* fn foreground(ray: vec3f, uv: vec2f, time: f32, depth: f32) -> vec4f
|
|
2050
|
-
*
|
|
2051
|
-
* `background` is a LAYER between the base background and the scene,
|
|
2052
|
-
* over-composited onto whichever base is active (solid color, 360 equirect, or
|
|
2053
|
-
* transparency) — its alpha lets the base show through, so a starfield is
|
|
2054
|
-
* stars over the user's background color. `foreground` composites over the
|
|
2055
|
-
* finished frame instead, which is where rain, snow, petals and fog live, and
|
|
2056
|
-
* is handed `depth`: the camera-space distance in metres of whatever the scene
|
|
2057
|
-
* drew at that pixel (the far plane where it drew nothing). Compare a
|
|
2058
|
-
* particle's own distance against it and the model occludes it; fog just reads
|
|
2059
|
-
* it, since fog's alpha IS a function of distance.
|
|
2060
|
-
*
|
|
2061
|
-
* `ray` is the pixel's normalized world-space view direction (LH, +Z forward —
|
|
2062
|
-
* what the skybox samples by), `uv` is 0..1 bottom-left origin, `time` is
|
|
2063
|
-
* seconds since apply, and `bgResolution()` gives the canvas size. Return sRGB
|
|
2064
|
-
* + alpha; alpha is the only "how much does this replace" control there is.
|
|
2065
|
-
* Declared `params` arrive as `params.<name>` (number → f32, Vec3 → vec3f),
|
|
2066
|
-
* shared by both mounts, and are later tweaked without recompiling via
|
|
2067
|
-
* setEffectParam.
|
|
2068
|
-
*
|
|
2069
|
-
* Both mounts are display-space: neither affects lighting, bloom or
|
|
2070
|
-
* tonemapping, and both are captured by offline export. A foreground makes the
|
|
2071
|
-
* scene pass STORE its depth buffer (it otherwise discards it into tile
|
|
2072
|
-
* memory) for as long as one is installed.
|
|
2073
|
-
*
|
|
2074
|
-
* Compiles off the hot path (async pipelines): on failure the previous effect
|
|
2075
|
-
* is KEPT and diagnostics are returned with line numbers relative to the
|
|
2076
|
-
* user's WGSL. Pass null to remove the effect.
|
|
2077
|
-
*/
|
|
2078
2046
|
async compileEffect(wgsl, params,
|
|
2079
2047
|
/** This effect's own declarations, already parsed by the caller — which had
|
|
2080
2048
|
* to read them anyway to build the scene table. */
|
|
@@ -2170,6 +2138,28 @@ export class Engine {
|
|
|
2170
2138
|
// pinning an effect that declares this has to keep installing; saying so is
|
|
2171
2139
|
// all that was ever missing.
|
|
2172
2140
|
const warnings = [];
|
|
2141
|
+
// A DIRECTIVE THAT PARSED AS NOTHING.
|
|
2142
|
+
//
|
|
2143
|
+
// Every pragma is matched with `\s*$` after it, so a line that carries a
|
|
2144
|
+
// note as well — `// @fullres — glyph edges are sub-pixel detail` — matches
|
|
2145
|
+
// none of them and is read as an ordinary comment. Nothing failed, nothing
|
|
2146
|
+
// said anything, and the effect simply ran without the property it asked
|
|
2147
|
+
// for: three shipped effects were silently half-res and a fourth silently
|
|
2148
|
+
// stopped being additive, each one's first line explaining why it needed
|
|
2149
|
+
// the thing it was not getting.
|
|
2150
|
+
//
|
|
2151
|
+
// Every directive this engine knows, so an unrecognised one is named rather
|
|
2152
|
+
// than ignored. Cheap: it runs once per install, over a file a human wrote.
|
|
2153
|
+
for (const m of wgsl.matchAll(/^[ \t]*\/\/[ \t]*(@[a-zA-Z]+)(.*)$/gm)) {
|
|
2154
|
+
const [, tag, rest] = m;
|
|
2155
|
+
if (!Engine.KNOWN.has(tag)) {
|
|
2156
|
+
warnings.push(`${tag} is not a directive this engine knows — it will be ignored.`);
|
|
2157
|
+
}
|
|
2158
|
+
else if (rest.trim() && !/^\s*[\w.\-+]+(\s+[\w.\-+]+)*\s*$/.test(rest)) {
|
|
2159
|
+
warnings.push(`${tag} has a note on the same line, so it does not parse and is being IGNORED. ` +
|
|
2160
|
+
`A directive must be alone on its line — put the note on the next one.`);
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2173
2163
|
if (parseParticleBloom(wgsl) && !wantsParticles && !wantsTrails) {
|
|
2174
2164
|
warnings.push("// @bloom does nothing here. A field effect (background/foreground) composites after tone " +
|
|
2175
2165
|
"mapping, past the bloom pyramid — the directive applies to particles and ribbons, which draw " +
|
|
@@ -2406,7 +2396,22 @@ export class Engine {
|
|
|
2406
2396
|
epochScene: this.sceneClock,
|
|
2407
2397
|
// Its OWN resolution, no longer the scene's: an effect that never asked
|
|
2408
2398
|
// for full res is not promoted because a neighbour did.
|
|
2409
|
-
|
|
2399
|
+
// FULL RESOLUTION UNLESS TOLD OTHERWISE.
|
|
2400
|
+
//
|
|
2401
|
+
// It was the other way round, and the default was the bug. An author
|
|
2402
|
+
// who has never heard of the flag writes an effect with an edge in it
|
|
2403
|
+
// and gets a soft one — nothing fails, nothing warns, because nothing
|
|
2404
|
+
// was declared to fail. Three shipped effects DID declare it and were
|
|
2405
|
+
// half-res anyway on a parsing technicality, which is the same bug
|
|
2406
|
+
// wearing a different hat: the safe answer has to be the one you get
|
|
2407
|
+
// for saying nothing.
|
|
2408
|
+
//
|
|
2409
|
+
// The cost is real and is why the half layer stays: `@halfres` is worth
|
|
2410
|
+
// about 3.7x on a full-screen effect (Footprints, measured, 1.2ms
|
|
2411
|
+
// against 4.5ms). It is the right call for a soft additive glow, which
|
|
2412
|
+
// upsamples invisibly — and it is now a claim an author makes about
|
|
2413
|
+
// their own effect rather than a fate that befalls one.
|
|
2414
|
+
fieldLayer: /^\s*\/\/\s*@halfres\s*$/m.test(wgsl) ? 1 : 0,
|
|
2410
2415
|
fieldPipeline,
|
|
2411
2416
|
fieldClock,
|
|
2412
2417
|
// Filled by rebuildFieldBindGroup below, which needs the instance to
|
|
@@ -3345,7 +3350,9 @@ export class Engine {
|
|
|
3345
3350
|
return null;
|
|
3346
3351
|
const view = this.camera.getViewMatrix().values;
|
|
3347
3352
|
for (const inst of this.modelInstances.values()) {
|
|
3348
|
-
|
|
3353
|
+
// Neither a stage nor a plane is a performer, so neither is a subject an
|
|
3354
|
+
// effect can follow.
|
|
3355
|
+
if (!inst.model.visible || inst.isStage || inst.isPlane)
|
|
3349
3356
|
continue;
|
|
3350
3357
|
const model = inst.model;
|
|
3351
3358
|
const matrices = model.getWorldMatrices();
|
|
@@ -4837,6 +4844,21 @@ export class Engine {
|
|
|
4837
4844
|
// refresh on resize or effects aspect-correct against the stale size.
|
|
4838
4845
|
if (this.compositeUniformBuffer)
|
|
4839
4846
|
this.writeCompositeViewUniforms();
|
|
4847
|
+
// RELEASED BEFORE REPLACING. WebGPU does not free a texture when the last
|
|
4848
|
+
// JS reference drops — it waits for GC, which has no idea a 130 MB MSAA
|
|
4849
|
+
// target is riding on a small object. The id and mirror targets below
|
|
4850
|
+
// already did this; the seven main scene targets did not, so every resize
|
|
4851
|
+
// orphaned the whole set.
|
|
4852
|
+
//
|
|
4853
|
+
// A video export is what made it hurt: it resizes UP to the output size
|
|
4854
|
+
// and back DOWN on the way out, so one 4K render orphaned roughly a third
|
|
4855
|
+
// of a gigabyte, twice. A few exports in one session and the tab is
|
|
4856
|
+
// starved — slow, then slow to reload.
|
|
4857
|
+
//
|
|
4858
|
+
// destroy() is safe against work already submitted: the implementation
|
|
4859
|
+
// defers the free until the GPU is done. What it forbids is USING a
|
|
4860
|
+
// destroyed texture in a new command, and every view is rebuilt below.
|
|
4861
|
+
this.multisampleTexture?.destroy();
|
|
4840
4862
|
this.multisampleTexture = this.device.createTexture({
|
|
4841
4863
|
label: "multisample HDR render target",
|
|
4842
4864
|
size: [width, height],
|
|
@@ -4844,6 +4866,7 @@ export class Engine {
|
|
|
4844
4866
|
format: this.hdrFormat,
|
|
4845
4867
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
4846
4868
|
});
|
|
4869
|
+
this.hdrResolveTexture?.destroy();
|
|
4847
4870
|
this.hdrResolveTexture = this.device.createTexture({
|
|
4848
4871
|
label: "HDR resolve target",
|
|
4849
4872
|
size: [width, height],
|
|
@@ -4856,6 +4879,7 @@ export class Engine {
|
|
|
4856
4879
|
this.createFieldTargets();
|
|
4857
4880
|
// Bloom-mask MRT attachments — same dims + MSAA as HDR so they share the render pass.
|
|
4858
4881
|
// MS buffer gets resolved into maskResolveTexture, which the bloom blit pass samples.
|
|
4882
|
+
this.multisampleMaskTexture?.destroy();
|
|
4859
4883
|
this.multisampleMaskTexture = this.device.createTexture({
|
|
4860
4884
|
label: "multisample bloom mask",
|
|
4861
4885
|
size: [width, height],
|
|
@@ -4863,6 +4887,7 @@ export class Engine {
|
|
|
4863
4887
|
format: Engine.BLOOM_MASK_FORMAT,
|
|
4864
4888
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
4865
4889
|
});
|
|
4890
|
+
this.maskResolveTexture?.destroy();
|
|
4866
4891
|
this.maskResolveTexture = this.device.createTexture({
|
|
4867
4892
|
label: "bloom mask resolve",
|
|
4868
4893
|
size: [width, height],
|
|
@@ -5002,6 +5027,7 @@ export class Engine {
|
|
|
5002
5027
|
const bh = Math.max(1, Math.floor(height / 2));
|
|
5003
5028
|
const shortSide = Math.max(1, Math.min(bw, bh));
|
|
5004
5029
|
this.bloomMipCount = Math.max(1, Math.min(Engine.BLOOM_MAX_LEVELS, Math.floor(Math.log2(shortSide)) - 1));
|
|
5030
|
+
this.bloomDownTexture?.destroy();
|
|
5005
5031
|
this.bloomDownTexture = this.device.createTexture({
|
|
5006
5032
|
label: "bloom down pyramid",
|
|
5007
5033
|
size: [bw, bh],
|
|
@@ -5009,6 +5035,7 @@ export class Engine {
|
|
|
5009
5035
|
format: this.hdrFormat,
|
|
5010
5036
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
5011
5037
|
});
|
|
5038
|
+
this.bloomUpTexture?.destroy();
|
|
5012
5039
|
this.bloomUpTexture = this.device.createTexture({
|
|
5013
5040
|
label: "bloom up pyramid",
|
|
5014
5041
|
size: [bw, bh],
|
|
@@ -5025,6 +5052,7 @@ export class Engine {
|
|
|
5025
5052
|
for (let i = 0; i < upLevels; i++) {
|
|
5026
5053
|
this.bloomUpMipViews.push(this.bloomUpTexture.createView({ baseMipLevel: i, mipLevelCount: 1 }));
|
|
5027
5054
|
}
|
|
5055
|
+
this.depthTexture?.destroy();
|
|
5028
5056
|
this.depthTexture = this.device.createTexture({
|
|
5029
5057
|
label: "depth texture",
|
|
5030
5058
|
size: [width, height],
|
|
@@ -5691,7 +5719,7 @@ export class Engine {
|
|
|
5691
5719
|
// is first in insertion order and was seeding this clock with its own
|
|
5692
5720
|
// permanent zero. In a scene with a stage, a camera VMD therefore sampled
|
|
5693
5721
|
// frame 0 forever and the shot never moved.
|
|
5694
|
-
if (inst.isStage)
|
|
5722
|
+
if (inst.isStage || inst.isPlane)
|
|
5695
5723
|
continue;
|
|
5696
5724
|
const p = inst.model.getAnimationProgress();
|
|
5697
5725
|
if (p.playing || p.paused)
|
|
@@ -6033,7 +6061,7 @@ export class Engine {
|
|
|
6033
6061
|
const reader = assetReader ?? createFetchAssetReader();
|
|
6034
6062
|
const basePath = deriveBasePathFromPmxPath(pmxPath);
|
|
6035
6063
|
model.setAssetContext(reader, basePath);
|
|
6036
|
-
await this.setupModelInstance(key, model, basePath, reader, options?.stage ?? false);
|
|
6064
|
+
await this.setupModelInstance(key, model, basePath, reader, options?.stage ?? false, options?.plane ?? false, options?.dynamic ?? false);
|
|
6037
6065
|
return key;
|
|
6038
6066
|
}
|
|
6039
6067
|
/**
|
|
@@ -6061,6 +6089,163 @@ export class Engine {
|
|
|
6061
6089
|
this.setModelTransform(key, options.transform);
|
|
6062
6090
|
return key;
|
|
6063
6091
|
}
|
|
6092
|
+
/**
|
|
6093
|
+
* Put a picture in the scene as a flat card.
|
|
6094
|
+
*
|
|
6095
|
+
* The thing compositors arrange in a post tool's fake 3D space — Nuke calls
|
|
6096
|
+
* it a Card, After Effects a 3D layer, MMD 板ポリ — except the space here is
|
|
6097
|
+
* the real one. A card is occluded by anything in front of it, occludes what
|
|
6098
|
+
* is behind it, takes perspective when turned, and is caught by depth of
|
|
6099
|
+
* field like everything else, because it is ordinary geometry rather than a
|
|
6100
|
+
* layer composited afterwards.
|
|
6101
|
+
*
|
|
6102
|
+
* It is a MODEL, deliberately. Not a new kind of scene object with its own
|
|
6103
|
+
* list, its own persistence and its own selection: a card wants a position,
|
|
6104
|
+
* a rotation and a size, which is exactly what a model already has, and
|
|
6105
|
+
* everything built around models — the transform, the shadow settings, the
|
|
6106
|
+
* material editor, the asset bundle — works on it the day it exists. It is
|
|
6107
|
+
* not a STAGE, though: it skips the same machinery for the same reasons, and
|
|
6108
|
+
* leaves the floor alone. See ModelInstance.isPlane.
|
|
6109
|
+
*
|
|
6110
|
+
* @returns the model key, for setModelTransform and removeModel.
|
|
6111
|
+
*/
|
|
6112
|
+
async addPlane(options) {
|
|
6113
|
+
const { image, name, width, height } = options;
|
|
6114
|
+
const hw = Math.max(width, 1e-4) / 2;
|
|
6115
|
+
const hh = Math.max(height, 1e-4) / 2;
|
|
6116
|
+
// A quad on the XY plane, facing +Z, centred on its own origin — so a
|
|
6117
|
+
// rotation turns it about its middle and a position places its centre,
|
|
6118
|
+
// which is what a handle in the viewport implies.
|
|
6119
|
+
//
|
|
6120
|
+
// V IS FLIPPED, and this is the whole of it: a picture's rows run downward
|
|
6121
|
+
// from its top-left, a UV runs upward from the bottom-left, and a card that
|
|
6122
|
+
// renders its image upside down looks like a bug in everything else.
|
|
6123
|
+
// prettier-ignore
|
|
6124
|
+
const vertexData = new Float32Array([
|
|
6125
|
+
// x y z nx ny nz u v
|
|
6126
|
+
-hw, -hh, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0,
|
|
6127
|
+
hw, -hh, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
|
|
6128
|
+
hw, hh, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0,
|
|
6129
|
+
-hw, hh, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
|
6130
|
+
]);
|
|
6131
|
+
// Two triangles, counter-clockwise seen from +Z. A second pair wound the
|
|
6132
|
+
// other way is how "visible from behind" is done here, rather than a
|
|
6133
|
+
// per-material cull flag the rest of the engine has no concept of.
|
|
6134
|
+
const indices = options.doubleSided ? [0, 1, 2, 0, 2, 3, 0, 2, 1, 0, 3, 2] : [0, 1, 2, 0, 2, 3];
|
|
6135
|
+
const indexData = new Uint32Array(indices);
|
|
6136
|
+
// The texture table's one entry. The path is a key, not a location — the
|
|
6137
|
+
// reader below answers it from memory, so nothing is fetched and nothing is
|
|
6138
|
+
// written to disk.
|
|
6139
|
+
//
|
|
6140
|
+
// A PLAIN RELATIVE NAME under a plain directory, because the loader treats
|
|
6141
|
+
// this exactly as it treats a PMX's: it takes the model path's directory
|
|
6142
|
+
// and JOINS the texture entry onto it. A scheme-looking path went through
|
|
6143
|
+
// that as `plane://` + `plane://name` and matched nothing, so every card
|
|
6144
|
+
// came out with the untextured fallback. `plane/<name>` joins to
|
|
6145
|
+
// `plane/<name>` and stays unique per card, which the engine-wide texture
|
|
6146
|
+
// cache needs it to be.
|
|
6147
|
+
const texturePath = `plane/${name}`;
|
|
6148
|
+
const material = {
|
|
6149
|
+
name,
|
|
6150
|
+
diffuse: [1, 1, 1, 1],
|
|
6151
|
+
specular: [0, 0, 0],
|
|
6152
|
+
ambient: [0, 0, 0],
|
|
6153
|
+
shininess: 0,
|
|
6154
|
+
diffuseTextureIndex: 0,
|
|
6155
|
+
normalTextureIndex: -1,
|
|
6156
|
+
sphereTextureIndex: -1,
|
|
6157
|
+
sphereMode: 0,
|
|
6158
|
+
toonTextureIndex: -1,
|
|
6159
|
+
sharedToon: false,
|
|
6160
|
+
// 0 CARRIES TWO DECISIONS, both wanted, and both silent if changed.
|
|
6161
|
+
//
|
|
6162
|
+
// No inverted-hull outline (bit 0x10): a card is not a character, and a
|
|
6163
|
+
// black rim around a light leak is the opposite of what it is for.
|
|
6164
|
+
//
|
|
6165
|
+
// AND NO SHADOW (bit 0x04, which is what castsShadow reads). A card is
|
|
6166
|
+
// usually light or artwork rather than an object, and a rectangle of hard
|
|
6167
|
+
// shadow thrown across the stage by a gradient reads as the renderer
|
|
6168
|
+
// being broken. Set geometry that SHOULD cast one is the rarer case, and
|
|
6169
|
+
// it can say so.
|
|
6170
|
+
edgeFlag: 0,
|
|
6171
|
+
edgeColor: [0, 0, 0, 1],
|
|
6172
|
+
edgeSize: 0,
|
|
6173
|
+
vertexCount: indices.length,
|
|
6174
|
+
};
|
|
6175
|
+
// ONE BONE, because Model requires one — it throws on an empty skeleton,
|
|
6176
|
+
// every vertex has to be skinned to something, and a card has nothing to
|
|
6177
|
+
// articulate. It is never posed; the model transform is what moves a card.
|
|
6178
|
+
const skeleton = {
|
|
6179
|
+
bones: [{ name: "全ての親", parentIndex: -1, bindTranslation: [0, 0, 0], children: [] }],
|
|
6180
|
+
inverseBindMatrices: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
|
|
6181
|
+
};
|
|
6182
|
+
const vertexCount = 4;
|
|
6183
|
+
const joints = new Uint16Array(vertexCount * 4);
|
|
6184
|
+
const weights = new Uint8Array(vertexCount * 4);
|
|
6185
|
+
for (let i = 0; i < vertexCount; i++)
|
|
6186
|
+
weights[i * 4] = 255;
|
|
6187
|
+
const model = new Model(vertexData, indexData, [{ path: name, name }], [material], skeleton, { joints, weights }, { morphs: [] });
|
|
6188
|
+
// ITS OWN PATH, not addStage's. A plane and a stage skip the same machinery
|
|
6189
|
+
// and mean different things, and routing one through the other is how the
|
|
6190
|
+
// ground came to be suppressed by adding a picture.
|
|
6191
|
+
// The picture answers from memory, whatever it is asked for: a card has
|
|
6192
|
+
// exactly ONE texture, so there is nothing to disambiguate and no way for a
|
|
6193
|
+
// path to be wrong. Matching the string instead is what silently produced
|
|
6194
|
+
// untextured cards, because the loader composes that string itself.
|
|
6195
|
+
const reader = { readBinary: async () => image };
|
|
6196
|
+
const key = await this.addModel(model, texturePath, name, reader, { plane: true, dynamic: options.dynamic });
|
|
6197
|
+
// UNLIT, because a card is FOOTAGE and not a surface.
|
|
6198
|
+
//
|
|
6199
|
+
// Its pixels were finished somewhere else — a gradient painted in
|
|
6200
|
+
// Photoshop, a title, a rendered element — so its brightness is the artwork
|
|
6201
|
+
// rather than a response to anything. Shading it means the sun dimming one
|
|
6202
|
+
// side of a thing that has no sides, and the world colour tinting a picture
|
|
6203
|
+
// whose colour was the point. Left ungrouped it would take the neutral
|
|
6204
|
+
// Principled base, which is exactly that mistake.
|
|
6205
|
+
//
|
|
6206
|
+
// A group, not a hard-coded pipeline: a card used as SET geometry — a photo
|
|
6207
|
+
// of a wall, a poster standing in the room — genuinely does want the light,
|
|
6208
|
+
// and this is the same control every other material is changed through, so
|
|
6209
|
+
// that case is a graph swap rather than a feature request.
|
|
6210
|
+
await this.applyStyleGroups(key, [
|
|
6211
|
+
{ id: "plane", label: "Plane", materials: [name], graph: UNLIT_GRAPH, alphaMode: "hashed" },
|
|
6212
|
+
]);
|
|
6213
|
+
if (options.transform)
|
|
6214
|
+
this.setModelTransform(key, options.transform);
|
|
6215
|
+
// Kept so a moving card can push frames into it. The cache is keyed by the
|
|
6216
|
+
// texture's logical path, which is derived rather than stored anywhere the
|
|
6217
|
+
// caller can see — and deriving it twice is how the two would drift.
|
|
6218
|
+
const tex = this.textureCache.get(texturePath);
|
|
6219
|
+
if (tex)
|
|
6220
|
+
this.planeTextures.set(key, tex);
|
|
6221
|
+
return key;
|
|
6222
|
+
}
|
|
6223
|
+
/**
|
|
6224
|
+
* Replace what a card is showing, in place.
|
|
6225
|
+
*
|
|
6226
|
+
* For a moving card: a video element, a decoded frame, a canvas — anything
|
|
6227
|
+
* copyExternalImageToTexture accepts. Nothing is reallocated and no bind group
|
|
6228
|
+
* is rebuilt, so this is a per-frame call rather than a per-clip one; the
|
|
6229
|
+
* texture is written where it stands and the material keeps pointing at it.
|
|
6230
|
+
*
|
|
6231
|
+
* The frame must be the size the card was created at. A card is a fixed
|
|
6232
|
+
* rectangle of texels and resizing one mid-clip would mean rebuilding the
|
|
6233
|
+
* material behind it — so the caller allocates the card at its video's size
|
|
6234
|
+
* and this refuses anything else rather than stretching it silently.
|
|
6235
|
+
*/
|
|
6236
|
+
setPlaneFrame(id, source, width, height) {
|
|
6237
|
+
const tex = this.planeTextures.get(id);
|
|
6238
|
+
if (!tex || !this.device)
|
|
6239
|
+
return false;
|
|
6240
|
+
if (tex.width !== width || tex.height !== height)
|
|
6241
|
+
return false;
|
|
6242
|
+
this.device.queue.copyExternalImageToTexture({ source }, { texture: tex }, [width, height]);
|
|
6243
|
+
// A moving card is allocated with one level precisely so this is never
|
|
6244
|
+
// reached: rebuilding a mip pyramid per frame is a pass per level per card.
|
|
6245
|
+
if (tex.mipLevelCount > 1)
|
|
6246
|
+
this.generateMipmaps(tex, tex.mipLevelCount);
|
|
6247
|
+
return true;
|
|
6248
|
+
}
|
|
6064
6249
|
/** True while a stage is in the scene. Two things turn on it: the built-in
|
|
6065
6250
|
* ground plane must not draw, and the far shadow cascade has nothing to
|
|
6066
6251
|
* cover without one (see the cascade loop). */
|
|
@@ -6079,6 +6264,9 @@ export class Engine {
|
|
|
6079
6264
|
const inst = this.modelInstances.get(name);
|
|
6080
6265
|
if (!inst)
|
|
6081
6266
|
return;
|
|
6267
|
+
// Before the texture cache below frees it: a stale entry here would hand a
|
|
6268
|
+
// destroyed texture to the next setPlaneFrame.
|
|
6269
|
+
this.planeTextures.delete(name);
|
|
6082
6270
|
inst.model.stop();
|
|
6083
6271
|
for (const path of inst.textureCacheKeys) {
|
|
6084
6272
|
const tex = this.textureCache.get(path);
|
|
@@ -6331,10 +6519,10 @@ export class Engine {
|
|
|
6331
6519
|
// A stage never solves IK — nothing drives its chains — and skips the pose
|
|
6332
6520
|
// pass entirely while it is idle. Morph changes still come through, since
|
|
6333
6521
|
// that is the one thing a stage's controls do move.
|
|
6334
|
-
const stageIdle = inst.isStage && inst.model.isIdle();
|
|
6522
|
+
const stageIdle = (inst.isStage || inst.isPlane) && inst.model.isIdle();
|
|
6335
6523
|
let verticesChanged = false;
|
|
6336
6524
|
if (!stageIdle) {
|
|
6337
|
-
verticesChanged = inst.model.update(deltaTime, inst.isStage ? false : this.ikEnabled);
|
|
6525
|
+
verticesChanged = inst.model.update(deltaTime, inst.isStage || inst.isPlane ? false : this.ikEnabled);
|
|
6338
6526
|
inst.skinMatricesDirty = true;
|
|
6339
6527
|
}
|
|
6340
6528
|
animMs += performance.now() - tAnim;
|
|
@@ -7284,7 +7472,7 @@ export class Engine {
|
|
|
7284
7472
|
});
|
|
7285
7473
|
}
|
|
7286
7474
|
}
|
|
7287
|
-
async setupModelInstance(name, model, basePath, assetReader, isStage = false) {
|
|
7475
|
+
async setupModelInstance(name, model, basePath, assetReader, isStage = false, isPlane = false, dynamicTexture = false) {
|
|
7288
7476
|
const vertices = model.getVertices();
|
|
7289
7477
|
const skinning = model.getSkinning();
|
|
7290
7478
|
const skeleton = model.getSkeleton();
|
|
@@ -7327,7 +7515,7 @@ export class Engine {
|
|
|
7327
7515
|
// A stage never simulates, so its bodies are never built — constructing the
|
|
7328
7516
|
// solver for the heaviest mesh in the scene and dropping it afterwards was
|
|
7329
7517
|
// both wasted work and an invariant maintained in the wrong place.
|
|
7330
|
-
const physics = !isStage && rbs.length > 0 ? new RezePhysics(rbs, model.getJoints()) : null;
|
|
7518
|
+
const physics = !isStage && !isPlane && rbs.length > 0 ? new RezePhysics(rbs, model.getJoints()) : null;
|
|
7331
7519
|
// Which bones the simulation will overwrite, handed to the pose pipeline so
|
|
7332
7520
|
// the append (付与) pass can consume the simulated result instead of the
|
|
7333
7521
|
// animated one. Precomputed here, once, because the answer is topology —
|
|
@@ -7399,6 +7587,8 @@ export class Engine {
|
|
|
7399
7587
|
pickPerInstanceBindGroup,
|
|
7400
7588
|
pickDrawCalls: [],
|
|
7401
7589
|
isStage,
|
|
7590
|
+
isPlane,
|
|
7591
|
+
dynamicTexture,
|
|
7402
7592
|
// Seeded true: the bind pose has to reach the GPU once before any frame.
|
|
7403
7593
|
skinMatricesDirty: true,
|
|
7404
7594
|
hiddenMaterials: new Set(),
|
|
@@ -7820,7 +8010,21 @@ export class Engine {
|
|
|
7820
8010
|
bounds[3] += grow;
|
|
7821
8011
|
bounds[4] += grow;
|
|
7822
8012
|
bounds[5] += grow;
|
|
7823
|
-
|
|
8013
|
+
// A CARD IS ALWAYS OPAQUE-PHASE, whatever its alpha says.
|
|
8014
|
+
//
|
|
8015
|
+
// The scene pass runs opaque -> ground -> transparent, and the ground
|
|
8016
|
+
// writes depth at every opacity (effects locate the floor by it). Every
|
|
8017
|
+
// card qualifies as transparent — a cutout has translucent texels, and a
|
|
8018
|
+
// video card starts from a blank sheet that is nothing but — so cards
|
|
8019
|
+
// drew after the ground and an INVISIBLE floor rejected them. Turning the
|
|
8020
|
+
// ground down for the shadow catcher made pictures disappear into it.
|
|
8021
|
+
//
|
|
8022
|
+
// Not a workaround: alphaMode "hashed" is alpha-to-coverage, which is the
|
|
8023
|
+
// transparency technique built for this phase, and addPlane already sets
|
|
8024
|
+
// it. The cost is dithering on a large soft gradient, where MSAA has four
|
|
8025
|
+
// coverage levels to spend — a cutout edge, which is what a card usually
|
|
8026
|
+
// has, resolves exactly.
|
|
8027
|
+
const type = inst.isPlane ? "opaque" : isTransparent ? "transparent" : "opaque";
|
|
7824
8028
|
inst.drawCalls.push({
|
|
7825
8029
|
type,
|
|
7826
8030
|
count: indexCount,
|
|
@@ -8113,7 +8317,13 @@ export class Engine {
|
|
|
8113
8317
|
`so sheer fabric will not blend. The canvas 2D readback is what failed.`);
|
|
8114
8318
|
}
|
|
8115
8319
|
this.textureAlphaCache.set(cacheKey, alphaPlane);
|
|
8116
|
-
|
|
8320
|
+
// NO MIPS FOR A MOVING CARD. The chain would have to be rebuilt on every
|
|
8321
|
+
// frame written into it — a full pyramid of render passes per video plane
|
|
8322
|
+
// per frame, which is most of what a moving card was costing. Level 0 is
|
|
8323
|
+
// the only level a card in frame reads anyway; the price is aliasing on one
|
|
8324
|
+
// shrunk far into the distance, which is the case a video card is least
|
|
8325
|
+
// often in.
|
|
8326
|
+
const mipLevelCount = inst.dynamicTexture ? 1 : Math.floor(Math.log2(Math.max(width, height))) + 1;
|
|
8117
8327
|
const texture = this.device.createTexture({
|
|
8118
8328
|
label: `texture: ${cacheKey}`,
|
|
8119
8329
|
size: [width, height],
|
|
@@ -10316,6 +10526,66 @@ Engine.FILMIC_LUT_WIDTH = 256;
|
|
|
10316
10526
|
// (vsync-to-vsync), recomputed at STATS_REFRESH_MS so the readout doesn't flicker.
|
|
10317
10527
|
Engine.STATS_WINDOW = 120;
|
|
10318
10528
|
Engine.STATS_REFRESH_MS = 500;
|
|
10529
|
+
/**
|
|
10530
|
+
* Install the scene's WGSL effect (shadertoy-style), rendered per-pixel in the
|
|
10531
|
+
* composite pass. ONE effect per scene, and the code says where it mounts by
|
|
10532
|
+
* which of these it defines — either, or both in one file:
|
|
10533
|
+
*
|
|
10534
|
+
* fn background(ray: vec3f, uv: vec2f, time: f32) -> vec4f
|
|
10535
|
+
* fn foreground(ray: vec3f, uv: vec2f, time: f32, depth: f32) -> vec4f
|
|
10536
|
+
*
|
|
10537
|
+
* `background` is a LAYER between the base background and the scene,
|
|
10538
|
+
* over-composited onto whichever base is active (solid color, 360 equirect, or
|
|
10539
|
+
* transparency) — its alpha lets the base show through, so a starfield is
|
|
10540
|
+
* stars over the user's background color. `foreground` composites over the
|
|
10541
|
+
* finished frame instead, which is where rain, snow, petals and fog live, and
|
|
10542
|
+
* is handed `depth`: the camera-space distance in metres of whatever the scene
|
|
10543
|
+
* drew at that pixel (the far plane where it drew nothing). Compare a
|
|
10544
|
+
* particle's own distance against it and the model occludes it; fog just reads
|
|
10545
|
+
* it, since fog's alpha IS a function of distance.
|
|
10546
|
+
*
|
|
10547
|
+
* `ray` is the pixel's normalized world-space view direction (LH, +Z forward —
|
|
10548
|
+
* what the skybox samples by), `uv` is 0..1 bottom-left origin, `time` is
|
|
10549
|
+
* seconds since apply, and `bgResolution()` gives the canvas size. Return sRGB
|
|
10550
|
+
* + alpha; alpha is the only "how much does this replace" control there is.
|
|
10551
|
+
* Declared `params` arrive as `params.<name>` (number → f32, Vec3 → vec3f),
|
|
10552
|
+
* shared by both mounts, and are later tweaked without recompiling via
|
|
10553
|
+
* setEffectParam.
|
|
10554
|
+
*
|
|
10555
|
+
* Both mounts are display-space: neither affects lighting, bloom or
|
|
10556
|
+
* tonemapping, and both are captured by offline export. A foreground makes the
|
|
10557
|
+
* scene pass STORE its depth buffer (it otherwise discards it into tile
|
|
10558
|
+
* memory) for as long as one is installed.
|
|
10559
|
+
*
|
|
10560
|
+
* Compiles off the hot path (async pipelines): on failure the previous effect
|
|
10561
|
+
* is KEPT and diagnostics are returned with line numbers relative to the
|
|
10562
|
+
* user's WGSL. Pass null to remove the effect.
|
|
10563
|
+
*/
|
|
10564
|
+
/**
|
|
10565
|
+
* Every directive an effect may declare — used ONLY to tell an author that
|
|
10566
|
+
* the line they wrote is not doing what they think. See compileEffect.
|
|
10567
|
+
*
|
|
10568
|
+
* It has to be complete, including the ones this engine does not read itself:
|
|
10569
|
+
* `@dissolve` is parsed by the host, and warning about it would be worse than
|
|
10570
|
+
* the silence this replaced — a false alarm on a working line teaches authors
|
|
10571
|
+
* to ignore the channel.
|
|
10572
|
+
*/
|
|
10573
|
+
Engine.KNOWN = new Set([
|
|
10574
|
+
"@anchor",
|
|
10575
|
+
"@layer",
|
|
10576
|
+
"@blend",
|
|
10577
|
+
"@bloom",
|
|
10578
|
+
"@lights",
|
|
10579
|
+
"@grid",
|
|
10580
|
+
"@particles",
|
|
10581
|
+
"@halfres",
|
|
10582
|
+
// Accepted and inert: full resolution is the default now, and an effect
|
|
10583
|
+
// that still says so is right about what it wants. Warning about it would
|
|
10584
|
+
// be telling authors off for the thing that used to be necessary.
|
|
10585
|
+
"@fullres",
|
|
10586
|
+
// The HOST's, not this engine's — see the note above.
|
|
10587
|
+
"@dissolve",
|
|
10588
|
+
]);
|
|
10319
10589
|
// ── GPU frustum cull ────────────────────────────────────────────────────────
|
|
10320
10590
|
//
|
|
10321
10591
|
// Sizes, once, so the arithmetic below is readable: a DrawMeta is 32 bytes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit.d.ts","sourceRoot":"","sources":["../../../src/graph/presets/unlit.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE5C,eAAO,MAAM,WAAW,EAAE,WAmBzB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Unlit — the texture, at its own brightness, and nothing else.
|
|
2
|
+
//
|
|
3
|
+
// What FOOTAGE needs. A media plane carries pixels somebody already finished
|
|
4
|
+
// somewhere else: a gradient painted in Photoshop, a title card, a rendered
|
|
5
|
+
// element. Shading it is not a stylistic choice but a mistake — the scene's sun
|
|
6
|
+
// would dim one side of a card that has no side, and the world colour would
|
|
7
|
+
// tint artwork whose colour is the point. Blender's answer is the same one:
|
|
8
|
+
// wire the image straight into an Emission shader and let it out at the value
|
|
9
|
+
// it was authored at.
|
|
10
|
+
//
|
|
11
|
+
// Emission rather than Principled with roughness 1: emission is radiance, so it
|
|
12
|
+
// leaves the light loop entirely instead of being an unusually flat surface
|
|
13
|
+
// inside it. That is also what lets a card sit in front of a lamp without
|
|
14
|
+
// picking up its highlight.
|
|
15
|
+
export const UNLIT_GRAPH = {
|
|
16
|
+
version: 1,
|
|
17
|
+
name: "Unlit",
|
|
18
|
+
tags: ["unlit", "plane"],
|
|
19
|
+
nodes: [
|
|
20
|
+
{ id: "tex", type: "texture" },
|
|
21
|
+
// The PMX material colour still multiplies in, so a plane can be tinted or
|
|
22
|
+
// faded through the same dial every other material uses rather than needing
|
|
23
|
+
// one of its own.
|
|
24
|
+
{ id: "mat", type: "material_diffuse" },
|
|
25
|
+
{ id: "base", type: "mix/multiply", inputs: { fac: 1.0 } },
|
|
26
|
+
{ id: "emit", type: "emission", inputs: { strength: 1.0 } },
|
|
27
|
+
],
|
|
28
|
+
links: [
|
|
29
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "base", socket: "a" } },
|
|
30
|
+
{ from: { node: "mat", socket: "color" }, to: { node: "base", socket: "b" } },
|
|
31
|
+
{ from: { node: "base", socket: "color" }, to: { node: "emit", socket: "color" } },
|
|
32
|
+
],
|
|
33
|
+
output: { node: "emit", socket: "color" },
|
|
34
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export { BODY_GRAPH } from "./graph/presets/body";
|
|
|
18
18
|
export { STOCKINGS_GRAPH } from "./graph/presets/stockings";
|
|
19
19
|
export { EYE_GRAPH } from "./graph/presets/eye";
|
|
20
20
|
export { FACE_GRAPH } from "./graph/presets/face";
|
|
21
|
+
export { UNLIT_GRAPH } from "./graph/presets/unlit";
|
|
21
22
|
export { Model, MATERIAL_MORPH_MULTIPLY, MATERIAL_MORPH_ADD, type ClipEventInfo, type RootMotionProfile, type Morph, type Morphing, type BoneMorphOffset, type MaterialMorphOffset, type UvMorphOffset, } from "./model";
|
|
22
23
|
export { Vec3, Quat, Mat4, easeInOut, type EulerOrder } from "./math";
|
|
23
24
|
export type { AnimationClip, AnimationPlayOptions, AnimationProgress, BlendEntry, BoneKeyframe, IkKeyframe, MorphKeyframe, BoneInterpolation, ControlPoint, } from "./animation";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export { BODY_GRAPH } from "./graph/presets/body";
|
|
|
22
22
|
export { STOCKINGS_GRAPH } from "./graph/presets/stockings";
|
|
23
23
|
export { EYE_GRAPH } from "./graph/presets/eye";
|
|
24
24
|
export { FACE_GRAPH } from "./graph/presets/face";
|
|
25
|
+
export { UNLIT_GRAPH } from "./graph/presets/unlit";
|
|
25
26
|
export { Model, MATERIAL_MORPH_MULTIPLY, MATERIAL_MORPH_ADD, } from "./model";
|
|
26
27
|
export { Vec3, Quat, Mat4, easeInOut } from "./math";
|
|
27
28
|
export { LocomotionController, } from "./locomotion";
|