This commit is contained in:
Crizomb 2025-09-29 15:34:29 +02:00
commit 3fa75abfb2
42 changed files with 5634 additions and 0 deletions

View file

@ -0,0 +1,322 @@
// Stolen from cmgriffing ghostty shaders repo
// This Ghostty shader is a port of https://www.shadertoy.com/view/MljXzz
const float timeMultiplier = 0.8f;
#define RGB( r, g, b ) vec3( float( r ) / 255.0, float( g ) / 255.0, float( b ) / 255.0 )
const vec3 RGB_WATER = RGB(52, 166, 202);
const vec3 RGB_BUILDING = RGB(219, 180, 144);
const vec3 RGB_RIGHT_WALL = RGB_BUILDING * 1.1;
const vec3 RGB_LEFT_WALL = RGB_BUILDING * 0.7;
const vec3 RGB_WINDOWS = RGB(90, 100, 180);
const vec3 RGB_ROAD = RGB(110, 125, 120) * 0.7;
const vec3 RGB_LANE = RGB(255, 255, 255) * 0.8;
const vec3 RGB_GRASS = RGB(129, 164, 66);
const vec3 RGB_TREE_LEAVES = RGB(129, 164, 66) * 0.6;
const vec3 RGB_TREE_TRUNK = RGB(80, 42, 42);
const float TILE_WATER = 0.0;
const float TILE_GRASS = 1.0;
const float TILE_ISLAND = 2.0;
const float TILE_ROAD_X = 3.0;
const float TILE_ROAD_Y = 4.0;
const float TILE_ROAD_XY = 5.0;
const float ISO_TILE = 13.0 * 8.0;
const float LARGE_FLOAT = 1e8;
void DrawBuilding(inout vec3 color, inout float zbuffer, vec2 tile, vec2 pixel, vec2 buildingTile, float h)
{
float depth = buildingTile.x + buildingTile.y;
if (depth > zbuffer)
{
return;
}
buildingTile.x += h;
buildingTile.y += h;
pixel.y -= ISO_TILE * 0.25;
vec2 iso = vec2((pixel.x + 2.0 * pixel.y) / ISO_TILE, (pixel.x - 2.0 * pixel.y) / -ISO_TILE);
tile = floor(iso);
vec2 off = iso - tile;
// roof
if (tile.x == buildingTile.x && tile.y == buildingTile.y && off.x > 0.2 && off.y > 0.2 && off.x < 0.98 && off.y < 0.98)
{
zbuffer = depth;
color = RGB_BUILDING;
if (off.x < 0.28 || off.y < 0.28 || off.x > 1.0 - 0.08 || off.y > 1.0 - 0.08)
{
color *= 1.2;
}
}
float px = (buildingTile.x - buildingTile.y) * ISO_TILE * 0.5;
// right wall
if (pixel.x >= px && pixel.x < px + 0.39 * ISO_TILE && iso.y < buildingTile.y + 0.20 && iso.y > buildingTile.y - h - 0.4)
{
zbuffer = depth;
color = RGB_RIGHT_WALL;
if (mod(iso.y + 0.2, 0.5) < 0.25)
{
color *= RGB_WINDOWS;
color *= mod(pixel.x, 16.0) < 8.0 ? 1.0 : 0.8;
}
}
// left wall
if (pixel.x >= px - 0.39 * ISO_TILE && pixel.x < px && iso.x < buildingTile.x + 0.20 && iso.x > buildingTile.x - h - 0.4)
{
zbuffer = depth;
color = RGB_LEFT_WALL;
if (mod(iso.x + 0.2, 0.5) < 0.25)
{
color *= RGB_WINDOWS;
color *= mod(pixel.x, 16.0) < 8.0 ? 1.0 : 0.8;
}
}
}
void DrawTree(inout vec3 color, inout float zbuffer, vec2 tile, vec2 pixel, vec2 treeTile)
{
float depth = treeTile.x + treeTile.y;
if (depth > zbuffer)
{
return;
}
pixel.y -= ISO_TILE * 0.25;
vec2 iso = vec2((pixel.x + 2.0 * pixel.y) / ISO_TILE, (pixel.x - 2.0 * pixel.y) / -ISO_TILE);
tile = floor(iso);
vec2 off = iso - tile;
float px = (treeTile.x - treeTile.y) * ISO_TILE * 0.5;
// top leaves
if (iso.x > treeTile.x + 0.2 && iso.y > treeTile.y + 0.2 && iso.x < treeTile.x + 0.45 && iso.y < treeTile.y + 0.45)
{
zbuffer = depth;
color = RGB_TREE_LEAVES * 1.0;
}
// left leaves
if (pixel.x >= px - 0.125 * ISO_TILE && pixel.x < px && iso.x > treeTile.x - 0.1 && iso.x < treeTile.x + 0.2 && iso.x > treeTile.x - 0.1)
{
zbuffer = depth;
color = RGB_TREE_LEAVES * 0.8;
}
// right leaves
if (pixel.x >= px && pixel.x < px + 0.125 * ISO_TILE && iso.y < treeTile.y + 0.2 && iso.y > treeTile.y - 0.1)
{
zbuffer = depth;
color = RGB_TREE_LEAVES * 1.2;
}
// left trunk
if (pixel.x >= px - 0.039 * ISO_TILE && pixel.x < px && iso.x <= treeTile.x - 0.1 && iso.x > treeTile.x - 0.4)
{
zbuffer = depth;
color = RGB_TREE_TRUNK * 0.8;
}
// right trunk
if (pixel.x >= px && pixel.x < px + 0.039 * ISO_TILE && iso.y <= treeTile.y - 0.1 && iso.y > treeTile.y - 0.4)
{
zbuffer = depth;
color = RGB_TREE_TRUNK * 1.1;
}
}
float TileID(vec2 tile)
{
float id = TILE_WATER;
vec4 tex = texture(iChannel0, tile / (iChannelResolution[0].xy * 4.0));
id = tex.y > 0.5 ? TILE_WATER : TILE_GRASS;
id = tex.y > 0.9 ? TILE_ISLAND : id;
if (id == TILE_GRASS && mod(tile.x + 1.0, 4.0) == 0.0)
{
id = TILE_ROAD_X;
}
if (mod(tile.y + 1.0, 4.0) == 0.0)
{
if (id == TILE_GRASS)
{
id = TILE_ROAD_Y;
}
if (id == TILE_ROAD_X)
{
id = TILE_ROAD_XY;
}
}
return id;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
float resMult = floor(max(iResolution.x, iResolution.y) / 800.0);
float resRcp = 1.0 / max(resMult, 1.0);
float cameraOffset = iTime * timeMultiplier * 10.0 + 0.5;
// float cameraOffset = float(iFrame);
vec2 pixel = fragCoord * resRcp + cameraOffset - iMouse.xy + vec2(-2000, -2000.0);
vec2 iso = vec2((pixel.x + 2.0 * pixel.y) / ISO_TILE, (pixel.x - 2.0 * pixel.y) / -ISO_TILE);
vec2 waterIso = vec2((pixel.x + 2.0 * pixel.y + 0.15625 * ISO_TILE) / ISO_TILE, (pixel.x - 2.0 * pixel.y - 0.15625 * ISO_TILE) / -ISO_TILE);
vec2 isoR = vec2((pixel.x + 2.0 * pixel.y - ISO_TILE * 0.5) / ISO_TILE, (pixel.x - 2.0 * pixel.y + ISO_TILE * 0.5) / -ISO_TILE);
vec2 tile = floor(iso);
vec2 tileR = floor(isoR);
vec2 waterTile = floor(waterIso);
vec2 off = iso - tile;
vec2 offR = isoR - tileR;
vec2 waterOff = waterIso - waterTile;
vec2 buildingTile0 = 2.0 * floor(tile / 2.0);
vec2 buildingTile1 = 3.0 * floor(tile / 3.0);
vec2 buildingTile2 = 4.0 * floor(tile / 4.0);
vec2 buildingTile3 = 5.0 * floor(tile / 5.0);
float tileId = TileID(tile);
float tileLId = TileID(vec2(tile.x - 1.0, tile.y));
float tileRId = TileID(vec2(tile.x + 1.0, tile.y));
float tileTId = TileID(vec2(tile.x, tile.y - 1.0));
float tileBId = TileID(vec2(tile.x, tile.y + 1.0));
float tileB0Id = TileID(buildingTile0);
float tileB1Id = TileID(buildingTile1);
float tileB2Id = TileID(buildingTile2);
float tileB3Id = TileID(buildingTile3);
// water
vec3 waterTexNoise = texture(iChannel0, waterTile / iChannelResolution[0].xy + fract(iTime * timeMultiplier * 0.005)).xyz;
vec3 color = RGB_WATER * mix(0.8, 1.1, waterTexNoise.z);
float waterTileId = TileID(waterTile);
float waterTileLId = TileID(vec2(waterTile.x - 1.0, waterTile.y));
float waterTileRId = TileID(vec2(waterTile.x + 1.0, waterTile.y));
float waterTileTId = TileID(vec2(waterTile.x, waterTile.y - 1.0));
float waterTileBId = TileID(vec2(waterTile.x, waterTile.y + 1.0));
float waterTileLTId = TileID(vec2(waterTile.x - 1.0, waterTile.y - 1.0));
float waterTileLBId = TileID(vec2(waterTile.x - 1.0, waterTile.y + 1.0));
float waterTileRTId = TileID(vec2(waterTile.x + 1.0, waterTile.y - 1.0));
float waterTileRBId = TileID(vec2(waterTile.x + 1.0, waterTile.y + 1.0));
// water shore shadow
if (waterTileId == TILE_WATER)
{
if ((waterTileLId != TILE_WATER && waterOff.x < 8.0 / 32.0)
|| (waterTileRId != TILE_WATER && waterOff.x > 24.0 / 32.0)
|| (waterTileTId != TILE_WATER && waterOff.y < 8.0 / 32.0)
|| (waterTileBId != TILE_WATER && waterOff.y > 24.0 / 32.0)
|| (waterTileLTId != TILE_WATER && waterOff.x < 8.0 / 32.0 && waterOff.y < 8.0 / 32.0)
|| (waterTileLBId != TILE_WATER && waterOff.x < 8.0 / 32.0 && waterOff.y > 24.0 / 32.0)
|| (waterTileRTId != TILE_WATER && waterOff.x > 24.0 / 32.0 && waterOff.y < 8.0 / 32.0)
|| (waterTileRBId != TILE_WATER && waterOff.x > 24.0 / 32.0 && waterOff.y > 24.0 / 32.0)
)
{
color *= vec3(0.8);
}
}
// shores
float waterPX = (waterTile.x - waterTile.y) * ISO_TILE * 0.5;
if ((waterTileId != TILE_WATER && pixel.x <= waterPX && waterTileLId == TILE_WATER)
|| (waterTileTId != TILE_WATER && pixel.x > waterPX && waterOff.x < 5.0 / 32.0))
{
color = RGB_GRASS * 0.7;
}
if ((waterTileId != TILE_WATER && pixel.x > waterPX && waterTileTId == TILE_WATER)
|| (waterTileLId != TILE_WATER && pixel.x <= waterPX && waterOff.x < 5.0 / 32.0))
{
color = RGB_GRASS * 0.9;
}
// grass and road
if (tileId != TILE_WATER)
{
color = RGB_GRASS;
}
float roadWidth = 0.3;
float laneWidth = 0.03;
if (((tileId == TILE_ROAD_X || tileId == TILE_ROAD_XY) && abs(0.5 - off.x) < roadWidth)
&& (tileTId != TILE_WATER || tileBId != TILE_WATER)
&& (tileTId != TILE_WATER || off.y >= 0.20)
&& (tileBId != TILE_WATER || off.y <= 0.80)
)
{
color = RGB_ROAD;
if (abs(0.5 - off.x) < laneWidth && mod(off.y, 0.5) < 0.2 && tileId != TILE_ROAD_XY)
{
color = RGB_LANE;
}
}
if ((tileId == TILE_ROAD_Y || tileId == TILE_ROAD_XY) && abs(0.5 - off.y) < roadWidth
&& (tileLId != TILE_WATER || tileRId != TILE_WATER)
&& (tileLId != TILE_WATER || off.x >= 0.20)
&& (tileRId != TILE_WATER || off.x <= 0.80))
{
color = RGB_ROAD;
if (abs(0.5 - off.y) < laneWidth && mod(off.x, 0.5) < 0.2 && tileId != TILE_ROAD_XY)
{
color = RGB_LANE;
}
}
if (tileId == TILE_GRASS && (
(buildingTile0.x == tile.x && buildingTile0.y == tile.y)
|| (buildingTile1.x == tile.x && buildingTile1.y == tile.y)
|| (buildingTile2.x == tile.x && buildingTile2.y == tile.y)
|| (buildingTile3.x == tile.x && buildingTile3.y == tile.y)))
{
// building AO
vec2 offAO = 7.0 * clamp((abs(0.5 - off) - 0.35), 0.0, 1.0);
color *= clamp(max(offAO.x, offAO.y), 0.0, 1.0);
}
else if (tileId == TILE_GRASS || tileId == TILE_ISLAND)
{
// tree AO
color *= clamp(max(8.0 * abs(0.15 - off.x), 8.0 * abs(0.15 - off.y)), 0.0, 1.0);
}
float zbuffer = LARGE_FLOAT;
if (tileB0Id == TILE_GRASS)
{
DrawBuilding(color, zbuffer, tile, pixel, buildingTile0, 0.0);
}
if (tileB1Id == TILE_GRASS)
{
DrawBuilding(color, zbuffer, tile, pixel, buildingTile1, 1.0);
}
if (tileB2Id == TILE_GRASS)
{
DrawBuilding(color, zbuffer, tile, pixel, buildingTile2, 2.0);
}
if (tileB3Id == TILE_GRASS)
{
DrawBuilding(color, zbuffer, tile, pixel, buildingTile3, 3.0);
}
if ((tileId == TILE_GRASS || tileId == TILE_ISLAND) && zbuffer >= LARGE_FLOAT)
{
DrawTree(color, zbuffer, tile, pixel, tile);
}
fragColor = vec4(sqrt(color), 1.0);
vec2 termUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, termUV);
float alpha = step(length(terminalColor.rgb), 0.4);
vec3 blendedColor = mix(terminalColor.rgb * 1.0, fragColor.rgb * 0.2, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}