FAForever / Neroxis-Map-Generator

MIT License
18 stars 10 forks source link

Odd symmetry fixes #400

Closed clivepaterson closed 2 weeks ago

clivepaterson commented 1 month ago

So after much digging and debugging, I found the main cause of the issue with Odd Symmetry mapgens. I basically affects functions that use applyWithSymmetry()

And the reason is because points can land on the same pixel after rotation: after_rotation

And then some points don't get filled in, and are missed.

So I've played with some strategies to resolve this issue, and so far it's looking pretty decent.

clivepaterson commented 1 month ago

Some before and afters:

Before: image

After: image

clivepaterson commented 1 month ago

So yes this is a quite a difficult challenge.

The traditional algorthims for pixel rotation are not gonna help much, mentioned in this article: https://gamedev.stackexchange.com/questions/135091/how-can-i-rotate-pixel-art-sprites-without-the-aesthetics-getting-ruined The RotSprite method is also impractical. So traditional rotation algorithms aren't overly useful.

There is an even crazier idea: detecting when a rotate pixel lands on occupied pixel, and move it to an adjacent pixel that hasn't been set. And I've actually tried this, but the results are not good: image

So another idea I've been thinking about is to: 1) draw the whole first slice 2) loop through the remaining pixels, and find their correct value by rotating backwards, to lookup the value in the original slice

It's kinda a reversal way of copying the slice, but is means that every pixel will get a value.

Of course this would only work for certain functions like Noise, Perlin, Dilute etc. And it wouldn't work for mex or spawn placements etc, which are a bit more immune from this rotation artifacting.

Sheikah45 commented 1 month ago

Hmm yeah your reversal of the symmetry point could work. Although would have to double check what that does to the performance.

Sheikah45 commented 1 month ago

It would also remove a lot of the if statements that the current solution has. Ideally a solution doesn't really break out of the applySymmetry function.

clivepaterson commented 1 month ago

Yep, I'm thinking I'll have a go at the reverse lookup strategy. And create a new branch if it works. I should be able to stay within the applySymmetry function too.

I can't see this current branch merging. But it has been useful discussion. Not sure if it's worth keeping the PR up.

I can see myself taking about 1-2 weeks to try the reverse lookup strategy, although it might be fairly easy once I get stuck into it.

For performance I'm guessing it'll be the same, because it should be only 1 rotation calculation per pixel still... But yeah, the rotation is likely one of the more expensive functions in the code. Can see the number of ops for sine and cosine here: https://www.agner.org/optimize/instruction_tables.pdf

clivepaterson commented 2 weeks ago

Closed because a better method was found.