@nodetool-ai/game-renderer 0.8.1
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/.nodetool-build-stamp +1 -0
- package/dist/audio.d.ts +39 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +227 -0
- package/dist/audio.js.map +1 -0
- package/dist/browser-fonts.d.ts +8 -0
- package/dist/browser-fonts.d.ts.map +1 -0
- package/dist/browser-fonts.js +39 -0
- package/dist/browser-fonts.js.map +1 -0
- package/dist/browser.d.ts +31 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +106 -0
- package/dist/browser.js.map +1 -0
- package/dist/build.d.ts +19 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +236 -0
- package/dist/build.js.map +1 -0
- package/dist/canvas2d.d.ts +34 -0
- package/dist/canvas2d.d.ts.map +1 -0
- package/dist/canvas2d.js +208 -0
- package/dist/canvas2d.js.map +1 -0
- package/dist/fonts.d.ts +5 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +10 -0
- package/dist/fonts.js.map +1 -0
- package/dist/frame.d.ts +55 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +123 -0
- package/dist/frame.js.map +1 -0
- package/dist/gpu-capture.d.ts +4 -0
- package/dist/gpu-capture.d.ts.map +1 -0
- package/dist/gpu-capture.js +192 -0
- package/dist/gpu-capture.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/input.d.ts +3 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +16 -0
- package/dist/input.js.map +1 -0
- package/dist/lighting.d.ts +17 -0
- package/dist/lighting.d.ts.map +1 -0
- package/dist/lighting.js +79 -0
- package/dist/lighting.js.map +1 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +177 -0
- package/dist/node.js.map +1 -0
- package/dist/standalone-player.d.ts +2 -0
- package/dist/standalone-player.d.ts.map +1 -0
- package/dist/standalone-player.js +286 -0
- package/dist/standalone-player.js.map +1 -0
- package/dist/touch-controls.d.ts +18 -0
- package/dist/touch-controls.d.ts.map +1 -0
- package/dist/touch-controls.js +136 -0
- package/dist/touch-controls.js.map +1 -0
- package/dist/webgpu.d.ts +75 -0
- package/dist/webgpu.d.ts.map +1 -0
- package/dist/webgpu.js +807 -0
- package/dist/webgpu.js.map +1 -0
- package/package.json +64 -0
package/dist/frame.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { gameFontFamily } from "./fonts.js";
|
|
2
|
+
/** A drawing rectangle by pixel center and size, snapped to whole pixels when the item asks for it. */
|
|
3
|
+
export function pixelRect(item, x, y, width, height) {
|
|
4
|
+
if (!item.snap)
|
|
5
|
+
return { x, y, width, height };
|
|
6
|
+
const left = Math.round(x - width / 2);
|
|
7
|
+
const top = Math.round(y - height / 2);
|
|
8
|
+
const snappedWidth = Math.round(x + width / 2) - left;
|
|
9
|
+
const snappedHeight = Math.round(y + height / 2) - top;
|
|
10
|
+
return { x: left + snappedWidth / 2, y: top + snappedHeight / 2, width: snappedWidth, height: snappedHeight };
|
|
11
|
+
}
|
|
12
|
+
/** Camera projection for the sample between the previous and current tick. */
|
|
13
|
+
export function projectedCamera(frame, interpolation) {
|
|
14
|
+
const alpha = Math.max(0, Math.min(1, interpolation));
|
|
15
|
+
return { x: (frame.camera.previousX ?? frame.camera.x) * (1 - alpha) + frame.camera.x * alpha,
|
|
16
|
+
y: (frame.camera.previousY ?? frame.camera.y) * (1 - alpha) + frame.camera.y * alpha, zoom: frame.camera.zoom };
|
|
17
|
+
}
|
|
18
|
+
export function interpolateTint(previous, current, alpha) {
|
|
19
|
+
if (!previous || !current || !/^#[0-9a-fA-F]{6}$/.test(previous) || !/^#[0-9a-fA-F]{6}$/.test(current))
|
|
20
|
+
return current;
|
|
21
|
+
return `#${[1, 3, 5].map((index) => Math.round(Number.parseInt(previous.slice(index, index + 2), 16) * (1 - alpha) +
|
|
22
|
+
Number.parseInt(current.slice(index, index + 2), 16) * alpha).toString(16).padStart(2, "0")).join("")}`;
|
|
23
|
+
}
|
|
24
|
+
export function visibleItems(frame, interpolation, overscanWorld = 0) {
|
|
25
|
+
const alpha = Math.max(0, Math.min(1, interpolation));
|
|
26
|
+
const camera = projectedCamera(frame, alpha);
|
|
27
|
+
const scale = camera.zoom;
|
|
28
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const halfWidth = frame.width / (2 * scale) + overscanWorld;
|
|
32
|
+
const halfHeight = frame.height / (2 * scale) + overscanWorld;
|
|
33
|
+
const items = [];
|
|
34
|
+
function add(item, x, y, width, height, rotation, opacity = item.opacity ?? 1, tint = item.tint, flipX = false, flipY = false, snap = false) {
|
|
35
|
+
const radius = Math.hypot(width, height) / 2;
|
|
36
|
+
if (x + radius < camera.x - halfWidth || x - radius > camera.x + halfWidth ||
|
|
37
|
+
y + radius < camera.y - halfHeight || y - radius > camera.y + halfHeight) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
items.push({
|
|
41
|
+
item,
|
|
42
|
+
x,
|
|
43
|
+
y,
|
|
44
|
+
width,
|
|
45
|
+
height,
|
|
46
|
+
rotation,
|
|
47
|
+
assetId: item.assetId,
|
|
48
|
+
frame: item.frame,
|
|
49
|
+
tint: tint && /^#[0-9a-fA-F]{6}$/.test(tint) ? tint : undefined,
|
|
50
|
+
opacity,
|
|
51
|
+
blend: "blend" in item && item.blend === "additive" ? "additive" : "normal",
|
|
52
|
+
sampling: item.sampling ?? "nearest",
|
|
53
|
+
flipX,
|
|
54
|
+
flipY,
|
|
55
|
+
unlit: "unlit" in item && item.unlit === true,
|
|
56
|
+
snap,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
for (const layer of frame.backgrounds ?? []) {
|
|
60
|
+
const time = Math.max(0, frame.tick - 1 + alpha) / 60;
|
|
61
|
+
const period = layer.mode === "mirror" ? 2 : 1;
|
|
62
|
+
const scrollX = layer.scrollRate.x * time;
|
|
63
|
+
const scrollY = layer.scrollRate.y * time;
|
|
64
|
+
const baseX = layer.origin.x + (layer.mode === "none" ? scrollX : scrollX % (layer.width * period)) + camera.x * (1 - layer.parallax.x);
|
|
65
|
+
const baseY = layer.origin.y + (layer.mode === "none" || layer.mode === "repeatX" ? scrollY : scrollY % (layer.height * period)) + camera.y * (1 - layer.parallax.y);
|
|
66
|
+
const minX = layer.mode === "none" ? 0 : Math.floor((camera.x - halfWidth - baseX) / layer.width);
|
|
67
|
+
const maxX = layer.mode === "none" ? 0 : Math.ceil((camera.x + halfWidth - baseX) / layer.width);
|
|
68
|
+
// A repeatX layer tiles sideways only, so a strip of scenery never stacks above itself.
|
|
69
|
+
const tilesY = layer.mode === "repeat" || layer.mode === "mirror";
|
|
70
|
+
const minY = tilesY ? Math.floor((camera.y - halfHeight - baseY) / layer.height) : 0;
|
|
71
|
+
const maxY = tilesY ? Math.ceil((camera.y + halfHeight - baseY) / layer.height) : 0;
|
|
72
|
+
if ((maxX - minX + 1) * (maxY - minY + 1) > 4096)
|
|
73
|
+
throw new Error(`Background ${layer.id} exceeds 4096 visible tiles`);
|
|
74
|
+
for (let iy = minY; iy <= maxY; iy += 1) {
|
|
75
|
+
for (let ix = minX; ix <= maxX; ix += 1) {
|
|
76
|
+
const item = { entityId: layer.id, assetId: layer.assetId,
|
|
77
|
+
x: baseX + ix * layer.width, y: baseY + iy * layer.height, previousX: baseX + ix * layer.width,
|
|
78
|
+
previousY: baseY + iy * layer.height, rotation: 0, scaleX: 1, scaleY: 1,
|
|
79
|
+
width: layer.width, height: layer.height, layer: layer.layer };
|
|
80
|
+
if (layer.frame)
|
|
81
|
+
item.frame = layer.frame;
|
|
82
|
+
if (layer.sampling)
|
|
83
|
+
item.sampling = layer.sampling;
|
|
84
|
+
add(item, item.x, item.y, item.width, item.height, 0, 1, undefined, layer.mode === "mirror" && Math.abs(ix % 2) === 1, layer.mode === "mirror" && Math.abs(iy % 2) === 1, true);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
for (const item of frame.tiles) {
|
|
89
|
+
add(item, item.x, item.y, item.width, item.height, 0, item.opacity ?? 1, item.tint, false, false, true);
|
|
90
|
+
}
|
|
91
|
+
for (const item of frame.sprites) {
|
|
92
|
+
add(item, item.previousX + (item.x - item.previousX) * alpha, item.previousY + (item.y - item.previousY) * alpha, item.width * ((item.previousScaleX ?? item.scaleX) * (1 - alpha) + item.scaleX * alpha), item.height * ((item.previousScaleY ?? item.scaleY) * (1 - alpha) + item.scaleY * alpha), (item.previousRotation ?? item.rotation) * (1 - alpha) + item.rotation * alpha, (item.previousOpacity ?? item.opacity ?? 1) * (1 - alpha) + (item.opacity ?? 1) * alpha, interpolateTint(item.previousTint, item.tint, alpha), item.flipX === true);
|
|
93
|
+
}
|
|
94
|
+
items.sort((a, b) => a.item.layer - b.item.layer);
|
|
95
|
+
return items;
|
|
96
|
+
}
|
|
97
|
+
export function parseTint(tint) {
|
|
98
|
+
if (!tint || !/^#[0-9a-fA-F]{6}$/.test(tint)) {
|
|
99
|
+
return [1, 1, 1];
|
|
100
|
+
}
|
|
101
|
+
return [
|
|
102
|
+
Number.parseInt(tint.slice(1, 3), 16) / 255,
|
|
103
|
+
Number.parseInt(tint.slice(3, 5), 16) / 255,
|
|
104
|
+
Number.parseInt(tint.slice(5, 7), 16) / 255,
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
/** Paint HUD labels in canvas pixels. Coordinates and sizes scale with the output. */
|
|
108
|
+
export function paintHud(context, hud, scale = 1, gameId = "") {
|
|
109
|
+
context.textBaseline = "top";
|
|
110
|
+
context.shadowColor = "rgba(0, 0, 0, 0.6)";
|
|
111
|
+
for (const label of hud) {
|
|
112
|
+
const size = (label.size ?? 16) * scale;
|
|
113
|
+
const family = label.fontId && gameId ? `"${gameFontFamily(gameId, label.fontId)}", ` : "";
|
|
114
|
+
context.font = `600 ${Math.round(size)}px ${family}system-ui, -apple-system, "Segoe UI", sans-serif`;
|
|
115
|
+
context.textAlign = label.align ?? "left";
|
|
116
|
+
context.fillStyle = label.color ?? "#ffffff";
|
|
117
|
+
context.shadowBlur = size / 4;
|
|
118
|
+
context.fillText(label.text, label.x * scale, label.y * scale);
|
|
119
|
+
}
|
|
120
|
+
context.shadowBlur = 0;
|
|
121
|
+
context.textAlign = "left";
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GameRendererEffect } from "./index.js";
|
|
2
|
+
/** Runs browser GPU effect modules on a straight-alpha sRGB Canvas2D capture. */
|
|
3
|
+
export declare function applyGpuEffects(rgba: Uint8ClampedArray, width: number, height: number, effects: readonly GameRendererEffect[], resolveAsset?: (assetId: string) => Promise<Uint8Array | null>, onDiagnostic?: (message: string) => void): Promise<Uint8ClampedArray>;
|
|
4
|
+
//# sourceMappingURL=gpu-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu-capture.d.ts","sourceRoot":"","sources":["../src/gpu-capture.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAiCrD,iFAAiF;AACjF,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC1F,OAAO,EAAE,SAAS,kBAAkB,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EACtG,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkJtE"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { colorBrightnessContrastV1, colorCubeLutV1, createDefaultRegistry, createExecutor, createGPUContextFromDevice, createLabeledTexture, createRecipeRunner, filtersGlowV1 } from "@nodetool-ai/gpu/pool";
|
|
2
|
+
import { createNodeGPUDevice } from "@nodetool-ai/gpu/node";
|
|
3
|
+
import { createCanvas, loadImage } from "@napi-rs/canvas";
|
|
4
|
+
import * as d from "typegpu/data";
|
|
5
|
+
const CONVERSION_SHADER = `
|
|
6
|
+
override encodeOutput: bool = true;
|
|
7
|
+
@group(0) @binding(0) var sourceSampler: sampler;
|
|
8
|
+
@group(0) @binding(1) var sourceTexture: texture_2d<f32>;
|
|
9
|
+
struct VertexOutput { @builtin(position) position: vec4f, @location(0) uv: vec2f };
|
|
10
|
+
@vertex fn vertexMain(@builtin(vertex_index) index: u32) -> VertexOutput {
|
|
11
|
+
let positions = array<vec2f, 3>(vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));
|
|
12
|
+
var output: VertexOutput;
|
|
13
|
+
output.position = vec4f(positions[index], 0.0, 1.0);
|
|
14
|
+
output.uv = positions[index] * vec2f(0.5, -0.5) + vec2f(0.5, 0.5);
|
|
15
|
+
return output;
|
|
16
|
+
}
|
|
17
|
+
@fragment fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
|
|
18
|
+
let premul = textureSample(sourceTexture, sourceSampler, input.uv);
|
|
19
|
+
let straight = premul.rgb / max(premul.a, 1.0 / 255.0);
|
|
20
|
+
let linear = select(straight / 12.92, pow((straight + 0.055) / 1.055, vec3f(2.4)),
|
|
21
|
+
straight > vec3f(0.04045));
|
|
22
|
+
let encoded = select(straight * 12.92, 1.055 * pow(straight, vec3f(1.0 / 2.4)) - 0.055,
|
|
23
|
+
straight > vec3f(0.0031308));
|
|
24
|
+
let converted = select(linear, encoded, encodeOutput);
|
|
25
|
+
return vec4f(clamp(converted, vec3f(0.0), vec3f(1.0)) * premul.a, premul.a);
|
|
26
|
+
}`;
|
|
27
|
+
function toLinear(value) {
|
|
28
|
+
return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
29
|
+
}
|
|
30
|
+
function toSrgb(value) {
|
|
31
|
+
return value <= 0.0031308 ? value * 12.92 : 1.055 * value ** (1 / 2.4) - 0.055;
|
|
32
|
+
}
|
|
33
|
+
/** Runs browser GPU effect modules on a straight-alpha sRGB Canvas2D capture. */
|
|
34
|
+
export async function applyGpuEffects(rgba, width, height, effects, resolveAsset, onDiagnostic) {
|
|
35
|
+
const device = await createNodeGPUDevice();
|
|
36
|
+
device.pushErrorScope("validation");
|
|
37
|
+
let validationScopeOpen = true;
|
|
38
|
+
const ctx = createGPUContextFromDevice(device);
|
|
39
|
+
const executor = createExecutor();
|
|
40
|
+
const runner = createRecipeRunner();
|
|
41
|
+
const registry = createDefaultRegistry();
|
|
42
|
+
const usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
|
|
43
|
+
const source = createLabeledTexture(device, { width, height, format: "rgba8unorm", usage, label: "game-capture-source" });
|
|
44
|
+
const target = createLabeledTexture(device, { width, height, format: "rgba8unorm", usage, label: "game-capture-target" });
|
|
45
|
+
const srgbSource = effects.some((effect) => effect.kind === "lut") ? createLabeledTexture(device, {
|
|
46
|
+
width, height, format: "rgba8unorm", usage, label: "game-capture-srgb-source", meta: { colorSpace: "srgb" }
|
|
47
|
+
}) : undefined;
|
|
48
|
+
const srgbTarget = effects.some((effect) => effect.kind === "lut") ? createLabeledTexture(device, {
|
|
49
|
+
width, height, format: "rgba8unorm", usage, label: "game-capture-srgb-target", meta: { colorSpace: "srgb" }
|
|
50
|
+
}) : undefined;
|
|
51
|
+
const lutTextures = [];
|
|
52
|
+
const module = device.createShaderModule({ code: CONVERSION_SHADER });
|
|
53
|
+
const layout = device.createBindGroupLayout({ entries: [
|
|
54
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
|
|
55
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float" } }
|
|
56
|
+
] });
|
|
57
|
+
const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [layout] });
|
|
58
|
+
const pipeline = (encodeOutput) => device.createRenderPipeline({
|
|
59
|
+
layout: pipelineLayout,
|
|
60
|
+
vertex: { module, entryPoint: "vertexMain" },
|
|
61
|
+
fragment: { module, entryPoint: "fragmentMain", constants: { encodeOutput: encodeOutput ? 1 : 0 }, targets: [{ format: "rgba8unorm" }] },
|
|
62
|
+
primitive: { topology: "triangle-list" }
|
|
63
|
+
});
|
|
64
|
+
const toSrgbPipeline = pipeline(true);
|
|
65
|
+
const toLinearPipeline = pipeline(false);
|
|
66
|
+
const sampler = device.createSampler({ magFilter: "nearest", minFilter: "nearest" });
|
|
67
|
+
const convert = (encoder, input, output, conversion) => {
|
|
68
|
+
const group = device.createBindGroup({ layout, entries: [
|
|
69
|
+
{ binding: 0, resource: sampler }, { binding: 1, resource: input.createView() }
|
|
70
|
+
] });
|
|
71
|
+
const pass = encoder.beginRenderPass({ colorAttachments: [{ view: output.createView(), loadOp: "clear", storeOp: "store",
|
|
72
|
+
clearValue: { r: 0, g: 0, b: 0, a: 0 } }] });
|
|
73
|
+
pass.setPipeline(conversion);
|
|
74
|
+
pass.setBindGroup(0, group);
|
|
75
|
+
pass.draw(3);
|
|
76
|
+
pass.end();
|
|
77
|
+
};
|
|
78
|
+
const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
|
|
79
|
+
const readback = device.createBuffer({ size: bytesPerRow * height, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ });
|
|
80
|
+
try {
|
|
81
|
+
const linear = new Uint8Array(width * height * 4);
|
|
82
|
+
for (let index = 0; index < rgba.length; index += 4) {
|
|
83
|
+
const alpha = (rgba[index + 3] ?? 0) / 255;
|
|
84
|
+
linear[index] = Math.round(toLinear((rgba[index] ?? 0) / 255) * alpha * 255);
|
|
85
|
+
linear[index + 1] = Math.round(toLinear((rgba[index + 1] ?? 0) / 255) * alpha * 255);
|
|
86
|
+
linear[index + 2] = Math.round(toLinear((rgba[index + 2] ?? 0) / 255) * alpha * 255);
|
|
87
|
+
linear[index + 3] = rgba[index + 3] ?? 0;
|
|
88
|
+
}
|
|
89
|
+
device.queue.writeTexture({ texture: source.texture }, linear, { bytesPerRow: width * 4 }, [width, height]);
|
|
90
|
+
const encoder = device.createCommandEncoder();
|
|
91
|
+
let input = source;
|
|
92
|
+
let output = target;
|
|
93
|
+
ctx.uniformRing.beginSubmission();
|
|
94
|
+
for (const effect of effects) {
|
|
95
|
+
if (effect.kind === "brightnessContrast") {
|
|
96
|
+
executor.encode({ ctx, module: colorBrightnessContrastV1, encoder, inputs: { source: input }, output,
|
|
97
|
+
params: { brightness: effect.brightness, contrast: effect.contrast }, dispatch: { kind: "fragment" } });
|
|
98
|
+
}
|
|
99
|
+
else if (effect.kind === "bloom") {
|
|
100
|
+
runner.encode({ ctx, module: filtersGlowV1, registry, executor, encoder, inputs: { source: input }, output,
|
|
101
|
+
params: { threshold: effect.threshold, softness: effect.softness, radius: effect.radius, intensity: effect.intensity } });
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
if (!srgbSource || !srgbTarget)
|
|
105
|
+
throw new Error("LUT capture targets are missing");
|
|
106
|
+
let lutPixels;
|
|
107
|
+
let lutWidth;
|
|
108
|
+
let lutHeight;
|
|
109
|
+
try {
|
|
110
|
+
const bytes = await resolveAsset?.(effect.assetId);
|
|
111
|
+
if (!bytes)
|
|
112
|
+
throw new Error(`LUT ${effect.assetId} is missing`);
|
|
113
|
+
const image = await loadImage(Buffer.from(bytes));
|
|
114
|
+
if (image.width !== effect.size * effect.size || image.height !== effect.size) {
|
|
115
|
+
throw new Error(`LUT ${effect.assetId} has invalid dimensions`);
|
|
116
|
+
}
|
|
117
|
+
const canvas = createCanvas(image.width, image.height);
|
|
118
|
+
const context = canvas.getContext("2d");
|
|
119
|
+
context.drawImage(image, 0, 0);
|
|
120
|
+
lutPixels = context.getImageData(0, 0, image.width, image.height).data;
|
|
121
|
+
for (let index = 3; index < lutPixels.length; index += 4) {
|
|
122
|
+
if (lutPixels[index] !== 255)
|
|
123
|
+
throw new Error(`LUT ${effect.assetId} must be opaque`);
|
|
124
|
+
}
|
|
125
|
+
lutWidth = image.width;
|
|
126
|
+
lutHeight = image.height;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (effect.required)
|
|
130
|
+
throw error;
|
|
131
|
+
onDiagnostic?.(`Optional LUT ${effect.assetId} omitted: ${error instanceof Error ? error.message : String(error)}`);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const lut = createLabeledTexture(device, { width: lutWidth, height: lutHeight, format: "rgba8unorm",
|
|
135
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST, label: `game-capture-lut-${effect.assetId}`,
|
|
136
|
+
meta: { colorSpace: "srgb" } });
|
|
137
|
+
lutTextures.push(lut.texture);
|
|
138
|
+
device.queue.writeTexture({ texture: lut.texture }, lutPixels, { bytesPerRow: lutWidth * 4 }, [lutWidth, lutHeight]);
|
|
139
|
+
convert(encoder, input.texture, srgbSource.texture, toSrgbPipeline);
|
|
140
|
+
srgbSource.markWritten();
|
|
141
|
+
executor.encode({ ctx, module: colorCubeLutV1, encoder, inputs: { source: srgbSource, lut }, output: srgbTarget,
|
|
142
|
+
params: { size: effect.size, intensity: effect.intensity,
|
|
143
|
+
domainMin: d.vec4f(...effect.domainMin, 0), domainMax: d.vec4f(...effect.domainMax, 0) },
|
|
144
|
+
dispatch: { kind: "fragment" } });
|
|
145
|
+
convert(encoder, srgbTarget.texture, output.texture, toLinearPipeline);
|
|
146
|
+
output.markWritten();
|
|
147
|
+
}
|
|
148
|
+
[input, output] = [output, input];
|
|
149
|
+
}
|
|
150
|
+
encoder.copyTextureToBuffer({ texture: input.texture }, { buffer: readback, bytesPerRow }, [width, height]);
|
|
151
|
+
device.queue.submit([encoder.finish()]);
|
|
152
|
+
await readback.mapAsync(GPUMapMode.READ);
|
|
153
|
+
const validationError = await device.popErrorScope();
|
|
154
|
+
validationScopeOpen = false;
|
|
155
|
+
if (validationError) {
|
|
156
|
+
throw new Error(`GPU capture failed: ${validationError.message}`);
|
|
157
|
+
}
|
|
158
|
+
const mapped = new Uint8Array(readback.getMappedRange());
|
|
159
|
+
const result = new Uint8ClampedArray(width * height * 4);
|
|
160
|
+
for (let y = 0; y < height; y += 1) {
|
|
161
|
+
for (let x = 0; x < width; x += 1) {
|
|
162
|
+
const index = (y * width + x) * 4;
|
|
163
|
+
const offset = y * bytesPerRow + x * 4;
|
|
164
|
+
const alpha = (mapped[offset + 3] ?? 0) / 255;
|
|
165
|
+
for (let channel = 0; channel < 3; channel += 1) {
|
|
166
|
+
const straight = alpha > 0 ? (mapped[offset + channel] ?? 0) / 255 / alpha : 0;
|
|
167
|
+
result[index + channel] = Math.round(Math.max(0, Math.min(1, toSrgb(straight))) * 255);
|
|
168
|
+
}
|
|
169
|
+
result[index + 3] = mapped[offset + 3] ?? 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
if (validationScopeOpen) {
|
|
176
|
+
await device.popErrorScope();
|
|
177
|
+
}
|
|
178
|
+
readback.unmap();
|
|
179
|
+
readback.destroy();
|
|
180
|
+
source.destroy();
|
|
181
|
+
target.destroy();
|
|
182
|
+
srgbSource?.destroy();
|
|
183
|
+
srgbTarget?.destroy();
|
|
184
|
+
for (const texture of lutTextures)
|
|
185
|
+
texture.destroy();
|
|
186
|
+
ctx.scratch.dispose();
|
|
187
|
+
ctx.uniformRing.dispose();
|
|
188
|
+
ctx.root.destroy();
|
|
189
|
+
device.destroy();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=gpu-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu-capture.js","sourceRoot":"","sources":["../src/gpu-capture.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { GameRenderEffect, GameRenderFrame } from "@nodetool-ai/protocol";
|
|
2
|
+
export { gameKeyAction } from "./input.js";
|
|
3
|
+
export { projectedCamera } from "./frame.js";
|
|
4
|
+
export type GameRendererBackend = "webgpu" | "canvas2d";
|
|
5
|
+
export type GameRendererEffect = GameRenderEffect;
|
|
6
|
+
export type GameHudEffectOrder = "beforeEffects" | "afterEffects";
|
|
7
|
+
export interface GameRendererCapabilities {
|
|
8
|
+
readonly backend: GameRendererBackend;
|
|
9
|
+
readonly core2D: true;
|
|
10
|
+
readonly gpuEffects: boolean;
|
|
11
|
+
readonly lighting: boolean;
|
|
12
|
+
readonly adapterType: "hardware" | "software" | "unknown";
|
|
13
|
+
readonly deviceStatus: "ready" | "lost" | "disposed";
|
|
14
|
+
readonly enabledFeatures: readonly string[];
|
|
15
|
+
readonly requestedFeatures: readonly string[];
|
|
16
|
+
readonly limits: {
|
|
17
|
+
readonly maxTextureDimension2D: number;
|
|
18
|
+
readonly maxBufferSize: number;
|
|
19
|
+
} | null;
|
|
20
|
+
readonly minimalRenderSucceeded: boolean;
|
|
21
|
+
readonly deviceLossCount: number;
|
|
22
|
+
readonly fallbackReason: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface GameRendererStats {
|
|
25
|
+
readonly backend: GameRendererBackend;
|
|
26
|
+
readonly visibleSprites: number;
|
|
27
|
+
readonly drawCalls: number;
|
|
28
|
+
readonly uploadedBytes: number;
|
|
29
|
+
readonly textureBytes: number;
|
|
30
|
+
readonly targetBytes: number;
|
|
31
|
+
readonly instanceBufferBytes: number;
|
|
32
|
+
}
|
|
33
|
+
export interface GameRenderer {
|
|
34
|
+
readonly backend: GameRendererBackend;
|
|
35
|
+
readonly canvas: HTMLCanvasElement;
|
|
36
|
+
readonly capabilities: GameRendererCapabilities;
|
|
37
|
+
render(frame: GameRenderFrame, interpolation: number): Promise<GameRendererStats>;
|
|
38
|
+
setEffects(effects: readonly GameRendererEffect[], hudOrder?: GameHudEffectOrder): void;
|
|
39
|
+
resize(width: number, height: number): void;
|
|
40
|
+
invalidateAsset(assetId: string): void;
|
|
41
|
+
dispose(): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAClD,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,cAAc,CAAC;AAElE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;IACrD,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnG,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,wBAAwB,CAAC;IAChD,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClF,UAAU,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EAAE,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACxF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/input.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAS/D"}
|
package/dist/input.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Map a physical key to the action name used by native game documents. */
|
|
2
|
+
export function gameKeyAction(code, key) {
|
|
3
|
+
switch (code) {
|
|
4
|
+
case "ArrowLeft":
|
|
5
|
+
case "KeyA": return "left";
|
|
6
|
+
case "ArrowRight":
|
|
7
|
+
case "KeyD": return "right";
|
|
8
|
+
case "ArrowUp":
|
|
9
|
+
case "KeyW": return "up";
|
|
10
|
+
case "ArrowDown":
|
|
11
|
+
case "KeyS": return "down";
|
|
12
|
+
case "Space": return "space";
|
|
13
|
+
default: return key.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,GAAW;IACrD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,MAAM,CAAC;QAC7C,KAAK,YAAY,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,OAAO,CAAC;QAC/C,KAAK,SAAS,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,IAAI,CAAC;QACzC,KAAK,WAAW,CAAC;QAAC,KAAK,MAAM,EAAE,OAAO,MAAM,CAAC;QAC7C,KAAK,OAAO,EAAE,OAAO,OAAO,CAAC;QAC7B,SAAS,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GameRenderFrame } from "@nodetool-ai/protocol";
|
|
2
|
+
export interface PixelBounds {
|
|
3
|
+
readonly x: number;
|
|
4
|
+
readonly y: number;
|
|
5
|
+
readonly width: number;
|
|
6
|
+
readonly height: number;
|
|
7
|
+
}
|
|
8
|
+
/** Conservative raster bounds for one rotated sprite, clipped to the viewport. */
|
|
9
|
+
export declare function spritePixelBounds(x: number, y: number, width: number, height: number, rotation: number, viewportWidth: number, viewportHeight: number): PixelBounds | null;
|
|
10
|
+
/** Multiplies world pixels by ambient and point-light irradiance without changing alpha. */
|
|
11
|
+
export declare function applyLighting(pixels: Uint8ClampedArray, width: number, height: number, frame: GameRenderFrame, interpolation: number, region?: {
|
|
12
|
+
readonly viewportWidth: number;
|
|
13
|
+
readonly viewportHeight: number;
|
|
14
|
+
readonly x: number;
|
|
15
|
+
readonly y: number;
|
|
16
|
+
}): void;
|
|
17
|
+
//# sourceMappingURL=lighting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lighting.d.ts","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,MAAM,WAAW,WAAW;IAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAExH,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EACrG,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAUnE;AAkBD,4FAA4F;AAC5F,wBAAgB,aAAa,CAC3B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GACnH,IAAI,CA8CN"}
|
package/dist/lighting.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { parseTint, projectedCamera } from "./frame.js";
|
|
2
|
+
/** Conservative raster bounds for one rotated sprite, clipped to the viewport. */
|
|
3
|
+
export function spritePixelBounds(x, y, width, height, rotation, viewportWidth, viewportHeight) {
|
|
4
|
+
const cosine = Math.abs(Math.cos(rotation));
|
|
5
|
+
const sine = Math.abs(Math.sin(rotation));
|
|
6
|
+
const halfWidth = (cosine * width + sine * height) / 2;
|
|
7
|
+
const halfHeight = (sine * width + cosine * height) / 2;
|
|
8
|
+
const left = Math.max(0, Math.floor(x - halfWidth - 1));
|
|
9
|
+
const top = Math.max(0, Math.floor(y - halfHeight - 1));
|
|
10
|
+
const right = Math.min(viewportWidth, Math.ceil(x + halfWidth + 1));
|
|
11
|
+
const bottom = Math.min(viewportHeight, Math.ceil(y + halfHeight + 1));
|
|
12
|
+
return right > left && bottom > top ? { x: left, y: top, width: right - left, height: bottom - top } : null;
|
|
13
|
+
}
|
|
14
|
+
const LINEAR_FROM_BYTE = Float32Array.from({ length: 256 }, (_, value) => {
|
|
15
|
+
const color = value / 255;
|
|
16
|
+
return color <= 0.04045 ? color / 12.92 : ((color + 0.055) / 1.055) ** 2.4;
|
|
17
|
+
});
|
|
18
|
+
const BYTE_FROM_LINEAR = Uint8Array.from({ length: 4097 }, (_, index) => {
|
|
19
|
+
const color = index / 4096;
|
|
20
|
+
return Math.round((color <= 0.0031308 ? color * 12.92 : 1.055 * color ** (1 / 2.4) - 0.055) * 255);
|
|
21
|
+
});
|
|
22
|
+
function linearColor(color) {
|
|
23
|
+
const channels = parseTint(color);
|
|
24
|
+
return [LINEAR_FROM_BYTE[Math.round(channels[0] * 255)],
|
|
25
|
+
LINEAR_FROM_BYTE[Math.round(channels[1] * 255)],
|
|
26
|
+
LINEAR_FROM_BYTE[Math.round(channels[2] * 255)]];
|
|
27
|
+
}
|
|
28
|
+
/** Multiplies world pixels by ambient and point-light irradiance without changing alpha. */
|
|
29
|
+
export function applyLighting(pixels, width, height, frame, interpolation, region) {
|
|
30
|
+
const lighting = frame.lighting;
|
|
31
|
+
if (!lighting)
|
|
32
|
+
return;
|
|
33
|
+
const camera = projectedCamera(frame, interpolation);
|
|
34
|
+
const viewportWidth = region?.viewportWidth ?? width;
|
|
35
|
+
const viewportHeight = region?.viewportHeight ?? height;
|
|
36
|
+
const originX = region?.x ?? 0;
|
|
37
|
+
const originY = region?.y ?? 0;
|
|
38
|
+
const scaleX = viewportWidth / frame.width * camera.zoom;
|
|
39
|
+
const scaleY = viewportHeight / frame.height * camera.zoom;
|
|
40
|
+
const ambient = linearColor(lighting.ambient.color);
|
|
41
|
+
const irradiance = new Float32Array(width * height * 3);
|
|
42
|
+
for (let index = 0; index < irradiance.length; index += 3) {
|
|
43
|
+
irradiance[index] = ambient[0] * lighting.ambient.intensity;
|
|
44
|
+
irradiance[index + 1] = ambient[1] * lighting.ambient.intensity;
|
|
45
|
+
irradiance[index + 2] = ambient[2] * lighting.ambient.intensity;
|
|
46
|
+
}
|
|
47
|
+
for (const point of lighting.points) {
|
|
48
|
+
const centerX = viewportWidth / 2 + (point.x - camera.x) * scaleX;
|
|
49
|
+
const centerY = viewportHeight / 2 - (point.y - camera.y) * scaleY;
|
|
50
|
+
const firstX = Math.max(0, Math.ceil(centerX - point.radius * scaleX - 0.5) - originX);
|
|
51
|
+
const lastX = Math.min(width - 1, Math.floor(centerX + point.radius * scaleX - 0.5) - originX);
|
|
52
|
+
const firstY = Math.max(0, Math.ceil(centerY - point.radius * scaleY - 0.5) - originY);
|
|
53
|
+
const lastY = Math.min(height - 1, Math.floor(centerY + point.radius * scaleY - 0.5) - originY);
|
|
54
|
+
const color = linearColor(point.color);
|
|
55
|
+
for (let y = firstY; y <= lastY; y += 1) {
|
|
56
|
+
const dy = (y + originY + 0.5 - centerY) / scaleY;
|
|
57
|
+
for (let x = firstX; x <= lastX; x += 1) {
|
|
58
|
+
const dx = (x + originX + 0.5 - centerX) / scaleX;
|
|
59
|
+
const distance = Math.hypot(dx, dy);
|
|
60
|
+
if (distance >= point.radius)
|
|
61
|
+
continue;
|
|
62
|
+
const amount = point.intensity * (1 - distance / point.radius) ** point.falloff;
|
|
63
|
+
const index = (y * width + x) * 3;
|
|
64
|
+
irradiance[index] += color[0] * amount;
|
|
65
|
+
irradiance[index + 1] += color[1] * amount;
|
|
66
|
+
irradiance[index + 2] += color[2] * amount;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
for (let index = 0, lightIndex = 0; index < pixels.length; index += 4, lightIndex += 3) {
|
|
71
|
+
if (pixels[index + 3] === 0)
|
|
72
|
+
continue;
|
|
73
|
+
for (let channel = 0; channel < 3; channel += 1) {
|
|
74
|
+
const linear = Math.min(1, LINEAR_FROM_BYTE[pixels[index + channel]] * irradiance[lightIndex + channel]);
|
|
75
|
+
pixels[index + channel] = BYTE_FROM_LINEAR[Math.round(linear * 4096)];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=lighting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lighting.js","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"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"}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GameRenderFrame } from "@nodetool-ai/protocol";
|
|
2
|
+
import type { GameHudEffectOrder, GameRendererEffect } from "./index.js";
|
|
3
|
+
export interface CaptureGameFrameOptions {
|
|
4
|
+
readonly resolveAsset?: (assetId: string) => Promise<Uint8Array | null>;
|
|
5
|
+
readonly interpolation?: number;
|
|
6
|
+
readonly scale?: number;
|
|
7
|
+
readonly onDiagnostic?: (message: string) => void;
|
|
8
|
+
readonly backend?: "canvas2d" | "webgpu";
|
|
9
|
+
readonly effects?: readonly GameRendererEffect[];
|
|
10
|
+
readonly hudEffectOrder?: GameHudEffectOrder;
|
|
11
|
+
}
|
|
12
|
+
/** Renders one frame to PNG with an explicit Canvas2D or GPU effect path. */
|
|
13
|
+
export declare function captureGameFrame(frame: GameRenderFrame, options?: CaptureGameFrameOptions): Promise<Uint8Array>;
|
|
14
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACjD,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAC;CAC9C;AAED,6EAA6E;AAC7E,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,UAAU,CAAC,CA8JzH"}
|