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
|
|
@ -29,6 +29,7 @@ out vec4 fragColor;
|
|||
|
||||
uniform uvec2 uTerrainHandle;
|
||||
uniform uvec2 uAlphaHandle;
|
||||
uniform float uTexTiling[36];
|
||||
#define uTerrain sampler2DArray(uTerrainHandle)
|
||||
#define uAlpha sampler2DArray(uAlphaHandle)
|
||||
|
||||
|
|
@ -46,7 +47,12 @@ layout(std140, binding = 1) uniform SceneLighting {
|
|||
vec4 uCameraAndTime;
|
||||
};
|
||||
|
||||
const float TILE = 1.0;
|
||||
// Retail TexMerge::CopyAndTile (0x00503580) and TexMerge::Merge
|
||||
// (0x005038C0) pass TerrainTex::tex_tiling to every terrain source before
|
||||
// the cell-scale alpha mask is applied. The atlas stores that value by layer.
|
||||
float terrainTiling(float layer) {
|
||||
return uTexTiling[int(layer)];
|
||||
}
|
||||
|
||||
vec4 maskBlend3(vec4 t0, vec4 t1, vec4 t2, float h0, float h1, float h2) {
|
||||
float a0 = h0 == 0.0 ? 1.0 : t0.a;
|
||||
|
|
@ -68,21 +74,21 @@ vec4 combineOverlays(vec2 baseUV, vec4 pOverlay0, vec4 pOverlay1, vec4 pOverlay2
|
|||
vec4 t0 = vec4(0.0), t1 = vec4(0.0), t2 = vec4(0.0);
|
||||
|
||||
if (h0 > 0.0) {
|
||||
t0 = texture(uTerrain, vec3(baseUV * TILE, pOverlay0.z));
|
||||
t0 = texture(uTerrain, vec3(baseUV * terrainTiling(pOverlay0.z), pOverlay0.z));
|
||||
if (pOverlay0.w >= 0.0) {
|
||||
vec4 a = texture(uAlpha, vec3(pOverlay0.xy, pOverlay0.w));
|
||||
t0.a = a.a;
|
||||
}
|
||||
}
|
||||
if (h1 > 0.0) {
|
||||
t1 = texture(uTerrain, vec3(baseUV * TILE, pOverlay1.z));
|
||||
t1 = texture(uTerrain, vec3(baseUV * terrainTiling(pOverlay1.z), pOverlay1.z));
|
||||
if (pOverlay1.w >= 0.0) {
|
||||
vec4 a = texture(uAlpha, vec3(pOverlay1.xy, pOverlay1.w));
|
||||
t1.a = a.a;
|
||||
}
|
||||
}
|
||||
if (h2 > 0.0) {
|
||||
t2 = texture(uTerrain, vec3(baseUV * TILE, pOverlay2.z));
|
||||
t2 = texture(uTerrain, vec3(baseUV * terrainTiling(pOverlay2.z), pOverlay2.z));
|
||||
if (pOverlay2.w >= 0.0) {
|
||||
vec4 a = texture(uAlpha, vec3(pOverlay2.xy, pOverlay2.w));
|
||||
t2.a = a.a;
|
||||
|
|
@ -96,7 +102,7 @@ vec4 combineRoad(vec2 baseUV, vec4 pRoad0, vec4 pRoad1) {
|
|||
float h1 = pRoad1.z < 0.0 ? 0.0 : 1.0;
|
||||
vec4 result = vec4(0.0);
|
||||
if (h0 > 0.0) {
|
||||
result = texture(uTerrain, vec3(baseUV * TILE, pRoad0.z));
|
||||
result = texture(uTerrain, vec3(baseUV * terrainTiling(pRoad0.z), pRoad0.z));
|
||||
if (pRoad0.w >= 0.0) {
|
||||
vec4 a0 = texture(uAlpha, vec3(pRoad0.xy, pRoad0.w));
|
||||
result.a = 1.0 - a0.a;
|
||||
|
|
@ -123,7 +129,7 @@ vec3 applyFog(vec3 lit, vec3 worldPos) {
|
|||
void main() {
|
||||
vec4 baseColor = vec4(0.0);
|
||||
if (vBaseTexIdx >= 0.0) {
|
||||
baseColor = texture(uTerrain, vec3(vBaseUV * TILE, vBaseTexIdx));
|
||||
baseColor = texture(uTerrain, vec3(vBaseUV * terrainTiling(vBaseTexIdx), vBaseTexIdx));
|
||||
}
|
||||
|
||||
vec4 overlays = vec4(0.0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue