Fill water tile gaps at coastlines with neighbor checking

Fixes visible square gaps in ocean near coastlines by rendering masked tiles
if they have any water neighbors. Creates smoother, more natural coastlines.

Implementation:
- Check 8 neighboring tiles when a tile is masked out
- If any neighbor is water, render the edge tile anyway
- Creates 1-tile overlap at coastline boundaries
- Fills square gaps between water tiles

Before: Hard square edges with missing ocean tiles at coast
After: Continuous water coverage with smooth blended coastlines

The straight-line grid artifacts are reduced by ensuring adjacent water
tiles connect properly instead of leaving rectangular voids.
This commit is contained in:
Kelsi 2026-02-08 22:27:11 -08:00
parent 709138cf5d
commit e98e0562b8

View file

@ -482,6 +482,7 @@ void WaterRenderer::createWaterMesh(WaterSurface& surface) {
for (int y = 0; y < gridHeight - 1; y++) {
for (int x = 0; x < gridWidth - 1; x++) {
// Check render mask - each bit represents a tile
// Also render edge tiles to blend coastlines (avoid square gaps)
bool renderTile = true;
if (!surface.mask.empty()) {
int tileIndex;
@ -501,6 +502,27 @@ void WaterRenderer::createWaterMesh(WaterSurface& surface) {
bool lsbOrder = (maskByte & (1 << bitIndex)) != 0;
bool msbOrder = (maskByte & (1 << (7 - bitIndex))) != 0;
renderTile = lsbOrder || msbOrder;
// If this tile is masked out, check neighbors to fill gaps
if (!renderTile && x > 0 && y > 0 && x < gridWidth-2 && y < gridHeight-2) {
// Check adjacent tiles - render if any neighbor is water (blend coastline)
for (int dy = -1; dy <= 1; dy++) {
for (int dx = -1; dx <= 1; dx++) {
if (dx == 0 && dy == 0) continue;
int neighborIdx = (y + dy) * surface.width + (x + dx);
int nByteIdx = neighborIdx / 8;
int nBitIdx = neighborIdx % 8;
if (nByteIdx < static_cast<int>(surface.mask.size())) {
uint8_t nMask = surface.mask[nByteIdx];
if ((nMask & (1 << nBitIdx)) || (nMask & (1 << (7 - nBitIdx)))) {
renderTile = true;
goto found_neighbor;
}
}
}
}
found_neighbor:;
}
}
}