I tried to create a shader that does the same as in the image (this is from OnionOS for the Miyoo mini)
Zoomed:
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:
| | | |
| 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.
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).