JARVIGManual

Textures and samplers

A texture is a logical engine resource. It is not an image file, not a GPU texture, and not a material instance. JRV-0052. ADR-0027.

programmatic RGBA8 bytes
    -> Texture in TextureLibrary
         dimension, mip_count, color space, revision
    -> renderer residency
         GpuTexture
         TextureView
    -> JARVIG RHI
    -> backend texture and view

The bootstrap images are 8×8 checkers generated in memory. There is no PNG, JPEG, or other decoder. Rows in the logical texture are tightly packed. The backend pads a copy to its own alignment. Callers do not pad.

Color space

KindStored bytesGPU formatSample result
Base color and other colorsRGBRgba8UnormSrgbLinear, by the hardware format
Roughness, metallic, AO, normal, height, masksLinear dataRgba8UnormLinear, no decode

The generated shader samples with textureSample and does not call a decode. The format is the conversion. A data texture must not use the sRGB format.

What is separate

ThingIs not
Source bytesThe logical texture
Logical textureThe GPU texture
TextureIts view
SamplerA texture
Material texture parameterA shader compile or a pipeline
Material instanceThe owner of a texture

TextureDimension::Texture2D is the only dimension implemented. Array, cube, and 3D are named as future kinds, not as code. mip_count is stored. The first textures use 1. A mip generator, compression, UDIM, and virtual pages are not built. Residency can still drop the GPU texture later without deleting the logical one. JRV-0048.

Sampler

A sampler is min, mag, and mip filter plus address modes U, V, and W. The bootstrap sampler is linear and repeat, so UVs outside 0..1 show another copy of the checker. Identical sampler state shares one GPU sampler. Changing the sampler on an instance rebuilds that instance's bind group. It does not recompile the master.

Material binding

Group 0 binding 0 is still the view and object transform.

Group 1 binding 0 is the material uniform. Later bindings are whatever resources that master compiled, in graph order. The standard master binds base color, the shared sampler, the packed map, the normal, and emissive. Those indices are compiler output. They are not an authoring API.

TextureId(0) is unbound. The renderer substitutes the semantic default from pbr.md. That is not the magenta error texture. A nonzero id missing from the library is invalid. Color semantics (BaseColor, Emissive, UnlitColor) then sample the magenta error texture and increment missing_texture_uses. Linear semantics fail the frame with UnknownTexture. Optional and broken are different.

A mesh that lacks a semantic the master requires is rejected. The standard master requires TexCoord0, Normal, and Tangent. Zero UVs are not invented. Normal and tangent are not inferred from garbage.

Both views share the uploaded textures and the sampler. Two cameras do not upload the checker twice. Hiding a render instance does not destroy the texture. The server does not create GPU textures, samplers, or shaders.

Not in this ticket

File import, block compression, streaming, virtual textures, and UDIM. Normal maps and the metallic/roughness surface are pbr.md. They use this texture split. They do not replace it.