Closed clivepaterson closed 2 weeks ago
Some before and afters:
Before:
After:
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:
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.
Hmm yeah your reversal of the symmetry point could work. Although would have to double check what that does to the performance.
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.
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
Closed because a better method was found.
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](https://github.com/FAForever/Neroxis-Map-Generator/assets/11024011/a7ca2a0e-f201-4377-91f6-41fe5cd7c77a)
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.