Page 1 of 1
Canvases and Text
Posted: Tue Jan 31, 2017 5:21 pm
by Rubix
Hey everybody, I'm new to LÖVE and I can't seem to find the answer to this on the forums.
I've been trying to figure out how to do split screen, and my current solution is to draw everything to two separate canvases and then draw those to the screen using setScissor() to crop them.
My only issue is that when I draw text to a canvas it looks different than if I just draw it to the screen.
- Capture.PNG (2.58 KiB) Viewed 5295 times
You can see in the image above the text on top is drawn directly to the screen, and the text below is drawn to a canvas that is rendered to the screen.
Any idea on what's causing this or how to fix it? Should I be attempting split screen in a different way entirely?
You can see the project for yourself here:
Thanks!
Edit: I should have been more specific about what is wrong with the text. The offset position is fine, that's just because I drew it while the camera was active. What I'm more concerned about is how the text looks like it's been scaled or compressed. The text on bottom is thinner and looks worse.
Re: Canvases and Text
Posted: Tue Jan 31, 2017 5:48 pm
by Beelz
I haven't looked at the code, but the text is moving because I assume you drew it within a push-pop. To draw a GUI, HUD, or mini-map you wan't to draw them after popping back. If that works the same with scissors I'm not sure, never used it. With them looking different is probably has to do with scaling the canvas. Maybe somebody wiser than I knows.
I'll check it out later after work.
Re: Canvases and Text
Posted: Tue Jan 31, 2017 6:02 pm
by zorg
You could forego the canvases entirely, and just setScissor half the screen, and draw everything at half the horizontal or vertical size, whichever orientation you have the two screens as... but canvases should be an easier way to not calculate things relative to their positioning.
Re: Canvases and Text
Posted: Tue Jan 31, 2017 7:40 pm
by Jasoco
The reason is because Canvases, even when they're transparent, still have a background color, even if it's 100% transparent. While you won't notice anything on fully transparent pixels, on partially transparent ones, like antialiased pixels around the edges of text, they will be "matted" with the color you use to clear the canvas. So if you use black, you get partially black pixels. Since your text is white, your partially transparent antialiased edge pixels are grey. So the text looks wrong.
To fix this, you can do many things.
1: Don't draw to a canvas with partially transparent pixels unless you are aware this will happen, and if you do, use a "clear" color of the same color. In this case, white.
2: Draw the text directly to the screen.
3: Clear the canvas with an opaque color, like that purple you use. Instead of using purple as the window background color, use it as the canvas background color. (Best results and the one that makes the text look identical.)
- Screen Shot 2017-01-31 at 2.39.31 PM.png (7.05 KiB) Viewed 5269 times
Bottom is the canvas one. Top is the directly drawn text.
4: Use a custom pixel font for a pixel game that doesn't have partially transparent pixels. (What I do)
Basically never draw partially transparent pixels in a location where there's nothing drawn yet unless you're aware of the underlying hidden background color of the canvas.
Re: Canvases and Text
Posted: Tue Jan 31, 2017 7:49 pm
by raidho36
That's a very common problem, but fret not - there is a very simple solution. Just draw to your canvas the graphics with premultiplied alpha while using according blend mode, and then use resulting canvas with normal blend mode to draw it onto the screen.
As a (quite a) bit of trivia, premultiplied alpha is a technique to get proper graphics out of vector computations that consider all 4 channels equally. You multiply color of all pixels by their alpha, so that fainter pixels are also darker. Then during blending you can take 100% color from the pixel being rendered and directly add it to the target color. Normally you'd need to multiply pixel by it's alpha (as is on alpha blending) to blend it right, but this step have already been done. If you use it on alpha-less canvas, result is identical. But on canvas with alpha, you blend in less alpha from the pixel than it really had, producing color artifacts. With no need to multiply alpha by itself (thereby reducing its value) you blend in right amount of it, eliminating said artifacts.
Normal screen doesn't have this problem because it doesn't have alpha channel.
Re: Canvases and Text
Posted: Tue Jan 31, 2017 7:57 pm
by Rubix
Thanks so much for the replies!
Re: Canvases and Text
Posted: Tue Jan 31, 2017 9:27 pm
by slime
Alternatively, draw to your Canvas as normal with regular blending, and then draw the Canvas to the screen with premultiplied alpha blending (love.graphics.setBlendMode("alpha", "premultiplied")).
This is demonstrated on the wiki:
https://love2d.org/wiki/Canvas#Examples
Re: Canvases and Text
Posted: Tue Jan 31, 2017 9:54 pm
by raidho36
Didn't know that you could do that in reverse, cool!