[SOLVED] Help with LCD Shader

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
User avatar
alberto_lara
Party member
Posts: 372
Joined: Wed Oct 30, 2013 8:59 pm

[SOLVED] Help with LCD Shader

Post by alberto_lara »

I tried to create a shader that does the same as in the image (this is from OnionOS for the Miyoo mini)

Image

Zoomed:

Image


For what I understand, this shader/filter takes the current pixel, separates R, G and B and puts them into A, B and C (respectively), like this, creating a 3x3 "virtual" pixel:

Code: Select all

|        |        |        |
|    A   |    B   |        |
|        |        |        |
----------------------------
|        |        |        |
|    A   |    B   |    C   |
|        |        |        |
----------------------------
|        |        |        |
|        |        |    C   |
|        |        |        |
----------------------------
Is that right? if so, the problem is that I suck at GLSL and have no idea of where to even start to create a shader that does this. Any help would be appreciated, thanks!
Last edited by alberto_lara on Sun Oct 30, 2022 5:05 pm, edited 1 time in total.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Help with LCD Shader

Post by ReFreezed »

Something like this:

Code: Select all

function love.load()
	image = love.graphics.newImage("game.png")
	image:setFilter("nearest")

	shader = love.graphics.newShader[[
		uniform vec2 imageSize;

		vec4 effect(vec4 loveColor, Image tex, vec2 uv, vec2 screenPos) {
			vec2 uvPx = uv * imageSize; // Get position in pixels.
			vec2 f    = fract(uvPx); // Get fractional position for determining the subpixel.

			vec4 pixel = Texel(tex, uv);

			if      (f.x < 1/3.)  return (f.y < 2/3.) ? vec4(pixel.r,0,0,1) : vec4(0,0,0,1); // Red subpixel.
			else if (f.x < 2/3.)  return (f.y < 2/3.) ? vec4(0,pixel.g,0,1) : vec4(0,0,0,1); // Green subpixel.
			else                  return (f.y > 1/3.) ? vec4(0,0,pixel.b,1) : vec4(0,0,0,1); // Blue subpixel.
		}
	]]
	shader:send("imageSize", {image:getDimensions()})
end

function love.draw()
	love.graphics.setShader(shader)
	love.graphics.draw(image, 0,0, 0, 3) -- The scale must be a multiple of three for the subpixels to have the same size.
end
Basically, the shader detects what pixel and subpixel it's currently rendering and returns the correct color component for that pixel (or black for the unlit areas).
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
alberto_lara
Party member
Posts: 372
Joined: Wed Oct 30, 2013 8:59 pm

Re: Help with LCD Shader

Post by alberto_lara »

That did the trick, thanks!
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot], Majestic-12 [Bot], slime and 8 guests