import { d } from './index'; import { GpuFragmentParams, KitTexture, GpuComputeStep } from '../contract'; import { BakedSdf, VolumetricFieldLayout } from './sdf3d'; export type VoxelStyle = 'cube' | 'sphere' | 'rounded'; export type VoxelGridSpace = 'shape' | 'view'; /** Cells per axis cap (device-tiered: the occupancy buffer is W·N² u32 words, 7 MB / 2 MB at the * caps). Indices pack into one f32 as ix + iy·256 + iz·65536, so the cap must stay below 256. */ export declare const VOXEL_GRID_MAX: number; /** Fixed occupancy-buffer allocation (words). */ export declare const OCC_BUFFER_WORDS: number; /** Shadow-map resolution (texels per side over the bounding diameter). ~30 texels per default * voxel edge on desktop — a hard shadow's edge lands well inside one voxel face. */ export declare const VOXEL_SHADOW_RES: number; export declare const VOXEL_SHADOW_FORMAT: "r32float"; /** * The voxel pre-march uniform (bound with the occupancy grid + shadow map). FULL-WRITE ONLY (the * `cam` member is Decorated — see MarchParams). * cam — camera pitch/yaw as a ZXY RotStruct, applied to the view ray BEFORE the shape rot * lightDir — unit light direction in GRID space; lightT1/T2 its tangent basis (the shadow-map frame) * voxelSize — cell edge (field UV) · fill — occupancy threshold in cells (sdf(centre) < fill·size) * voxelScale — sub-shape size within its cell (1 = touching) · bevel — rounded style radius fraction * gridOrigin — grid min corner (all axes; = −rBound) · gridN / gridW — cells per axis, words per row */ export declare const VoxelMarchParams: d.WgslStruct<{ cam: d.Decorated, [d.Align<16>, d.Size<32>]>; lightDir: d.Vec3f; voxelSize: d.F32; lightT1: d.Vec3f; fill: d.F32; lightT2: d.Vec3f; voxelScale: d.F32; bevel: d.F32; gridOrigin: d.F32; gridN: d.F32; gridW: d.F32; }>; /** * The march + shadow-map bind group: the voxel params, the baked OCCUPANCY GRID (read-only) and * the SHADOW MAP (the shadow pass writes it; the march pipeline simply never touches it). Each grid * cell is a u8 packed four-per-u32 along x: 0 = solid · k ≥ 1 = empty with (k − 1) cells of * guaranteed clearance (the empty-space skip distance). Baked once per geometry change by * `buildVoxelBakeFn`, so the march, the AO taps and the shadow rays never evaluate the shape SDF. */ export declare function makeVoxelLayout(): import('typegpu').TgpuBindGroupLayout<{ vox: { uniform: d.WgslStruct<{ cam: d.Decorated, [d.Align<16>, d.Size<32>]>; lightDir: d.Vec3f; voxelSize: d.F32; lightT1: d.Vec3f; fill: d.F32; lightT2: d.Vec3f; voxelScale: d.F32; bevel: d.F32; gridOrigin: d.F32; gridN: d.F32; gridW: d.F32; }>; }; occ: { storage: d.WgslArray; access: "readonly"; }; shadowMap: { storageTexture: d.WgslStorageTexture2d<"r32float", string>; }; }>; export type VoxelLayout = ReturnType; /** The bake's bind group over the SAME uniform + buffer, with the grid writable. */ export declare function makeVoxelBakeLayout(): import('typegpu').TgpuBindGroupLayout<{ vox: { uniform: d.WgslStruct<{ cam: d.Decorated, [d.Align<16>, d.Size<32>]>; lightDir: d.Vec3f; voxelSize: d.F32; lightT1: d.Vec3f; fill: d.F32; lightT2: d.Vec3f; voxelScale: d.F32; bevel: d.F32; gridOrigin: d.F32; gridN: d.F32; gridW: d.F32; }>; }; occ: { storage: d.WgslArray; access: "mutable"; }; }>; export type VoxelBakeLayout = ReturnType; export interface VoxelFieldOptions { style: VoxelStyle; /** `'shape'`: the grid rotates with the solid (a voxel MODEL). `'view'`: the grid is fixed to * the screen and the solid moves through it (a 3D pixelation). */ gridSpace: VoxelGridSpace; } /** * Build the occupancy BAKE kernel: one thread per u32 word (four x-adjacent cells), dispatched * `(gridW, gridN, gridN)`. Each cell's value is 0 when the shape SDF at its centre is below the fill * threshold, else 1 + the cells of clearance the SDF guarantees around it (see CLEARANCE_MARGIN). * `sdfFn` is the setup's baked shape SDF; `marchLayout` is the setup's layout (the SDF reads its * params off it, and `'view'` grids read `rot`). The only place the shape SDF runs. */ export declare function buildVoxelBakeFn(sdfFn: BakedSdf, marchLayout: VolumetricFieldLayout, bakeLayout: VoxelBakeLayout, gridSpace: VoxelGridSpace): import('typegpu').TgpuFn<(wx: d.U32, iy: d.U32, iz: d.U32) => d.Void>; /** * The grid TRAVERSAL vocabulary over a `VoxelLayout` — shared by the march and the shadow-map * pass: baked cell reads, the sub-shape ray test and the DDA with empty-space leaps. `style` is a * build-time string; only its branch is emitted. */ export declare function buildVoxelTraversal(voxLayout: VoxelLayout, style: VoxelStyle): { cellValue: import('typegpu').TgpuFn<(cx: d.F32, cy: d.F32, cz: d.F32) => d.F32>; cellCentre: import('typegpu').TgpuFn<(cx: d.F32, cy: d.F32, cz: d.F32) => d.Vec3f>; occupied: import('typegpu').TgpuFn<(cx: d.F32, cy: d.F32, cz: d.F32) => d.F32>; subShapeHit: import('typegpu').TgpuFn<(ro: d.Vec3f, rd: d.Vec3f, c: d.Vec3f, tNow: d.F32) => d.WgslStruct<{ hit: d.F32; t: d.F32; }>>; voxelDda: import('typegpu').TgpuFn<(ro: d.Vec3f, rd: d.Vec3f, tStart: d.F32, tEnd: d.F32, skip: d.Vec3f, maxSteps: d.I32) => d.WgslStruct<{ hit: d.F32; t: d.F32; cx: d.F32; cy: d.F32; cz: d.F32; minD: d.F32; }>>; }; /** * Build the SHADOW-MAP kernel: dispatched `(VOXEL_SHADOW_RES, VOXEL_SHADOW_RES)`, each texel an * orthographic ray from the light side of the bounding sphere along −lightDir, storing the distance * to the first solid (SHADOW_FAR on a miss). The map frame is `lightT1/lightT2` over ±rBound. */ export declare function buildVoxelShadowMapFn(voxLayout: VoxelLayout, style: VoxelStyle): import('typegpu').TgpuFn<(i: d.U32, j: d.U32) => d.Void>; /** * Contact-hardening soft shadow (PCSS) from the voxel shadow map, for a receiver point `p` in grid * space (already offset off its surface along the normal). `L`/`T1`/`T2` are the map frame, * `rBound` its half extent, `softness` 0..1 (0 = one bilinear-compared tap), `voxel` the cell edge * (depth bias scale). Returns the shadowed fraction, 1 = fully in shadow. */ export declare const voxelShadowLookup: import('typegpu').TgpuFn<(tex: d.WgslTexture2d, p: d.Vec3f, L: d.Vec3f, T1: d.Vec3f, T2: d.Vec3f, rBound: d.F32, softness: d.F32, voxel: d.F32) => d.F32>; /** Ray vs the axis-aligned box of half size `h` centred at `c`. */ export declare const voxelRayBox: import('typegpu').TgpuFn<(ro: d.Vec3f, rd: d.Vec3f, c: d.Vec3f, h: d.F32) => d.F32>; /** Ray vs the sphere of radius `h` centred at `c`. */ export declare const voxelRaySphere: import('typegpu').TgpuFn<(ro: d.Vec3f, rd: d.Vec3f, c: d.Vec3f, h: d.F32) => d.F32>; /** Ray vs the rounded box (half `h`, corner radius `r`) centred at `c`: the box entry refined by a * short sphere trace inside its slab bracket. */ export declare const voxelRayRoundedBox: import('typegpu').TgpuFn<(ro: d.Vec3f, rd: d.Vec3f, c: d.Vec3f, h: d.F32, r: d.F32) => d.F32>; /** * Build the voxel march fn — plug-compatible with `buildVolumetricFieldKernel` (`(fuv, rot, rBound) * → vec4`). Walks the BAKED occupancy grid (`voxLayout.occ`) — no shape SDF and no light here; * `marchLayout` is the setup's layout (the kernel reads the field domain off it). `style` and * `gridSpace` are build-time strings — only the selected branches are emitted. */ export declare function buildVoxelFieldFn(marchLayout: VolumetricFieldLayout, voxLayout: VoxelLayout, opts: VoxelFieldOptions): import('typegpu').TgpuFn<(fuv: d.Vec2f, rot: d.WgslStruct<{ cx: d.F32; sx: d.F32; cy: d.F32; sy: d.F32; cz: d.F32; sz: d.F32; }>, rBound: d.F32) => d.Vec4f>; /** The live values the voxel pre-march reads each frame (a consumer maps its props onto these). */ export interface VoxelMarchValues { /** Cell edge in field UV. */ voxelSize: number; /** Occupancy threshold in cells: sdf(centre) < fill·size. 0 = centre inside; +0.5 fatter. */ fill: number; /** Sub-shape size within its cell (1 = touching neighbours, <1 = gaps). */ voxelScale: number; /** Rounded-style corner radius as a fraction of the half size. */ bevel: number; /** Camera pitch / yaw in degrees (yaw includes any turntable spin). */ pitch: number; yaw: number; /** Key light azimuth (degrees, the fleet's screen-space `lightAngle` convention) / elevation * above the screen plane (degrees). */ lightAngle: number; lightElevation: number; /** Slab thickness given to FLAT shapes (field UV). */ depth: number; } export interface VoxelFieldSpec extends VoxelFieldOptions { getShapeConfig: () => unknown; getValues: () => VoxelMarchValues; } /** The extraFields a voxel consumer's fragment reads: the view→grid rotation (columns), the live * voxel size, the grid origin, and the shadow-map frame (light direction + tangents, grid space) * — everything needed to reconstruct a hit from the G-buffer and look up its shadow. */ export declare const VOXEL_FIELD_EXTRA_FIELDS: Record; /** * The voxel counterpart of `createVolumetricFieldComputeNode`: routes EVERY shape type to a * volumetric setup (3D analytic · SVG extrude · flat SVG lifted by `depth` · flat analytic lifted by * `depth`), bakes its occupancy grid, renders the shadow map and marches the field — each on its own * dirty key — and publishes the `_vf*` SampleParams plus the `_vx*` reconstruction fields. Outputs * the field texture AND the shadow map (`voxelShadowMap`). Returns null without a device. */ export declare function createVoxelFieldComputeNode(params: GpuFragmentParams, spec: VoxelFieldSpec): { outputs: { volumetricFieldTexture: KitTexture; voxelShadowMap: KitTexture; }; getComputeNodes: (frameParams?: unknown) => GpuComputeStep[] | null; } | null; //# sourceMappingURL=voxels.d.ts.map