Help us shape the future of Go! Take the 2026 Go Developer Survey

worldlightmap

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 13 Imported by: 0

README

Build-generated world lightmap layout

Fixed combined lighting, version 1

Candidate Go module v0.0.19 adds world/fixed-lighting@1. One authored fixed sun/sky and the layout's selected eligible static lamps enter the same CPU transport and directional RNM surface result. BakeFixed and Baker.BakeFixed emit cpu-fixed-rnm3@3; NewFixedLighting binds its result to a separately encoded linear RGBA QOI image. Existing KLM1, KPB1 and environment producers retain their bytes and behavior. The new output has no runtime condition variants, fetching, blending or whole-atlas weather lighting multiplier.

Producer revision 2 preserves translucent liquid/glass surfaces as fixed RNM receivers. They receive the same static sun, sky, lamps and artistic fill as opaque surfaces, including covered black when unlit. Their polygons remain excluded from the transport accelerator: they never occlude direct or sky lighting or reflect bounced light into other receivers. Runtime opacity, refraction and specular remain material/presentation behavior. Receiver rasterization and opaque transport share semantic surface indices without sharing their polygon inclusion rule. This corrects empty translucent charts being sampled as complete fixed lighting; no live diffuse fallback is needed.

Producer revision 3 identifies terrain hemisphere samples by exact physical position and normalized shading normal, rather than a patch-local vertex index. Shared vertices therefore retain identical finite-sample RNM across patch partitions and chunk crops of the same full transport world. Signed zero is canonicalized; a nonnegative 31-bit coordinate hash gives the same sample index on 32-bit and 64-bit hosts. The authored seed still controls sample rotation. Ordinary atlas texel and actor-probe sampling sequences remain unchanged.

The KFL1 wire/schema remains unchanged. Completed revision-1/2 artifacts remain readable and retain their producer identity when rebound. New fixed input/cache digests include the revision-3 producer, so old pixels cannot satisfy a fresh bake. The separate legacy environment producer still excludes translucent receivers and retains its original pixels and producer/cache identity.

Each owning chunk carries @world/lightmaps/fixed (KFL1) and @world/lightmaps/fixed-rnm3, plus layout, geometry and optional terrain. Root and child metadata use kartyWorldFixedLighting: karty.world-fixed-lighting@1. Admission verifies the whole child first, then bounded typed records, canonical hashes, image/layout identities, full QOI integrity and receiver ownership. Build/cache validation additionally checks world/source provenance. Surface, reflectance and input hashes bind fixed sources, original albedo, sampling and full/cropped terrain. Worker count is excluded from identity.

FixedLighting stores chunk-local compiled point/sun records and six-axis ambient probes in +X,-X,+Y,-Y,+Z,-Z order. Each probe nominates at most two visible direct sources. Its ambient cube contains sky, bounced light and every non-nominated source's direct illumination; nominated direct illumination is excluded. Runtime uses the nearest probe in the object's sector and evaluates exactly its nominated sources. Mixing ambient cubes whose exclusion sets differ would double-count or lose light and is outside this contract. Compiled source records never re-light already baked static surfaces.

Probe placement uses the convex sector centroid plus an interior 2-by-2 XY grid at three heights, at most 15 probes per sector and 3840 per world. Terrain raises probe floors and solid interiors are excluded. This bounded layout approximates fine visibility variation; it is not a visibility field.

Authored Lighting.Ambient/AmbientCube is preserved as non-bounced fixed artistic fill, baked into surface RNM and matching probe ambient exactly once. The cube replaces the constant fill. Runtime global fill is disabled for these receivers; source identities and RGBM bounds include the authored fill.

KFL1 has the standard 16-byte typed header, bounded strings/scalars followed by compiled lights, probes and terrain coefficients. Limits are 2 MiB encoded, 4097 sources, 4096 probes and two direct slots. Complete preflight precedes owned slice allocation. FixedLightingBytes separately bounds resident scalar storage. Colors and coefficients are finite nonnegative linear RGB. Ordinary RNM, normal maps and scalar material AO remain. SSBump/reflection probes are outside v1.

Terrain receives genuine baked per-vertex RNM3, nine float32 values per exact worldterrain.CompilePatch vertex. TerrainLightingBasis defines the shared normal-derived frame. Full terrain enters the same transport accelerator; only the chunk's cropped terrain emits coefficients. TerrainSHA256 and TerrainReceiverSHA256 bind full/child documents independently. ValidateFixedTerrainBinding checks child digest, patch identity and exact vertex counts. Terrain bounces use low-frequency far-colour reflectance in v1; detailed normal/albedo textures still control runtime material appearance.

Fixed catalogs use semantic karty.world-chunks@2, KCC3 binary version 3, 136-byte chunk records. LightmapBytes remains decoded RNM image storage; LightingBytes is exactly FixedLightingBytes, and TerrainBytes is exactly worldterrain.ResidentGeometryBytes for the child terrain. Publication/eviction own them together. KCC2 remains unchanged and rejects nonzero new reservations.

Compiler-authoritative chunk resources

For world/chunk-ready@1 children, the build pipeline completes the source geometry, chart packing, UV/basis and bake-input proof before publishing exact child hashes in the accepted parent catalog. After whole-child size/SHA-256 verification, runtime uses DecodeLayoutArtifact with LayoutAdmission root sector/solid counts. It checks schema/count/page/rectangle/reference bounds, receiver indexes, finite chart fields and bounded bake recipes; it does not rebuild surfaces, recompute geometry digests, prove chart overlap/coverage or reconstruct authored basis and affine mapping. Hosts compare the carried geometry digest and receiver selection directly to their accepted descriptor.

DecodePrebakeArtifact and ValidatePrebakeArtifact check a manifest against an already admitted layout, exact image bytes/digest, complete bounded linear RGBA QOI, dimensions and a finite GPU-representable RGBM range. They accept existing direct and offline producer algorithms without recomputing source lighting, reflectance/surface or bake-input digests. DecodeEnvironmentVariantsArtifact and ValidateEnvironmentVariantsArtifact similarly check bounded catalog and layout/image identities without re-proving environment source geometry.

These structural APIs require prior whole-artifact catalog integrity admission; metadata alone does not establish authenticity or producer correctness. The existing Decode/Validate, DecodePrebake/PrebakePair.Validate and environment source validators keep their complete checks for builders, offline cache acceptance and the semantic-only runtime path. No binary layout changes.

Chunk receiver algorithm 2

world/chunks@1 adds CompileReceivers(document, options, sectors, solids) and layout receiver algorithm 2. Its receivers field contains sorted, unique global sector and solid indexes. The complete world geometry digest and complete binding table remain present; unselected surfaces have chart -1. Algorithm 1 retains its bounds, mandatory receiver coverage and one-component bake scope under the candidate binary wire. Algorithm 2 merges charts only through selected ordinary adjacent sectors and packs at the requested density without a global atlas.

Compile and CompileReceivers use the configured fixed page size. Finite charts that exceed that page, or exhaust its packing capacity, return ErrPageCapacity while preserving errors.Is(err, ErrLayout). Invalid geometry, options and lighting recipes return their existing errors without that capacity identity. The chunk planner uses this distinction to try a 512 page first under a configured 1024 maximum, keeping the same density, padding and recipe.

ReceiverScope identifies the full ordinary physical component used for transport. Receivers spanning transformed spaces, or volumes touching multiple spaces, fail explicitly. A global direct light selection is filtered to that component; an empty resulting selection stores covered black. No light travels through transformed portals. Chunk producers still validate every light identifier and reject duplicate or unknown selectors. See format/worldchunk for packaging and mesh ownership.

Environment sky receivers

Candidate world/environment@1 sky ceilings and opaque horizon walls retain their semantic bindings with Chart: -1 and no receiver polygons. Upper strips between two sky sectors behave the same way; indoor roofs and sky-to-indoor lintels remain physical. Sky markers participate in the geometry digest, using canonical boolean bytes. Sky palette, preset and sun direction do not change receiver layout identity.

Existing bake recipes select named point lights only. Directional sun and sky illumination are runtime contributions; the existing offline producer does not bake them or sky-driven indirect transport. Unsupported sun selection fails explicitly as an unknown point light. A sky opening is never treated as a roof or an albedo receiver. The ordinary physical-component and transformed-portal bake restrictions still apply.

Candidate binary wire, version 1

Layouts use KLM1; prebake manifests use KPB1. Both have a 16-byte little-endian header: magic, uint16 version 1, uint16 zero flags, uint32 exact payload length and uint32 zero reserved. Fields follow public Go declaration order using the shared typed primitives. Semantic schemas and receiver/bake algorithms remain separate from this binary version. JSON has no decode fallback. The new binary layout, geometry, selected light, offline surface and reflectance identities require rebuilt artifacts and bake caches; sampling and image pixels are unchanged.

LayoutDigest checks bounded structural encoding and returns SHA-256 over the same bytes as Encode; full authored validation still requires a document. DecodePrebakeManifest checks the manifest without image decoding, including hash syntax, dimensions, encoded image bounds and algorithm controls, so callers can authorize image paths and reserve decoded storage. DecodePrebake additionally checks the complete image/layout/world identity before publication.

Layout contract

world/lightmaps@1 is a capability available in SDK 0.0.8. The public CLI generates @world/lightmaps/layout as an EntryData entry in the existing KLD envelope. Metadata contains kartyWorldLightmaps: "karty.world-lightmaps@1". Cartridges require this feature together with world/sectors@1. Semantic world and cartridge capability versions are independent of the candidate binary envelope. Older released SDK manifests remain unchanged.

The canonical typed binary Layout has schema karty.world-lightmaps@1, algorithm 1, a lower-case SHA-256 geometry digest, requested texels per world unit, padding, pages, charts and semantic bindings. This version permits exactly one square 512 or 1024 page, at most 1,048,576 allocated texels and 8,192 charts. Layout payloads are bounded to 8 MiB and remain subject to the envelope aggregate bound. Density is finite in (0,64]; padding is 1–16 pixels. Builders never silently lower density to fit. Oversized charts or a full page are explicit errors.

Charts contain orthonormal world-space normal, tangent and bitangent vectors, normalized affine U/V planes and integer receiver/padded rectangles. Rectangles are [minimumX, minimumY, maximumX, maximumY], with exclusive maximums. The receiver rectangle is exactly the padded rectangle inset by padding. Receiver bounds start at texel centres, and each axis spans at least two texels to give thin steps interior raster samples. No material UV is reused or changed.

Semantic binding kinds are sector-floor, sector-ceiling, sector-wall, solid-top, solid-bottom, solid-side. index addresses the sector or solid array; edge is the directed wall/footprint edge, or -1 for caps. chart is a zero-based chart index, or -1 only for a fully open wall with no opaque receiver. Every semantic face has exactly one binding, in sector floor/ceiling/wall order followed by solid top/bottom/side order. Every solid side has its own identity; the repeating Solid.SideUV field does not affect these bindings.

Algorithm 1 merges coplanar sector floors/ceilings only across coincident, reciprocal ordinary portals. Equal coordinates in disconnected spaces do not merge. Opaque bands around partial portals follow the shared pure world.WallProfile crossing/controller rules; the doorway receives no opaque geometry. Solid caps and sides remain separate charts. Deterministic rectangle packing sorts by descending height, descending width and stable chart identity. Default charts are not rotated, and their reserved rectangles cannot overlap. Candidate SDK 0.0.12 adds optional build policies Options.CapsWithinSourceRoom and Options.CompactPacking. The former limits coplanar cap merging to the same authored room and prefab instance. The latter packs charts by area into bounded maximal free rectangles and can turn a chart by 90 degrees. A turn updates its right-handed tangent/bitangent basis and affine UV planes together, preserving the surface normal, texel density and RNM interpretation. The existing complete layout validator checks every turned receiver and nonoverlapping rectangle. Free-rectangle scratch has at most MaxCharts*4 records in each of two buffers (two MiB on 64-bit platforms). Neither policy changes layout fields, page bounds, the default compiler output or existing point-light recipes.

The geometry digest covers stable sector/solid identities, coordinates, elevation planes, directed portal indexes and reciprocal wall indexes. Actor state, materials, material UVs and lighting do not affect it. Geometry changes invalidate the layout. Light movement invalidates runtime lighting rather than the geometry layout. Consumers validate complete bounds, digest, bases, affine maps, receiver coverage and semantic binding identities before GPU allocation. Decoding scans the complete bounded payload before typed allocation and rejects truncation, bad counts/presence tags, nonfinite or negative-zero primitives, unsupported binary versions and trailing bytes.

Optional runtime_bake has two explicitly versioned encodings. A single visibility recipe retains its behavior. Its typed fields are illustrated here:

encoding: point-visibility@1
light_id: court-light
shadow_size: 512

An ordered direct-light recipe selects up to 4,096 unique authored IDs in the unreleased SDK 0.0.11 candidate:

encoding: direct-rnm3@1
light_ids: [brazier-north, brazier-south]
shadow_size: 512

light_id and light_ids are mutually exclusive. Visibility requires the single nonempty ID and no list; direct RNM requires a nonnil list and no single field. IDs must exist in Document.Lighting.Lights; selection order is preserved, with no implicit first-light selection. Shadow size is 32–512. Omission packages reusable coordinates without requesting a runtime bake. Unknown encodings, duplicate selections and malformed binary records fail complete validation.

Build-only Options.AllStatic selects all fixed point sources without a nonzero linked emission pulse, in authored order. It is mutually exclusive with the explicit Light and Lights selectors. StaticLightIDs exposes the same validated selection to producers. Compile with no selector remains layout-only; explicit Lights: []string{} remains an options error. An automatic selection with no eligible sources creates an explicit empty direct RNM recipe and covered black coefficients. LightIDsInReceiverScope performs the authoritative physical-component filtering without repacking charts.

Source count does not change receiver charts, page dimensions or the three RNM coefficient tiles. Source records are retained in the authored world and bound by the prebake identity; they do not require runtime GPU-slot masks. The digest input scratch is separately bounded to 8 MiB so it can hash the full source set; the published fixed prebake manifest remains bounded to 16 KiB.

Both runtime recipes require all sectors to belong to one ordinary reciprocal physical component, every selected emitter to be inside its floor/ceiling volume, and every solid to have a host receiver association. Association uses conservative XY bounding-box overlap including tangent boundaries; it does not impose a new exact polygon or height restriction on solid placement. Builders validate the complete selection before publication. Layout-only data still accepts disconnected/transformed spaces, outside lights and unassociated solids. point-visibility@1 stores static shadow visibility, leaving selected light colour/falloff and material normal response live at runtime.

The runtime direct-rnm3@1 recipe stores static direct diffuse lighting as three horizontal RGBM coefficient tiles per logical page, with matching chart coordinates in each tile. The logical page bounds above do not count those physical coefficient copies. A 1024 logical page therefore has a 3072×1024 RGBA8 image (12 MiB); additional scratch and cached recipes require separate runtime accounting. No RGBM range field is authored: range = max(1, 3 Σ max(R,G,B)) over the selected linear RGB light colours. Each coefficient encodes RGB = C/(range*M) and A = M, with quantized M rounded upward and at least 1/255 for covered texels, including black. Alpha zero means uncovered. Decode each filter tap as RGB*A*range before interpolation; normalize filter weights over covered taps using binary alpha coverage rather than weighting by the RGBM multiplier. Dilation preserves covered samples and cannot cross chart boundaries.

In chart coordinates (tangent, bitangent, normal), the RNM basis is:

  • B0 = (√(2/3), 0, 1/√3)
  • B1 = (-1/√6, 1/√2, 1/√3)
  • B2 = (-1/√6, -1/√2, 1/√3)

For receiver normal N and unit receiver-to-light direction L, use the existing squared Half Lambert function H(N,L) = (0.5 dot(N,L)+0.5)². For each selected light, wi = H(Bi,L) and accumulate Ci = Tint * attenuation² * visibility * 3*H(N,L)*wi/Σwi. Here attenuation = max(0, 1-distance²/radius²). Geometric backfaces have zero visibility. Runtime material normal n uses weights max(dot(n,Bi),0)², normalized by their sum, to combine the decoded coefficients. A neutral material normal reproduces the existing Half Lambert response before RGBM quantization. This is a Source-inspired directional approximation, not radiosity or an exact integration of incident lighting.

Only static environment direct diffuse is baked by the runtime recipe. Once the complete atlas is published, its selected environment lights are excluded from runtime diffuse but retain their front-facing live rim contribution. The combined directional atlas has no per-light occlusion for that rim. Selected lights still illuminate actors at runtime. Ambient cube and material texture AO remain runtime terms, applied once; the bake includes neither ambient nor material AO. Camera movement reuses the atlas; changes to selected colour, position or radius invalidate it while retaining the geometry layout. Partial atlases are never published. Neither runtime encoding supplies bounced lighting, moving actor shadows or transformed-portal light transport. Multipage layouts require a separate versioned decision. Completed direct or offline-bounced atlas images use the prebake extension below.

Compile, Surfaces, GeometryDigest, Validate, Encode and Decode are pure public Go helpers. They neither import private engine packages nor triangulate renderer meshes. The host associates retained triangle semantic identities with these bindings and evaluates the affine planes per vertex.

Optional completed prebake, version 1

SDK 0.0.8 also defines world/lightmaps-prebaked@1, requiring world/lightmaps@1, world/lighting@1 and world/sectors@1. This semantic extension packages one completed three-tile RNM atlas without rebaking it during startup. The existing algorithm 1 stores direct lighting only. Algorithm 2 adds the explicit offline diffuse-bounce producer described below, while retaining the same direct-rnm3@1 coefficient encoding and image layout. The candidate binary wire explicitly replaces the earlier serialized layout and manifest bytes while preserving these lighting semantics.

A level carries both fixed EntryData entries @world/lightmaps/prebake and @world/lightmaps/prebake-rnm3, plus metadata kartyWorldLightmapPrebake: "karty.world-lightmap-prebake@1". Both entries and the marker are mutually required, alongside the existing complete layout. The image is QOI RGBA tagged linear (1), with raw straight RGBM channels: never premultiply by its multiplier alpha. Width is three times the logical page width; height is the page height. The encoded image is bounded to 8 MiB and the existing level envelope remains bounded to 16 MiB. A valid 1024-page image costs 12 MiB decoded; QOI data with insufficient compression can exceed the encoded bound and must fail explicitly. This extension does not raise level or shared decoded-texture budgets.

The algorithm-1 canonical binary manifest schema karty.world-lightmap-prebake@1 has required fields in this order: schema, algorithm (1), encoding (direct-rnm3@1), layout_sha256, bake_sha256, image_sha256, image_bytes, width, height, rgbm_range, followed by the offline control fields (zero/empty for algorithm 1). It is bounded to 16 KiB. All digests are lowercase SHA-256. layout_sha256 hashes the exact KLM1 binary layout, including charts, bindings, coordinates and the ordered recipe. bake_sha256 hashes the KDI1 binary identity containing schema, algorithm, layout_sha256, and lights in that field order, with lights containing the selected complete world.PointLight records in recipe order. This binds IDs, position, linear colour and radius while excluding unselected lights, ambient, actors and material AO. rgbm_range is the exact derived float64 range described above, not an authoring control. image_sha256 and image_bytes identify the exact lossless QOI bytes.

NewPrebake derives validated algorithm-1 metadata from a completed direct image; EncodePrebake emits a canonical manifest and DecodePrebake accepts only that binary encoding. PrebakePair.Validate checks the complete layout, lighting identity, dimensions, channel/colourspace tags, every manifest field and the full bounded QOI stream before decoded image allocation. Truncated, malformed or noncanonical binary records fail. Validation cannot prove lighting quality or honest producer provenance; signed/hashed level packaging protects the final artifact. Pairs retain caller ownership of image slices; consumers must clone them before mounted publication. The host rejects stale packaged inputs rather than silently rebuilding a different atlas.

Offline diffuse-bounce producer, algorithm 2

NewOfflinePrebake accepts a completed image and OfflineBakeInputs, producing the same manifest schema with algorithm: 2 and producer: "cpu-rnm3-pathtrace@2" in SDK 0.0.11. Additional canonical fields follow rgbm_range in this order: producer, samples, bounces, seed, reflectance_sha256, surface_sha256. Samples are 1–256, bounces are 0–4 and seed is an unsigned 64-bit integer. Zero bounces and zero seed are valid fixed binary fields. Worker count does not affect identity because scheduling must not change pixels.

The public bake/worldlightmap package provides this deterministic CPU producer. It rasterizes actual receiver polygons, uses a triangle BVH for point-light visibility and traces bounded cosine-weighted diffuse paths. Primary direct coefficients retain the existing Half-Lambert contract. Bounced transfer uses Lambertian cosine response and actual nearest albedo texture pixels evaluated with compiled affine projections and triplanar weights, decoded from sRGB to linear RGB. Reflection channels are bounded to MaxDiffuseReflectance = 0.95. Normal/height/AO maps do not alter transport in this slice; material normals still combine the three directional coefficients at runtime. This is a Source-inspired RNM implementation with diffuse indirect light, not an exact reproduction of Valve's bake equations.

For b bounces, producer revision 2 derives the storage range max(1, 3 E * Σ(k=0..b) 0.95^k). For each axis, a weighted interval sweep finds the maximum sum of selected source max(R,G,B) weights whose radius intervals overlap; E is the minimum of the three axis bounds. This is a conservative upper bound on sphere overlap everywhere in the scene. Outward interval and accumulation rounding prevent underestimation. The manifest must contain that exact float64 value. Distant lights no longer reduce precision by inflating a global range. Producer revision 1 retains its original global E = Σ max(R,G,B) during validation. This reserves bounded indirect energy; it does not guarantee a particular brightness. The RGBM channel, coverage, dimensions, chart-isolated dilation, QOI and memory bounds remain the same.

surface_sha256 is OfflineSurfaceDigest of the canonical compiled document with contents and lighting removed, committing geometry, topology, material identities and compiled UVs. reflectance_sha256 is supplied by the public baker's ReflectanceDigestForLayout, committing scoped used decoded albedo pixels and their semantic material/UV assignments. The CLI rechecks reflectance against source before packaging; a host lacks original source images and can verify the surface identity and recorded digest, but cannot independently recompute those source pixels.

Algorithm-2 bake_sha256 hashes the KOI1 binary identity containing producer, direct_sha256, surface_sha256, reflectance_sha256, samples, bounces, and seed in that field order. Producer revision 2 additionally appends rgbm_range; revision 1 retains its exact old identity. direct_sha256 is the existing algorithm-1 bake identity for the same layout and selected light records. The identity therefore includes selected lighting and all offline transport controls without including ambient, actor state or material AO. Pair validation derives and checks the entire expected manifest and image hash; it cannot prove solver quality or honest producer provenance.

A valid algorithm-2 atlas supplies selected static environment diffuse as combined direct and indirect light. Consumers can remove those sources from direct-light slots and approximate static gloss/rim from the combined field; the format supplies no exact per-source view-dependent specular. Ambient cube and material AO remain runtime terms. Actor lighting can sample loaded receiver coefficients, while this format supplies no separate spatial actor probes, per-light rim visibility, moving shadows or transformed-portal transport. The first CPU producer has hard point shadows and finite-sample noise; it does not supply soft area-light sampling. The optional denoised producers below reduce indirect grain. If no completed bake is packaged, the original runtime direct recipe remains available. Malformed or stale packaged prebakes are errors, rather than permission to silently use an unrelated fallback atlas.

The public codec/qoi.Validate utility returns bounded metadata after header and complete stream validation without allocating decoded pixels. Inspect remains header/end-marker inspection; Decode reuses Validate before its pixel allocation. This permits preflight of a complete shared image budget without decoding images twice.

Versioned decision: indirect denoising producers v1

For the next Go module and host release after v0.0.8, algorithm 2 also accepts cpu-rnm3-pathtrace-atrous-low@1 and cpu-rnm3-pathtrace-atrous-medium@1. The producer string commits the complete filter recipe and preset; it participates in BakeSHA256. No typed payload fields, RNM encoding, coefficient count or runtime composition semantics change. Revision-1 OfflineBakeInputs.Denoise selected these producers; empty/off used the original cpu-rnm3-pathtrace@1 manifest and pixel contracts. SDK 0.0.11 now produces cpu-rnm3-pathtrace-atrous-low@2 and cpu-rnm3-pathtrace-atrous-medium@2 with the spatial range decision above; empty/off selects cpu-rnm3-pathtrace@2. All six named producers remain independently verifiable. Unknown producers are still rejected. Older hosts reject these new producers and require an updated host; they must not silently reinterpret a denoised artifact as @1. See the baker package for the filtering and memory contract.

Versioned decision: bounded transport producers v3

SDK 0.0.11 additionally accepts cpu-rnm3-pathtrace@3, cpu-rnm3-pathtrace-atrous-low@3 and cpu-rnm3-pathtrace-atrous-medium@3. OfflineBakeInputs.MaxRayDistance selects these producers only when finite, positive and at most MaxBakeRayDistance (1,000,000 world units). Zero selects the unchanged unbounded revision-2 producers. Every primary/bounce-hit source contribution and diffuse transport segment uses this maximum distance. The offline chart-local denoising guide segments keep their geometric barrier tests.

For recognized revision-3 producers only, the generated KPB1 manifest appends one canonical float64 max_ray_distance after surface_sha256. The preflight scan recognizes these three exact producer strings without allocating decoded strings, scans the required distance and validates the complete payload before decoding. Revision-1/2 manifests retain their exact canonical bytes and identities; they reject a trailing distance field. Unknown producer revisions are rejected. Manifest/image bounds, algorithm 2, RNM encoding and runtime texture count remain unchanged. Older hosts reject revision 3 rather than reinterpreting its pixels.

The revision-3 KOI1 identity appends rgbm_range and then max_ray_distance. Its range uses the same overlap bound as revision 2, restricted to sources whose min(radius,distance) spheres intersect bounce-reachable receiver bounds. The shared BoundedInfluenceScope exposes the conservative derived geometry and source dependencies, retaining guards for floating-point/raster offsets. OfflineRGBMRangeBounded is the authoritative exact float64 range helper. The separate public baker BakeInputDigest allows local pixel-cache reuse; full-world layout, selected-source and surface identities remain freshly bound and verified when those pixels are packaged into the current level.

Versioned decision: environment variants v1

Candidate SDK 0.0.12 adds optional world/lightmaps-environment-variants@1. It requires world/chunks@1, world/environment@1, world/lightmaps@1 and world/sectors@1. Existing layout and point-light prebake formats retain their bytes and semantics. Each render chunk uses one plain algorithm-2 receiver layout (RuntimeBake == nil) and its unchanged RNM UVs for every condition.

The new KLV1 binary catalog at EnvironmentVariantsEntryName uses schema karty.world-lightmap-environment-variants@1 and metadata marker kartyWorldLightmapEnvironmentVariants. Typed codecs are generated from the public declarations. A complete scan precedes record allocation. The catalog is bounded to 32 KiB and 32 endpoint records. Time-only catalogs contain one clear (CloudAmount == 0) record per distinct increasing clock, with 1–32 clocks. Explicit weather catalogs retain increasing clear/overcast pairs (CloudAmount == 0 then 1) for 1–16 clocks. Mixed orders and duplicate clocks in time-only catalogs are rejected. The default record must be clear. It binds exact geometry, canonical chart layout, static surface/opacity and used reflectance digests, producer cpu-environment-rnm3@1, sampling controls and default record index. EnvironmentSurfaceDigest binds effective translucent liquid opacity on static geometry because it changes opaque transport; actor-only animations, point lights and authored ambient are excluded. Each record binds exact passive-module SHA256/size, straight linear QOI SHA256/size, decoded bytes and the authoritative EnvironmentRGBMRange. Decoded bytes are exactly page_width*page_height*12.

The default image is embedded at EnvironmentImageEntryName in the render chunk. Every condition also has a separately staged passive module containing only that same image entry. Its exact metadata keys are kartyWorldLightmapEnvironmentVariant (the catalog schema), layoutSha256 and imageSha256. These modules are resources of the owning logical level, not additional mounted game levels. Content addressing permits identical endpoint bytes to share downloads. ValidateEnvironmentImage checks length, hash, dimensions, colorspace and complete bounded QOI stream before pixel allocation.

SelectEnvironmentVariants chooses the nearest authored clock by circular 24-hour distance; ties choose the first authored clock. A time-only catalog returns the same index twice and zero blend for every valid cloud amount. Cloud cover can therefore use a cheap brightness multiplier without fetching, decoding, blending or baking another image, preserving the selected state's shadow pattern and direction. Explicit weather catalogs interpolate the selected clear/overcast endpoints continuously. Decode RGBM to linear coefficients before interpolation and re-encode the result if uploading one texture: interpolating encoded RGBA is incorrect. A consumer keeps the previous verified map while fetching the next conditions and rejects stale completions. The catalog default is clear at the authored default clock. Consumers explicitly budget resident maps and transition scratch; 1024 RNM pixels occupy 12 MiB per map, independent of compressed download size. Static sun/sky diffuse is replaced only on covered receivers. Dynamic actors, point lights, authored ambient and specular remain separate runtime contributions.

Single-BVH producer decision, version 1

Candidate Go module v0.0.15 consolidates CPU baking into one geometry BVH4 and one nearest/any-hit traversal. A 16-bin surface-area builder uses balanced median partitions only for degenerate/deep splits; its temporary binary construction nodes are released after packing. No original-median compatibility tree, rank mapping or ambiguous-hit replay is retained. This is a producer behavior change, not a new receiver layout or runtime texture format.

Nearest hits choose the smallest accepted float64 distance. Exact distance ties choose the lowest semantic surface index in Surfaces(document), independently of child order, worker count or SIMD width. Conservative node bounds include existing barycentric/origin tolerances. Intersections keep their strict upper endpoint and shifted-origin minimum guard. Visibility stops at the first valid opaque blocker; it does not promise nearest material identity. These rules can change pixels at ambiguous edges/coplanar faces compared with the old tree.

Current unbounded producers are cpu-rnm3-pathtrace@4, cpu-rnm3-pathtrace-atrous-low@4 and cpu-rnm3-pathtrace-atrous-medium@4. Positive MaxRayDistance selects bounded revision 5 with the corresponding three names. Sun/sky baking emits cpu-environment-rnm3@2 and still requires unbounded rays. Samples, bounce limits, RNM, reflectance, RGBM energy bounds, filtering and dilation retain their existing contracts.

Revision 4 uses the revision-2 manifest field layout. Revision 5 uses the revision-3 layout, including the required trailing float64 maximum distance. The owning handwritten generator recognizes bounded revisions 3 and 5 during allocation-free preflight. Unbounded producers reject an extra distance field; bounded producers reject a missing, zero, nonfinite or out-of-range distance. Environment catalogs retain their existing field layout and accept producer 1 and 2. No generated codec is edited by hand.

Readers continue validating completed point artifacts from revisions 1–3 and environment artifacts from revision 1. Baking emits only the new producers; there are no old tracing branches. New producer strings commit new prebake and pixel-cache identities even on fixtures with unchanged pixels. Rebuild the host/CLI together for new producer support; older hosts reject new producer names. Released documentation and SDK manifests are unchanged.

Spatial receiver layouts

Selected layout schema karty.world-lightmaps@3 / algorithm 4 is encoded as KLM3, a bounded typed envelope around the unchanged base fields and an explicit SurfaceSelection. Its face bindings retain global discovery order and use Chart=-1 as source identity; the compiled layout supplies actual chart indexes. An optional XY rectangle clips receivers before packing. Missing selected faces are legal only with the independently validated root spatial ownership table. The complete ordinary physical component still supplies transport geometry.

CompileSelectedReceivers retains requested local texel density and supports 32/64/128/256 pages in addition to the existing 512/1024 sizes. Old schema readers and their page-size rules remain unchanged. Compile and CompileReceivers continue producing the previous schema.

Clipped fixed bakes use producer cpu-fixed-spatial-rnm3@1. They carry no actor probes or terrain receiver coefficients. The shared terrain/opaque world remains transport, and every source/selector/tile/quality input remains in the fixed input and layout digests. Sampling rotation uses physical position and normal, rather than atlas placement. Shared tile boundary estimates are kept unfiltered by low/medium denoise so independently filtered interiors cannot change the two sides of one common edge. Covered black remains RGBM alpha 1; uncovered pixels remain alpha 0. Normal mapping still evaluates the same three linear RNM lobes.

Exact uniform fixed spatial charts

Optional world/fixed-compact-lighting@1 uses FixedCompactSchema (KFL2) for spatial children whose whole atlas can be replaced by ConstantRNM. Each ChartRNM record contains the existing nine linear RNM coefficients, including valid covered black, and canonical chart identity. All layout charts must be present; partial compact/atlas mixtures are not supported. Compact results retain the full layout and input identity, have zero image dimensions and bytes, and accept no image entry. Ordinary fixed atlas manifests keep KFL1 bytes unchanged. NewFixedLighting, ValidateFixedLighting and artifact validation enforce the same atomic geometry/layout/source contract for both representations. See the versioned spatial decision.

Geometry cells inside larger loading units

Selected layout algorithm 4 adds up to 64 LiquidTiles geometry cells to the versioned KLS2 selection payload. Each cell stores its original XY Clip and LiquidMaxSubdivisions. Together they must cover the selection's outer clip exactly, have no positive overlap, remain inside its finite bounds and share the existing liquid edge grid. Missing cells preserve the ordinary one-clip geometry policy. Compiler-owned copies prevent caller mutation during layout construction. Selection digests and exact mesh/catalog binding include every cell and its geometry policy.

The geometry compiler emits each original cell independently into a shared mesh and atlas. This preserves source positions, triangle interpolation, material/secondary coordinates and animated wave phase while loading fewer units. Receiver charts keep the requested texel density across the combined rectangle; their atlas coordinates and packing may change. The cell list does not prescribe geometry LOD and does not lower lightmap detail.

Documentation

Overview

Code generated by internal/codegen/binary; DO NOT EDIT.

Package worldlightmap defines the independently versioned, build-generated static receiver layout. It has no renderer or private engine dependencies.

Index

Constants

View Source
const (
	EnvironmentVariantsSchema      = "karty.world-lightmap-environment-variants@1"
	EnvironmentVariantsEntryName   = "@world/lightmaps/environment-variants"
	EnvironmentImageEntryName      = "@world/lightmaps/environment-image"
	EnvironmentVariantsMetadataKey = "kartyWorldLightmapEnvironmentVariants"
	EnvironmentVariantMetadataKey  = "kartyWorldLightmapEnvironmentVariant"
	EnvironmentVariantsFeature     = cartridge.FeatureWorldLightmapsEnvironmentVariantsV1
	EnvironmentPrebakeProducer     = "cpu-environment-rnm3@2"
	MaxEnvironmentVariants         = 32
	MaxEnvironmentCatalogSize      = 32 * 1024
)
View Source
const (
	FixedSchema          = "karty.world-fixed-lighting@1"
	FixedCompactSchema   = "karty.world-fixed-lighting@2"
	FixedEntryName       = "@world/lightmaps/fixed"
	FixedImageEntryName  = "@world/lightmaps/fixed-rnm3"
	FixedMetadataKey     = "kartyWorldFixedLighting"
	FixedFeature         = cartridge.FeatureWorldFixedLightingV1
	FixedCompactFeature  = cartridge.FeatureWorldFixedCompactLightingV1
	FixedProducer        = "cpu-fixed-rnm3@3"
	FixedSpatialProducer = "cpu-fixed-spatial-rnm3@1"
	MaxFixedLightingSize = 2 << 20
	MaxLightingProbes    = 4096
	MaxCompiledLights    = world.MaxLights + 1
)
View Source
const (
	Schema                  = "karty.world-lightmaps@1"
	Algorithm               = uint32(1)
	ReceiverAlgorithm       = uint32(2)
	EntryName               = "@world/lightmaps/layout"
	MetadataKey             = "kartyWorldLightmaps"
	Feature                 = cartridge.FeatureWorldLightmapsV1
	MaxEncodedSize          = 8 * 1024 * 1024
	MaxCharts               = 8192
	MaxTexels               = 1024 * 1024
	MaxBakeLights           = world.MaxLights
	PointVisibilityEncoding = "point-visibility@1"
	DirectRNMEncoding       = "direct-rnm3@1"
	BinaryMagic             = "KLM1"
)
View Source
const (
	OfflinePrebakeAlgorithm       = 2
	OfflinePrebakeProducer        = "cpu-rnm3-pathtrace@4"
	BoundedOfflinePrebakeProducer = "cpu-rnm3-pathtrace@5"
	LegacyOfflinePrebakeProducer  = "cpu-rnm3-pathtrace@1"
	MaxOfflineSamples             = 256
	MaxOfflineBounces             = 4
	MaxDiffuseReflectance         = .95
	MaxBakeRayDistance            = world.MaxCoordinate
)
View Source
const (
	PrebakeSchema          = "karty.world-lightmap-prebake@1"
	PrebakeAlgorithm       = 1
	PrebakeEntryName       = "@world/lightmaps/prebake"
	PrebakeImageEntryName  = "@world/lightmaps/prebake-rnm3"
	PrebakeMetadataKey     = "kartyWorldLightmapPrebake"
	PrebakeFeature         = cartridge.FeatureWorldLightmapsPrebakedV1
	MaxPrebakeManifestSize = 16 * 1024
	MaxPrebakeImageSize    = level.MaxEntrySize
	PrebakeBinaryMagic     = "KPB1"
)
View Source
const MaxLiquidTiles = 64
View Source
const SelectedAlgorithm = uint32(4)
View Source
const SelectedSchema = "karty.world-lightmaps@3"

Variables

View Source
var (
	ErrLayout = errors.New("world lightmap layout is invalid")
	// ErrPageCapacity identifies finite receiver charts that cannot fit the
	// requested page. Capacity errors also wrap ErrLayout. Invalid geometry,
	// options and lighting recipes do not wrap ErrPageCapacity.
	ErrPageCapacity = errors.New("world lightmap page capacity is exhausted")
)

Functions

func ApplySurfaceSelection added in v0.0.19

func ApplySurfaceSelection(surfaces []Surface, selection *SurfaceSelection) error

ApplySurfaceSelection preserves global surface indexing while selecting and clipping convex source polygons. Input polygon backing arrays are not changed.

func ClipSurfacePolygon added in v0.0.19

func ClipSurfacePolygon(polygon []world.Vec3, rectangle [4]float64) []world.Vec3

ClipSurfacePolygon retains stable authored world coordinates on shared edges.

func Encode

func Encode(layout Layout, document *world.Document) ([]byte, error)

func EncodeEnvironmentVariants added in v0.0.14

func EncodeEnvironmentVariants(catalog EnvironmentVariants, layout Layout, document *world.Document) ([]byte, error)

func EncodeFixedLighting added in v0.0.19

func EncodeFixedLighting(lighting FixedLighting) ([]byte, error)

func EncodePrebake

func EncodePrebake(pair PrebakePair, layout Layout, document *world.Document) ([]byte, error)

EncodePrebake returns a canonical manifest only after complete pair validation.

func EncodeSurfaceSelection added in v0.0.19

func EncodeSurfaceSelection(selection SurfaceSelection) ([]byte, error)

EncodeSurfaceSelection exposes the bounded typed face selector to mesh envelopes. Its bytes participate in both layout and mesh content identities.

func EnvironmentRGBMRange added in v0.0.14

func EnvironmentRGBMRange(environment *world.Environment, settings world.EnvironmentSettings, bounces int) (float64, error)

func EnvironmentSurfaceDigest added in v0.0.14

func EnvironmentSurfaceDigest(document *world.Document) (string, error)

func EqualSurfaceSelections added in v0.0.19

func EqualSurfaceSelections(a, b *SurfaceSelection) bool

func FixedLightingBytes added in v0.0.19

func FixedLightingBytes(lighting *FixedLighting) uint64

FixedLightingBytes bounds retained scalar data, including Go slice/string headers and alignment. Image storage is charged separately by the owner.

func GeometryDigest

func GeometryDigest(document *world.Document) (string, error)

GeometryDigest includes stable semantic identity, boundary topology and elevation geometry. Actor state, lighting, materials and UVs do not affect it.

func LayoutDigest added in v0.0.12

func LayoutDigest(layout *Layout) (string, error)

LayoutDigest hashes the exact canonical binary layout. It checks structural bounds and finite fields without a world; callers validate semantic bindings against the complete world before mounting a layout.

func LightIDsInReceiverScope added in v0.0.12

func LightIDsInReceiverScope(document *world.Document, selection *ReceiverSelection, ids []string) ([]string, error)

LightIDsInReceiverScope preserves the given source order while filtering to the receivers' ordinary physical component. Unknown and duplicate IDs fail even when their source would be outside that component.

func OfflineDenoiseMode added in v0.0.9

func OfflineDenoiseMode(producer string) (string, error)

OfflineDenoiseMode rejects unknown producer versions before image allocation.

func OfflineDenoiseProducer added in v0.0.9

func OfflineDenoiseProducer(mode string) (string, error)

OfflineDenoiseProducer versions the complete filter, including its preset. Empty and off select the same revision-4 producer and manifest identity.

func OfflineProducer added in v0.0.12

func OfflineProducer(mode string, maxRayDistance float64) (string, error)

OfflineProducer selects a separately versioned bounded producer only for a finite positive ray limit. Zero selects the unbounded revision-4 producer.

func OfflineRGBMRange

func OfflineRGBMRange(layout Layout, document *world.Document, bounces int) (float64, error)

OfflineRGBMRange reserves a conservative finite range for direct lighting plus bounded diffuse transport. Each bounce attenuates maximum radiance by MaxDiffuseReflectance; three coefficient lobes need the same factor as the direct producer. This is a storage bound, not a promised illumination level.

func OfflineRGBMRangeBounded added in v0.0.12

func OfflineRGBMRangeBounded(layout Layout, document *world.Document, bounces int, maxRayDistance float64) (float64, error)

OfflineRGBMRangeBounded uses exactly the producer's conservative source scope and clipped influence radii. Zero is identical to OfflineRGBMRange.

func OfflineSurfaceDigest

func OfflineSurfaceDigest(document *world.Document) (string, error)

OfflineSurfaceDigest binds material identities and authored projection data in addition to geometry. Actor state and artistic ambient are not transport inputs. The original albedo pixels are checked separately by the public CLI.

func ReceiverScope added in v0.0.12

func ReceiverScope(document *world.Document, selection *ReceiverSelection) ([]bool, []bool, error)

ReceiverScope returns transport geometry in the selected receivers' ordinary physical component. Transformed and one-way portals are lighting boundaries. The caller must validate the complete document before using these masks. Solids touching multiple physical spaces are rejected: coordinate overlap cannot unambiguously assign an independently authored volume to either space.

func SelectEnvironmentVariants added in v0.0.14

func SelectEnvironmentVariants(catalog *EnvironmentVariants, settings world.EnvironmentSettings) (int, int, float64, error)

SelectEnvironmentVariants chooses one authored clock. Clear-only catalogs return the same index twice and zero blend regardless of cloud amount; cloud brightness remains a shader control and does not change the selected image. Paired catalogs return clear/overcast indexes and a linear weather blend. Clock distance wraps midnight. Ties retain the first authored time.

func StaticLightIDs added in v0.0.12

func StaticLightIDs(document *world.Document) ([]string, error)

StaticLightIDs returns independently owned authored-order IDs of all fixed point sources without a nonzero linked emission pulse. It validates the world first. Compiler options decide the receiver/component scope separately.

func SurfaceSelected added in v0.0.19

func SurfaceSelected(binding Binding, selection *SurfaceSelection) bool

SurfaceSelected tests exact source identity, ignoring a caller's chart slot.

func TerrainLightingBasis added in v0.0.19

func TerrainLightingBasis(normal world.Vec3) (world.Vec3, world.Vec3)

TerrainLightingBasis is the shared producer/consumer RNM terrain frame.

func Validate

func Validate(layout *Layout, document *world.Document) error

Validate checks every record, rectangle, semantic binding and receiver before a caller can allocate GPU resources. The geometry digest prevents stale UVs.

func ValidateEnvironmentImage added in v0.0.14

func ValidateEnvironmentImage(variant EnvironmentVariant, encoded []byte, layout Layout) error

ValidateEnvironmentImage checks exact content, dimensions and complete QOI stream before callers allocate decoded pixels or replace a resident map.

func ValidateEnvironmentVariants added in v0.0.14

func ValidateEnvironmentVariants(catalog *EnvironmentVariants, layout Layout, document *world.Document) error

func ValidateEnvironmentVariantsArtifact added in v0.0.18

func ValidateEnvironmentVariantsArtifact(catalog *EnvironmentVariants, layout Layout) error

ValidateEnvironmentVariantsArtifact checks runtime references and allocation bounds. Builder callers retain ValidateEnvironmentVariants for source proof.

func ValidateFixedLighting added in v0.0.19

func ValidateFixedLighting(lighting FixedLighting, layout Layout, document *world.Document) error

func ValidateFixedLightingArtifact added in v0.0.19

func ValidateFixedLightingArtifact(lighting FixedLighting, image []byte, layout Layout) error

func ValidateFixedLightingMetadata added in v0.1.0

func ValidateFixedLightingMetadata(lighting FixedLighting, layout Layout) error

ValidateFixedLightingMetadata admits scalar, chart and probe metadata without its compiler-only image. Physical-only KCC6 children use this after binding their exact module digest and ownership. Historical full-image APIs remain unchanged and still require the image provenance to match.

func ValidateFixedTerrainBinding added in v0.0.19

func ValidateFixedTerrainBinding(lighting FixedLighting, terrain *worldterrain.Document) error

func ValidateLayoutArtifact added in v0.0.18

func ValidateLayoutArtifact(layout *Layout, admission LayoutAdmission) error

ValidateLayoutArtifact checks structural layout constraints only. Full authored-source proof remains available through Validate for build/cache use. Callers establish artifact integrity separately; the supplied counts are not evidence that an artifact was produced correctly. Inputs are read-only.

func ValidatePrebakeArtifact added in v0.0.18

func ValidatePrebakeArtifact(pair PrebakePair, layout Layout) error

ValidatePrebakeArtifact validates structural/resource identities against an already admitted immutable layout. BakeSHA256, SurfaceSHA256 and reflectance record compiler provenance; full source proof remains PrebakePair.Validate.

func ValidateSurfaceSelection added in v0.0.19

func ValidateSurfaceSelection(selection *SurfaceSelection, admission LayoutAdmission) error

Types

type Binding

type Binding struct {
	Kind  string
	Index int
	Edge  int
	Chart int
}

Binding associates a world surface with its receiver chart. Index addresses the world sector or solid array. Edge is -1 for caps, and addresses the directed wall or footprint edge otherwise. Chart -1 explicitly marks a wall with no opaque receiver. Array order is semantic discovery order.

type Chart

type Chart struct {
	ID           int
	Page         int
	Rect         [4]int
	ReceiverRect [4]int
	Normal       world.Vec3
	Tangent      world.Vec3
	Bitangent    world.Vec3
	UPlane       [4]float64
	VPlane       [4]float64
}

Chart describes a receiver's atlas placement and basis. Rectangles are [minimumX,minimumY,maximumX,maximumY] in page pixels, maximums exclusive. Plane values are normalized page coordinates.

type ChartRNM added in v0.0.19

type ChartRNM struct {
	Chart        int
	Coefficients [9]float32
}

ChartRNM stores linear RGB irradiance for the three existing RNM lobes. All zero coefficients are valid covered black, not missing lighting.

type CompiledLight added in v0.0.19

type CompiledLight struct {
	ID, Kind                   string
	Position, Direction, Color world.Vec3
	Radius                     float64
}

type EnvironmentVariant added in v0.0.14

type EnvironmentVariant struct {
	TimeOfDay, CloudAmount, RGBMRange float64
	ContentSHA256, ImageSHA256        string
	Size, ImageSize, DecodedBytes     uint64
}

type EnvironmentVariants added in v0.0.14

type EnvironmentVariants struct {
	Schema, GeometrySHA256, LayoutSHA256, SurfaceSHA256, ReflectanceSHA256, Producer string
	Samples, Bounces                                                                 int
	Seed                                                                             uint64
	Denoise                                                                          string
	Default                                                                          int
	Variants                                                                         []EnvironmentVariant
}

EnvironmentVariants binds one immutable receiver layout and a bounded set of content-addressed passive condition modules. The default image is embedded in the owning render chunk; other images need not be fetched until selected.

func DecodeEnvironmentVariants added in v0.0.14

func DecodeEnvironmentVariants(encoded []byte, layout Layout, document *world.Document) (EnvironmentVariants, error)

func DecodeEnvironmentVariantsArtifact added in v0.0.18

func DecodeEnvironmentVariantsArtifact(encoded []byte, layout Layout) (EnvironmentVariants, error)

DecodeEnvironmentVariantsArtifact decodes a builder-approved catalog after whole-file integrity admission. It checks binary/resource bounds and identities without reconstructing source geometry, surface digests or lighting proofs.

type FixedLighting added in v0.0.19

type FixedLighting struct {
	TerrainSHA256, TerrainReceiverSHA256 string
	Terrain                              []TerrainPatchLighting
	// ConstantRNM replaces the entire atlas only when every chart is uniform.
	// Every layout chart is present in canonical index order.
	ConstantRNM                                           []ChartRNM
	Schema, GeometrySHA256, LayoutSHA256, SurfaceSHA256   string
	ReflectanceSHA256, InputSHA256, ImageSHA256, Producer string
	ImageBytes, Width, Height, Samples, Bounces           int
	Seed                                                  uint64
	Denoise                                               string
	RGBMRange                                             float64
	Lights                                                []CompiledLight
	Probes                                                []LightingProbe
}

FixedLighting is an atomic, chunk-owned fixed illumination result. Ambient cubes contain sky, bounced light and non-nominated direct sources. The two nominated sources are evaluated only through Direct, never again in Ambient. Cubes use +X,-X,+Y,-Y,+Z,-Z order. No runtime condition variants exist.

func DecodeFixedLighting added in v0.0.19

func DecodeFixedLighting(data []byte) (FixedLighting, error)

DecodeFixedLighting preflights the complete bounded stream before allocating owned source/probe slices. Artifact identity admission is a separate operation.

func DecodeFixedLightingArtifact added in v0.0.19

func DecodeFixedLightingArtifact(encoded, image []byte, layout Layout) (FixedLighting, error)

func NewFixedLighting added in v0.0.19

func NewFixedLighting(layout Layout, document *world.Document, image []byte, lighting FixedLighting) (FixedLighting, error)

NewFixedLighting binds a producer result to its immutable layout and QOI image.

type InfluenceScope added in v0.0.12

type InfluenceScope struct {
	Bounds         [6]float64
	SurfaceIndices []int
	LightIDs       []string
}

InfluenceScope describes conservative pixel dependencies in stable semantic surface and recipe order. SurfaceIndices index Surfaces(document); LightIDs never change which authored sources are classified as completed static lights.

func BoundedInfluenceScope added in v0.0.12

func BoundedInfluenceScope(document *world.Document, layout Layout, bounces int, maxRayDistance float64) (InfluenceScope, error)

BoundedInfluenceScope keeps geometry within (bounces+1)*distance of receiver bounds, and sources whose min(radius,distance) sphere reaches receiver bounds expanded by bounces*distance. Small guards cover ray-origin and raster rounding. Zero distance retains the complete ordinary physical-component dependency set.

type Layout

type Layout struct {
	Schema         string
	Algorithm      uint32
	GeometrySHA256 string
	TexelsPerUnit  float64
	Padding        int
	Pages          []Page
	Charts         []Chart
	Bindings       []Binding
	RuntimeBake    *RuntimeBake
	Receivers      *ReceiverSelection
	Selection      *SurfaceSelection
}

func Compile

func Compile(document world.Document, options Options) (Layout, error)

Compile discovers and packs unique receiver coordinates without triangulating sectors or importing runtime code. Algorithm 1 merges only coplanar floors and ceilings across ordinary reciprocal portals, never across transformed or disconnected spaces. Walls and solid sides retain semantic chart identities.

func CompileReceivers added in v0.0.12

func CompileReceivers(document world.Document, options Options, sectors, solids []int) (Layout, error)

CompileReceivers packs only selected receivers at the requested density. Global bindings and the full geometry digest keep chunk identity stable. Algorithm 2 never merges charts across an unselected sector.

func CompileSelectedReceivers added in v0.0.19

func CompileSelectedReceivers(document world.Document, options Options, sectors, solids []int, selection SurfaceSelection) (Layout, error)

CompileSelectedReceivers clips before chart allocation; it never lowers the requested density to accommodate a large unrelated source face.

func Decode

func Decode(encoded []byte, document *world.Document) (Layout, error)

func DecodeLayoutArtifact added in v0.0.18

func DecodeLayoutArtifact(encoded []byte, admission LayoutAdmission) (Layout, error)

DecodeLayoutArtifact admits compiler-authoritative layout data after exact whole-child catalog hash/size verification. It validates bounded records, arrays, rectangles, references and finite fields, without rediscovering source surfaces, proving chart coverage/overlap or reconstructing authored geometry.

type LayoutAdmission added in v0.0.18

type LayoutAdmission struct{ SectorCount, SolidCount int }

LayoutAdmission supplies accepted root array bounds for compiled lightmap references. Geometry digest equality and the receiver selection's equality to its parent chunk descriptor are direct metadata checks performed by the host.

type LightingProbe added in v0.0.19

type LightingProbe struct {
	Sector   int
	Position world.Vec3
	Ambient  [6]world.Vec3
	Direct   [2]ProbeDirect
}

type LiquidTile added in v0.0.19

type LiquidTile struct {
	Clip                  [4]float64
	LiquidMaxSubdivisions int
}

LiquidTile preserves an original geometry cell inside a larger loading unit. Clips cover the whole selection rectangle exactly, with no positive overlap.

type OfflineBakeInputs

type OfflineBakeInputs struct {
	Samples, Bounces  int
	Seed              uint64
	ReflectanceSHA256 string
	RGBMRange         float64
	Denoise           string  // empty/off, low or medium; encoded in the producer identity
	MaxRayDistance    float64 // zero is unbounded; positive selects producer revision 5
}

OfflineBakeInputs identifies the public deterministic CPU producer. Worker count is deliberately absent: changing parallelism must not change pixels.

type Options

type Options struct {
	TexelsPerUnit                          float64
	PageSize, Padding, MaxPages, MaxTexels int
	Light                                  string
	Lights                                 []string
	// AllStatic selects every fixed source without a nonzero emission pulse.
	// It is build policy, not an additional runtime wire field.
	AllStatic  bool
	ShadowSize int
	// CapsWithinSourceRoom prevents cap charts from spanning authored room or
	// prefab-instance boundaries, while retaining efficient cap merging inside
	// each room. It is optional build policy; canonical layouts remain unchanged.
	CapsWithinSourceRoom bool
	// CompactPacking uses bounded free-rectangle packing and optional 90-degree
	// chart turns instead of default shelves. Density and limits are retained.
	CompactPacking bool
}

type Page

type Page struct {
	Width  int
	Height int
}

type PrebakeManifest

type PrebakeManifest struct {
	Schema            string
	Algorithm         int
	Encoding          string
	LayoutSHA256      string
	BakeSHA256        string
	ImageSHA256       string
	ImageBytes        int
	Width             int
	Height            int
	RGBMRange         float64
	Producer          string
	Samples           int
	Bounces           int
	Seed              uint64
	ReflectanceSHA256 string
	SurfaceSHA256     string
	// MaxRayDistance is present on the wire only for bounded producer revision
	// 3. Zero retains the exact unbounded revision-1/2 manifest bytes.
	MaxRayDistance float64
}

PrebakeManifest binds one completed direct RNM image to exact layout and selected lighting inputs. Its canonical binary is the public manifest entry.

func DecodePrebakeManifest added in v0.0.12

func DecodePrebakeManifest(encoded []byte) (PrebakeManifest, error)

DecodePrebakeManifest inspects a bounded canonical binary manifest without decoding pixels. Full layout, source and image identity requires DecodePrebake.

type PrebakePair

type PrebakePair struct {
	Manifest PrebakeManifest
	Image    []byte
}

PrebakePair retains caller ownership of Image; consumers clone it before publication. It is not the wire format: levels carry two fixed data entries.

func DecodePrebake

func DecodePrebake(encoded, image []byte, layout Layout, document *world.Document) (PrebakePair, error)

DecodePrebake rejects malformed binary fields before returning a completely validated pair. Image remains borrowed; JSON and trailing data are rejected.

func DecodePrebakeArtifact added in v0.0.18

func DecodePrebakeArtifact(encoded, image []byte, layout Layout) (PrebakePair, error)

DecodePrebakeArtifact admits a compiled RNM manifest and image after exact whole-artifact catalog integrity checks. Layout must already be admitted. It validates manifest shape, layout/image identity, complete bounded QOI and dimensions/range, without reconstructing geometry or authored bake inputs. Image remains borrowed and must stay immutable throughout pair publication.

func NewOfflinePrebake

func NewOfflinePrebake(layout Layout, document *world.Document, image []byte, inputs OfflineBakeInputs) (PrebakePair, error)

NewOfflinePrebake binds a combined direct/indirect image to transport inputs. Format validation verifies identity and QOI integrity, not solver quality. ReflectanceSHA256 commits original decoded albedo; the CLI verifies it against source before packaging. Hosts can verify surface identity, but do not possess those original source images and cannot independently rehash their pixels.

func NewPrebake

func NewPrebake(layout Layout, document *world.Document, image []byte) (PrebakePair, error)

NewPrebake validates a completed raw linear RGBM QOI atlas and derives its identity. It neither decodes pixels nor imports runtime or filesystem code.

func (PrebakePair) Validate

func (pair PrebakePair) Validate(layout Layout, document *world.Document) error

Validate checks every identity and the complete bounded QOI stream without allocating decoded pixels. It cannot prove the lighting quality of a producer.

type ProbeDirect added in v0.0.19

type ProbeDirect struct {
	Light      int // -1 means no source; Visibility must then be zero.
	Visibility float64
}

type ReceiverSelection added in v0.0.12

type ReceiverSelection struct {
	Sectors []int
	Solids  []int
}

ReceiverSelection scopes an atlas to global sector/solid identities. The complete ordinary physical component remains the transport context.

type RuntimeBake

type RuntimeBake struct {
	Encoding   string
	LightID    string
	LightIDs   []string
	ShadowSize int
}

type Surface

type Surface struct {
	Binding  Binding
	Normal   world.Vec3
	Polygons [][]world.Vec3
}

Surface describes actual receiver polygons before triangulation. Empty Polygons explicitly describes a fully open portal wall or sky ceiling.

func Surfaces

func Surfaces(document *world.Document) ([]Surface, error)

Surfaces discovers semantic receivers in stable sector-floor/ceiling/wall, then solid-top/bottom/side order. It preserves separate solid edge identities.

type SurfaceSelection added in v0.0.19

type SurfaceSelection struct {
	// LiquidEdgeStep anchors all spatial water boundaries to one world XY grid.
	LiquidEdgeStep float64
	// LiquidMaxSubdivisions is an explicit geometric detail cap, not lighting density.
	// Zero preserves normal error-based tessellation; nonzero values are 1..32.
	LiquidMaxSubdivisions int
	LiquidTiles           []LiquidTile
	Bindings              []Binding
	Clip                  *[4]float64
}

SurfaceSelection explicitly selects complete source faces, or their common XY rectangle. Transport remains the entire ordinary physical component. Bindings are in source discovery order and have Chart=-1. Missing bindings mean delegated/replaced geometry only under a versioned root ownership table.

func DecodeSurfaceSelection added in v0.0.19

func DecodeSurfaceSelection(data []byte) (SurfaceSelection, error)

type TerrainPatchLighting added in v0.0.19

type TerrainPatchLighting struct {
	Patch        int
	Coefficients []float32
}

TerrainPatchLighting stores three directional RGB coefficients per exact CompilePatch vertex. Vertices use TerrainLightingBasis for their RNM frame.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL