Noxagonal / Vulkan2DRenderer

Easy to use 2D rendering engine using Vulkan API as backend.
MIT License
118 stars 6 forks source link

Blurry text with TEXEL_SPACE_CENTERED #158

Open exuvo opened 3 years ago

exuvo commented 3 years ago

I am a bit stumped on this problem i have encountered. Lets say i am rendering some text at [15, 15].

With RenderCoordinateSpace::TEXEL_SPACE the text remains crisp while i am resizing the window. But with RenderCoordinateSpace::TEXEL_SPACE_CENTERED the text becomes blurry when either window height or width is uneven.

There must be a rounding error somewhere but i cant figure out where. The only difference between the modes should be a [-1,-1] offset. As you can see below imgui still renders the text normally so its not a global thing. I have also tried without imgui but that does not change the behavior.

https://user-images.githubusercontent.com/2049338/103461943-30547400-4d22-11eb-8a31-75667464f94b.mp4

https://user-images.githubusercontent.com/2049338/103461945-334f6480-4d22-11eb-99a0-898188212bce.mp4

exuvo commented 3 years ago

On a related note: Is it possible to change coordinate space mid frame? I would like to use TEXEL_SPACE_CENTERED when rendering the game world but use TEXEL_SPACE when rendering the UI text (the non imgui parts). Or maybe i should just render the game world to a RenderTargetTexture as i see in the example they can have different settings?

Noxagonal commented 3 years ago

Likely caused by the center coordinate landing between pixels when window size is an odd number.

I could add a test for this and move center coordinate towards top left corner by half a pixel when window size is odd number, or I could limit the size of the window to even numbers when using centered coordinates.

Noxagonal commented 3 years ago

Coordinate space can be changed between renders. I can add a function for this.

Noxagonal commented 3 years ago

Added possibility to change coordinate space for windows and render targets. However this only applies to full renders.

I'll get to the other stuff when I have time.

exuvo commented 3 years ago

Ok, if it can't be done mid frame i'll have to go the RenderTargetTexture path instead then or always use TEXEL_SPACE and manually offset the game world rendering.

-edit- Actually it was pretty easy to offset the game world rendering since i structured the rendering better than i did in my old java version of the game.

Noxagonal commented 3 years ago

Can't easily do mid-frame. Offsetting works for as long as you round text position to integer multiples. You should have it easy by using matrices.

The root of the problem really is about the center coordinates landing in between pixels. This seems to be a problem only for integer offsets for vertices and when texture size is 1:1 to output, in which case the texture fetch also happens in-between pixels giving the appearance of blurry texture. It's most noticeable in text... So yeah, floating point rounding errors in GPU paired with texture fetches in-between texels.

It's technically not a bug... However I'll investigate if I can get window to stick to even number sizes when using centered coordinates.