Page 11 of 33
Re: Share a Shader!
Posted: Mon Jul 09, 2012 7:49 am
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
Re: Share a Shader!
Posted: Mon Jul 09, 2012 3:17 pm
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.
Re: Share a Shader!
Posted: Mon Jul 09, 2012 4:01 pm
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:
- It makes the image opaque (alpha = 1).
- 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);
}]]
Re: Share a Shader!
Posted: Mon Jul 09, 2012 9:00 pm
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.
Re: Share a Shader!
Posted: Wed Jul 25, 2012 3:49 pm
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.
Re: Share a Shader!
Posted: Tue Jul 31, 2012 10:41 am
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.
Re: Share a Shader!
Posted: Tue Jul 31, 2012 6:10 pm
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.
Re: Share a Shader!
Posted: Wed Aug 01, 2012 1:06 am
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.
Re: Share a Shader!
Posted: Wed Aug 01, 2012 3:38 pm
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.
Re: Share a Shader!
Posted: Thu Aug 02, 2012 1:26 am
by Ref
Just another boring shader.