Fix scanline comb artifact in road shader by using integer-rounded tile coordinates
This commit is contained in:
+23
-41
@@ -169,9 +169,10 @@ float getRiverDistance(vec2 p, int mask) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float getRoadDistance(vec2 p, int mask, vec2 tileCenterWorld, float amp) {
|
float getRoadDistance(vec2 p, int mask, int ix, int iy, float amp) {
|
||||||
float h1 = fract(sin(dot(tileCenterWorld, vec2(12.9898, 78.233))) * 43758.5453);
|
// Exact integer parity per hex tile: completely immune to floating-point interpolation jitter across scanlines!
|
||||||
float s1 = (h1 > 0.5) ? 1.0 : -1.0;
|
int parity = (ix * 3 + iy * 5) & 1;
|
||||||
|
float s1 = (parity == 0) ? 1.0 : -1.0;
|
||||||
|
|
||||||
int edges[6];
|
int edges[6];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -363,63 +364,44 @@ void main() {
|
|||||||
vec4 landColor = mix(nonSnowLand, snowColor, snowWeight);
|
vec4 landColor = mix(nonSnowLand, snowColor, snowWeight);
|
||||||
|
|
||||||
// 6b. Road Texture Integration (blended directly into the tile surface texture)
|
// 6b. Road Texture Integration (blended directly into the tile surface texture)
|
||||||
if (hasRoad == 1 && oceanWaterFac < 0.95) {
|
if (hasRoad == 1) {
|
||||||
|
// Recover exact integer grid indices of the tile center (spacing is 0.75 in X and 0.43287992 in Y)
|
||||||
vec2 tileCenterWorld = vWorldPos.xy - fragVert.xy;
|
vec2 tileCenterWorld = vWorldPos.xy - fragVert.xy;
|
||||||
|
int ix = int(floor(tileCenterWorld.x / 0.75 + 0.5));
|
||||||
|
int iy = int(floor(tileCenterWorld.y / 0.43287992 + 0.5));
|
||||||
float amp = max(0.0, roadMeander);
|
float amp = max(0.0, roadMeander);
|
||||||
|
|
||||||
float rawRoadDist = getRoadDistance(fragVert.xy, roadMask, tileCenterWorld, amp);
|
|
||||||
float rScale = max(1.0, roadTextureScale);
|
float rScale = max(1.0, roadTextureScale);
|
||||||
vec2 uvRoad = vWorldPos.xy * rScale;
|
vec2 uvRoad = vWorldPos.xy * rScale;
|
||||||
|
|
||||||
|
// Sample textures in uniform control flow (before any fragment-dependent branch) to avoid mipmap derivative glitches
|
||||||
vec3 soilTex = texture(texSand, uvRoad).rgb;
|
vec3 soilTex = texture(texSand, uvRoad).rgb;
|
||||||
vec3 stoneTex = texture(texRock, uvRoad * 1.25).rgb;
|
vec3 saharaTex = texture(texSahara, uvRoad * 0.9).rgb;
|
||||||
float pebbleRelief = mix(soilTex.r, stoneTex.r, 0.5) - 0.5;
|
float fineGrain = (mix(soilTex.r, saharaTex.r, 0.5) - 0.5) * 0.18;
|
||||||
|
|
||||||
// Very subtle micro-edge grain (0.0018) so the road has crisp, clean borders
|
float rawRoadDist = getRoadDistance(fragVert.xy, roadMask, ix, iy, amp);
|
||||||
float dRoad = max(0.0, rawRoadDist + pebbleRelief * 0.0018);
|
|
||||||
|
|
||||||
float rCore = max(0.014, roadRadius);
|
float rCore = max(0.012, roadRadius);
|
||||||
float rOuter = rCore + max(0.006, roadBorderWidth);
|
float rOuter = rCore + max(0.005, roadBorderWidth);
|
||||||
|
|
||||||
// Crisp road deck and distinct dark casing/curb
|
float roadCoreFac = 1.0 - smoothstep(rCore * 0.65, rCore, rawRoadDist);
|
||||||
float roadCoreFac = 1.0 - smoothstep(rCore * 0.80, rCore, dRoad);
|
float roadTotalFac = (1.0 - smoothstep(rCore, rOuter, rawRoadDist)) * (1.0 - oceanWaterFac);
|
||||||
float roadTotalFac = 1.0 - smoothstep(rOuter * 0.82, rOuter, dRoad);
|
|
||||||
|
|
||||||
if (roadTotalFac > 0.001) {
|
if (roadTotalFac > 0.001) {
|
||||||
vec3 roadSurf;
|
vec3 centerTone = clamp(roadColor * (1.0 + fineGrain), 0.0, 1.0);
|
||||||
if (roadType == 1) {
|
vec3 borderTone = clamp(roadBorderColor * (1.0 + fineGrain * 0.7), 0.0, 1.0);
|
||||||
// Stone / Cobblestone road: bright paved stone with crisp dark curb
|
vec3 roadSurf = mix(borderTone, centerTone, roadCoreFac);
|
||||||
vec3 cobbleSurface = roadColor * (0.88 + 0.35 * pebbleRelief);
|
|
||||||
vec3 stoneCurb = roadBorderColor * (0.85 + 0.25 * pebbleRelief);
|
|
||||||
roadSurf = mix(stoneCurb, cobbleSurface, roadCoreFac);
|
|
||||||
} else if (roadType == 2) {
|
|
||||||
// Railroad: dark gravel ballast bed with steel twin rails
|
|
||||||
vec3 ballast = roadBorderColor * (0.85 + 0.35 * pebbleRelief);
|
|
||||||
float railLine = smoothstep(rCore * 0.38, rCore * 0.48, rawRoadDist)
|
|
||||||
* (1.0 - smoothstep(rCore * 0.56, rCore * 0.68, rawRoadDist));
|
|
||||||
vec3 steelRail = vec3(0.75, 0.78, 0.82);
|
|
||||||
vec3 innerBed = mix(roadColor * (0.85 + 0.30 * pebbleRelief), steelRail, railLine);
|
|
||||||
roadSurf = mix(ballast, innerBed, roadCoreFac);
|
|
||||||
} else {
|
|
||||||
// Dirt / Country road: warm sandy-ochre packed earth with two subtle cart wheel tracks & dark curb
|
|
||||||
float wheelRut = smoothstep(rCore * 0.30, rCore * 0.48, rawRoadDist)
|
|
||||||
* (1.0 - smoothstep(rCore * 0.55, rCore * 0.72, rawRoadDist));
|
|
||||||
vec3 brightDeck = roadColor * (0.92 + 0.32 * pebbleRelief);
|
|
||||||
vec3 darkCurb = roadBorderColor * (0.85 + 0.25 * pebbleRelief);
|
|
||||||
vec3 trackedDeck = mix(brightDeck, darkCurb, wheelRut * 0.35);
|
|
||||||
roadSurf = mix(darkCurb, trackedDeck, roadCoreFac);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If crossing a river, render a crisp bridge deck and suppress river water under the bridge
|
// If crossing a river, render a bridge deck and suppress river water under the bridge
|
||||||
if (riverWaterFac > 0.01) {
|
if (riverWaterFac > 0.01) {
|
||||||
vec3 bridgeCol = (roadType >= 1)
|
vec3 bridgeCol = (roadType >= 1)
|
||||||
? vec3(0.72, 0.70, 0.66) * (0.90 + 0.25 * pebbleRelief)
|
? vec3(0.72, 0.70, 0.66) * (1.0 + fineGrain)
|
||||||
: vec3(0.68, 0.48, 0.28) * (0.90 + 0.25 * pebbleRelief);
|
: vec3(0.68, 0.48, 0.28) * (1.0 + fineGrain);
|
||||||
roadSurf = mix(roadSurf, bridgeCol, riverWaterFac);
|
roadSurf = mix(roadSurf, bridgeCol, riverWaterFac);
|
||||||
waterFac *= (1.0 - roadTotalFac * 0.98);
|
waterFac *= (1.0 - roadTotalFac * 0.98);
|
||||||
}
|
}
|
||||||
|
|
||||||
float blendAlpha = roadTotalFac * clamp(roadOpacity, 0.0, 1.0) * (1.0 - oceanWaterFac);
|
float blendAlpha = roadTotalFac * clamp(roadOpacity, 0.0, 1.0);
|
||||||
landColor.rgb = mix(landColor.rgb, roadSurf, blendAlpha);
|
landColor.rgb = mix(landColor.rgb, roadSurf, blendAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user