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

worldreflection

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: 11 Imported by: 0

README

Saved reflection cubemaps

world/reflection-cubemaps@1 packages immutable static cubemaps for a fixed, renderer-ready chunk level. It requires world/fixed-lighting@1 and either world/chunk-ready@1 or world/gpu-chunks@1. GPU cells retain their shared material and world capability dependencies; live-only cells cannot declare saved reflections. @world/reflection-cubemaps contains a KRC1 bundle with explicit sector/solid bindings, independent capture origins and projection bounds, and six lossless 128 × 128 RGBA faces per environment. The horizontal strip orders faces +X, -X, +Y, -Y, +Z, -Z and preserves graphics bottom-up rows.

InputDigest binds the original root metadata and every original payload, including catalog hashes of chunk geometry and baked lighting. It excludes only the reflection entry itself. A consumer calls Decode and ValidateSource before accepting the bundle. A changed level requires a fresh capture.

The format allows at most 256 environments, 256 sector bindings and 1024 solid bindings. Each binding is -1 or references a present environment. Bounds must be finite, contain the capture origin strictly, and span at most 65536 units on each axis. Images must be complete RGBA/sRGB QOI strips. The full encoded bundle fits the level entry's 8 MiB bound; decoded pixels total at most 96 MiB and count against the consumer's aggregate texture budget before allocation.

Decode borrows admitted image bytes from its input. Callers must retain the input and keep it immutable. No game code or renderer dependency is required to validate the public artifact. The engine owns capture and GPU projection; the CLI owns invoking offline capture and packaging matching cached output.

Prepared GPU mip arrays

world/reflection-gpu@1 extends the fixed GPU-chunk profile with KRG1 at the same entry name. It contains the same source-bound receiver/probe metadata and one RGBA8/sRGB + Zstd KTX2 array: 768 by 128, one layer per probe, and exactly four offline mip levels. Probe metadata has no QOI payload. KRC1 remains the offline capture cache and legacy artifact representation.

The current per-record GPU profile packs planned one-based reflection slots into immutable cell records before capture. Opaque batches can therefore retain independent receiver slots without an owner draw split. Capture uses a valid neutral prepared resource at this same entry; replacement by captured images leaves InputDigest and all cell bytes unchanged. Neutral resources are never published as a fallback by ordinary builds. Worlds without saved reflections suppress their inactive planned slots.

Prepared.DrawProbes retains its bounded wire shape for this candidate; the per-record profile writes zero entries and performs receiver/slot agreement checks offline. It does not perform an owner-to-probe lookup during rendering. Earlier per-draw profile entries use final little-endian uint32 slots, grouped by dense CellID and then by the unchanged cell draw order. Zero means no environment; other values are one-based positions in the sorted probe table, never authored probe IDs. The build resolves sector/solid ownership after capture and matches render artifacts by catalog content hash. Cell bytes, hashes and GPU records stay unchanged. The table has at most 4,096 cells and 1,024 slots per cell; the existing complete encoded-size limit also applies. Decoders borrow the slot bytes. Root admission checks the catalog cell count before image allocation; new-cell admission checks the exact draw count. Runtime reads one scalar slot without resolving authored owners. GPU-cell artifacts with an earlier raw KRC1 entry must be rebuilt; non-GPU legacy KRC1 remains supported.

The build filters each face independently in linear light. Admission uses DecodePreparedSource to check source identity and the complete metadata/image layout once before allocation. The four validated frames are decompressed into their final GPU mip/layer order; loading does not filter, resize or repack them. InputDigest continues to exclude only this entry, avoiding a self-reference.

The existing 96 MiB reflection limit includes all mip levels. One environment uses 524,160 decoded bytes, so at most 192 environments fit the prepared profile. For 26 environments the exact total is 13,578,240 bytes. Prepared and its codec are independent of the engine and renderer.

Documentation

Overview

Package worldreflection defines saved static parallax-corrected environments.

Index

Constants

View Source
const (
	Feature         = "world/reflection-cubemaps@1"
	EntryName       = "@world/reflection-cubemaps"
	Producer        = "karty-static-cubemap@1"
	FaceSize        = 128
	Faces           = 6
	MaxProbes       = world.MaxSectors
	MaxEncodedSize  = level.MaxEntrySize
	ImageBytes      = FaceSize * FaceSize * Faces * 4
	MaxDecodedBytes = MaxProbes * ImageBytes
)
View Source
const (
	GPUFeature    = "world/reflection-gpu@1"
	GPUProducer   = "karty-static-cubemap-gpu@1"
	GPUMipLevels  = 4
	GPUImageBytes = ImageBytes + ImageBytes/4 + ImageBytes/16 + ImageBytes/64
)

Variables

View Source
var ErrCubemaps = errors.New("saved reflection cubemaps are invalid")

Functions

func Encode

func Encode(bundle Bundle) ([]byte, error)

func EncodePrepared added in v0.1.0

func EncodePrepared(prepared Prepared) ([]byte, error)

func InputDigest

func InputDigest(envelope level.Envelope) string

InputDigest binds every original level payload and metadata, transitively including immutable child hashes and their baked lighting through the catalog. Only this package's own payload is omitted, avoiding a self-referential hash.

Types

type Bundle

type Bundle struct {
	InputSHA256     string
	Producer        string
	Sectors, Solids []int // -1 means no environment; otherwise an explicit probe ID.
	Probes          []Probe
}

func Decode

func Decode(data []byte) (Bundle, error)

func (*Bundle) Validate

func (bundle *Bundle) Validate() error

func (*Bundle) ValidateSource

func (bundle *Bundle) ValidateSource(envelope level.Envelope, document *world.Document) error

type Prepared added in v0.1.0

type Prepared struct {
	Metadata Bundle
	Texture  []byte

	// DrawProbes contains final LE32 slots in dense CellID/draw order.
	// Each slice borrows immutable wire bytes after decoding.
	DrawProbes [][]byte
}

Prepared contains metadata and one final sRGB RGBA8+Zstd array. Every probe occupies one layer; its four explicit mip levels preserve all six faces. Metadata.Probes contain no QOI images, so shipped levels have one image copy.

func DecodePrepared added in v0.1.0

func DecodePrepared(data []byte) (Prepared, error)

DecodePrepared scans complete lengths before allocating metadata tables. Texture bytes remain borrowed from the admitted entry and are immutable.

func DecodePreparedSource added in v0.1.0

func DecodePreparedSource(data []byte, envelope level.Envelope, document *world.Document) (Prepared, ktx2.Info, error)

DecodePreparedSource admits a newly loaded asset and its exact source binding once, returning the already checked texture layout for allocation preflight.

func (*Prepared) Validate added in v0.1.0

func (prepared *Prepared) Validate() error

func (*Prepared) ValidateSource added in v0.1.0

func (prepared *Prepared) ValidateSource(envelope level.Envelope, document *world.Document) error

type Probe

type Probe struct {
	ID                int
	Origin, Low, High [3]float32
	Image             []byte // Straight RGBA QOI, six faces in +X,-X,+Y,-Y,+Z,-Z order.
}

Jump to

Keyboard shortcuts

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