fix(rendering): restore retail terrain texture tiling
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>
This commit is contained in:
parent
84b7d2d7cd
commit
bb5acab9e6
7 changed files with 297 additions and 7 deletions
40
src/AcDream.App/Rendering/TerrainTextureTilingTable.cs
Normal file
40
src/AcDream.App/Rendering/TerrainTextureTilingTable.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
namespace AcDream.App.Rendering;
|
||||
|
||||
/// <summary>
|
||||
/// Builds the layer-indexed adapter table consumed by
|
||||
/// <c>terrain_modern.frag</c>. Retail passes <c>TerrainTex::tex_tiling</c>
|
||||
/// directly to <c>ImgTex::TileCSI</c> / <c>ImgTex::MergeTexture</c>
|
||||
/// (`TexMerge::CopyAndTile` 0x00503580, `TexMerge::Merge` 0x005038C0).
|
||||
/// The table is the modern texture-array equivalent of that per-texture
|
||||
/// argument.
|
||||
/// </summary>
|
||||
internal static class TerrainTextureTilingTable
|
||||
{
|
||||
// WorldBuilder's extracted terrain-array path uses the same 36-layer
|
||||
// contract. Packed terrain layer indices are validated against this
|
||||
// capacity before the shader table is built.
|
||||
internal const int LayerCapacity = 36;
|
||||
|
||||
internal static float[] Build(IEnumerable<(uint Layer, uint RepeatCount)> entries)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entries);
|
||||
|
||||
var table = new float[LayerCapacity];
|
||||
Array.Fill(table, 1f);
|
||||
|
||||
foreach (var (layer, repeatCount) in entries)
|
||||
{
|
||||
if (layer >= LayerCapacity)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Terrain atlas layer {layer} exceeds the shader capacity of {LayerCapacity} layers.");
|
||||
}
|
||||
|
||||
// Preserve the dat value exactly. Retail forwards the unsigned
|
||||
// field without normalizing it in both CopyAndTile and Merge.
|
||||
table[layer] = repeatCount;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue