Share a 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.
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Share a Shader!

Post by vrld »

Ref wrote:Anybody create a Sobel (edge detection) PixelEffect
Untested:

Code: Select all

effect = love.graphics.newPixelEffect[[
extern vec2 pixel_size;

vec4 effect(vec4 color, Image tex, vec2 tc, vec2 pixel_coords)
{
    color = vec4(0.0);
    // the kernel
    color += 1. * Texel(tex, tc + vec2(-1./pixel_size.x, -pixel_size.y));
    color += 2. * Texel(tex, tc + vec2(0, -pixel_size.y));
    color += 1. *Texel(tex, tc + vec2(pixel_size.x, -pixel_size.y));
    color += -1. * Texel(tex, tc + vec2(-pixel_size.x, pixel_size.y));
    color += -2. * Texel(tex, tc + vec2(0, pixel_size.y));
    color += -1. *Texel(tex, tc + vec2(pixel_size.x, pixel_size.y));

    return color;
}]]
effect:send('pixel_size', {1/love.graphics.getWidth(), 1/love.graphics.getHeight()})
You can implement any convolution using this code, e.g. simple blur:

Code: Select all

1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Thanks vrid for sobel effect!
Made a minor change to effect to avoid white screen of oblivion.
Changed color = vec4(0.0); to color = vec4(1.0);
Worked.
Don't appreciate why first color change was:
color += 1. * Texel(tex, tc + vec2(-1./pixel_size.x, -pixel_size.y));
Didn't see to be consisting with following code so I changed it to:
color += 1. * Texel(tex, tc + vec2(-pixel_size.x, -pixel_size.y));
This also works as far as I can see.
Any reason for difference (really just key punching here)?
Provided a 'Love" file for those who would like to see what a Sobel effect is.
Attachments
sobel.love
Sobel Effect - Edge Detection
(99.25 KiB) Downloaded 501 times
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Share a Shader!

Post by vrld »

Oh, I totally forgot about the alpha value. Since the kernel (with an e) sums to 0 and the alpha value is consistent over the image, the alpha value will be \(1 + 2 + 1 - 1 - 2 - 1 = 0\).
You should get the correct result using

Code: Select all

return vec4(color.rgb * 0.5 + vec3(0.5), 1.0);
This does two things:
  1. It makes the image opaque (alpha = 1).
  2. It "normalizes" the image, so that you can see negative and positive edges (color.rgb*0.5 + vec3(0.5)).
Initializing the color with white is possible, but will return a technically incorrect result.

Btw: to get the "full" sobel operator, apply it horizontally and vertically (just rotate the kernel about 90 degree):

Code: Select all

kernel = love.graphics.newPixelEffect[[
extern vec2 pixel_size;

vec4 effect(vec4 color, Image tex, vec2 tc, vec2 pixel_coords)
{
    vec4 vert = vec4(0.0);
    // the kernel
    vert +=  1. * Texel(tex, tc + vec2(-pixel_size.x, -pixel_size.y));
    vert +=  2. * Texel(tex, tc + vec2( 0, -pixel_size.y));
    vert +=  1. * Texel(tex, tc + vec2( pixel_size.x, -pixel_size.y));
    vert += -1. * Texel(tex, tc + vec2(-pixel_size.x, pixel_size.y));
    vert += -2. * Texel(tex, tc + vec2( 0, pixel_size.y));
    vert += -1. * Texel(tex, tc + vec2(pixel_size.x, pixel_size.y));

    vec4 horiz = vec4(0.0);
    horiz +=  1. * Texel(tex, tc + vec2(-pixel_size.x,  pixel_size.y));
    horiz +=  2. * Texel(tex, tc + vec2(-pixel_size.x, 0));
    horiz +=  1. * Texel(tex, tc + vec2(-pixel_size.x, -pixel_size.y));
    horiz += -1. * Texel(tex, tc + vec2( pixel_size.x,  pixel_size.y));
    horiz += -2. * Texel(tex, tc + vec2( pixel_size.x,  0));
    horiz += -1. * Texel(tex, tc + vec2( pixel_size.x, -pixel_size.y));

    return vec4((horiz+vert).rgb * .5 + vec3(.5), 1.0);
}]]
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Ah! Ha!
Thought there was something not quite right.
Thanks vrid for the update.
Made some minor changes to the effect (always messing around).

Code: Select all

kernal = love.graphics.newPixelEffect[[
    extern vec2 pixel_size;
    extern mat3x3 ker;
    int ix = -1;
    int iy = -1;
    vec4 effect(vec4 color, Image tex, vec2 tc, vec2 pixel_coords)
    {
    vec4 vert  = vec4(0.0);
    vec4 horiz = vec4(0.0);
    for( int j = 0; j < 3; j++ ){
        for( int i = 0; i < 3 ; i++ ){
            vert  +=  ker[j][i] * Texel(tex, tc + vec2(ix*pixel_size.x, iy*pixel_size.y));
            horiz +=  ker[j][i] * Texel(tex, tc + vec2(ix*pixel_size.x, iy*pixel_size.y));
            ix = ix + 1;
            }
        iy = iy + 1;
        ix = -1;
        }
   return vec4((horiz+vert).rgb * .5 + vec3(.5), 1.0);
    } ]]
This allows me to pass a 3x3 kernal directly to the effect via:

Code: Select all

ker={
    {{1, 2,  1}, {0, 0, 0}, {-1, -2, -1}},	-- Sobel
    {{-1,-1,-1},{-1,8,-1},{-1,-1,-1}},	-- Laplacian8
    {{1/9,1/9,1/9},{1/9,1/9,1/9},{1/9,1/9,1/9}}, -- blur
    {{-2,0,0},{0,0,0},{0,2,0}},		-- gradian
    }
kernal:send( 'ker', ker[sel] )
Would apprectate it if you look and see if there isn't a better way as I really don't have a good grasp of GLSL.
Attachments
kernal.love
Pixel effects created using kernals
(99.51 KiB) Downloaded 411 times
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Just another (not to complicated) shader.
Thought it might be useful for a lead-in screen to a game (if you had a more inspired image with a transparent background.)
Edit: title2.love is essentially the same as title_screen.love with keyboard control over effect - so you can see if there is a combination of interest. I didn't put any constraints on the keyboard entries and left it to you to find out which one really gives a strange effect. Have fun.
Attachments
title2.love
caution: uses canvases
(26.45 KiB) Downloaded 429 times
title_page.love
simple shader
(25.02 KiB) Downloaded 559 times
User avatar
dreadkillz
Party member
Posts: 223
Joined: Sun Mar 04, 2012 2:04 pm
Location: USA

Re: Share a Shader!

Post by dreadkillz »

Shader utilizing grayscale images as transitions. Can be used to do scene transitions ala RPG Maker style. Use your own gradient grayscale for cool transitions!

Code: Select all

function love.load()
	lg = love.graphics
	li = love.image
	lf = love.filesystem
	w,h = lg.getWidth(),lg.getHeight()
	
	transitions = lf.enumerate('transitions')
	
	transIndex = 1
	transition = lg.newImage('transitions/' .. transitions[transIndex])
	
	image = lg.newImage('test.jpg')	
	
	effect = lg.newPixelEffect [[
		extern Image trans;
		extern number time;
		extern number duration;
		vec4 effect(vec4 color,Image tex,vec2 tc,vec2 pc)
		{
			vec4 img_color = Texel(tex,tc);
			vec4 trans_color = Texel(trans,tc);
			number white_level	= (trans_color.r + trans_color.b + trans_color.b)/3;
			number max_white	= time/duration;
			
			if (white_level <= max_white)
			{
				return img_color;
			}
			
			img_color.a = 0;
			return img_color;
		}
	]]
	
	t = 0
	duration = 1
	effect:send("duration",duration)
	effect:send("trans",transition)
	
	canvas = lg.newCanvas(lg.getWidth(),lg.getHeight())
	canvas:renderTo(function() lg.draw(image) end)
end
function love.update(dt)
	t = t + dt
	effect:send("time",t)
end

function love.keypressed(key)
	if key == 'r' then
		t = 0
	end
	
	if key == 'left' or key == 'right' then
		if key == 'left' then
			if transIndex >=2 then
				transIndex = transIndex - 1
			end
		elseif key == 'right' then
			if transIndex <= #transitions-1 then
				transIndex = transIndex + 1
			end
		end
		transition = lg.newImage('transitions/' .. transitions[transIndex])
		effect:send("trans",transition)
		t = 0
	end
end

function love.draw()
	lg.setPixelEffect(effect)
	lg.draw(image)
	lg.setPixelEffect()
	lg.print(love.timer.getFPS(),lg.getWidth()-30,10)
	lg.print(transitions[transIndex],10,10)
end
Left or right arrow to change transitions. R to reload transition.

EDIT: Fixed, Thanks Ref
EDIT2: My initial idea came from this, and I used to play around with RPG Maker XP and wanted to implement their transition systems in LOVE.
Attachments
transitions.love
(384.82 KiB) Downloaded 472 times
Last edited by dreadkillz on Thu Aug 02, 2012 10:11 am, edited 5 times in total.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Ohps!
drearkilz, the Love errors.
Problem is extraneous ';' at end of effect.

Code: Select all

canv_color.a = 0;
return canv_color;
};    // unneeded semicolon
]]
should be

Code: Select all

canv_color.a = 0;
return canv_color;
}    // no semicolon
]]
Then all's well.
Nice shader.
Last edited by Ref on Tue Jul 31, 2012 9:24 pm, edited 1 time in total.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Hi dreadkillz!
I'm sure mickeyim will catch this is a prime example of where you don't need canvases.
You can remove all references to canvas and do gr.draw( image ) to get the effect you want.
Thanks again for the shader.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

fasilkj wrote:I can't understand this code.Can someone explain me.please
Hi fasikj!
In case you haven't figured it out, what dreadkillz is doing is useing a 2nd (B&W) image as a filter.
He selects a brightness level (time/duration) and the shader replaces any pixel in the 2nd image who's brightness is less than the selected brightness with a pixel from the 1st image. As a function of time, the selected brightness is increases (t = t + dt) and more of the 1st image is revealed.
Dreadkillz doesn't say whether he's a genius or just a good hacker of someone else's shader.
Fun to play with.
Attached is a slightly modified version of dreadkillz's shader which transitions from a B&W image to a colored image.
Note: This doesn't use canvases but I'm not sure whether canvas impaired systems can do pixelEffects.
Attachments
colorize.love
changes B&W image to color
(1.06 MiB) Downloaded 427 times
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Just another boring shader.
Attachments
inverse.love
very simple color altering shader
(2.2 MiB) Downloaded 405 times
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 3 guests