import type { Vector3 } from '@holoscript/core'; /** * AdvancedTexturing.ts * * Advanced texturing techniques (CPU-side): * - Displacement mapping (tessellation height scale helpers) * - Parallax Occlusion Mapping (iterative ray-step algorithm) * - Triplanar mapping (normal-based blend weights + UV generation) * - Detail maps (fine-grain albedo + normal overlay at a higher tiling) * - Texture atlas UV packing (row-based guillotine) * * Works with arbitrary Float32Array textures (RGBA, row-major). * No WebGPU / DOM — fully testable in Vitest. * * @module rendering */ export type Vec2 = [number, number]; /** Simple flat texture (row-major, RGBA, linear) */ export interface Texture2D { width: number; height: number; pixels: Float32Array; } /** Create a solid-colour texture */ export declare function createSolidTexture(w: number, h: number, r?: number, g?: number, b?: number, a?: number): Texture2D; /** Sample a texture at UV coordinates [0–1], clamped. Returns [R, G, B, A]. */ export declare function sampleTexture(tex: Texture2D, u: number, v: number): [number, number, number, number]; /** Sample a texture with bilinear interpolation */ export declare function sampleTextureBilinear(tex: Texture2D, u: number, v: number): [number, number, number, number]; export interface DisplacementConfig { /** Height scale in world units */ scale: number; /** Bias (offset applied symmetrically around 0) */ bias: number; } /** * Compute a displaced position given a surface position, normal, * and a height map sample at the corresponding UV. */ export declare function computeDisplacedPosition(position: Vector3, normal: Vector3, heightMap: Texture2D, u: number, v: number, config?: Partial): Vector3; /** * Compute vertex normals for a displaced mesh via finite differences. * heights: per-vertex height samples (row-major, same size as vertex grid). * Returns per-vertex Vector3 normals (not normalised). */ export declare function computeDisplacementNormalsFromHeightMap(heights: Float32Array, gridW: number, gridH: number, cellSizeX: number, cellSizeZ: number): Vector3[]; export interface POMConfig { /** Height scale (0–1, typ. 0.05–0.15) */ heightScale: number; /** Min ray march layers (far from surface) */ minLayers: number; /** Max ray march layers (near surface) */ maxLayers: number; } /** * Perform Parallax Occlusion Mapping to compute an offset UV. * * @param uv - Input surface UV * @param viewDir - View direction in tangent space (must point away from surface) * @param heightMap - Single-channel height map (R channel) * @param config - POM settings * @returns Parallax-offset UV */ export declare function computePOM(uv: Vec2, viewDir: Vector3, heightMap: Texture2D, config?: Partial): Vec2; /** * Compute triplanar blend weights from a surface normal. * Higher sharpness → sharper transitions between planes. */ export declare function triplanarWeights(normal: Vector3, sharpness?: number): Vector3; /** * Sample a texture using triplanar UV projection. * position: world-space position; tileScale: how fast the texture tiles. * Returns blended RGBA from all three planes. */ export declare function sampleTriplanar(tex: Texture2D, position: Vector3, normal: Vector3, tileScale?: number, sharpness?: number): [number, number, number, number]; export interface DetailMapConfig { /** How many times the detail map tiles over the base UV */ tileScale: number; /** Blend intensity 0–1 */ intensity: number; } /** Overlay a detail albedo texture on top of a base albedo sample */ export declare function applyDetailAlbedo(baseColor: [number, number, number, number], detailTex: Texture2D, u: number, v: number, config?: Partial): [number, number, number, number]; /** * Blend detail normal with base normal (Reoriented Normal Mapping). * Both normals must be unit-length, in tangent space. */ export declare function blendDetailNormal(base: Vector3, detail: Vector3): Vector3; export interface AtlasRect { x: number; y: number; width: number; height: number; /** Source identifier */ id: string; } export interface AtlasPacker { atlasWidth: number; atlasHeight: number; rects: AtlasRect[]; /** Number of rows stacked */ rowCount: number; /** Current row cursor */ cursorX: number; cursorY: number; rowHeight: number; } /** Create a new atlas packer */ export declare function createAtlasPacker(width?: number, height?: number): AtlasPacker; /** * Pack a texture region into the atlas (row-based guillotine). * Returns the allocated AtlasRect or null if out of space. */ export declare function packRect(packer: AtlasPacker, id: string, width: number, height: number, padding?: number): AtlasRect | null; /** Get UV coordinates [0–1] of a packed rect within the atlas */ export declare function getRectUV(packer: AtlasPacker, rect: AtlasRect): { u0: number; v0: number; u1: number; v1: number; }; /** Total packing efficiency (used area / total area) */ export declare function getAtlasEfficiency(packer: AtlasPacker): number; //# sourceMappingURL=AdvancedTexturing.d.ts.map