Shader problem: spliting image into rgb.

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
jangsy5
Prole
Posts: 3
Joined: Tue Apr 15, 2014 6:35 am

Shader problem: spliting image into rgb.

Post by jangsy5 »

Code: Select all

local default = [[	
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {

	vec4 tc = Texel(texture, texture_coords);
	number shift = 0.1f;
	vec4 r = Texel(texture, vec2(tc.x + shift, tc.y - shift));
	vec4 g = Texel(texture, vec2(tc.x, tc.y + shift));
	vec4 b = Texel(texture, vec2(tc.x - shift, tc.y - shift));
	number a = r.a*g.a*b.a / 3.0f;

	return vec4(r.r, g.g, b.b, a);
}
]]

function love.load()
	
	shader = love.graphics.newShader(default)

end

function love.draw()
	
	love.graphics.setShader(shader)
	love.graphics.printf("TestingTestingTestingTestingTesting", 100,100,500,'left')
	love.graphics.rectangle('fill', 400,400, 50,50)
	love.graphics.setShader()

end
I'm total noob at shaders as you can see. I was looking into chromatic aberration and wanted to see if I could write one up. I shamelessly copied a snippit of code from this forum but didn't work out too well. I was wondering what the problem was. So I started doing shader tests myself. And the code above is what I wrote up. Unfortunately it doesn't seem to split the image into r/g/b as I wanted to something similar to chromatic aberration effect. All I get is a grey square and no text. Am I missing something? Did I do the algorithm for the shader wrong and/or just how I coded the draw method?



***Edit: I just fixed it somewhat. Futher problem is that the square isn't splitting as it should. Also the text are just in boxes.

Code: Select all

local default = [[	
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {

	vec2 tc = texture_coords;
	vec2 scale = vec2(1.0/800.0, 1.0/600.0);
	number shift = 5.0;
	vec4 r = Texel(texture, vec2(tc.x + shift * scale.x, tc.y - shift * scale.y));
	vec4 g = Texel(texture, vec2(tc.x, tc.y + shift*scale.y));
	vec4 b = Texel(texture, vec2(tc.x - shift*scale.x, tc.y - shift*scale.y));
	//number a = r.a*g.a*b.a / 3.0;

	return vec4(r.r, g.g, b.b, 1.0);
}
]]

function love.load()
	
	shader = love.graphics.newShader(default)

end

function love.draw()
	
	love.graphics.setShader(shader)
	love.graphics.printf("TestingTestingTestingTestingTesting", 100,100,500,'left')
	love.graphics.rectangle('fill', 400,400, 50,50)
	love.graphics.setShader()

end


***Edit: Just fixed the text not appearing, I just averaged the alpha of the sampled r/g/b from around the current pixel. It does look somewhat nice, probably should just set it to the highest alpha out of the alpha returns. I also haven't fixed the box though. Maybe I need to put it into a canvas?

Code: Select all

local default = [[	
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {

	vec2 tc = texture_coords;
	vec2 scale = vec2(1.0/800.0, 1.0/600.0);
	number shift = 2.0;
	vec4 r = Texel(texture, vec2(tc.x + shift * scale.x, tc.y - shift * scale.y));
	vec4 g = Texel(texture, vec2(tc.x, tc.y + shift*scale.y));
	vec4 b = Texel(texture, vec2(tc.x - shift*scale.x, tc.y - shift*scale.y));
	number a = r.a+g.a+b.a / 3.0;

	return vec4(r.r, g.g, b.b, a);
}
]]

function love.load()
	
	shader = love.graphics.newShader(default)

end

function love.draw()
	
	love.graphics.setShader(shader)
	love.graphics.printf("TestingTestingTestingTestingTesting", 100,100,500,'left')
	love.graphics.rectangle('fill', 400,400, 50,50)
	love.graphics.setShader()

end
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Shader problem: spliting image into rgb.

Post by Ref »

Is this really what you're trying to do?
Attachments
ColorSplitShader.love
Draw to canvas, then apply shader
(14.34 KiB) Downloaded 140 times
jangsy5
Prole
Posts: 3
Joined: Tue Apr 15, 2014 6:35 am

Re: Shader problem: spliting image into rgb.

Post by jangsy5 »

Oh wow thank you. That is indeed what I was looking for! And from what I can understand a canvas was set up. Would I need to set up a canvas every time a new image or an image in the canvas moves?


***EDIT, I've done a bit of work on canvases and I thought trying to set canvases in the draw loop would be expensive enough to have an impact on performance but it isn't for me. Probably because so few are being drawn. Maybe if there were many things to draw on canvas could cause issues.

Code: Select all

local default = [[	
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {

	vec2 tc = texture_coords;
	vec2 scale = vec2(1.0/800.0, 1.0/600.0);
	number shift = 0.5;
	vec4 r = Texel(texture, vec2(tc.x + shift * scale.x, tc.y - shift * scale.y));
	vec4 g = Texel(texture, vec2(tc.x + shift * scale.x, tc.y + shift*scale.y));
	vec4 b = Texel(texture, vec2(tc.x - shift * scale.x, tc.y - shift*scale.y));
	//number a = max(r.a,g.a);
	//a = max(a,b.a);
	number a = r.a+b.a+g.a / 3.0;

	return vec4(r.r, g.g, b.b, a);
}
]]

local shift = 0
local dx = 100
local fps = 0

function love.load()
	
	font = love.graphics.newFont(32)
	font18 = love.graphics.newFont(18)
	shader = love.graphics.newShader(default)
	canvas = love.graphics.newCanvas()

end

function love.update(dt)

	if shift > 800 then
		shift = -50
	end
	
	shift = shift + dx * dt
	fps = love.timer.getFPS()

end

function love.draw()
	
	love.graphics.setFont(font)
	
	love.graphics.setCanvas(canvas)
		canvas:clear()
		love.graphics.printf("TestingTestingTestingTestingTesting", 100,100,500,'left')
		love.graphics.rectangle('fill', 0 + shift,400, 50,50)
	love.graphics.setCanvas()
	
	love.graphics.setFont(font18)
	love.graphics.setCanvas(canvas)
		love.graphics.printf(string.format("FPS: %.2f", fps),5,5,150,'left')
	love.graphics.setCanvas()
	
	love.graphics.setShader(shader)
	love.graphics.draw(canvas)
	love.graphics.setShader()

end
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Shader problem: spliting image into rgb.

Post by Ref »

I would be more concerned with recreating the shader every frame than with redrawing the canvas. Could limit the size of the canvas to minimize traffic to the GPU (only an uneducated guess).
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 8 guests