@motion-core/motion-gpu 0.5.0 → 0.7.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/README.md +35 -2
- package/dist/core/compute-bindgroup-cache.d.ts +13 -0
- package/dist/core/compute-bindgroup-cache.d.ts.map +1 -0
- package/dist/core/compute-bindgroup-cache.js +45 -0
- package/dist/core/compute-bindgroup-cache.js.map +1 -0
- package/dist/core/compute-shader.d.ts +48 -0
- package/dist/core/compute-shader.d.ts.map +1 -1
- package/dist/core/compute-shader.js +34 -1
- package/dist/core/compute-shader.js.map +1 -1
- package/dist/core/error-diagnostics.d.ts +8 -1
- package/dist/core/error-diagnostics.d.ts.map +1 -1
- package/dist/core/error-diagnostics.js +7 -3
- package/dist/core/error-diagnostics.js.map +1 -1
- package/dist/core/error-report.d.ts.map +1 -1
- package/dist/core/error-report.js +19 -1
- package/dist/core/error-report.js.map +1 -1
- package/dist/core/material.d.ts.map +1 -1
- package/dist/core/material.js +2 -1
- package/dist/core/material.js.map +1 -1
- package/dist/core/pointer.d.ts +96 -0
- package/dist/core/pointer.d.ts.map +1 -0
- package/dist/core/pointer.js +71 -0
- package/dist/core/pointer.js.map +1 -0
- package/dist/core/renderer.d.ts.map +1 -1
- package/dist/core/renderer.js +150 -85
- package/dist/core/renderer.js.map +1 -1
- package/dist/core/runtime-loop.d.ts.map +1 -1
- package/dist/core/runtime-loop.js +26 -14
- package/dist/core/runtime-loop.js.map +1 -1
- package/dist/core/shader.d.ts +7 -2
- package/dist/core/shader.d.ts.map +1 -1
- package/dist/core/shader.js +1 -0
- package/dist/core/shader.js.map +1 -1
- package/dist/core/textures.d.ts +4 -0
- package/dist/core/textures.d.ts.map +1 -1
- package/dist/core/textures.js +2 -1
- package/dist/core/textures.js.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/react/advanced.js +2 -1
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -1
- package/dist/react/use-pointer.d.ts +94 -0
- package/dist/react/use-pointer.d.ts.map +1 -0
- package/dist/react/use-pointer.js +285 -0
- package/dist/react/use-pointer.js.map +1 -0
- package/dist/svelte/advanced.js +2 -1
- package/dist/svelte/index.d.ts +2 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +2 -1
- package/dist/svelte/use-pointer.d.ts +94 -0
- package/dist/svelte/use-pointer.d.ts.map +1 -0
- package/dist/svelte/use-pointer.js +292 -0
- package/dist/svelte/use-pointer.js.map +1 -0
- package/package.json +1 -1
- package/src/lib/core/compute-bindgroup-cache.ts +73 -0
- package/src/lib/core/compute-shader.ts +86 -0
- package/src/lib/core/error-diagnostics.ts +29 -4
- package/src/lib/core/error-report.ts +26 -1
- package/src/lib/core/material.ts +2 -1
- package/src/lib/core/pointer.ts +177 -0
- package/src/lib/core/renderer.ts +198 -92
- package/src/lib/core/runtime-loop.ts +37 -16
- package/src/lib/core/shader.ts +13 -2
- package/src/lib/core/textures.ts +6 -1
- package/src/lib/core/types.ts +1 -1
- package/src/lib/react/index.ts +10 -0
- package/src/lib/react/use-pointer.ts +515 -0
- package/src/lib/svelte/index.ts +10 -0
- package/src/lib/svelte/use-pointer.ts +507 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-report.js","names":[],"sources":["../../src/lib/core/error-report.ts"],"sourcesContent":["import {\n\tgetShaderCompilationDiagnostics,\n\ttype ShaderCompilationDiagnostic\n} from './error-diagnostics.js';\nimport { formatShaderSourceLocation } from './shader.js';\n\n/**\n * Runtime phase in which an error occurred.\n */\nexport type MotionGPUErrorPhase = 'initialization' | 'render';\n\n/**\n * Stable machine-readable error category code.\n */\nexport type MotionGPUErrorCode =\n\t| 'WEBGPU_UNAVAILABLE'\n\t| 'WEBGPU_ADAPTER_UNAVAILABLE'\n\t| 'WEBGPU_CONTEXT_UNAVAILABLE'\n\t| 'WGSL_COMPILATION_FAILED'\n\t| 'MATERIAL_PREPROCESS_FAILED'\n\t| 'WEBGPU_DEVICE_LOST'\n\t| 'WEBGPU_UNCAPTURED_ERROR'\n\t| 'BIND_GROUP_MISMATCH'\n\t| 'RUNTIME_RESOURCE_MISSING'\n\t| 'UNIFORM_VALUE_INVALID'\n\t| 'STORAGE_BUFFER_OUT_OF_BOUNDS'\n\t| 'STORAGE_BUFFER_READ_FAILED'\n\t| 'RENDER_GRAPH_INVALID'\n\t| 'PINGPONG_CONFIGURATION_INVALID'\n\t| 'TEXTURE_USAGE_INVALID'\n\t| 'TEXTURE_REQUEST_FAILED'\n\t| 'TEXTURE_DECODE_UNAVAILABLE'\n\t| 'TEXTURE_REQUEST_ABORTED'\n\t| 'COMPUTE_COMPILATION_FAILED'\n\t| 'COMPUTE_CONTRACT_INVALID'\n\t| 'MOTIONGPU_RUNTIME_ERROR';\n\n/**\n * Severity level for user-facing diagnostics.\n */\nexport type MotionGPUErrorSeverity = 'error' | 'fatal';\n\n/**\n * One source-code line displayed in diagnostics snippet.\n */\nexport interface MotionGPUErrorSourceLine {\n\tnumber: number;\n\tcode: string;\n\thighlight: boolean;\n}\n\n/**\n * Structured source context displayed for shader compilation errors.\n */\nexport interface MotionGPUErrorSource {\n\tcomponent: string;\n\tlocation: string;\n\tline: number;\n\tcolumn?: number;\n\tsnippet: MotionGPUErrorSourceLine[];\n}\n\n/**\n * Optional runtime context captured with diagnostics payload.\n */\nexport interface MotionGPUErrorContext {\n\tmaterialSignature?: string;\n\tpassGraph?: {\n\t\tpassCount: number;\n\t\tenabledPassCount: number;\n\t\tinputs: string[];\n\t\toutputs: string[];\n\t};\n\tactiveRenderTargets: string[];\n}\n\n/**\n * Structured error payload used by UI diagnostics.\n */\nexport interface MotionGPUErrorReport {\n\t/**\n\t * Stable machine-readable category code.\n\t */\n\tcode: MotionGPUErrorCode;\n\t/**\n\t * Severity level used by diagnostics UIs and telemetry.\n\t */\n\tseverity: MotionGPUErrorSeverity;\n\t/**\n\t * Whether runtime may recover without full renderer re-creation.\n\t */\n\trecoverable: boolean;\n\t/**\n\t * Short category title.\n\t */\n\ttitle: string;\n\t/**\n\t * Primary human-readable message.\n\t */\n\tmessage: string;\n\t/**\n\t * Suggested remediation hint.\n\t */\n\thint: string;\n\t/**\n\t * Additional parsed details (for example WGSL line errors).\n\t */\n\tdetails: string[];\n\t/**\n\t * Stack trace lines when available.\n\t */\n\tstack: string[];\n\t/**\n\t * Original unmodified message.\n\t */\n\trawMessage: string;\n\t/**\n\t * Runtime phase where the error occurred.\n\t */\n\tphase: MotionGPUErrorPhase;\n\t/**\n\t * Optional source context for shader-related diagnostics.\n\t */\n\tsource: MotionGPUErrorSource | null;\n\t/**\n\t * Optional runtime context snapshot (material/pass graph/render targets).\n\t */\n\tcontext: MotionGPUErrorContext | null;\n}\n\n/**\n * Splits multi-line values into trimmed non-empty lines.\n */\nfunction splitLines(value: string): string[] {\n\treturn value\n\t\t.split('\\n')\n\t\t.map((line) => line.trim())\n\t\t.filter((line) => line.length > 0);\n}\n\nfunction toDisplayName(path: string): string {\n\tconst normalized = path.split(/[?#]/)[0] ?? path;\n\tconst chunks = normalized.split(/[\\\\/]/);\n\tconst last = chunks[chunks.length - 1];\n\treturn last && last.length > 0 ? last : path;\n}\n\nfunction toSnippet(source: string, line: number, radius = 3): MotionGPUErrorSourceLine[] {\n\tconst lines = source.replace(/\\r\\n?/g, '\\n').split('\\n');\n\tif (lines.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst targetLine = Math.min(Math.max(1, line), lines.length);\n\tconst start = Math.max(1, targetLine - radius);\n\tconst end = Math.min(lines.length, targetLine + radius);\n\tconst snippet: MotionGPUErrorSourceLine[] = [];\n\n\tfor (let index = start; index <= end; index += 1) {\n\t\tsnippet.push({\n\t\t\tnumber: index,\n\t\t\tcode: lines[index - 1] ?? '',\n\t\t\thighlight: index === targetLine\n\t\t});\n\t}\n\n\treturn snippet;\n}\n\nfunction buildSourceFromDiagnostics(error: unknown): MotionGPUErrorSource | null {\n\tconst diagnostics = getShaderCompilationDiagnostics(error);\n\tif (!diagnostics || diagnostics.diagnostics.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst primary = diagnostics.diagnostics.find((entry) => entry.sourceLocation !== null);\n\tif (!primary?.sourceLocation) {\n\t\treturn null;\n\t}\n\n\tconst location = primary.sourceLocation;\n\tconst column = primary.linePos && primary.linePos > 0 ? primary.linePos : undefined;\n\n\tif (location.kind === 'fragment') {\n\t\tconst component =\n\t\t\tdiagnostics.materialSource?.component ??\n\t\t\t(diagnostics.materialSource?.file\n\t\t\t\t? toDisplayName(diagnostics.materialSource.file)\n\t\t\t\t: 'User shader fragment');\n\t\tconst locationLabel = formatShaderSourceLocation(location) ?? `fragment line ${location.line}`;\n\t\treturn {\n\t\t\tcomponent,\n\t\t\tlocation: `${component} (${locationLabel})`,\n\t\t\tline: location.line,\n\t\t\t...(column !== undefined ? { column } : {}),\n\t\t\tsnippet: toSnippet(diagnostics.fragmentSource, location.line)\n\t\t};\n\t}\n\n\tif (location.kind === 'include') {\n\t\tconst includeName = location.include ?? 'unknown';\n\t\tconst includeSource = diagnostics.includeSources[includeName] ?? '';\n\t\tconst component = `#include <${includeName}>`;\n\t\tconst locationLabel = formatShaderSourceLocation(location) ?? `include <${includeName}>`;\n\t\treturn {\n\t\t\tcomponent,\n\t\t\tlocation: `${component} (${locationLabel})`,\n\t\t\tline: location.line,\n\t\t\t...(column !== undefined ? { column } : {}),\n\t\t\tsnippet: toSnippet(includeSource, location.line)\n\t\t};\n\t}\n\n\tconst defineName = location.define ?? 'unknown';\n\tconst defineLine = Math.max(1, location.line);\n\tconst component = `#define ${defineName}`;\n\tconst locationLabel =\n\t\tformatShaderSourceLocation(location) ?? `define \"${defineName}\" line ${defineLine}`;\n\treturn {\n\t\tcomponent,\n\t\tlocation: `${component} (${locationLabel})`,\n\t\tline: defineLine,\n\t\t...(column !== undefined ? { column } : {}),\n\t\tsnippet: toSnippet(diagnostics.defineBlockSource ?? '', defineLine, 2)\n\t};\n}\n\nfunction formatDiagnosticMessage(entry: ShaderCompilationDiagnostic): string {\n\tconst sourceLabel = formatShaderSourceLocation(entry.sourceLocation);\n\tconst generatedLineLabel =\n\t\tentry.generatedLine > 0 ? `generated WGSL line ${entry.generatedLine}` : null;\n\tconst labels = [sourceLabel, generatedLineLabel].filter((value) => Boolean(value));\n\tif (labels.length === 0) {\n\t\treturn entry.message;\n\t}\n\n\treturn `[${labels.join(' | ')}] ${entry.message}`;\n}\n\n/**\n * Maps known WebGPU/WGSL error patterns to a user-facing title and hint.\n */\nfunction classifyErrorMessage(\n\tmessage: string\n): Pick<MotionGPUErrorReport, 'code' | 'severity' | 'recoverable' | 'title' | 'hint'> {\n\tif (message.includes('WebGPU is not available in this browser')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_UNAVAILABLE',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'WebGPU unavailable',\n\t\t\thint: 'Use a browser with WebGPU enabled (latest Chrome/Edge/Safari TP) and secure context.'\n\t\t};\n\t}\n\n\tif (message.includes('Unable to acquire WebGPU adapter')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_ADAPTER_UNAVAILABLE',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'WebGPU adapter unavailable',\n\t\t\thint: 'GPU adapter request failed. Check browser permissions, flags and device support.'\n\t\t};\n\t}\n\n\tif (message.includes('Canvas does not support webgpu context')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_CONTEXT_UNAVAILABLE',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Canvas cannot create WebGPU context',\n\t\t\thint: 'Make sure this canvas is attached to DOM and not using an unsupported context option.'\n\t\t};\n\t}\n\n\tif (message.includes('WGSL compilation failed')) {\n\t\treturn {\n\t\t\tcode: 'WGSL_COMPILATION_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'WGSL compilation failed',\n\t\t\thint: 'Check WGSL line numbers below and verify struct/binding/function signatures.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Invalid include directive in fragment shader.') ||\n\t\tmessage.includes('Unknown include \"') ||\n\t\tmessage.includes('Circular include detected for \"') ||\n\t\tmessage.includes('Invalid define value for \"') ||\n\t\tmessage.includes('Invalid include \"')\n\t) {\n\t\treturn {\n\t\t\tcode: 'MATERIAL_PREPROCESS_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Material preprocess failed',\n\t\t\thint: 'Validate #include keys, define values and include expansion order before retrying.'\n\t\t};\n\t}\n\n\tif (message.includes('Compute shader compilation failed')) {\n\t\treturn {\n\t\t\tcode: 'COMPUTE_COMPILATION_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Compute shader compilation failed',\n\t\t\thint: 'Check WGSL compute shader sources below and verify storage bindings.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes(\n\t\t\t'Compute shader must declare `@compute @workgroup_size(...) fn compute(...)`.'\n\t\t) ||\n\t\tmessage.includes('Compute shader must include a `@builtin(global_invocation_id)` parameter.') ||\n\t\tmessage.includes('Could not extract @workgroup_size from compute shader source.') ||\n\t\tmessage.includes('@workgroup_size dimensions must be integers in range') ||\n\t\tmessage.includes('Unsupported storage buffer access mode \"')\n\t) {\n\t\treturn {\n\t\t\tcode: 'COMPUTE_CONTRACT_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Compute contract is invalid',\n\t\t\thint: 'Ensure compute shader contract (@compute, @workgroup_size, global_invocation_id, storage access) is valid.'\n\t\t};\n\t}\n\n\tif (message.includes('WebGPU device lost') || message.includes('Device Lost')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_DEVICE_LOST',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'WebGPU device lost',\n\t\t\thint: 'GPU device/context was lost. Recreate the renderer and check OS/GPU stability.'\n\t\t};\n\t}\n\n\tif (message.includes('WebGPU uncaptured error')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_UNCAPTURED_ERROR',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'WebGPU uncaptured error',\n\t\t\thint: 'A GPU command failed asynchronously. Review details and validate resource/state usage.'\n\t\t};\n\t}\n\n\tif (message.includes('CreateBindGroup') || message.includes('bind group layout')) {\n\t\treturn {\n\t\t\tcode: 'BIND_GROUP_MISMATCH',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Bind group mismatch',\n\t\t\thint: 'Bindings in shader and runtime resources are out of sync. Verify uniforms/textures layout.'\n\t\t};\n\t}\n\n\tif (message.includes('Storage buffer \"') && message.includes('write out of bounds:')) {\n\t\treturn {\n\t\t\tcode: 'STORAGE_BUFFER_OUT_OF_BOUNDS',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Storage buffer write out of bounds',\n\t\t\thint: 'Ensure offset + write byte length does not exceed declared storage buffer size.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Cannot read storage buffer \"') ||\n\t\tmessage.includes('Cannot read storage buffer: GPU device unavailable.') ||\n\t\tmessage.includes('not allocated on GPU.')\n\t) {\n\t\treturn {\n\t\t\tcode: 'STORAGE_BUFFER_READ_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Storage buffer read failed',\n\t\t\thint: 'Readbacks require an initialized renderer, allocated GPU buffer and active device.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Unknown uniform \"') ||\n\t\tmessage.includes('Unknown uniform type for \"') ||\n\t\tmessage.includes('Unknown texture \"') ||\n\t\tmessage.includes('Unknown storage buffer \"') ||\n\t\tmessage.includes('Missing definition for storage buffer \"') ||\n\t\tmessage.includes('Missing texture definition for \"') ||\n\t\t(message.includes('Storage buffer \"') && message.includes('\" not allocated.')) ||\n\t\t(message.includes('Storage texture \"') && message.includes('\" not allocated.'))\n\t) {\n\t\treturn {\n\t\t\tcode: 'RUNTIME_RESOURCE_MISSING',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Runtime resource binding failed',\n\t\t\thint: 'Check material declarations and runtime keys for uniforms, textures and storage resources.'\n\t\t};\n\t}\n\n\tif (message.includes('Uniform ') && message.includes(' value must')) {\n\t\treturn {\n\t\t\tcode: 'UNIFORM_VALUE_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Uniform value is invalid',\n\t\t\thint: 'Provide finite values with tuple/matrix sizes matching the uniform type.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Render pass #') ||\n\t\tmessage.includes('Render graph references unknown runtime target')\n\t) {\n\t\treturn {\n\t\t\tcode: 'RENDER_GRAPH_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Render graph configuration is invalid',\n\t\t\thint: 'Verify pass inputs/outputs, declared render targets and execution order.'\n\t\t};\n\t}\n\n\tif (message.includes('PingPongComputePass must provide a target texture key.')) {\n\t\treturn {\n\t\t\tcode: 'PINGPONG_CONFIGURATION_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Ping-pong compute pass is misconfigured',\n\t\t\thint: 'Configure a valid target texture key for PingPongComputePass.'\n\t\t};\n\t}\n\n\tif (message.includes('Destination texture needs to have CopyDst')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_USAGE_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Invalid texture usage flags',\n\t\t\thint: 'Texture used as upload destination must include CopyDst (and often RenderAttachment).'\n\t\t};\n\t}\n\n\tif (message.includes('Texture request failed')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_REQUEST_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Texture request failed',\n\t\t\thint: 'Verify texture URL, CORS policy and response status before retrying.'\n\t\t};\n\t}\n\n\tif (message.includes('createImageBitmap is not available in this runtime')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_DECODE_UNAVAILABLE',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'Texture decode unavailable',\n\t\t\thint: 'Runtime lacks createImageBitmap support. Use a browser/runtime with image bitmap decoding.'\n\t\t};\n\t}\n\n\tif (message.toLowerCase().includes('texture request was aborted')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_REQUEST_ABORTED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Texture request aborted',\n\t\t\thint: 'Texture load was cancelled. Retry the request when source inputs stabilize.'\n\t\t};\n\t}\n\n\treturn {\n\t\tcode: 'MOTIONGPU_RUNTIME_ERROR',\n\t\tseverity: 'error',\n\t\trecoverable: true,\n\t\ttitle: 'MotionGPU render error',\n\t\thint: 'Review technical details below. If issue persists, isolate shader/uniform/texture changes.'\n\t};\n}\n\n/**\n * Converts unknown errors to a consistent, display-ready error report.\n *\n * @param error - Unknown thrown value.\n * @param phase - Phase during which error occurred.\n * @returns Normalized error report.\n */\nexport function toMotionGPUErrorReport(\n\terror: unknown,\n\tphase: MotionGPUErrorPhase\n): MotionGPUErrorReport {\n\tconst shaderDiagnostics = getShaderCompilationDiagnostics(error);\n\tconst rawMessage =\n\t\terror instanceof Error\n\t\t\t? error.message\n\t\t\t: typeof error === 'string'\n\t\t\t\t? error\n\t\t\t\t: 'Unknown FragCanvas error';\n\tconst rawLines = splitLines(rawMessage);\n\tconst defaultMessage = rawLines[0] ?? rawMessage;\n\tconst defaultDetails = rawLines.slice(1);\n\tconst source = buildSourceFromDiagnostics(error);\n\tconst context = shaderDiagnostics?.runtimeContext ?? null;\n\tconst message =\n\t\tshaderDiagnostics && shaderDiagnostics.diagnostics[0]\n\t\t\t? formatDiagnosticMessage(shaderDiagnostics.diagnostics[0])\n\t\t\t: defaultMessage;\n\tconst details = shaderDiagnostics\n\t\t? shaderDiagnostics.diagnostics.slice(1).map((entry) => formatDiagnosticMessage(entry))\n\t\t: defaultDetails;\n\tconst stack =\n\t\terror instanceof Error && error.stack\n\t\t\t? splitLines(error.stack).filter((line) => line !== message)\n\t\t\t: [];\n\tconst classification = classifyErrorMessage(rawMessage);\n\n\treturn {\n\t\tcode: classification.code,\n\t\tseverity: classification.severity,\n\t\trecoverable: classification.recoverable,\n\t\ttitle: classification.title,\n\t\tmessage,\n\t\thint: classification.hint,\n\t\tdetails,\n\t\tstack,\n\t\trawMessage,\n\t\tphase,\n\t\tsource,\n\t\tcontext\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"error-report.js","names":[],"sources":["../../src/lib/core/error-report.ts"],"sourcesContent":["import {\n\tgetShaderCompilationDiagnostics,\n\ttype ShaderCompilationDiagnostic\n} from './error-diagnostics.js';\nimport { formatShaderSourceLocation } from './shader.js';\n\n/**\n * Runtime phase in which an error occurred.\n */\nexport type MotionGPUErrorPhase = 'initialization' | 'render';\n\n/**\n * Stable machine-readable error category code.\n */\nexport type MotionGPUErrorCode =\n\t| 'WEBGPU_UNAVAILABLE'\n\t| 'WEBGPU_ADAPTER_UNAVAILABLE'\n\t| 'WEBGPU_CONTEXT_UNAVAILABLE'\n\t| 'WGSL_COMPILATION_FAILED'\n\t| 'MATERIAL_PREPROCESS_FAILED'\n\t| 'WEBGPU_DEVICE_LOST'\n\t| 'WEBGPU_UNCAPTURED_ERROR'\n\t| 'BIND_GROUP_MISMATCH'\n\t| 'RUNTIME_RESOURCE_MISSING'\n\t| 'UNIFORM_VALUE_INVALID'\n\t| 'STORAGE_BUFFER_OUT_OF_BOUNDS'\n\t| 'STORAGE_BUFFER_READ_FAILED'\n\t| 'RENDER_GRAPH_INVALID'\n\t| 'PINGPONG_CONFIGURATION_INVALID'\n\t| 'TEXTURE_USAGE_INVALID'\n\t| 'TEXTURE_REQUEST_FAILED'\n\t| 'TEXTURE_DECODE_UNAVAILABLE'\n\t| 'TEXTURE_REQUEST_ABORTED'\n\t| 'COMPUTE_COMPILATION_FAILED'\n\t| 'COMPUTE_CONTRACT_INVALID'\n\t| 'MOTIONGPU_RUNTIME_ERROR';\n\n/**\n * Severity level for user-facing diagnostics.\n */\nexport type MotionGPUErrorSeverity = 'error' | 'fatal';\n\n/**\n * One source-code line displayed in diagnostics snippet.\n */\nexport interface MotionGPUErrorSourceLine {\n\tnumber: number;\n\tcode: string;\n\thighlight: boolean;\n}\n\n/**\n * Structured source context displayed for shader compilation errors.\n */\nexport interface MotionGPUErrorSource {\n\tcomponent: string;\n\tlocation: string;\n\tline: number;\n\tcolumn?: number;\n\tsnippet: MotionGPUErrorSourceLine[];\n}\n\n/**\n * Optional runtime context captured with diagnostics payload.\n */\nexport interface MotionGPUErrorContext {\n\tmaterialSignature?: string;\n\tpassGraph?: {\n\t\tpassCount: number;\n\t\tenabledPassCount: number;\n\t\tinputs: string[];\n\t\toutputs: string[];\n\t};\n\tactiveRenderTargets: string[];\n}\n\n/**\n * Structured error payload used by UI diagnostics.\n */\nexport interface MotionGPUErrorReport {\n\t/**\n\t * Stable machine-readable category code.\n\t */\n\tcode: MotionGPUErrorCode;\n\t/**\n\t * Severity level used by diagnostics UIs and telemetry.\n\t */\n\tseverity: MotionGPUErrorSeverity;\n\t/**\n\t * Whether runtime may recover without full renderer re-creation.\n\t */\n\trecoverable: boolean;\n\t/**\n\t * Short category title.\n\t */\n\ttitle: string;\n\t/**\n\t * Primary human-readable message.\n\t */\n\tmessage: string;\n\t/**\n\t * Suggested remediation hint.\n\t */\n\thint: string;\n\t/**\n\t * Additional parsed details (for example WGSL line errors).\n\t */\n\tdetails: string[];\n\t/**\n\t * Stack trace lines when available.\n\t */\n\tstack: string[];\n\t/**\n\t * Original unmodified message.\n\t */\n\trawMessage: string;\n\t/**\n\t * Runtime phase where the error occurred.\n\t */\n\tphase: MotionGPUErrorPhase;\n\t/**\n\t * Optional source context for shader-related diagnostics.\n\t */\n\tsource: MotionGPUErrorSource | null;\n\t/**\n\t * Optional runtime context snapshot (material/pass graph/render targets).\n\t */\n\tcontext: MotionGPUErrorContext | null;\n}\n\n/**\n * Splits multi-line values into trimmed non-empty lines.\n */\nfunction splitLines(value: string): string[] {\n\treturn value\n\t\t.split('\\n')\n\t\t.map((line) => line.trim())\n\t\t.filter((line) => line.length > 0);\n}\n\nfunction toDisplayName(path: string): string {\n\tconst normalized = path.split(/[?#]/)[0] ?? path;\n\tconst chunks = normalized.split(/[\\\\/]/);\n\tconst last = chunks[chunks.length - 1];\n\treturn last && last.length > 0 ? last : path;\n}\n\nfunction toSnippet(source: string, line: number, radius = 3): MotionGPUErrorSourceLine[] {\n\tconst lines = source.replace(/\\r\\n?/g, '\\n').split('\\n');\n\tif (lines.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst targetLine = Math.min(Math.max(1, line), lines.length);\n\tconst start = Math.max(1, targetLine - radius);\n\tconst end = Math.min(lines.length, targetLine + radius);\n\tconst snippet: MotionGPUErrorSourceLine[] = [];\n\n\tfor (let index = start; index <= end; index += 1) {\n\t\tsnippet.push({\n\t\t\tnumber: index,\n\t\t\tcode: lines[index - 1] ?? '',\n\t\t\thighlight: index === targetLine\n\t\t});\n\t}\n\n\treturn snippet;\n}\n\nfunction buildSourceFromDiagnostics(error: unknown): MotionGPUErrorSource | null {\n\tconst diagnostics = getShaderCompilationDiagnostics(error);\n\tif (!diagnostics || diagnostics.diagnostics.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst primary = diagnostics.diagnostics.find((entry) => entry.sourceLocation !== null);\n\tif (!primary?.sourceLocation) {\n\t\treturn null;\n\t}\n\n\tconst location = primary.sourceLocation;\n\tconst column = primary.linePos && primary.linePos > 0 ? primary.linePos : undefined;\n\n\tif (location.kind === 'fragment') {\n\t\tconst component =\n\t\t\tdiagnostics.materialSource?.component ??\n\t\t\t(diagnostics.materialSource?.file\n\t\t\t\t? toDisplayName(diagnostics.materialSource.file)\n\t\t\t\t: 'User shader fragment');\n\t\tconst locationLabel = formatShaderSourceLocation(location) ?? `fragment line ${location.line}`;\n\t\treturn {\n\t\t\tcomponent,\n\t\t\tlocation: `${component} (${locationLabel})`,\n\t\t\tline: location.line,\n\t\t\t...(column !== undefined ? { column } : {}),\n\t\t\tsnippet: toSnippet(diagnostics.fragmentSource, location.line)\n\t\t};\n\t}\n\n\tif (location.kind === 'include') {\n\t\tconst includeName = location.include ?? 'unknown';\n\t\tconst includeSource = diagnostics.includeSources[includeName] ?? '';\n\t\tconst component = `#include <${includeName}>`;\n\t\tconst locationLabel = formatShaderSourceLocation(location) ?? `include <${includeName}>`;\n\t\treturn {\n\t\t\tcomponent,\n\t\t\tlocation: `${component} (${locationLabel})`,\n\t\t\tline: location.line,\n\t\t\t...(column !== undefined ? { column } : {}),\n\t\t\tsnippet: toSnippet(includeSource, location.line)\n\t\t};\n\t}\n\n\tif (location.kind === 'compute') {\n\t\tconst computeSource = diagnostics.computeSource ?? diagnostics.fragmentSource;\n\t\tconst component = 'Compute shader';\n\t\tconst locationLabel = formatShaderSourceLocation(location) ?? `compute line ${location.line}`;\n\t\treturn {\n\t\t\tcomponent,\n\t\t\tlocation: `${component} (${locationLabel})`,\n\t\t\tline: location.line,\n\t\t\t...(column !== undefined ? { column } : {}),\n\t\t\tsnippet: toSnippet(computeSource, location.line)\n\t\t};\n\t}\n\n\tconst defineName = location.define ?? 'unknown';\n\tconst defineLine = Math.max(1, location.line);\n\tconst component = `#define ${defineName}`;\n\tconst locationLabel =\n\t\tformatShaderSourceLocation(location) ?? `define \"${defineName}\" line ${defineLine}`;\n\treturn {\n\t\tcomponent,\n\t\tlocation: `${component} (${locationLabel})`,\n\t\tline: defineLine,\n\t\t...(column !== undefined ? { column } : {}),\n\t\tsnippet: toSnippet(diagnostics.defineBlockSource ?? '', defineLine, 2)\n\t};\n}\n\nfunction formatDiagnosticMessage(entry: ShaderCompilationDiagnostic): string {\n\tconst sourceLabel = formatShaderSourceLocation(entry.sourceLocation);\n\tconst generatedLineLabel =\n\t\tentry.generatedLine > 0 ? `generated WGSL line ${entry.generatedLine}` : null;\n\tconst labels = [sourceLabel, generatedLineLabel].filter((value) => Boolean(value));\n\tif (labels.length === 0) {\n\t\treturn entry.message;\n\t}\n\n\treturn `[${labels.join(' | ')}] ${entry.message}`;\n}\n\n/**\n * Maps known WebGPU/WGSL error patterns to a user-facing title and hint.\n */\nfunction classifyErrorMessage(\n\tmessage: string\n): Pick<MotionGPUErrorReport, 'code' | 'severity' | 'recoverable' | 'title' | 'hint'> {\n\tif (message.includes('WebGPU is not available in this browser')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_UNAVAILABLE',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'WebGPU unavailable',\n\t\t\thint: 'Use a browser with WebGPU enabled (latest Chrome/Edge/Safari TP) and secure context.'\n\t\t};\n\t}\n\n\tif (message.includes('Unable to acquire WebGPU adapter')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_ADAPTER_UNAVAILABLE',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'WebGPU adapter unavailable',\n\t\t\thint: 'GPU adapter request failed. Check browser permissions, flags and device support.'\n\t\t};\n\t}\n\n\tif (message.includes('Canvas does not support webgpu context')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_CONTEXT_UNAVAILABLE',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Canvas cannot create WebGPU context',\n\t\t\thint: 'Make sure this canvas is attached to DOM and not using an unsupported context option.'\n\t\t};\n\t}\n\n\tif (message.includes('WGSL compilation failed')) {\n\t\treturn {\n\t\t\tcode: 'WGSL_COMPILATION_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'WGSL compilation failed',\n\t\t\thint: 'Check WGSL line numbers below and verify struct/binding/function signatures.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Invalid include directive in fragment shader.') ||\n\t\tmessage.includes('Unknown include \"') ||\n\t\tmessage.includes('Circular include detected for \"') ||\n\t\tmessage.includes('Invalid define value for \"') ||\n\t\tmessage.includes('Invalid include \"')\n\t) {\n\t\treturn {\n\t\t\tcode: 'MATERIAL_PREPROCESS_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Material preprocess failed',\n\t\t\thint: 'Validate #include keys, define values and include expansion order before retrying.'\n\t\t};\n\t}\n\n\tif (message.includes('Compute shader compilation failed')) {\n\t\treturn {\n\t\t\tcode: 'COMPUTE_COMPILATION_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Compute shader compilation failed',\n\t\t\thint: 'Check WGSL compute shader sources below and verify storage bindings.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes(\n\t\t\t'Compute shader must declare `@compute @workgroup_size(...) fn compute(...)`.'\n\t\t) ||\n\t\tmessage.includes('Compute shader must include a `@builtin(global_invocation_id)` parameter.') ||\n\t\tmessage.includes('Could not extract @workgroup_size from compute shader source.') ||\n\t\tmessage.includes('@workgroup_size dimensions must be integers in range') ||\n\t\tmessage.includes('Unsupported storage buffer access mode \"')\n\t) {\n\t\treturn {\n\t\t\tcode: 'COMPUTE_CONTRACT_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Compute contract is invalid',\n\t\t\thint: 'Ensure compute shader contract (@compute, @workgroup_size, global_invocation_id, storage access) is valid.'\n\t\t};\n\t}\n\n\tif (message.includes('WebGPU device lost') || message.includes('Device Lost')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_DEVICE_LOST',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'WebGPU device lost',\n\t\t\thint: 'GPU device/context was lost. Recreate the renderer and check OS/GPU stability.'\n\t\t};\n\t}\n\n\tif (message.includes('WebGPU uncaptured error')) {\n\t\treturn {\n\t\t\tcode: 'WEBGPU_UNCAPTURED_ERROR',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'WebGPU uncaptured error',\n\t\t\thint: 'A GPU command failed asynchronously. Review details and validate resource/state usage.'\n\t\t};\n\t}\n\n\tif (message.includes('CreateBindGroup') || message.includes('bind group layout')) {\n\t\treturn {\n\t\t\tcode: 'BIND_GROUP_MISMATCH',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Bind group mismatch',\n\t\t\thint: 'Bindings in shader and runtime resources are out of sync. Verify uniforms/textures layout.'\n\t\t};\n\t}\n\n\tif (message.includes('Storage buffer \"') && message.includes('write out of bounds:')) {\n\t\treturn {\n\t\t\tcode: 'STORAGE_BUFFER_OUT_OF_BOUNDS',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Storage buffer write out of bounds',\n\t\t\thint: 'Ensure offset + write byte length does not exceed declared storage buffer size.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Cannot read storage buffer \"') ||\n\t\tmessage.includes('Cannot read storage buffer: GPU device unavailable.') ||\n\t\tmessage.includes('not allocated on GPU.')\n\t) {\n\t\treturn {\n\t\t\tcode: 'STORAGE_BUFFER_READ_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Storage buffer read failed',\n\t\t\thint: 'Readbacks require an initialized renderer, allocated GPU buffer and active device.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Unknown uniform \"') ||\n\t\tmessage.includes('Unknown uniform type for \"') ||\n\t\tmessage.includes('Unknown texture \"') ||\n\t\tmessage.includes('Unknown storage buffer \"') ||\n\t\tmessage.includes('Missing definition for storage buffer \"') ||\n\t\tmessage.includes('Missing texture definition for \"') ||\n\t\t(message.includes('Storage buffer \"') && message.includes('\" not allocated.')) ||\n\t\t(message.includes('Storage texture \"') && message.includes('\" not allocated.'))\n\t) {\n\t\treturn {\n\t\t\tcode: 'RUNTIME_RESOURCE_MISSING',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Runtime resource binding failed',\n\t\t\thint: 'Check material declarations and runtime keys for uniforms, textures and storage resources.'\n\t\t};\n\t}\n\n\tif (message.includes('Uniform ') && message.includes(' value must')) {\n\t\treturn {\n\t\t\tcode: 'UNIFORM_VALUE_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Uniform value is invalid',\n\t\t\thint: 'Provide finite values with tuple/matrix sizes matching the uniform type.'\n\t\t};\n\t}\n\n\tif (\n\t\tmessage.includes('Render pass #') ||\n\t\tmessage.includes('Render graph references unknown runtime target')\n\t) {\n\t\treturn {\n\t\t\tcode: 'RENDER_GRAPH_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Render graph configuration is invalid',\n\t\t\thint: 'Verify pass inputs/outputs, declared render targets and execution order.'\n\t\t};\n\t}\n\n\tif (message.includes('PingPongComputePass must provide a target texture key.')) {\n\t\treturn {\n\t\t\tcode: 'PINGPONG_CONFIGURATION_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Ping-pong compute pass is misconfigured',\n\t\t\thint: 'Configure a valid target texture key for PingPongComputePass.'\n\t\t};\n\t}\n\n\tif (message.includes('Destination texture needs to have CopyDst')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_USAGE_INVALID',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Invalid texture usage flags',\n\t\t\thint: 'Texture used as upload destination must include CopyDst (and often RenderAttachment).'\n\t\t};\n\t}\n\n\tif (message.includes('Texture request failed')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_REQUEST_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Texture request failed',\n\t\t\thint: 'Verify texture URL, CORS policy and response status before retrying.'\n\t\t};\n\t}\n\n\tif (message.includes('createImageBitmap is not available in this runtime')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_DECODE_UNAVAILABLE',\n\t\t\tseverity: 'fatal',\n\t\t\trecoverable: false,\n\t\t\ttitle: 'Texture decode unavailable',\n\t\t\thint: 'Runtime lacks createImageBitmap support. Use a browser/runtime with image bitmap decoding.'\n\t\t};\n\t}\n\n\tif (message.toLowerCase().includes('texture request was aborted')) {\n\t\treturn {\n\t\t\tcode: 'TEXTURE_REQUEST_ABORTED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Texture request aborted',\n\t\t\thint: 'Texture load was cancelled. Retry the request when source inputs stabilize.'\n\t\t};\n\t}\n\n\treturn {\n\t\tcode: 'MOTIONGPU_RUNTIME_ERROR',\n\t\tseverity: 'error',\n\t\trecoverable: true,\n\t\ttitle: 'MotionGPU render error',\n\t\thint: 'Review technical details below. If issue persists, isolate shader/uniform/texture changes.'\n\t};\n}\n\n/**\n * Converts unknown errors to a consistent, display-ready error report.\n *\n * @param error - Unknown thrown value.\n * @param phase - Phase during which error occurred.\n * @returns Normalized error report.\n */\nexport function toMotionGPUErrorReport(\n\terror: unknown,\n\tphase: MotionGPUErrorPhase\n): MotionGPUErrorReport {\n\tconst shaderDiagnostics = getShaderCompilationDiagnostics(error);\n\tconst rawMessage =\n\t\terror instanceof Error\n\t\t\t? error.message\n\t\t\t: typeof error === 'string'\n\t\t\t\t? error\n\t\t\t\t: 'Unknown FragCanvas error';\n\tconst rawLines = splitLines(rawMessage);\n\tconst defaultMessage = rawLines[0] ?? rawMessage;\n\tconst defaultDetails = rawLines.slice(1);\n\tconst source = buildSourceFromDiagnostics(error);\n\tconst context = shaderDiagnostics?.runtimeContext ?? null;\n\tconst message =\n\t\tshaderDiagnostics && shaderDiagnostics.diagnostics[0]\n\t\t\t? formatDiagnosticMessage(shaderDiagnostics.diagnostics[0])\n\t\t\t: defaultMessage;\n\tconst details = shaderDiagnostics\n\t\t? shaderDiagnostics.diagnostics.slice(1).map((entry) => formatDiagnosticMessage(entry))\n\t\t: defaultDetails;\n\tconst stack =\n\t\terror instanceof Error && error.stack\n\t\t\t? splitLines(error.stack).filter((line) => line !== message)\n\t\t\t: [];\n\tlet classification = classifyErrorMessage(rawMessage);\n\tif (\n\t\tshaderDiagnostics?.shaderStage === 'compute' &&\n\t\tclassification.code === 'WGSL_COMPILATION_FAILED'\n\t) {\n\t\tclassification = {\n\t\t\tcode: 'COMPUTE_COMPILATION_FAILED',\n\t\t\tseverity: 'error',\n\t\t\trecoverable: true,\n\t\t\ttitle: 'Compute shader compilation failed',\n\t\t\thint: 'Check WGSL compute shader sources below and verify storage bindings.'\n\t\t};\n\t}\n\n\treturn {\n\t\tcode: classification.code,\n\t\tseverity: classification.severity,\n\t\trecoverable: classification.recoverable,\n\t\ttitle: classification.title,\n\t\tmessage,\n\t\thint: classification.hint,\n\t\tdetails,\n\t\tstack,\n\t\trawMessage,\n\t\tphase,\n\t\tsource,\n\t\tcontext\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/lib/core/material.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/lib/core/material.ts"],"names":[],"mappings":"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"}
|
package/dist/core/material.js
CHANGED
|
@@ -203,7 +203,8 @@ function buildTextureConfigSignature(textures, textureKeys) {
|
|
|
203
203
|
normalized.anisotropy,
|
|
204
204
|
normalized.filter,
|
|
205
205
|
normalized.addressModeU,
|
|
206
|
-
normalized.addressModeV
|
|
206
|
+
normalized.addressModeV,
|
|
207
|
+
normalized.fragmentVisible ? "1" : "0"
|
|
207
208
|
].join(":");
|
|
208
209
|
}
|
|
209
210
|
return signature;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.js","names":[],"sources":["../../src/lib/core/material.ts"],"sourcesContent":["import { normalizeTextureDefinition } from './textures.js';\nimport type { MaterialSourceMetadata } from './error-diagnostics.js';\nimport {\n\tassertUniformName,\n\tassertUniformValueForType,\n\tinferUniformType,\n\tresolveUniformLayout\n} from './uniforms.js';\nimport {\n\tnormalizeDefines,\n\tnormalizeIncludes,\n\tpreprocessMaterialFragment,\n\ttoDefineLine,\n\ttype MaterialLineMap,\n\ttype PreprocessedMaterialFragment\n} from './material-preprocess.js';\nimport { assertStorageBufferDefinition, assertStorageTextureFormat } from './storage-buffers.js';\nimport type {\n\tStorageBufferDefinition,\n\tStorageBufferDefinitionMap,\n\tTextureData,\n\tTextureDefinition,\n\tTextureDefinitionMap,\n\tTextureValue,\n\tTypedUniform,\n\tUniformMap,\n\tUniformValue\n} from './types.js';\n\n/**\n * Typed compile-time define declaration.\n */\nexport type TypedMaterialDefineValue =\n\t| {\n\t\t\t/**\n\t\t\t * WGSL scalar type.\n\t\t\t */\n\t\t\ttype: 'bool';\n\t\t\t/**\n\t\t\t * Literal value for the selected WGSL type.\n\t\t\t */\n\t\t\tvalue: boolean;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * WGSL scalar type.\n\t\t\t */\n\t\t\ttype: 'f32' | 'i32' | 'u32';\n\t\t\t/**\n\t\t\t * Literal value for the selected WGSL type.\n\t\t\t */\n\t\t\tvalue: number;\n\t };\n\n/**\n * Allowed value types for WGSL `const` define injection.\n */\nexport type MaterialDefineValue = boolean | number | TypedMaterialDefineValue;\n\n/**\n * Define map keyed by uniform-compatible identifier names.\n */\nexport type MaterialDefines<TKey extends string = string> = Record<TKey, MaterialDefineValue>;\n\n/**\n * Include map keyed by include identifier used in `#include <name>` directives.\n */\nexport type MaterialIncludes<TKey extends string = string> = Record<TKey, string>;\n\n/**\n * External material input accepted by {@link defineMaterial}.\n */\nexport interface FragMaterialInput<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n> {\n\t/**\n\t * User WGSL source containing `frag(uv: vec2f) -> vec4f`.\n\t */\n\tfragment: string;\n\t/**\n\t * Initial uniform values.\n\t */\n\tuniforms?: UniformMap<TUniformKey>;\n\t/**\n\t * Texture definitions keyed by texture uniform name.\n\t */\n\ttextures?: TextureDefinitionMap<TTextureKey>;\n\t/**\n\t * Optional compile-time define constants injected into WGSL.\n\t */\n\tdefines?: MaterialDefines<TDefineKey>;\n\t/**\n\t * Optional WGSL include chunks used by `#include <name>` directives.\n\t */\n\tincludes?: MaterialIncludes<TIncludeKey>;\n\t/**\n\t * Optional storage buffer definitions for compute shaders.\n\t */\n\tstorageBuffers?: StorageBufferDefinitionMap<TStorageBufferKey>;\n}\n\n/**\n * Normalized and immutable material declaration consumed by `FragCanvas`.\n */\nexport interface FragMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n> {\n\t/**\n\t * User WGSL source containing `frag(uv: vec2f) -> vec4f`.\n\t */\n\treadonly fragment: string;\n\t/**\n\t * Initial uniform values.\n\t */\n\treadonly uniforms: Readonly<UniformMap<TUniformKey>>;\n\t/**\n\t * Texture definitions keyed by texture uniform name.\n\t */\n\treadonly textures: Readonly<TextureDefinitionMap<TTextureKey>>;\n\t/**\n\t * Optional compile-time define constants injected into WGSL.\n\t */\n\treadonly defines: Readonly<MaterialDefines<TDefineKey>>;\n\t/**\n\t * Optional WGSL include chunks used by `#include <name>` directives.\n\t */\n\treadonly includes: Readonly<MaterialIncludes<TIncludeKey>>;\n\t/**\n\t * Storage buffer definitions for compute shaders. Empty when not provided.\n\t */\n\treadonly storageBuffers: Readonly<StorageBufferDefinitionMap<TStorageBufferKey>>;\n}\n\n/**\n * Fully resolved, immutable material snapshot used for renderer creation/caching.\n */\nexport interface ResolvedMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n> {\n\t/**\n\t * Final fragment WGSL after define injection.\n\t */\n\tfragmentWgsl: string;\n\t/**\n\t * 1-based map from generated fragment lines to user source lines.\n\t */\n\tfragmentLineMap: MaterialLineMap;\n\t/**\n\t * Cloned uniforms.\n\t */\n\tuniforms: UniformMap<TUniformKey>;\n\t/**\n\t * Cloned texture definitions.\n\t */\n\ttextures: TextureDefinitionMap<TTextureKey>;\n\t/**\n\t * Resolved packed uniform layout.\n\t */\n\tuniformLayout: ReturnType<typeof resolveUniformLayout>;\n\t/**\n\t * Sorted texture keys.\n\t */\n\ttextureKeys: TTextureKey[];\n\t/**\n\t * Deterministic JSON signature for cache invalidation.\n\t */\n\tsignature: string;\n\t/**\n\t * Original user fragment source before preprocessing.\n\t */\n\tfragmentSource: string;\n\t/**\n\t * Normalized include sources map.\n\t */\n\tincludeSources: MaterialIncludes<TIncludeKey>;\n\t/**\n\t * Deterministic define block source used for diagnostics mapping.\n\t */\n\tdefineBlockSource: string;\n\t/**\n\t * Source metadata used for diagnostics.\n\t */\n\tsource: Readonly<MaterialSourceMetadata> | null;\n\t/**\n\t * Sorted storage buffer keys. Empty array when no storage buffers declared.\n\t */\n\tstorageBufferKeys: TStorageBufferKey[];\n\t/**\n\t * Sorted storage texture keys (textures with storage: true).\n\t */\n\tstorageTextureKeys: TTextureKey[];\n}\n\n/**\n * Strict fragment contract used by MotionGPU.\n */\nconst FRAGMENT_FUNCTION_SIGNATURE_PATTERN =\n\t/\\bfn\\s+frag\\s*\\(\\s*([^)]*?)\\s*\\)\\s*->\\s*([A-Za-z_][A-Za-z0-9_<>\\s]*)\\s*(?:\\{|$)/m;\nconst FRAGMENT_FUNCTION_NAME_PATTERN = /\\bfn\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*\\(/g;\n\n/**\n * Cache of resolved material snapshots keyed by immutable material instance.\n */\ntype AnyFragMaterial = FragMaterial<string, string, string, string, string>;\ntype AnyResolvedMaterial = ResolvedMaterial<string, string, string, string>;\n\nconst resolvedMaterialCache = new WeakMap<AnyFragMaterial, AnyResolvedMaterial>();\nconst preprocessedFragmentCache = new WeakMap<AnyFragMaterial, PreprocessedMaterialFragment>();\nconst materialSourceMetadataCache = new WeakMap<AnyFragMaterial, MaterialSourceMetadata | null>();\n\nfunction getCachedResolvedMaterial<\n\tTUniformKey extends string,\n\tTTextureKey extends string,\n\tTIncludeKey extends string,\n\tTStorageBufferKey extends string\n>(\n\tmaterial: FragMaterial<TUniformKey, TTextureKey, string, TIncludeKey, TStorageBufferKey>\n): ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey> | null {\n\tconst cached = resolvedMaterialCache.get(material);\n\tif (!cached) {\n\t\treturn null;\n\t}\n\n\t// Invariant: the cache key is the same material object used to produce this resolved payload.\n\treturn cached as ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey>;\n}\n\nconst STACK_TRACE_CHROME_PATTERN = /^\\s*at\\s+(?:(.*?)\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/;\nconst STACK_TRACE_FIREFOX_PATTERN = /^(.*?)@(.+?):(\\d+):(\\d+)$/;\n\nfunction getPathBasename(path: string): string {\n\tconst normalized = path.split(/[?#]/)[0] ?? path;\n\tconst parts = normalized.split(/[\\\\/]/);\n\tconst last = parts[parts.length - 1];\n\treturn last && last.length > 0 ? last : path;\n}\n\nfunction normalizeSignaturePart(value: string): string {\n\treturn value.replace(/\\s+/g, ' ').trim();\n}\n\nfunction listFunctionNames(fragment: string): string[] {\n\tconst names = new Set<string>();\n\tfor (const match of fragment.matchAll(FRAGMENT_FUNCTION_NAME_PATTERN)) {\n\t\tconst name = match[1];\n\t\tif (!name) {\n\t\t\tcontinue;\n\t\t}\n\t\tnames.add(name);\n\t}\n\n\treturn Array.from(names);\n}\n\nfunction captureMaterialSourceFromStack(): MaterialSourceMetadata | null {\n\tconst stack = new Error().stack;\n\tif (!stack) {\n\t\treturn null;\n\t}\n\n\tconst stackLines = stack.split('\\n').slice(1);\n\tfor (const rawLine of stackLines) {\n\t\tconst line = rawLine.trim();\n\t\tif (line.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst chromeMatch = line.match(STACK_TRACE_CHROME_PATTERN);\n\t\tconst firefoxMatch = line.match(STACK_TRACE_FIREFOX_PATTERN);\n\t\tconst functionName = chromeMatch?.[1] ?? firefoxMatch?.[1] ?? undefined;\n\t\tconst file = chromeMatch?.[2] ?? firefoxMatch?.[2];\n\t\tconst lineValue = chromeMatch?.[3] ?? firefoxMatch?.[3];\n\t\tconst columnValue = chromeMatch?.[4] ?? firefoxMatch?.[4];\n\n\t\tif (!file || !lineValue || !columnValue) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (file.includes('/core/material') || file.includes('\\\\core\\\\material')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parsedLine = Number.parseInt(lineValue, 10);\n\t\tconst parsedColumn = Number.parseInt(columnValue, 10);\n\t\tif (!Number.isFinite(parsedLine) || !Number.isFinite(parsedColumn)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn {\n\t\t\tcomponent: getPathBasename(file),\n\t\t\tfile,\n\t\t\tline: parsedLine,\n\t\t\tcolumn: parsedColumn,\n\t\t\t...(functionName ? { functionName } : {})\n\t\t};\n\t}\n\n\treturn null;\n}\n\nfunction resolveSourceMetadata(\n\tsource: MaterialSourceMetadata | undefined\n): MaterialSourceMetadata | null {\n\tconst captured = captureMaterialSourceFromStack();\n\tconst component = source?.component ?? captured?.component;\n\tconst file = source?.file ?? captured?.file;\n\tconst line = source?.line ?? captured?.line;\n\tconst column = source?.column ?? captured?.column;\n\tconst functionName = source?.functionName ?? captured?.functionName;\n\n\tif (\n\t\tcomponent === undefined &&\n\t\tfile === undefined &&\n\t\tline === undefined &&\n\t\tcolumn === undefined &&\n\t\tfunctionName === undefined\n\t) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\t...(component !== undefined ? { component } : {}),\n\t\t...(file !== undefined ? { file } : {}),\n\t\t...(line !== undefined ? { line } : {}),\n\t\t...(column !== undefined ? { column } : {}),\n\t\t...(functionName !== undefined ? { functionName } : {})\n\t};\n}\n\n/**\n * Asserts that material has been normalized by {@link defineMaterial}.\n */\nfunction assertDefinedMaterial(material: AnyFragMaterial): void {\n\tif (\n\t\t!Object.isFrozen(material) ||\n\t\t!material.uniforms ||\n\t\t!material.textures ||\n\t\t!material.defines ||\n\t\t!material.includes\n\t) {\n\t\tthrow new Error(\n\t\t\t'Invalid material instance. Create materials with defineMaterial(...) before passing them to <FragCanvas>.'\n\t\t);\n\t}\n}\n\n/**\n * Clones uniform value input to decouple material instances from external objects.\n */\nfunction cloneUniformValue(value: UniformValue): UniformValue {\n\tif (typeof value === 'number') {\n\t\treturn value;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn Object.freeze([...value]) as UniformValue;\n\t}\n\n\tif (typeof value === 'object' && value !== null && 'type' in value && 'value' in value) {\n\t\tconst typed = value as TypedUniform;\n\t\tconst typedValue = typed.value as unknown;\n\n\t\tlet clonedTypedValue = typedValue;\n\t\tif (typedValue instanceof Float32Array) {\n\t\t\tclonedTypedValue = new Float32Array(typedValue);\n\t\t} else if (Array.isArray(typedValue)) {\n\t\t\tclonedTypedValue = Object.freeze([...typedValue]);\n\t\t}\n\n\t\treturn Object.freeze({\n\t\t\ttype: typed.type,\n\t\t\tvalue: clonedTypedValue\n\t\t}) as UniformValue;\n\t}\n\n\treturn value;\n}\n\n/**\n * Clones optional texture value payload.\n */\nfunction cloneTextureValue(value: TextureValue | undefined): TextureValue {\n\tif (value === undefined || value === null) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === 'object' && 'source' in value) {\n\t\tconst data = value as TextureData;\n\t\treturn {\n\t\t\tsource: data.source,\n\t\t\t...(data.width !== undefined ? { width: data.width } : {}),\n\t\t\t...(data.height !== undefined ? { height: data.height } : {}),\n\t\t\t...(data.colorSpace !== undefined ? { colorSpace: data.colorSpace } : {}),\n\t\t\t...(data.flipY !== undefined ? { flipY: data.flipY } : {}),\n\t\t\t...(data.premultipliedAlpha !== undefined\n\t\t\t\t? { premultipliedAlpha: data.premultipliedAlpha }\n\t\t\t\t: {}),\n\t\t\t...(data.generateMipmaps !== undefined ? { generateMipmaps: data.generateMipmaps } : {}),\n\t\t\t...(data.update !== undefined ? { update: data.update } : {})\n\t\t};\n\t}\n\n\treturn value;\n}\n\n/**\n * Clones and validates fragment source contract.\n */\nfunction resolveFragment(fragment: string): string {\n\tif (typeof fragment !== 'string' || fragment.trim().length === 0) {\n\t\tthrow new Error('Material fragment shader must be a non-empty WGSL string.');\n\t}\n\n\tconst signature = fragment.match(FRAGMENT_FUNCTION_SIGNATURE_PATTERN);\n\tif (!signature) {\n\t\tconst discoveredFunctions = listFunctionNames(fragment).slice(0, 4);\n\t\tconst discoveredLabel =\n\t\t\tdiscoveredFunctions.length > 0\n\t\t\t\t? `Found: ${discoveredFunctions.map((name) => `\\`${name}(...)\\``).join(', ')}.`\n\t\t\t\t: 'No WGSL function declarations were found.';\n\n\t\tthrow new Error(\n\t\t\t`Material fragment contract mismatch: missing entrypoint \\`fn frag(uv: vec2f) -> vec4f\\`. ${discoveredLabel}`\n\t\t);\n\t}\n\n\tconst params = normalizeSignaturePart(signature[1] ?? '');\n\tconst returnType = normalizeSignaturePart(signature[2] ?? '');\n\n\tif (params !== 'uv: vec2f') {\n\t\tthrow new Error(\n\t\t\t`Material fragment contract mismatch for \\`frag\\`: expected parameter list \\`(uv: vec2f)\\`, received \\`(${params || '...'})\\`.`\n\t\t);\n\t}\n\n\tif (returnType !== 'vec4f') {\n\t\tthrow new Error(\n\t\t\t`Material fragment contract mismatch for \\`frag\\`: expected return type \\`vec4f\\`, received \\`${returnType}\\`.`\n\t\t);\n\t}\n\n\treturn fragment;\n}\n\n/**\n * Clones and validates uniform declarations.\n */\nfunction resolveUniforms<TUniformKey extends string>(\n\tuniforms: UniformMap<TUniformKey> | undefined\n): UniformMap<TUniformKey> {\n\tconst resolved: UniformMap<TUniformKey> = {} as UniformMap<TUniformKey>;\n\n\tfor (const [name, value] of Object.entries(uniforms ?? {}) as Array<\n\t\t[TUniformKey, UniformValue]\n\t>) {\n\t\tassertUniformName(name);\n\t\tconst clonedValue = cloneUniformValue(value);\n\t\tconst type = inferUniformType(clonedValue);\n\t\tassertUniformValueForType(type, clonedValue);\n\t\tresolved[name] = clonedValue;\n\t}\n\n\tresolveUniformLayout(resolved);\n\treturn resolved;\n}\n\n/**\n * Clones and validates texture declarations.\n */\nfunction resolveTextures<TTextureKey extends string>(\n\ttextures: TextureDefinitionMap<TTextureKey> | undefined\n): TextureDefinitionMap<TTextureKey> {\n\tconst resolved: TextureDefinitionMap<TTextureKey> = {} as TextureDefinitionMap<TTextureKey>;\n\n\tfor (const [name, definition] of Object.entries(textures ?? {}) as Array<\n\t\t[TTextureKey, TextureDefinition]\n\t>) {\n\t\tassertUniformName(name);\n\t\tconst source = definition?.source;\n\t\tconst normalizedSource = cloneTextureValue(source);\n\n\t\tconst clonedDefinition: TextureDefinition = {\n\t\t\t...(definition ?? {}),\n\t\t\t...(source !== undefined ? { source: normalizedSource } : {})\n\t\t};\n\n\t\tresolved[name] = Object.freeze(clonedDefinition);\n\t}\n\n\treturn resolved;\n}\n\n/**\n * Clones and validates define declarations.\n */\nfunction resolveDefines<TDefineKey extends string>(\n\tdefines: MaterialDefines<TDefineKey> | undefined\n): MaterialDefines<TDefineKey> {\n\treturn normalizeDefines(defines);\n}\n\n/**\n * Clones and validates include declarations.\n */\nfunction resolveIncludes<TIncludeKey extends string>(\n\tincludes: MaterialIncludes<TIncludeKey> | undefined\n): MaterialIncludes<TIncludeKey> {\n\treturn normalizeIncludes(includes);\n}\n\n/**\n * Builds a deterministic texture-config signature map used in material cache signatures.\n *\n * @param textures - Raw texture definitions from material input.\n * @param textureKeys - Sorted texture keys.\n * @returns Compact signature entries describing effective texture config per key.\n */\nfunction buildTextureConfigSignature<TTextureKey extends string>(\n\ttextures: TextureDefinitionMap<TTextureKey>,\n\ttextureKeys: TTextureKey[]\n): Record<TTextureKey, string> {\n\tconst signature = {} as Record<TTextureKey, string>;\n\n\tfor (const key of textureKeys) {\n\t\tconst normalized = normalizeTextureDefinition(textures[key]);\n\t\tsignature[key] = [\n\t\t\tnormalized.colorSpace,\n\t\t\tnormalized.flipY ? '1' : '0',\n\t\t\tnormalized.generateMipmaps ? '1' : '0',\n\t\t\tnormalized.premultipliedAlpha ? '1' : '0',\n\t\t\tnormalized.anisotropy,\n\t\t\tnormalized.filter,\n\t\t\tnormalized.addressModeU,\n\t\t\tnormalized.addressModeV\n\t\t].join(':');\n\t}\n\n\treturn signature;\n}\n\n/**\n * Creates a stable WGSL define block from the provided map.\n *\n * @param defines - Optional material defines.\n * @returns Joined WGSL const declarations ordered by key.\n */\nexport function buildDefinesBlock(defines: MaterialDefines | undefined): string {\n\tconst normalizedDefines = normalizeDefines(defines);\n\tif (Object.keys(normalizedDefines).length === 0) {\n\t\treturn '';\n\t}\n\n\treturn Object.entries(normalizedDefines)\n\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t.map(([key, value]) => {\n\t\t\tassertUniformName(key);\n\t\t\treturn toDefineLine(key, value);\n\t\t})\n\t\t.join('\\n');\n}\n\n/**\n * Prepends resolved defines to a fragment shader.\n *\n * @param fragment - Raw WGSL fragment source.\n * @param defines - Optional define map.\n * @returns Fragment source with a leading define block when defines are present.\n */\nexport function applyMaterialDefines(\n\tfragment: string,\n\tdefines: MaterialDefines | undefined\n): string {\n\tconst defineBlock = buildDefinesBlock(defines);\n\tif (defineBlock.length === 0) {\n\t\treturn fragment;\n\t}\n\n\treturn `${defineBlock}\\n\\n${fragment}`;\n}\n\n/**\n * Creates an immutable material object with validated shader/uniform/texture contracts.\n *\n * @param input - User material declaration.\n * @returns Frozen material object safe to share and cache.\n */\nexport function defineMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n>(\n\tinput: FragMaterialInput<TUniformKey, TTextureKey, TDefineKey, TIncludeKey, TStorageBufferKey>\n): FragMaterial<TUniformKey, TTextureKey, TDefineKey, TIncludeKey, TStorageBufferKey> {\n\tconst fragment = resolveFragment(input.fragment);\n\tconst uniforms = Object.freeze(resolveUniforms(input.uniforms));\n\tconst textures = Object.freeze(resolveTextures(input.textures));\n\tconst defines = Object.freeze(resolveDefines(input.defines));\n\tconst includes = Object.freeze(resolveIncludes(input.includes));\n\tconst source = Object.freeze(resolveSourceMetadata(undefined));\n\n\t// Validate and freeze storage buffers\n\tconst rawStorageBuffers =\n\t\tinput.storageBuffers ?? ({} as StorageBufferDefinitionMap<TStorageBufferKey>);\n\tfor (const [name, definition] of Object.entries(rawStorageBuffers) as Array<\n\t\t[string, StorageBufferDefinition]\n\t>) {\n\t\tassertStorageBufferDefinition(name, definition);\n\t}\n\tconst storageBuffers = Object.freeze(\n\t\tObject.fromEntries(\n\t\t\tObject.entries(rawStorageBuffers).map(([name, definition]) => {\n\t\t\t\tconst def = definition as StorageBufferDefinition;\n\t\t\t\tconst cloned: StorageBufferDefinition = {\n\t\t\t\t\tsize: def.size,\n\t\t\t\t\ttype: def.type,\n\t\t\t\t\t...(def.access !== undefined ? { access: def.access } : {}),\n\t\t\t\t\t...(def.initialData !== undefined\n\t\t\t\t\t\t? { initialData: def.initialData.slice() as typeof def.initialData }\n\t\t\t\t\t\t: {})\n\t\t\t\t};\n\t\t\t\treturn [name, Object.freeze(cloned)];\n\t\t\t})\n\t\t)\n\t) as Readonly<StorageBufferDefinitionMap<TStorageBufferKey>>;\n\n\t// Validate storage textures\n\tfor (const [name, definition] of Object.entries(textures) as Array<[string, TextureDefinition]>) {\n\t\tif (definition?.storage) {\n\t\t\tif (!definition.format) {\n\t\t\t\tthrow new Error(`Texture \"${name}\" with storage:true requires a \\`format\\` field.`);\n\t\t\t}\n\t\t\tassertStorageTextureFormat(name, definition.format);\n\t\t}\n\t}\n\n\tconst preprocessed = preprocessMaterialFragment({\n\t\tfragment,\n\t\tdefines,\n\t\tincludes\n\t});\n\n\tconst material: FragMaterial<\n\t\tTUniformKey,\n\t\tTTextureKey,\n\t\tTDefineKey,\n\t\tTIncludeKey,\n\t\tTStorageBufferKey\n\t> = Object.freeze({\n\t\tfragment,\n\t\tuniforms,\n\t\ttextures,\n\t\tdefines,\n\t\tincludes,\n\t\tstorageBuffers\n\t});\n\n\tpreprocessedFragmentCache.set(material, preprocessed);\n\tmaterialSourceMetadataCache.set(material, source);\n\treturn material;\n}\n\n/**\n * Resolves a material to renderer-ready data and a deterministic signature.\n *\n * @param material - Material input created via {@link defineMaterial}.\n * @returns Resolved material with packed uniform layout, sorted texture keys and cache signature.\n */\nexport function resolveMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n>(\n\tmaterial: FragMaterial<TUniformKey, TTextureKey, TDefineKey, TIncludeKey, TStorageBufferKey>\n): ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey> {\n\tassertDefinedMaterial(material);\n\n\tconst cached = getCachedResolvedMaterial(material);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\tconst uniforms = material.uniforms as UniformMap<TUniformKey>;\n\tconst textures = material.textures as TextureDefinitionMap<TTextureKey>;\n\tconst uniformLayout = resolveUniformLayout(uniforms);\n\tconst textureKeys = Object.keys(textures).sort() as TTextureKey[];\n\tconst preprocessed =\n\t\tpreprocessedFragmentCache.get(material) ??\n\t\tpreprocessMaterialFragment({\n\t\t\tfragment: material.fragment,\n\t\t\tdefines: material.defines,\n\t\t\tincludes: material.includes\n\t\t});\n\tconst fragmentWgsl = preprocessed.fragment;\n\tconst textureConfig = buildTextureConfigSignature(textures, textureKeys);\n\n\tconst storageBufferKeys = Object.keys(\n\t\tmaterial.storageBuffers ?? {}\n\t).sort() as TStorageBufferKey[];\n\tconst storageTextureKeys = textureKeys.filter(\n\t\t(key) => (textures[key] as TextureDefinition)?.storage === true\n\t);\n\n\tconst signature = JSON.stringify({\n\t\tfragmentWgsl,\n\t\tuniforms: uniformLayout.entries.map((entry) => `${entry.name}:${entry.type}`),\n\t\ttextureKeys,\n\t\ttextureConfig,\n\t\tstorageBufferKeys: storageBufferKeys.map((key) => {\n\t\t\tconst def = (material.storageBuffers as StorageBufferDefinitionMap)[key];\n\t\t\treturn `${key}:${def?.type ?? '?'}:${def?.size ?? 0}:${def?.access ?? 'read-write'}`;\n\t\t}),\n\t\tstorageTextureKeys\n\t});\n\n\tconst resolved: ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey> = {\n\t\tfragmentWgsl,\n\t\tfragmentLineMap: preprocessed.lineMap,\n\t\tuniforms,\n\t\ttextures,\n\t\tuniformLayout,\n\t\ttextureKeys,\n\t\tsignature,\n\t\tfragmentSource: material.fragment,\n\t\tincludeSources: material.includes as MaterialIncludes<TIncludeKey>,\n\t\tdefineBlockSource: preprocessed.defineBlockSource,\n\t\tsource: materialSourceMetadataCache.get(material) ?? null,\n\t\tstorageBufferKeys,\n\t\tstorageTextureKeys\n\t};\n\n\tresolvedMaterialCache.set(material, resolved);\n\treturn resolved;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"material.js","names":[],"sources":["../../src/lib/core/material.ts"],"sourcesContent":["import { normalizeTextureDefinition } from './textures.js';\nimport type { MaterialSourceMetadata } from './error-diagnostics.js';\nimport {\n\tassertUniformName,\n\tassertUniformValueForType,\n\tinferUniformType,\n\tresolveUniformLayout\n} from './uniforms.js';\nimport {\n\tnormalizeDefines,\n\tnormalizeIncludes,\n\tpreprocessMaterialFragment,\n\ttoDefineLine,\n\ttype MaterialLineMap,\n\ttype PreprocessedMaterialFragment\n} from './material-preprocess.js';\nimport { assertStorageBufferDefinition, assertStorageTextureFormat } from './storage-buffers.js';\nimport type {\n\tStorageBufferDefinition,\n\tStorageBufferDefinitionMap,\n\tTextureData,\n\tTextureDefinition,\n\tTextureDefinitionMap,\n\tTextureValue,\n\tTypedUniform,\n\tUniformMap,\n\tUniformValue\n} from './types.js';\n\n/**\n * Typed compile-time define declaration.\n */\nexport type TypedMaterialDefineValue =\n\t| {\n\t\t\t/**\n\t\t\t * WGSL scalar type.\n\t\t\t */\n\t\t\ttype: 'bool';\n\t\t\t/**\n\t\t\t * Literal value for the selected WGSL type.\n\t\t\t */\n\t\t\tvalue: boolean;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * WGSL scalar type.\n\t\t\t */\n\t\t\ttype: 'f32' | 'i32' | 'u32';\n\t\t\t/**\n\t\t\t * Literal value for the selected WGSL type.\n\t\t\t */\n\t\t\tvalue: number;\n\t };\n\n/**\n * Allowed value types for WGSL `const` define injection.\n */\nexport type MaterialDefineValue = boolean | number | TypedMaterialDefineValue;\n\n/**\n * Define map keyed by uniform-compatible identifier names.\n */\nexport type MaterialDefines<TKey extends string = string> = Record<TKey, MaterialDefineValue>;\n\n/**\n * Include map keyed by include identifier used in `#include <name>` directives.\n */\nexport type MaterialIncludes<TKey extends string = string> = Record<TKey, string>;\n\n/**\n * External material input accepted by {@link defineMaterial}.\n */\nexport interface FragMaterialInput<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n> {\n\t/**\n\t * User WGSL source containing `frag(uv: vec2f) -> vec4f`.\n\t */\n\tfragment: string;\n\t/**\n\t * Initial uniform values.\n\t */\n\tuniforms?: UniformMap<TUniformKey>;\n\t/**\n\t * Texture definitions keyed by texture uniform name.\n\t */\n\ttextures?: TextureDefinitionMap<TTextureKey>;\n\t/**\n\t * Optional compile-time define constants injected into WGSL.\n\t */\n\tdefines?: MaterialDefines<TDefineKey>;\n\t/**\n\t * Optional WGSL include chunks used by `#include <name>` directives.\n\t */\n\tincludes?: MaterialIncludes<TIncludeKey>;\n\t/**\n\t * Optional storage buffer definitions for compute shaders.\n\t */\n\tstorageBuffers?: StorageBufferDefinitionMap<TStorageBufferKey>;\n}\n\n/**\n * Normalized and immutable material declaration consumed by `FragCanvas`.\n */\nexport interface FragMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n> {\n\t/**\n\t * User WGSL source containing `frag(uv: vec2f) -> vec4f`.\n\t */\n\treadonly fragment: string;\n\t/**\n\t * Initial uniform values.\n\t */\n\treadonly uniforms: Readonly<UniformMap<TUniformKey>>;\n\t/**\n\t * Texture definitions keyed by texture uniform name.\n\t */\n\treadonly textures: Readonly<TextureDefinitionMap<TTextureKey>>;\n\t/**\n\t * Optional compile-time define constants injected into WGSL.\n\t */\n\treadonly defines: Readonly<MaterialDefines<TDefineKey>>;\n\t/**\n\t * Optional WGSL include chunks used by `#include <name>` directives.\n\t */\n\treadonly includes: Readonly<MaterialIncludes<TIncludeKey>>;\n\t/**\n\t * Storage buffer definitions for compute shaders. Empty when not provided.\n\t */\n\treadonly storageBuffers: Readonly<StorageBufferDefinitionMap<TStorageBufferKey>>;\n}\n\n/**\n * Fully resolved, immutable material snapshot used for renderer creation/caching.\n */\nexport interface ResolvedMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n> {\n\t/**\n\t * Final fragment WGSL after define injection.\n\t */\n\tfragmentWgsl: string;\n\t/**\n\t * 1-based map from generated fragment lines to user source lines.\n\t */\n\tfragmentLineMap: MaterialLineMap;\n\t/**\n\t * Cloned uniforms.\n\t */\n\tuniforms: UniformMap<TUniformKey>;\n\t/**\n\t * Cloned texture definitions.\n\t */\n\ttextures: TextureDefinitionMap<TTextureKey>;\n\t/**\n\t * Resolved packed uniform layout.\n\t */\n\tuniformLayout: ReturnType<typeof resolveUniformLayout>;\n\t/**\n\t * Sorted texture keys.\n\t */\n\ttextureKeys: TTextureKey[];\n\t/**\n\t * Deterministic JSON signature for cache invalidation.\n\t */\n\tsignature: string;\n\t/**\n\t * Original user fragment source before preprocessing.\n\t */\n\tfragmentSource: string;\n\t/**\n\t * Normalized include sources map.\n\t */\n\tincludeSources: MaterialIncludes<TIncludeKey>;\n\t/**\n\t * Deterministic define block source used for diagnostics mapping.\n\t */\n\tdefineBlockSource: string;\n\t/**\n\t * Source metadata used for diagnostics.\n\t */\n\tsource: Readonly<MaterialSourceMetadata> | null;\n\t/**\n\t * Sorted storage buffer keys. Empty array when no storage buffers declared.\n\t */\n\tstorageBufferKeys: TStorageBufferKey[];\n\t/**\n\t * Sorted storage texture keys (textures with storage: true).\n\t */\n\tstorageTextureKeys: TTextureKey[];\n}\n\n/**\n * Strict fragment contract used by MotionGPU.\n */\nconst FRAGMENT_FUNCTION_SIGNATURE_PATTERN =\n\t/\\bfn\\s+frag\\s*\\(\\s*([^)]*?)\\s*\\)\\s*->\\s*([A-Za-z_][A-Za-z0-9_<>\\s]*)\\s*(?:\\{|$)/m;\nconst FRAGMENT_FUNCTION_NAME_PATTERN = /\\bfn\\s+([A-Za-z_][A-Za-z0-9_]*)\\s*\\(/g;\n\n/**\n * Cache of resolved material snapshots keyed by immutable material instance.\n */\ntype AnyFragMaterial = FragMaterial<string, string, string, string, string>;\ntype AnyResolvedMaterial = ResolvedMaterial<string, string, string, string>;\n\nconst resolvedMaterialCache = new WeakMap<AnyFragMaterial, AnyResolvedMaterial>();\nconst preprocessedFragmentCache = new WeakMap<AnyFragMaterial, PreprocessedMaterialFragment>();\nconst materialSourceMetadataCache = new WeakMap<AnyFragMaterial, MaterialSourceMetadata | null>();\n\nfunction getCachedResolvedMaterial<\n\tTUniformKey extends string,\n\tTTextureKey extends string,\n\tTIncludeKey extends string,\n\tTStorageBufferKey extends string\n>(\n\tmaterial: FragMaterial<TUniformKey, TTextureKey, string, TIncludeKey, TStorageBufferKey>\n): ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey> | null {\n\tconst cached = resolvedMaterialCache.get(material);\n\tif (!cached) {\n\t\treturn null;\n\t}\n\n\t// Invariant: the cache key is the same material object used to produce this resolved payload.\n\treturn cached as ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey>;\n}\n\nconst STACK_TRACE_CHROME_PATTERN = /^\\s*at\\s+(?:(.*?)\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/;\nconst STACK_TRACE_FIREFOX_PATTERN = /^(.*?)@(.+?):(\\d+):(\\d+)$/;\n\nfunction getPathBasename(path: string): string {\n\tconst normalized = path.split(/[?#]/)[0] ?? path;\n\tconst parts = normalized.split(/[\\\\/]/);\n\tconst last = parts[parts.length - 1];\n\treturn last && last.length > 0 ? last : path;\n}\n\nfunction normalizeSignaturePart(value: string): string {\n\treturn value.replace(/\\s+/g, ' ').trim();\n}\n\nfunction listFunctionNames(fragment: string): string[] {\n\tconst names = new Set<string>();\n\tfor (const match of fragment.matchAll(FRAGMENT_FUNCTION_NAME_PATTERN)) {\n\t\tconst name = match[1];\n\t\tif (!name) {\n\t\t\tcontinue;\n\t\t}\n\t\tnames.add(name);\n\t}\n\n\treturn Array.from(names);\n}\n\nfunction captureMaterialSourceFromStack(): MaterialSourceMetadata | null {\n\tconst stack = new Error().stack;\n\tif (!stack) {\n\t\treturn null;\n\t}\n\n\tconst stackLines = stack.split('\\n').slice(1);\n\tfor (const rawLine of stackLines) {\n\t\tconst line = rawLine.trim();\n\t\tif (line.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst chromeMatch = line.match(STACK_TRACE_CHROME_PATTERN);\n\t\tconst firefoxMatch = line.match(STACK_TRACE_FIREFOX_PATTERN);\n\t\tconst functionName = chromeMatch?.[1] ?? firefoxMatch?.[1] ?? undefined;\n\t\tconst file = chromeMatch?.[2] ?? firefoxMatch?.[2];\n\t\tconst lineValue = chromeMatch?.[3] ?? firefoxMatch?.[3];\n\t\tconst columnValue = chromeMatch?.[4] ?? firefoxMatch?.[4];\n\n\t\tif (!file || !lineValue || !columnValue) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (file.includes('/core/material') || file.includes('\\\\core\\\\material')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parsedLine = Number.parseInt(lineValue, 10);\n\t\tconst parsedColumn = Number.parseInt(columnValue, 10);\n\t\tif (!Number.isFinite(parsedLine) || !Number.isFinite(parsedColumn)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn {\n\t\t\tcomponent: getPathBasename(file),\n\t\t\tfile,\n\t\t\tline: parsedLine,\n\t\t\tcolumn: parsedColumn,\n\t\t\t...(functionName ? { functionName } : {})\n\t\t};\n\t}\n\n\treturn null;\n}\n\nfunction resolveSourceMetadata(\n\tsource: MaterialSourceMetadata | undefined\n): MaterialSourceMetadata | null {\n\tconst captured = captureMaterialSourceFromStack();\n\tconst component = source?.component ?? captured?.component;\n\tconst file = source?.file ?? captured?.file;\n\tconst line = source?.line ?? captured?.line;\n\tconst column = source?.column ?? captured?.column;\n\tconst functionName = source?.functionName ?? captured?.functionName;\n\n\tif (\n\t\tcomponent === undefined &&\n\t\tfile === undefined &&\n\t\tline === undefined &&\n\t\tcolumn === undefined &&\n\t\tfunctionName === undefined\n\t) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\t...(component !== undefined ? { component } : {}),\n\t\t...(file !== undefined ? { file } : {}),\n\t\t...(line !== undefined ? { line } : {}),\n\t\t...(column !== undefined ? { column } : {}),\n\t\t...(functionName !== undefined ? { functionName } : {})\n\t};\n}\n\n/**\n * Asserts that material has been normalized by {@link defineMaterial}.\n */\nfunction assertDefinedMaterial(material: AnyFragMaterial): void {\n\tif (\n\t\t!Object.isFrozen(material) ||\n\t\t!material.uniforms ||\n\t\t!material.textures ||\n\t\t!material.defines ||\n\t\t!material.includes\n\t) {\n\t\tthrow new Error(\n\t\t\t'Invalid material instance. Create materials with defineMaterial(...) before passing them to <FragCanvas>.'\n\t\t);\n\t}\n}\n\n/**\n * Clones uniform value input to decouple material instances from external objects.\n */\nfunction cloneUniformValue(value: UniformValue): UniformValue {\n\tif (typeof value === 'number') {\n\t\treturn value;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn Object.freeze([...value]) as UniformValue;\n\t}\n\n\tif (typeof value === 'object' && value !== null && 'type' in value && 'value' in value) {\n\t\tconst typed = value as TypedUniform;\n\t\tconst typedValue = typed.value as unknown;\n\n\t\tlet clonedTypedValue = typedValue;\n\t\tif (typedValue instanceof Float32Array) {\n\t\t\tclonedTypedValue = new Float32Array(typedValue);\n\t\t} else if (Array.isArray(typedValue)) {\n\t\t\tclonedTypedValue = Object.freeze([...typedValue]);\n\t\t}\n\n\t\treturn Object.freeze({\n\t\t\ttype: typed.type,\n\t\t\tvalue: clonedTypedValue\n\t\t}) as UniformValue;\n\t}\n\n\treturn value;\n}\n\n/**\n * Clones optional texture value payload.\n */\nfunction cloneTextureValue(value: TextureValue | undefined): TextureValue {\n\tif (value === undefined || value === null) {\n\t\treturn null;\n\t}\n\n\tif (typeof value === 'object' && 'source' in value) {\n\t\tconst data = value as TextureData;\n\t\treturn {\n\t\t\tsource: data.source,\n\t\t\t...(data.width !== undefined ? { width: data.width } : {}),\n\t\t\t...(data.height !== undefined ? { height: data.height } : {}),\n\t\t\t...(data.colorSpace !== undefined ? { colorSpace: data.colorSpace } : {}),\n\t\t\t...(data.flipY !== undefined ? { flipY: data.flipY } : {}),\n\t\t\t...(data.premultipliedAlpha !== undefined\n\t\t\t\t? { premultipliedAlpha: data.premultipliedAlpha }\n\t\t\t\t: {}),\n\t\t\t...(data.generateMipmaps !== undefined ? { generateMipmaps: data.generateMipmaps } : {}),\n\t\t\t...(data.update !== undefined ? { update: data.update } : {})\n\t\t};\n\t}\n\n\treturn value;\n}\n\n/**\n * Clones and validates fragment source contract.\n */\nfunction resolveFragment(fragment: string): string {\n\tif (typeof fragment !== 'string' || fragment.trim().length === 0) {\n\t\tthrow new Error('Material fragment shader must be a non-empty WGSL string.');\n\t}\n\n\tconst signature = fragment.match(FRAGMENT_FUNCTION_SIGNATURE_PATTERN);\n\tif (!signature) {\n\t\tconst discoveredFunctions = listFunctionNames(fragment).slice(0, 4);\n\t\tconst discoveredLabel =\n\t\t\tdiscoveredFunctions.length > 0\n\t\t\t\t? `Found: ${discoveredFunctions.map((name) => `\\`${name}(...)\\``).join(', ')}.`\n\t\t\t\t: 'No WGSL function declarations were found.';\n\n\t\tthrow new Error(\n\t\t\t`Material fragment contract mismatch: missing entrypoint \\`fn frag(uv: vec2f) -> vec4f\\`. ${discoveredLabel}`\n\t\t);\n\t}\n\n\tconst params = normalizeSignaturePart(signature[1] ?? '');\n\tconst returnType = normalizeSignaturePart(signature[2] ?? '');\n\n\tif (params !== 'uv: vec2f') {\n\t\tthrow new Error(\n\t\t\t`Material fragment contract mismatch for \\`frag\\`: expected parameter list \\`(uv: vec2f)\\`, received \\`(${params || '...'})\\`.`\n\t\t);\n\t}\n\n\tif (returnType !== 'vec4f') {\n\t\tthrow new Error(\n\t\t\t`Material fragment contract mismatch for \\`frag\\`: expected return type \\`vec4f\\`, received \\`${returnType}\\`.`\n\t\t);\n\t}\n\n\treturn fragment;\n}\n\n/**\n * Clones and validates uniform declarations.\n */\nfunction resolveUniforms<TUniformKey extends string>(\n\tuniforms: UniformMap<TUniformKey> | undefined\n): UniformMap<TUniformKey> {\n\tconst resolved: UniformMap<TUniformKey> = {} as UniformMap<TUniformKey>;\n\n\tfor (const [name, value] of Object.entries(uniforms ?? {}) as Array<\n\t\t[TUniformKey, UniformValue]\n\t>) {\n\t\tassertUniformName(name);\n\t\tconst clonedValue = cloneUniformValue(value);\n\t\tconst type = inferUniformType(clonedValue);\n\t\tassertUniformValueForType(type, clonedValue);\n\t\tresolved[name] = clonedValue;\n\t}\n\n\tresolveUniformLayout(resolved);\n\treturn resolved;\n}\n\n/**\n * Clones and validates texture declarations.\n */\nfunction resolveTextures<TTextureKey extends string>(\n\ttextures: TextureDefinitionMap<TTextureKey> | undefined\n): TextureDefinitionMap<TTextureKey> {\n\tconst resolved: TextureDefinitionMap<TTextureKey> = {} as TextureDefinitionMap<TTextureKey>;\n\n\tfor (const [name, definition] of Object.entries(textures ?? {}) as Array<\n\t\t[TTextureKey, TextureDefinition]\n\t>) {\n\t\tassertUniformName(name);\n\t\tconst source = definition?.source;\n\t\tconst normalizedSource = cloneTextureValue(source);\n\n\t\tconst clonedDefinition: TextureDefinition = {\n\t\t\t...(definition ?? {}),\n\t\t\t...(source !== undefined ? { source: normalizedSource } : {})\n\t\t};\n\n\t\tresolved[name] = Object.freeze(clonedDefinition);\n\t}\n\n\treturn resolved;\n}\n\n/**\n * Clones and validates define declarations.\n */\nfunction resolveDefines<TDefineKey extends string>(\n\tdefines: MaterialDefines<TDefineKey> | undefined\n): MaterialDefines<TDefineKey> {\n\treturn normalizeDefines(defines);\n}\n\n/**\n * Clones and validates include declarations.\n */\nfunction resolveIncludes<TIncludeKey extends string>(\n\tincludes: MaterialIncludes<TIncludeKey> | undefined\n): MaterialIncludes<TIncludeKey> {\n\treturn normalizeIncludes(includes);\n}\n\n/**\n * Builds a deterministic texture-config signature map used in material cache signatures.\n *\n * @param textures - Raw texture definitions from material input.\n * @param textureKeys - Sorted texture keys.\n * @returns Compact signature entries describing effective texture config per key.\n */\nfunction buildTextureConfigSignature<TTextureKey extends string>(\n\ttextures: TextureDefinitionMap<TTextureKey>,\n\ttextureKeys: TTextureKey[]\n): Record<TTextureKey, string> {\n\tconst signature = {} as Record<TTextureKey, string>;\n\n\tfor (const key of textureKeys) {\n\t\tconst normalized = normalizeTextureDefinition(textures[key]);\n\t\tsignature[key] = [\n\t\t\tnormalized.colorSpace,\n\t\t\tnormalized.flipY ? '1' : '0',\n\t\t\tnormalized.generateMipmaps ? '1' : '0',\n\t\t\tnormalized.premultipliedAlpha ? '1' : '0',\n\t\t\tnormalized.anisotropy,\n\t\t\tnormalized.filter,\n\t\t\tnormalized.addressModeU,\n\t\t\tnormalized.addressModeV,\n\t\t\tnormalized.fragmentVisible ? '1' : '0'\n\t\t].join(':');\n\t}\n\n\treturn signature;\n}\n\n/**\n * Creates a stable WGSL define block from the provided map.\n *\n * @param defines - Optional material defines.\n * @returns Joined WGSL const declarations ordered by key.\n */\nexport function buildDefinesBlock(defines: MaterialDefines | undefined): string {\n\tconst normalizedDefines = normalizeDefines(defines);\n\tif (Object.keys(normalizedDefines).length === 0) {\n\t\treturn '';\n\t}\n\n\treturn Object.entries(normalizedDefines)\n\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t.map(([key, value]) => {\n\t\t\tassertUniformName(key);\n\t\t\treturn toDefineLine(key, value);\n\t\t})\n\t\t.join('\\n');\n}\n\n/**\n * Prepends resolved defines to a fragment shader.\n *\n * @param fragment - Raw WGSL fragment source.\n * @param defines - Optional define map.\n * @returns Fragment source with a leading define block when defines are present.\n */\nexport function applyMaterialDefines(\n\tfragment: string,\n\tdefines: MaterialDefines | undefined\n): string {\n\tconst defineBlock = buildDefinesBlock(defines);\n\tif (defineBlock.length === 0) {\n\t\treturn fragment;\n\t}\n\n\treturn `${defineBlock}\\n\\n${fragment}`;\n}\n\n/**\n * Creates an immutable material object with validated shader/uniform/texture contracts.\n *\n * @param input - User material declaration.\n * @returns Frozen material object safe to share and cache.\n */\nexport function defineMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n>(\n\tinput: FragMaterialInput<TUniformKey, TTextureKey, TDefineKey, TIncludeKey, TStorageBufferKey>\n): FragMaterial<TUniformKey, TTextureKey, TDefineKey, TIncludeKey, TStorageBufferKey> {\n\tconst fragment = resolveFragment(input.fragment);\n\tconst uniforms = Object.freeze(resolveUniforms(input.uniforms));\n\tconst textures = Object.freeze(resolveTextures(input.textures));\n\tconst defines = Object.freeze(resolveDefines(input.defines));\n\tconst includes = Object.freeze(resolveIncludes(input.includes));\n\tconst source = Object.freeze(resolveSourceMetadata(undefined));\n\n\t// Validate and freeze storage buffers\n\tconst rawStorageBuffers =\n\t\tinput.storageBuffers ?? ({} as StorageBufferDefinitionMap<TStorageBufferKey>);\n\tfor (const [name, definition] of Object.entries(rawStorageBuffers) as Array<\n\t\t[string, StorageBufferDefinition]\n\t>) {\n\t\tassertStorageBufferDefinition(name, definition);\n\t}\n\tconst storageBuffers = Object.freeze(\n\t\tObject.fromEntries(\n\t\t\tObject.entries(rawStorageBuffers).map(([name, definition]) => {\n\t\t\t\tconst def = definition as StorageBufferDefinition;\n\t\t\t\tconst cloned: StorageBufferDefinition = {\n\t\t\t\t\tsize: def.size,\n\t\t\t\t\ttype: def.type,\n\t\t\t\t\t...(def.access !== undefined ? { access: def.access } : {}),\n\t\t\t\t\t...(def.initialData !== undefined\n\t\t\t\t\t\t? { initialData: def.initialData.slice() as typeof def.initialData }\n\t\t\t\t\t\t: {})\n\t\t\t\t};\n\t\t\t\treturn [name, Object.freeze(cloned)];\n\t\t\t})\n\t\t)\n\t) as Readonly<StorageBufferDefinitionMap<TStorageBufferKey>>;\n\n\t// Validate storage textures\n\tfor (const [name, definition] of Object.entries(textures) as Array<[string, TextureDefinition]>) {\n\t\tif (definition?.storage) {\n\t\t\tif (!definition.format) {\n\t\t\t\tthrow new Error(`Texture \"${name}\" with storage:true requires a \\`format\\` field.`);\n\t\t\t}\n\t\t\tassertStorageTextureFormat(name, definition.format);\n\t\t}\n\t}\n\n\tconst preprocessed = preprocessMaterialFragment({\n\t\tfragment,\n\t\tdefines,\n\t\tincludes\n\t});\n\n\tconst material: FragMaterial<\n\t\tTUniformKey,\n\t\tTTextureKey,\n\t\tTDefineKey,\n\t\tTIncludeKey,\n\t\tTStorageBufferKey\n\t> = Object.freeze({\n\t\tfragment,\n\t\tuniforms,\n\t\ttextures,\n\t\tdefines,\n\t\tincludes,\n\t\tstorageBuffers\n\t});\n\n\tpreprocessedFragmentCache.set(material, preprocessed);\n\tmaterialSourceMetadataCache.set(material, source);\n\treturn material;\n}\n\n/**\n * Resolves a material to renderer-ready data and a deterministic signature.\n *\n * @param material - Material input created via {@link defineMaterial}.\n * @returns Resolved material with packed uniform layout, sorted texture keys and cache signature.\n */\nexport function resolveMaterial<\n\tTUniformKey extends string = string,\n\tTTextureKey extends string = string,\n\tTDefineKey extends string = string,\n\tTIncludeKey extends string = string,\n\tTStorageBufferKey extends string = string\n>(\n\tmaterial: FragMaterial<TUniformKey, TTextureKey, TDefineKey, TIncludeKey, TStorageBufferKey>\n): ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey> {\n\tassertDefinedMaterial(material);\n\n\tconst cached = getCachedResolvedMaterial(material);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\tconst uniforms = material.uniforms as UniformMap<TUniformKey>;\n\tconst textures = material.textures as TextureDefinitionMap<TTextureKey>;\n\tconst uniformLayout = resolveUniformLayout(uniforms);\n\tconst textureKeys = Object.keys(textures).sort() as TTextureKey[];\n\tconst preprocessed =\n\t\tpreprocessedFragmentCache.get(material) ??\n\t\tpreprocessMaterialFragment({\n\t\t\tfragment: material.fragment,\n\t\t\tdefines: material.defines,\n\t\t\tincludes: material.includes\n\t\t});\n\tconst fragmentWgsl = preprocessed.fragment;\n\tconst textureConfig = buildTextureConfigSignature(textures, textureKeys);\n\n\tconst storageBufferKeys = Object.keys(\n\t\tmaterial.storageBuffers ?? {}\n\t).sort() as TStorageBufferKey[];\n\tconst storageTextureKeys = textureKeys.filter(\n\t\t(key) => (textures[key] as TextureDefinition)?.storage === true\n\t);\n\n\tconst signature = JSON.stringify({\n\t\tfragmentWgsl,\n\t\tuniforms: uniformLayout.entries.map((entry) => `${entry.name}:${entry.type}`),\n\t\ttextureKeys,\n\t\ttextureConfig,\n\t\tstorageBufferKeys: storageBufferKeys.map((key) => {\n\t\t\tconst def = (material.storageBuffers as StorageBufferDefinitionMap)[key];\n\t\t\treturn `${key}:${def?.type ?? '?'}:${def?.size ?? 0}:${def?.access ?? 'read-write'}`;\n\t\t}),\n\t\tstorageTextureKeys\n\t});\n\n\tconst resolved: ResolvedMaterial<TUniformKey, TTextureKey, TIncludeKey, TStorageBufferKey> = {\n\t\tfragmentWgsl,\n\t\tfragmentLineMap: preprocessed.lineMap,\n\t\tuniforms,\n\t\ttextures,\n\t\tuniformLayout,\n\t\ttextureKeys,\n\t\tsignature,\n\t\tfragmentSource: material.fragment,\n\t\tincludeSources: material.includes as MaterialIncludes<TIncludeKey>,\n\t\tdefineBlockSource: preprocessed.defineBlockSource,\n\t\tsource: materialSourceMetadataCache.get(material) ?? null,\n\t\tstorageBufferKeys,\n\t\tstorageTextureKeys\n\t};\n\n\tresolvedMaterialCache.set(material, resolved);\n\treturn resolved;\n}\n"],"mappings":";;;;;;;;AA+MA,IAAM,sCACL;AACD,IAAM,iCAAiC;AAQvC,IAAM,wCAAwB,IAAI,SAA+C;AACjF,IAAM,4CAA4B,IAAI,SAAwD;AAC9F,IAAM,8CAA8B,IAAI,SAAyD;AAEjG,SAAS,0BAMR,UACoF;CACpF,MAAM,SAAS,sBAAsB,IAAI,SAAS;AAClD,KAAI,CAAC,OACJ,QAAO;AAIR,QAAO;;AAGR,IAAM,6BAA6B;AACnC,IAAM,8BAA8B;AAEpC,SAAS,gBAAgB,MAAsB;CAE9C,MAAM,SADa,KAAK,MAAM,OAAO,CAAC,MAAM,MACnB,MAAM,QAAQ;CACvC,MAAM,OAAO,MAAM,MAAM,SAAS;AAClC,QAAO,QAAQ,KAAK,SAAS,IAAI,OAAO;;AAGzC,SAAS,uBAAuB,OAAuB;AACtD,QAAO,MAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM;;AAGzC,SAAS,kBAAkB,UAA4B;CACtD,MAAM,wBAAQ,IAAI,KAAa;AAC/B,MAAK,MAAM,SAAS,SAAS,SAAS,+BAA+B,EAAE;EACtE,MAAM,OAAO,MAAM;AACnB,MAAI,CAAC,KACJ;AAED,QAAM,IAAI,KAAK;;AAGhB,QAAO,MAAM,KAAK,MAAM;;AAGzB,SAAS,iCAAgE;CACxE,MAAM,yBAAQ,IAAI,OAAO,EAAC;AAC1B,KAAI,CAAC,MACJ,QAAO;CAGR,MAAM,aAAa,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE;AAC7C,MAAK,MAAM,WAAW,YAAY;EACjC,MAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,KAAK,WAAW,EACnB;EAGD,MAAM,cAAc,KAAK,MAAM,2BAA2B;EAC1D,MAAM,eAAe,KAAK,MAAM,4BAA4B;EAC5D,MAAM,eAAe,cAAc,MAAM,eAAe,MAAM;EAC9D,MAAM,OAAO,cAAc,MAAM,eAAe;EAChD,MAAM,YAAY,cAAc,MAAM,eAAe;EACrD,MAAM,cAAc,cAAc,MAAM,eAAe;AAEvD,MAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,YAC3B;AAGD,MAAI,KAAK,SAAS,iBAAiB,IAAI,KAAK,SAAS,mBAAmB,CACvE;EAGD,MAAM,aAAa,OAAO,SAAS,WAAW,GAAG;EACjD,MAAM,eAAe,OAAO,SAAS,aAAa,GAAG;AACrD,MAAI,CAAC,OAAO,SAAS,WAAW,IAAI,CAAC,OAAO,SAAS,aAAa,CACjE;AAGD,SAAO;GACN,WAAW,gBAAgB,KAAK;GAChC;GACA,MAAM;GACN,QAAQ;GACR,GAAI,eAAe,EAAE,cAAc,GAAG,EAAE;GACxC;;AAGF,QAAO;;AAGR,SAAS,sBACR,QACgC;CAChC,MAAM,WAAW,gCAAgC;CACjD,MAAM,YAAY,QAAQ,aAAa,UAAU;CACjD,MAAM,OAAO,QAAQ,QAAQ,UAAU;CACvC,MAAM,OAAO,QAAQ,QAAQ,UAAU;CACvC,MAAM,SAAS,QAAQ,UAAU,UAAU;CAC3C,MAAM,eAAe,QAAQ,gBAAgB,UAAU;AAEvD,KACC,cAAc,UACd,SAAS,UACT,SAAS,UACT,WAAW,UACX,iBAAiB,OAEjB,QAAO;AAGR,QAAO;EACN,GAAI,cAAc,SAAY,EAAE,WAAW,GAAG,EAAE;EAChD,GAAI,SAAS,SAAY,EAAE,MAAM,GAAG,EAAE;EACtC,GAAI,SAAS,SAAY,EAAE,MAAM,GAAG,EAAE;EACtC,GAAI,WAAW,SAAY,EAAE,QAAQ,GAAG,EAAE;EAC1C,GAAI,iBAAiB,SAAY,EAAE,cAAc,GAAG,EAAE;EACtD;;;;;AAMF,SAAS,sBAAsB,UAAiC;AAC/D,KACC,CAAC,OAAO,SAAS,SAAS,IAC1B,CAAC,SAAS,YACV,CAAC,SAAS,YACV,CAAC,SAAS,WACV,CAAC,SAAS,SAEV,OAAM,IAAI,MACT,4GACA;;;;;AAOH,SAAS,kBAAkB,OAAmC;AAC7D,KAAI,OAAO,UAAU,SACpB,QAAO;AAGR,KAAI,MAAM,QAAQ,MAAM,CACvB,QAAO,OAAO,OAAO,CAAC,GAAG,MAAM,CAAC;AAGjC,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,WAAW,OAAO;EACvF,MAAM,QAAQ;EACd,MAAM,aAAa,MAAM;EAEzB,IAAI,mBAAmB;AACvB,MAAI,sBAAsB,aACzB,oBAAmB,IAAI,aAAa,WAAW;WACrC,MAAM,QAAQ,WAAW,CACnC,oBAAmB,OAAO,OAAO,CAAC,GAAG,WAAW,CAAC;AAGlD,SAAO,OAAO,OAAO;GACpB,MAAM,MAAM;GACZ,OAAO;GACP,CAAC;;AAGH,QAAO;;;;;AAMR,SAAS,kBAAkB,OAA+C;AACzE,KAAI,UAAU,UAAa,UAAU,KACpC,QAAO;AAGR,KAAI,OAAO,UAAU,YAAY,YAAY,OAAO;EACnD,MAAM,OAAO;AACb,SAAO;GACN,QAAQ,KAAK;GACb,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,OAAO,GAAG,EAAE;GACzD,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,QAAQ,GAAG,EAAE;GAC5D,GAAI,KAAK,eAAe,SAAY,EAAE,YAAY,KAAK,YAAY,GAAG,EAAE;GACxE,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,OAAO,GAAG,EAAE;GACzD,GAAI,KAAK,uBAAuB,SAC7B,EAAE,oBAAoB,KAAK,oBAAoB,GAC/C,EAAE;GACL,GAAI,KAAK,oBAAoB,SAAY,EAAE,iBAAiB,KAAK,iBAAiB,GAAG,EAAE;GACvF,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,QAAQ,GAAG,EAAE;GAC5D;;AAGF,QAAO;;;;;AAMR,SAAS,gBAAgB,UAA0B;AAClD,KAAI,OAAO,aAAa,YAAY,SAAS,MAAM,CAAC,WAAW,EAC9D,OAAM,IAAI,MAAM,4DAA4D;CAG7E,MAAM,YAAY,SAAS,MAAM,oCAAoC;AACrE,KAAI,CAAC,WAAW;EACf,MAAM,sBAAsB,kBAAkB,SAAS,CAAC,MAAM,GAAG,EAAE;EACnE,MAAM,kBACL,oBAAoB,SAAS,IAC1B,UAAU,oBAAoB,KAAK,SAAS,KAAK,KAAK,SAAS,CAAC,KAAK,KAAK,CAAC,KAC3E;AAEJ,QAAM,IAAI,MACT,4FAA4F,kBAC5F;;CAGF,MAAM,SAAS,uBAAuB,UAAU,MAAM,GAAG;CACzD,MAAM,aAAa,uBAAuB,UAAU,MAAM,GAAG;AAE7D,KAAI,WAAW,YACd,OAAM,IAAI,MACT,0GAA0G,UAAU,MAAM,MAC1H;AAGF,KAAI,eAAe,QAClB,OAAM,IAAI,MACT,gGAAgG,WAAW,KAC3G;AAGF,QAAO;;;;;AAMR,SAAS,gBACR,UAC0B;CAC1B,MAAM,WAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,YAAY,EAAE,CAAC,EAEvD;AACF,oBAAkB,KAAK;EACvB,MAAM,cAAc,kBAAkB,MAAM;AAE5C,4BADa,iBAAiB,YAAY,EACV,YAAY;AAC5C,WAAS,QAAQ;;AAGlB,sBAAqB,SAAS;AAC9B,QAAO;;;;;AAMR,SAAS,gBACR,UACoC;CACpC,MAAM,WAA8C,EAAE;AAEtD,MAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,YAAY,EAAE,CAAC,EAE5D;AACF,oBAAkB,KAAK;EACvB,MAAM,SAAS,YAAY;EAC3B,MAAM,mBAAmB,kBAAkB,OAAO;EAElD,MAAM,mBAAsC;GAC3C,GAAI,cAAc,EAAE;GACpB,GAAI,WAAW,SAAY,EAAE,QAAQ,kBAAkB,GAAG,EAAE;GAC5D;AAED,WAAS,QAAQ,OAAO,OAAO,iBAAiB;;AAGjD,QAAO;;;;;AAMR,SAAS,eACR,SAC8B;AAC9B,QAAO,iBAAiB,QAAQ;;;;;AAMjC,SAAS,gBACR,UACgC;AAChC,QAAO,kBAAkB,SAAS;;;;;;;;;AAUnC,SAAS,4BACR,UACA,aAC8B;CAC9B,MAAM,YAAY,EAAE;AAEpB,MAAK,MAAM,OAAO,aAAa;EAC9B,MAAM,aAAa,2BAA2B,SAAS,KAAK;AAC5D,YAAU,OAAO;GAChB,WAAW;GACX,WAAW,QAAQ,MAAM;GACzB,WAAW,kBAAkB,MAAM;GACnC,WAAW,qBAAqB,MAAM;GACtC,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW,kBAAkB,MAAM;GACnC,CAAC,KAAK,IAAI;;AAGZ,QAAO;;;;;;;;AASR,SAAgB,kBAAkB,SAA8C;CAC/E,MAAM,oBAAoB,iBAAiB,QAAQ;AACnD,KAAI,OAAO,KAAK,kBAAkB,CAAC,WAAW,EAC7C,QAAO;AAGR,QAAO,OAAO,QAAQ,kBAAkB,CACtC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,CACtC,KAAK,CAAC,KAAK,WAAW;AACtB,oBAAkB,IAAI;AACtB,SAAO,aAAa,KAAK,MAAM;GAC9B,CACD,KAAK,KAAK;;;;;;;;;AAUb,SAAgB,qBACf,UACA,SACS;CACT,MAAM,cAAc,kBAAkB,QAAQ;AAC9C,KAAI,YAAY,WAAW,EAC1B,QAAO;AAGR,QAAO,GAAG,YAAY,MAAM;;;;;;;;AAS7B,SAAgB,eAOf,OACqF;CACrF,MAAM,WAAW,gBAAgB,MAAM,SAAS;CAChD,MAAM,WAAW,OAAO,OAAO,gBAAgB,MAAM,SAAS,CAAC;CAC/D,MAAM,WAAW,OAAO,OAAO,gBAAgB,MAAM,SAAS,CAAC;CAC/D,MAAM,UAAU,OAAO,OAAO,eAAe,MAAM,QAAQ,CAAC;CAC5D,MAAM,WAAW,OAAO,OAAO,gBAAgB,MAAM,SAAS,CAAC;CAC/D,MAAM,SAAS,OAAO,OAAO,sBAAsB,OAAU,CAAC;CAG9D,MAAM,oBACL,MAAM,kBAAmB,EAAE;AAC5B,MAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,kBAAkB,CAGjE,+BAA8B,MAAM,WAAW;CAEhD,MAAM,iBAAiB,OAAO,OAC7B,OAAO,YACN,OAAO,QAAQ,kBAAkB,CAAC,KAAK,CAAC,MAAM,gBAAgB;EAC7D,MAAM,MAAM;EACZ,MAAM,SAAkC;GACvC,MAAM,IAAI;GACV,MAAM,IAAI;GACV,GAAI,IAAI,WAAW,SAAY,EAAE,QAAQ,IAAI,QAAQ,GAAG,EAAE;GAC1D,GAAI,IAAI,gBAAgB,SACrB,EAAE,aAAa,IAAI,YAAY,OAAO,EAA4B,GAClE,EAAE;GACL;AACD,SAAO,CAAC,MAAM,OAAO,OAAO,OAAO,CAAC;GACnC,CACF,CACD;AAGD,MAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,SAAS,CACxD,KAAI,YAAY,SAAS;AACxB,MAAI,CAAC,WAAW,OACf,OAAM,IAAI,MAAM,YAAY,KAAK,kDAAkD;AAEpF,6BAA2B,MAAM,WAAW,OAAO;;CAIrD,MAAM,eAAe,2BAA2B;EAC/C;EACA;EACA;EACA,CAAC;CAEF,MAAM,WAMF,OAAO,OAAO;EACjB;EACA;EACA;EACA;EACA;EACA;EACA,CAAC;AAEF,2BAA0B,IAAI,UAAU,aAAa;AACrD,6BAA4B,IAAI,UAAU,OAAO;AACjD,QAAO;;;;;;;;AASR,SAAgB,gBAOf,UAC6E;AAC7E,uBAAsB,SAAS;CAE/B,MAAM,SAAS,0BAA0B,SAAS;AAClD,KAAI,OACH,QAAO;CAGR,MAAM,WAAW,SAAS;CAC1B,MAAM,WAAW,SAAS;CAC1B,MAAM,gBAAgB,qBAAqB,SAAS;CACpD,MAAM,cAAc,OAAO,KAAK,SAAS,CAAC,MAAM;CAChD,MAAM,eACL,0BAA0B,IAAI,SAAS,IACvC,2BAA2B;EAC1B,UAAU,SAAS;EACnB,SAAS,SAAS;EAClB,UAAU,SAAS;EACnB,CAAC;CACH,MAAM,eAAe,aAAa;CAClC,MAAM,gBAAgB,4BAA4B,UAAU,YAAY;CAExE,MAAM,oBAAoB,OAAO,KAChC,SAAS,kBAAkB,EAAE,CAC7B,CAAC,MAAM;CACR,MAAM,qBAAqB,YAAY,QACrC,QAAS,SAAS,MAA4B,YAAY,KAC3D;CAED,MAAM,YAAY,KAAK,UAAU;EAChC;EACA,UAAU,cAAc,QAAQ,KAAK,UAAU,GAAG,MAAM,KAAK,GAAG,MAAM,OAAO;EAC7E;EACA;EACA,mBAAmB,kBAAkB,KAAK,QAAQ;GACjD,MAAM,MAAO,SAAS,eAA8C;AACpE,UAAO,GAAG,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,EAAE,GAAG,KAAK,UAAU;IACrE;EACF;EACA,CAAC;CAEF,MAAM,WAAuF;EAC5F;EACA,iBAAiB,aAAa;EAC9B;EACA;EACA;EACA;EACA;EACA,gBAAgB,SAAS;EACzB,gBAAgB,SAAS;EACzB,mBAAmB,aAAa;EAChC,QAAQ,4BAA4B,IAAI,SAAS,IAAI;EACrD;EACA;EACA;AAED,uBAAsB,IAAI,UAAU,SAAS;AAC7C,QAAO"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { RenderMode } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pointer kind normalized from DOM `PointerEvent.pointerType`.
|
|
4
|
+
*/
|
|
5
|
+
export type PointerKind = 'mouse' | 'pen' | 'touch';
|
|
6
|
+
/**
|
|
7
|
+
* 2D tuple used by pointer coordinate payloads.
|
|
8
|
+
*/
|
|
9
|
+
export type PointerVec2 = [number, number];
|
|
10
|
+
/**
|
|
11
|
+
* Normalized pointer coordinates exposed to runtime hooks.
|
|
12
|
+
*/
|
|
13
|
+
export interface PointerPoint {
|
|
14
|
+
/**
|
|
15
|
+
* CSS pixel coordinates relative to canvas top-left corner.
|
|
16
|
+
*/
|
|
17
|
+
px: PointerVec2;
|
|
18
|
+
/**
|
|
19
|
+
* UV coordinates in shader-friendly orientation (`y` grows upward).
|
|
20
|
+
*/
|
|
21
|
+
uv: PointerVec2;
|
|
22
|
+
/**
|
|
23
|
+
* Normalized device coordinates (`-1..1`, `y` grows upward).
|
|
24
|
+
*/
|
|
25
|
+
ndc: PointerVec2;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Mutable pointer state snapshot exposed by `usePointer`.
|
|
29
|
+
*/
|
|
30
|
+
export interface PointerState extends PointerPoint {
|
|
31
|
+
inside: boolean;
|
|
32
|
+
pressed: boolean;
|
|
33
|
+
dragging: boolean;
|
|
34
|
+
pointerType: PointerKind | null;
|
|
35
|
+
pointerId: number | null;
|
|
36
|
+
button: number | null;
|
|
37
|
+
buttons: number;
|
|
38
|
+
time: number;
|
|
39
|
+
downPx: PointerVec2 | null;
|
|
40
|
+
downUv: PointerVec2 | null;
|
|
41
|
+
deltaPx: PointerVec2;
|
|
42
|
+
deltaUv: PointerVec2;
|
|
43
|
+
velocityPx: PointerVec2;
|
|
44
|
+
velocityUv: PointerVec2;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Modifier key snapshot attached to pointer click events.
|
|
48
|
+
*/
|
|
49
|
+
export interface PointerModifiers {
|
|
50
|
+
alt: boolean;
|
|
51
|
+
ctrl: boolean;
|
|
52
|
+
shift: boolean;
|
|
53
|
+
meta: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Click/tap payload produced by `usePointer`.
|
|
57
|
+
*/
|
|
58
|
+
export interface PointerClick extends PointerPoint {
|
|
59
|
+
id: number;
|
|
60
|
+
time: number;
|
|
61
|
+
pointerType: PointerKind;
|
|
62
|
+
pointerId: number;
|
|
63
|
+
button: number;
|
|
64
|
+
modifiers: PointerModifiers;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Frame wake-up strategy for pointer-driven interactions.
|
|
68
|
+
*/
|
|
69
|
+
export type PointerFrameRequestMode = 'advance' | 'auto' | 'invalidate' | 'none';
|
|
70
|
+
/**
|
|
71
|
+
* Returns a monotonic timestamp in seconds.
|
|
72
|
+
*/
|
|
73
|
+
export declare function getPointerNowSeconds(): number;
|
|
74
|
+
/**
|
|
75
|
+
* Creates the initial pointer state snapshot.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createInitialPointerState(): PointerState;
|
|
78
|
+
/**
|
|
79
|
+
* Normalized coordinate payload for a pointer position against a canvas rect.
|
|
80
|
+
*/
|
|
81
|
+
export interface PointerCoordinates extends PointerPoint {
|
|
82
|
+
inside: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Converts client coordinates to canvas-relative pointer coordinates.
|
|
86
|
+
*/
|
|
87
|
+
export declare function getPointerCoordinates(clientX: number, clientY: number, rect: Pick<DOMRectReadOnly, 'height' | 'left' | 'top' | 'width'>): PointerCoordinates;
|
|
88
|
+
/**
|
|
89
|
+
* Resolves frame wake-up strategy for pointer-driven updates.
|
|
90
|
+
*/
|
|
91
|
+
export declare function resolvePointerFrameRequestMode(mode: PointerFrameRequestMode, renderMode: RenderMode): Exclude<PointerFrameRequestMode, 'auto'>;
|
|
92
|
+
/**
|
|
93
|
+
* Normalizes unknown pointer kind values to the public `PointerKind`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function normalizePointerKind(pointerType: string): PointerKind;
|
|
96
|
+
//# sourceMappingURL=pointer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/lib/core/pointer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,EAAE,EAAE,WAAW,CAAC;IAChB;;OAEG;IACH,EAAE,EAAE,WAAW,CAAC;IAChB;;OAEG;IACH,GAAG,EAAE,WAAW,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,YAAY;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,WAAW,CAAC;IACxB,UAAU,EAAE,WAAW,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,YAAY;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;AAEjF;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,YAAY,CAoBxD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACvD,MAAM,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,GAC9D,kBAAkB,CAgBpB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC7C,IAAI,EAAE,uBAAuB,EAC7B,UAAU,EAAE,UAAU,GACpB,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAc1C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAMrE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
//#region src/lib/core/pointer.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns a monotonic timestamp in seconds.
|
|
4
|
+
*/
|
|
5
|
+
function getPointerNowSeconds() {
|
|
6
|
+
if (typeof performance !== "undefined" && typeof performance.now === "function") return performance.now() / 1e3;
|
|
7
|
+
return Date.now() / 1e3;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Creates the initial pointer state snapshot.
|
|
11
|
+
*/
|
|
12
|
+
function createInitialPointerState() {
|
|
13
|
+
return {
|
|
14
|
+
px: [0, 0],
|
|
15
|
+
uv: [0, 0],
|
|
16
|
+
ndc: [-1, -1],
|
|
17
|
+
inside: false,
|
|
18
|
+
pressed: false,
|
|
19
|
+
dragging: false,
|
|
20
|
+
pointerType: null,
|
|
21
|
+
pointerId: null,
|
|
22
|
+
button: null,
|
|
23
|
+
buttons: 0,
|
|
24
|
+
time: getPointerNowSeconds(),
|
|
25
|
+
downPx: null,
|
|
26
|
+
downUv: null,
|
|
27
|
+
deltaPx: [0, 0],
|
|
28
|
+
deltaUv: [0, 0],
|
|
29
|
+
velocityPx: [0, 0],
|
|
30
|
+
velocityUv: [0, 0]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Converts client coordinates to canvas-relative pointer coordinates.
|
|
35
|
+
*/
|
|
36
|
+
function getPointerCoordinates(clientX, clientY, rect) {
|
|
37
|
+
const width = Math.max(rect.width, 1);
|
|
38
|
+
const height = Math.max(rect.height, 1);
|
|
39
|
+
const nx = (clientX - rect.left) / width;
|
|
40
|
+
const ny = (clientY - rect.top) / height;
|
|
41
|
+
const pxX = clientX - rect.left;
|
|
42
|
+
const pxY = clientY - rect.top;
|
|
43
|
+
const uvX = nx;
|
|
44
|
+
const uvY = 1 - ny;
|
|
45
|
+
return {
|
|
46
|
+
px: [pxX, pxY],
|
|
47
|
+
uv: [uvX, uvY],
|
|
48
|
+
ndc: [nx * 2 - 1, uvY * 2 - 1],
|
|
49
|
+
inside: nx >= 0 && nx <= 1 && ny >= 0 && ny <= 1
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolves frame wake-up strategy for pointer-driven updates.
|
|
54
|
+
*/
|
|
55
|
+
function resolvePointerFrameRequestMode(mode, renderMode) {
|
|
56
|
+
if (mode !== "auto") return mode;
|
|
57
|
+
if (renderMode === "manual") return "advance";
|
|
58
|
+
if (renderMode === "on-demand") return "invalidate";
|
|
59
|
+
return "none";
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Normalizes unknown pointer kind values to the public `PointerKind`.
|
|
63
|
+
*/
|
|
64
|
+
function normalizePointerKind(pointerType) {
|
|
65
|
+
if (pointerType === "mouse" || pointerType === "pen" || pointerType === "touch") return pointerType;
|
|
66
|
+
return "mouse";
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { createInitialPointerState, getPointerCoordinates, getPointerNowSeconds, normalizePointerKind, resolvePointerFrameRequestMode };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=pointer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pointer.js","names":[],"sources":["../../src/lib/core/pointer.ts"],"sourcesContent":["import type { RenderMode } from './types.js';\n\n/**\n * Pointer kind normalized from DOM `PointerEvent.pointerType`.\n */\nexport type PointerKind = 'mouse' | 'pen' | 'touch';\n\n/**\n * 2D tuple used by pointer coordinate payloads.\n */\nexport type PointerVec2 = [number, number];\n\n/**\n * Normalized pointer coordinates exposed to runtime hooks.\n */\nexport interface PointerPoint {\n\t/**\n\t * CSS pixel coordinates relative to canvas top-left corner.\n\t */\n\tpx: PointerVec2;\n\t/**\n\t * UV coordinates in shader-friendly orientation (`y` grows upward).\n\t */\n\tuv: PointerVec2;\n\t/**\n\t * Normalized device coordinates (`-1..1`, `y` grows upward).\n\t */\n\tndc: PointerVec2;\n}\n\n/**\n * Mutable pointer state snapshot exposed by `usePointer`.\n */\nexport interface PointerState extends PointerPoint {\n\tinside: boolean;\n\tpressed: boolean;\n\tdragging: boolean;\n\tpointerType: PointerKind | null;\n\tpointerId: number | null;\n\tbutton: number | null;\n\tbuttons: number;\n\ttime: number;\n\tdownPx: PointerVec2 | null;\n\tdownUv: PointerVec2 | null;\n\tdeltaPx: PointerVec2;\n\tdeltaUv: PointerVec2;\n\tvelocityPx: PointerVec2;\n\tvelocityUv: PointerVec2;\n}\n\n/**\n * Modifier key snapshot attached to pointer click events.\n */\nexport interface PointerModifiers {\n\talt: boolean;\n\tctrl: boolean;\n\tshift: boolean;\n\tmeta: boolean;\n}\n\n/**\n * Click/tap payload produced by `usePointer`.\n */\nexport interface PointerClick extends PointerPoint {\n\tid: number;\n\ttime: number;\n\tpointerType: PointerKind;\n\tpointerId: number;\n\tbutton: number;\n\tmodifiers: PointerModifiers;\n}\n\n/**\n * Frame wake-up strategy for pointer-driven interactions.\n */\nexport type PointerFrameRequestMode = 'advance' | 'auto' | 'invalidate' | 'none';\n\n/**\n * Returns a monotonic timestamp in seconds.\n */\nexport function getPointerNowSeconds(): number {\n\tif (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n\t\treturn performance.now() / 1000;\n\t}\n\n\treturn Date.now() / 1000;\n}\n\n/**\n * Creates the initial pointer state snapshot.\n */\nexport function createInitialPointerState(): PointerState {\n\treturn {\n\t\tpx: [0, 0],\n\t\tuv: [0, 0],\n\t\tndc: [-1, -1],\n\t\tinside: false,\n\t\tpressed: false,\n\t\tdragging: false,\n\t\tpointerType: null,\n\t\tpointerId: null,\n\t\tbutton: null,\n\t\tbuttons: 0,\n\t\ttime: getPointerNowSeconds(),\n\t\tdownPx: null,\n\t\tdownUv: null,\n\t\tdeltaPx: [0, 0],\n\t\tdeltaUv: [0, 0],\n\t\tvelocityPx: [0, 0],\n\t\tvelocityUv: [0, 0]\n\t};\n}\n\n/**\n * Normalized coordinate payload for a pointer position against a canvas rect.\n */\nexport interface PointerCoordinates extends PointerPoint {\n\tinside: boolean;\n}\n\n/**\n * Converts client coordinates to canvas-relative pointer coordinates.\n */\nexport function getPointerCoordinates(\n\tclientX: number,\n\tclientY: number,\n\trect: Pick<DOMRectReadOnly, 'height' | 'left' | 'top' | 'width'>\n): PointerCoordinates {\n\tconst width = Math.max(rect.width, 1);\n\tconst height = Math.max(rect.height, 1);\n\tconst nx = (clientX - rect.left) / width;\n\tconst ny = (clientY - rect.top) / height;\n\tconst pxX = clientX - rect.left;\n\tconst pxY = clientY - rect.top;\n\tconst uvX = nx;\n\tconst uvY = 1 - ny;\n\n\treturn {\n\t\tpx: [pxX, pxY],\n\t\tuv: [uvX, uvY],\n\t\tndc: [nx * 2 - 1, uvY * 2 - 1],\n\t\tinside: nx >= 0 && nx <= 1 && ny >= 0 && ny <= 1\n\t};\n}\n\n/**\n * Resolves frame wake-up strategy for pointer-driven updates.\n */\nexport function resolvePointerFrameRequestMode(\n\tmode: PointerFrameRequestMode,\n\trenderMode: RenderMode\n): Exclude<PointerFrameRequestMode, 'auto'> {\n\tif (mode !== 'auto') {\n\t\treturn mode;\n\t}\n\n\tif (renderMode === 'manual') {\n\t\treturn 'advance';\n\t}\n\n\tif (renderMode === 'on-demand') {\n\t\treturn 'invalidate';\n\t}\n\n\treturn 'none';\n}\n\n/**\n * Normalizes unknown pointer kind values to the public `PointerKind`.\n */\nexport function normalizePointerKind(pointerType: string): PointerKind {\n\tif (pointerType === 'mouse' || pointerType === 'pen' || pointerType === 'touch') {\n\t\treturn pointerType;\n\t}\n\n\treturn 'mouse';\n}\n"],"mappings":";;;;AAgFA,SAAgB,uBAA+B;AAC9C,KAAI,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,WACpE,QAAO,YAAY,KAAK,GAAG;AAG5B,QAAO,KAAK,KAAK,GAAG;;;;;AAMrB,SAAgB,4BAA0C;AACzD,QAAO;EACN,IAAI,CAAC,GAAG,EAAE;EACV,IAAI,CAAC,GAAG,EAAE;EACV,KAAK,CAAC,IAAI,GAAG;EACb,QAAQ;EACR,SAAS;EACT,UAAU;EACV,aAAa;EACb,WAAW;EACX,QAAQ;EACR,SAAS;EACT,MAAM,sBAAsB;EAC5B,QAAQ;EACR,QAAQ;EACR,SAAS,CAAC,GAAG,EAAE;EACf,SAAS,CAAC,GAAG,EAAE;EACf,YAAY,CAAC,GAAG,EAAE;EAClB,YAAY,CAAC,GAAG,EAAE;EAClB;;;;;AAaF,SAAgB,sBACf,SACA,SACA,MACqB;CACrB,MAAM,QAAQ,KAAK,IAAI,KAAK,OAAO,EAAE;CACrC,MAAM,SAAS,KAAK,IAAI,KAAK,QAAQ,EAAE;CACvC,MAAM,MAAM,UAAU,KAAK,QAAQ;CACnC,MAAM,MAAM,UAAU,KAAK,OAAO;CAClC,MAAM,MAAM,UAAU,KAAK;CAC3B,MAAM,MAAM,UAAU,KAAK;CAC3B,MAAM,MAAM;CACZ,MAAM,MAAM,IAAI;AAEhB,QAAO;EACN,IAAI,CAAC,KAAK,IAAI;EACd,IAAI,CAAC,KAAK,IAAI;EACd,KAAK,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,EAAE;EAC9B,QAAQ,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM;EAC/C;;;;;AAMF,SAAgB,+BACf,MACA,YAC2C;AAC3C,KAAI,SAAS,OACZ,QAAO;AAGR,KAAI,eAAe,SAClB,QAAO;AAGR,KAAI,eAAe,YAClB,QAAO;AAGR,QAAO;;;;;AAMR,SAAgB,qBAAqB,aAAkC;AACtE,KAAI,gBAAgB,WAAW,gBAAgB,SAAS,gBAAgB,QACvE,QAAO;AAGR,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/lib/core/renderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/lib/core/renderer.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAOX,QAAQ,EACR,eAAe,EAMf,MAAM,YAAY,CAAC;AAmepB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,YAAY,EAClB,iBAAiB,SAAwB,GACvC,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAwCzC;AAsFD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CA+jDhF"}
|