import { Expr, GpuFragmentParams } from '../../gpu/contract'; import { voxels as voxelKit } from '../../gpu/kit/index'; import { PropRef } from '../values'; import { ShapedSurfaceEffect, SurfaceFrame, SurfaceField } from './materials'; /** What each block is: `'cube'`, `'sphere'` or `'rounded'` (a cube with rounded corners). */ export type VoxelStyle = voxelKit.VoxelStyle; /** Where the grid sits: `'shape'` turns with the shape like a built model, `'view'` stays fixed to the canvas. */ export type VoxelGridSpace = voxelKit.VoxelGridSpace; /** What `voxelSurface` needs. Every field but `surface` is a prop ref, `p('name')`. */ export interface VoxelSurfaceSpec { /** The block style, `'cube' | 'sphere' | 'rounded'`. Mark the prop `compileTime: true`. */ style: PropRef; /** Where the grid sits, `'shape' | 'view'`. Mark the prop `compileTime: true`. */ gridSpace: PropRef; /** The edge length of one block, relative to the shape. 0.035 is about a tenth of the default sphere. */ voxelSize: PropRef; /** How eagerly cells along the surface fill in, −0.5 to 0.5. Negative carves the model thinner, positive puffs it out. */ fill: PropRef; /** The size of each block inside its cell, 0.3–1. 1 touches its neighbours, less opens gaps. */ voxelScale: PropRef; /** Corner rounding as a fraction of the block size, 0–1. A hairline chamfer on cubes, the corner radius of rounded cubes. */ bevel: PropRef; /** The soft-edge width of cast shadows, 0–1. 0 is razor sharp. */ shadowSoftness: PropRef; /** Optional camera tilt, in degrees. */ pitch?: PropRef; /** Optional camera turn, in degrees. */ yaw?: PropRef; /** Optional turntable speed. Declare `animatedTime: {speed: 'spin'}` too. A speed of 1 is one turn every ten seconds. */ spin?: PropRef; /** The direction the key light comes from, in degrees around the canvas. Shadows fall away from it. */ lightAngle: PropRef; /** How high the key light sits above the canvas, in degrees. Low for long shadows, high for flat top light. */ lightElevation: PropRef; /** The thickness given to flat shapes so they become a slab of blocks, relative to the shape. 3D shapes ignore it. */ depth: PropRef; /** Your material: the color of one block. Return `vec4(rgb, vox.coverage)`. */ surface: (vox: VoxelFrame, frame: SurfaceFrame, params: GpuFragmentParams) => Expr; } /** One block, as `voxelSurface` hands it to your `surface`. */ export interface VoxelFrame { /** The shape field basics: `sdf`, `pxH` (one pixel in uv) and `aspect`. */ field: SurfaceField; /** 1 when this is a real block, 0 for an empty slot. Return it as your alpha. */ coverage: Expr; /** The block's unit normal at this pixel. x right, y down, z negative toward the viewer. */ normal: Expr; /** How open the block's surroundings are, 1 in the open and lower in creases. Multiply ambient light by it. */ ao: Expr; /** How much shadow other blocks cast here, 0 in the light and 1 fully shadowed. */ shadow: Expr; /** The block's grid position as three whole numbers in a vec3. */ cell: Expr; /** A random 0–1 number that stays the same for this block every frame. Use it for per-block color variation. */ cellHash: Expr; /** How high the block sits, 0 at the bottom of the model and 1 at the top. */ heightT: Expr; /** How deep the block sits, 0 nearest the viewer and 1 farthest. */ depthT: Expr; /** How far this pixel is from the centre of its face toward the edge, 0–1. Seams live near 1. */ edge: Expr; /** The view ray into the scene, in the same convention as `normal`. */ view: Expr; /** The block style in force, known when the shader compiles. */ style: VoxelStyle; } /** * Rebuild the shape from blocks and shade each block with your `surface`. * * Returns `{extraFields, compute, gpu}` to spread into a shape-effect definition. Your props * must include the standard shape props (`center`, `scale`, `rotation`, `shape`, `shapeSdfUrl`, * `shapeType`), a `shadows` amount (0–1) and everything the spec names. Your `surface` gets a * `VoxelFrame` per block and returns `vec4(rgb, vox.coverage)`. Geometry props re-build the * model when they change. Color and light props never do. * * @example * ```ts * ...voxelSurface({style: p('voxelShape'), gridSpace: p('gridSpace'), voxelSize: p('voxelSize'), fill: p('fill'), voxelScale: p('voxelScale'), bevel: p('bevel'), shadowSoftness: p('shadowSoftness'), lightAngle: p('lightAngle'), lightElevation: p('lightElevation'), depth: p('depth'), surface: (vox, frame, params) => math.vec4(shade(vox), vox.coverage)}) * ``` * @tip Light with `materials.lambert(vox.normal, L, {wrap: 0.12})` times `1 − vox.shadow · shadows` and the blocks read as solid. * @see shapedSurface, lambert */ export declare function voxelSurface(spec: VoxelSurfaceSpec): ShapedSurfaceEffect; //# sourceMappingURL=voxels.d.ts.map