Carry TerrainTex.TexTiling through the terrain atlas and upload a layer-indexed table to the modern bindless shader so base, overlay, and road textures repeat at retail scale. Keep alpha masks cell-scaled and preserve retail's verified source-level-zero high-detail selection. Add the named-retail pseudocode, WorldBuilder/ACE/ACME cross-reference, adapter conformance tests, and inventory documentation so a future renderer migration keeps the contract. Co-Authored-By: Codex <noreply@openai.com>
4 KiB
Retail terrain texture tiling
Question
Why do acdream's grass, dirt, and road textures look lower-detail than the September 2013 retail client even though the modern terrain atlas loads 512 x 512 source images, generates mipmaps, and enables anisotropic filtering?
Retail oracle
Named retail symbols in
docs/research/named-retail/acclient_2013_pseudo_c.txt:
TexMerge::CopyAndTileat0x00503580TexMerge::Mergeat0x005038C0ImgTex::TileCSIat0x0053E740ImgTex::GetSurfaceDIDat0x0053F0E0Render::ShouldDropHighDetailat0x0054C700
The verbatim TerrainTex declaration in
docs/research/named-retail/acclient.h contains unsigned int tex_tiling.
Readable pseudocode
CopyAndTile(destination, destinationSize, terrainTexture):
baseTexture = terrainTexture.base_texture
if baseTexture is null:
if terrainTexture.tex_gid is valid:
terrainTexture.base_texture = load ImgTex(terrainTexture.tex_gid)
baseTexture = terrainTexture.base_texture
if baseTexture is null:
CopyCSI(destination, destinationSize, destinationSize, null, 1)
return false
CopyCSI(
destination,
destinationSize,
destinationSize,
baseTexture,
terrainTexture.tex_tiling)
return true
Merge(destination, destinationSize, alphaTexture, rotation, terrainTexture):
if alphaTexture is null:
return false
if terrainTexture.base_texture is null:
if not terrainTexture.InitEnd():
return false
MergeTexture(
destination,
destinationSize,
destinationSize,
terrainTexture.base_texture,
terrainTexture.tex_tiling,
alphaTexture,
rotation)
return true
GetSurfaceDID(surfaceTexture):
if surfaceTexture has one source level:
return sourceLevels[0]
if surfaceTexture has two source levels:
if ShouldDropHighDetail():
return sourceLevels[1]
return sourceLevels[0]
report invalid source-level count
ImgTex::TileCSI repeats the source image tex_tiling times in both axes.
TexMerge::Merge applies the same repeat count to every terrain layer before
the cell-scale alpha mask is merged. Therefore the modern shader must multiply
the terrain UV independently for the base layer, each overlay layer, and each
road layer. The alpha-map UV must not be multiplied.
The source image selection is a separate policy. Retail uses source level zero
unless its quality policy explicitly drops high detail, so changing acdream's
atlas from SurfaceTexture.Textures[0] would invert the verified retail rule.
Cross-references
- Extracted WorldBuilder lineage:
LandSurfaceManagerstores a 36-entry layer-indexed tiling table populated fromTerrainTex.TexTiling, and its terrain shader multiplies each texture layer's UV by that value. The pinned WorldBuilder change introducing the path is commit0d1405af65. - ACE:
ACE.Server/Physics/Common/TexMerge.csforwardsTerrainTex.TexTilingfrom bothCopyAndTileandMerge;ImgTex.csresolves the normal source asTextures[0]. - ACME-derived
tests/AcDream.Core.Tests/Terrain/ClientReference.cscovers terrain split, pal/road codes, and blend selection, but not image tiling or source-level selection. It supplies no competing behavior for this path.
Retail remains the oracle where a reference differs: the pinned WorldBuilder
reader selects the last surface source, while retail's GetSurfaceDID proves
that the normal/high-detail source is index zero.
acdream port shape
- Capture
TerrainTex.TexTilingwhileTerrainAtlasassigns each terrain type to an array layer. - Convert the type-keyed values into the renderer's 36-entry layer-indexed
uniform table. Unused layers default to
1.0; mapped values are preserved verbatim. - Upload the table after binding
terrain_modern.frag. - Sample base, overlay, and road textures with
cellUv * uTexTiling[layer]; sample alpha masks with their original UV.