Canvases and Text

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Rubix
Prole
Posts: 5
Joined: Mon Jan 30, 2017 10:12 pm
Location: Arizona, United States

Canvases and Text

Post 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
Capture.PNG (2.58 KiB) Viewed 5118 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:
CanvasText.love
(410.14 KiB) Downloaded 161 times
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.
Last edited by Rubix on Tue Jan 31, 2017 6:13 pm, edited 1 time in total.
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Canvases and Text

Post 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.

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Canvases and Text

Post 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.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Canvases and Text

Post 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
Screen Shot 2017-01-31 at 2.39.31 PM.png (7.05 KiB) Viewed 5092 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.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Canvases and Text

Post 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.
Last edited by raidho36 on Tue Jan 31, 2017 7:57 pm, edited 1 time in total.
Rubix
Prole
Posts: 5
Joined: Mon Jan 30, 2017 10:12 pm
Location: Arizona, United States

Re: Canvases and Text

Post by Rubix »

Thanks so much for the replies!
User avatar
slime
Solid Snayke
Posts: 3133
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Canvases and Text

Post 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
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Canvases and Text

Post by raidho36 »

Didn't know that you could do that in reverse, cool!
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 61 guests