惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
爱范儿
爱范儿
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
博客园 - 聂微东
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 司徒正美
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
宝玉的分享
宝玉的分享
罗磊的独立博客
Jina AI
Jina AI

Red Blob Games: latest blog posts

Red Blob Games: Differential heuristics Red Blob Games: Responsive design calculator Red Blob Games: Academic citations Red Blob Games: Highlighting interactive code blocks Red Blob Games: Optimizing page size Red Blob Games: Writing a guide to SDF fonts Red Blob Games: URLs with trailing punctuation Red Blob Games: What I did in 2025 Red Blob Games: Goodbye Sass Goodbye Sass Red Blob Games: RotMG map seeds Red Blob Games: Mapgen4 Mapgen4's use of WebGL2 Red Blob Games: Mapgen4 renderer Red Blob Games: Harnessing ChatGPT hallucinations Red Blob Games: Let Let's write a search engine, part 2 of 2 Red Blob Games: Let Let's write a search engine, part 1 of 2 Red Blob Games: Hexagon conversions Red Blob Games: Mapgen4 trade routes Red Blob Games: De-optimizing mapgen4 Red Blob Games: Hexagon spiral coordinates Red Blob Games: Thoughts on Flash Red Blob Games: What I did in 2024 Red Blob Games: Hexagon page animations Red Blob Games: SDF Halos SDF Halos Red Blob Games: SDF headless tests, part 2 Red Blob Games: SDF headless tests, part 1
Red Blob Games: Mapgen4 river shader
2025-10-01 · via Red Blob Games: latest blog posts
Blog post: 30 Sep 2025

Back in 2018 I had the idea to prerender short segments of river bends and confluences into a texture, and then use that texture to draw the rivers to the screen. I was trying to have draw exactly one triangle per Delaunay triangle, so that I could generate the geometry ahead of time and only change the texture coordinates. I planned to implement this[1] as a 2D table:

Debug visualization of river rendering texture

To simplify, I switched to using bezier curves:

Debug visualization of curved river rendering texture

I was planning to use the input and output width as the indices into the table, but ended up using only one width. What I didn’t realize at the time was that I no longer needed a 2D table; I could’ve used a 1D table. And even better, I could’ve drawn the curve in a shader, like I did in these shader experiments. But I was focused on shipping and not doing things the cleanest or most efficient way.

After I rewrote the main renderer, I decided to rewrite the river renderer too. I adapted one of the earlier shader experiments to make a river shader, and compared before/after:

Old and new river renderer

It’s a bit hard to tell at that zoom level, but if you open the two images in separate tabs you can flip back and forth to compare. Here’s a closer view:

Old and new rendering, close up

The rivers look sharper. But some of the flaws that were hidden before by the blurriness are now visible.

To fix those flaws, I wanted to use a shader to draw wide bezier curves inside a triangle. I didn’t have a good intuition for bezier curves with barycentric coordinates, so I had an LLM generate a quick & dirty tool to help me build my intuition. It’s like shadertoy but for one triangle[2]. This was an attempt at learning how to “vibe code”, and I have mixed feelings about it, but that’s a story for another time.

Playing with the toy made me see that there should be a way to do what I want, but it’s not from bezier curves like I originally thought. Instead, I can curve fit two degree-5 polynomials, one for each side of the river. Using the LLM-generated code helped me figure this out, but it wasn’t able to directly give me a solution. I’ll have to work out the details myself at some point.

I added “better river shader” to my list, but at a low priority, so I’m going to work on some other things next and come back to it.