Shaders, Color Palettes, and Unit Animations

What makes sense for multi-threading is another area that is interesting. Certainly, trade connections is a huge bottleneck in Civ3. But I am definitely interested in multithreading in general.

Which probably sounds contradictory given my previous post. In my mind though, there's a distinction between JavaScript-style async/await (where at some unknown point in the future, a result will return), and parallelizing calculations (where you run a bunch of tasks in parallel). The latter is multithreaded, but can effectively be thought of synchronously. Run a bunch of threads on this task, wait for them to finish, go do the next thing.

I don't know how well parallel calculations will work with mod/Lua interop. But as someone who plays Civ3 over Civ5/Civ6 in no small part for the larger maps (and lack of 1 UPT), being able to scale performance effectively is a significant appeal.

Although I also wonder if the performance can be improved simply by using better algorithms. In my experience, there are often more significant speedups available via algorithms than via threading, and trade calculations in Civ3 are slow enough that I've long wondered if there is low-hanging fruit in terms of optimization.
 
Way into speculation land here, but I've presumed trade calculation loops adjacent tile comparisons repeatedly. Thats basically a problem for a convolution matrix which should be reasonable to translate into a library of some sort that uses parallel computation. Not necessarily the GPU, but perhaps processor multiprocessing features.

There should be a number of handy libraries as convolution matrices are used in image processing and convolutional neural networks which are all the rage in recent years.
 
the only things wrong with the terrain drawing are the seams between the base layer tiles

On a completely different project and completely different engine I just got another insight about this. I dug some more to make sure we're not missing a filter clearing (I still can't find one), but I think I have an idea of what the problem is:

Our scrolling and scaling aligns pixels off of their int-based positions, and OpenGL is sampling the interval between the edge and the transparency.

Other game engines have some sort of "nearest pixel" filtering for such occasions, but I haven't yet seen that Godot does.

Huh, I just noticed that OpenGL has a GL_NEAREST filter in its shaders. This is just the beginning of an idea, but maybe we can use a shader to go over the base tiles and apply this filter? I have no idea if what I just said is even a possible thing.

Alternately I guess our options are to draw an extra solid pixel in each direction or snap the drawn position to integer values. We should only need to do that for base terrain tiles, though, in any case. Well, maybe fog of war, too.

May or may not be of use: https://learnopengl.com/Getting-started/Textures
 
Last edited:
Our scrolling and scaling aligns pixels off of their int-based positions, and OpenGL is sampling the interval between the edge and the transparency.
Other game engines have some sort of "nearest pixel" filtering for such occasions, but I haven't yet seen that Godot does.
Using nearest neighbor filtering might fix the seams but if we switch to that we lose bilinear filtering. That's not necessarily a bad thing, the choice between the two is a choice between pixelated/grainy sprites (nearest) and blurry sprites (bilinear). Personally I don't think either one looks good. In fact I think we should ditch the zoom slider and only support zoom levels of 1.0 and 0.5 like the original game. Making 50% zoom look good is a relatively simple matter of averaging four pixels into one, whereas we'll never be able to make sprites look good at f.e. 110% zoom without recreating them.
Alternately I guess our options are to draw an extra solid pixel in each direction or snap the drawn position to integer values. We should only need to do that for base terrain tiles, though, in any case. Well, maybe fog of war, too.
My idea for a lazy fix is to scale up the sprites by something like 0.1% as they're drawn so that way, hopefully, the sample locations are nudged off the transparent pixels onto the opaque ones without otherwise changing the appearance noticeably. Drawing an extra opaque pixel around the opaque areas on each texture is another option. I tried quickly rounding off the draw position to integer coords but that didn't make any difference. I suspect that doesn't help since the sprites are still drawn at non-integer locations once the scaling factor is applied. Keep in mind the seams only appear at zoom levels other than 1.0.

Another way we might be able to fix the seams is by changing the blend mode. It's somewhat strange that the seams are fully transparent instead of something like 1% transparent, which is what I would expect if the texture samples went slightly into the transparent region. It's possible that the blending mode is set to throw away pixels if their opacity is anything less than a full 1.0.
 
Top Bottom