Shaders and FBOs

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
The Burrito
Party member
Posts: 153
Joined: Mon Sep 21, 2009 12:14 am
Contact:

Re: Shaders and FBOs

Post by The Burrito »

Well if it can't be made to run on the xbox360 then that would be even less reason to put effort into directX.

With shaders as they are, is there any way to control a shader through lua? like adjusting a value to increase or decrease blur/glow/colour/whatever, or would I have to make seperate shaders and swap and/or combine them?
User avatar
Luiji
Party member
Posts: 396
Joined: Mon May 17, 2010 6:59 pm

Re: Shaders and FBOs

Post by Luiji »

First: The Burrito is the funniest user name I've ever heard.
Second: I don't understand why LOVE being able to run on 360 being a reason not to support Direct3D. Also, the mainstream LOVE cannot be compiled to XBOX 360.
Third: I am making a 360 edition of LOVE, which is a complete rewrite of the engine that runs on XNA.
Good bye.
User avatar
The Burrito
Party member
Posts: 153
Joined: Mon Sep 21, 2009 12:14 am
Contact:

Re: Shaders and FBOs

Post by The Burrito »

Luiji wrote:First: The Burrito is the funniest user name I've ever heard.
Second: I don't understand why LOVE being able to run on 360 being a reason not to support Direct3D. Also, the mainstream LOVE cannot be compiled to XBOX 360.
Third: I am making a 360 edition of LOVE, which is a complete rewrite of the engine that runs on XNA.
1: Thanks. ^^

2: Well what I meant was that if it couldn't run on the 360 anyway, the only remaining reason for DX would be graphic cards that suck at openGL, and thus not something I would consider worth it

3: Thats cool, good luck.
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Shaders and FBOs

Post by vrld »

The Burrito wrote:With shaders as they are, is there any way to control a shader through lua? like adjusting a value to increase or decrease blur/glow/colour/whatever, or would I have to make seperate shaders and swap and/or combine them?
There are so called uniforms, which are a way to send values, vectors, matrices and other stuff to your shader program. With uniforms it is possible to do lighting, specular maps, transformations, and other cool things. I am working on exposing that to love right now. :megagrin:
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
Fruchthieb
Prole
Posts: 20
Joined: Sat Sep 26, 2009 12:04 pm
Location: austria

Re: Shaders and FBOs

Post by Fruchthieb »

Awesome, thank you

Greets
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Shaders and FBOs

Post by vrld »

Added uniforms. The program-Interface got extended:

program:uniform(name, type [, value1, value2, value3, value4])
Shortcut to uniformGet and uniformSet that should be used in any case.

program:uniformGet(name, type)
Get the value of an uniform.
name is the name of the uniform in the shader program. Note that the uniform needs to be active, i.e. used in the program somehow.
type is either "int" or "float", depending on what value type the uniform is. I am no way happy with this parameter. Not sure how to get rid of it though.
Returns: The value of the uniform. Actually, 4 values are returned, but each unused value is set to 0 (if getting the value of a vec2 or float).

program:uniformSet(name, type, value1 [, value2, value3, value4])
Set the value of an uniform. Depending of the type of the uniform, value2 to value4 can be omitted.
name and type are the same as for uniformGet().
Returns: Nothing.


These functions will throw errors if the uniform value is not found or something else went wrong.


Example code of the new interface:
Set blur radius dynaically.

Blur shader (fragment):

Code: Select all

uniform sampler2D tex0;
uniform int size;
uniform vec2 step;

void main(void)
{
    vec4 sample = vec4(0.0);
    vec2 uv = gl_TexCoord[0].st;
    float a = texture2D(tex0, uv).a;
    int hs = size / 2;

    // gaussian blur
    int i, k;
    for (i = -hs; i <= hs; i++) {
        for (k = -hs; k <= hs; k++) {
            sample += texture2D(tex0, uv + vec2( float(i) * step.x, float(k) * step.y ));
        }
    }

    sample /= float(size * size);
    sample.a = a;

    if (sample.r + sample.b + sample.g > 0.0)
        gl_FragColor = sample;
    else
        gl_FragColor = gl_Color;
}
In love:

Code: Select all

-- in love.load()
blur = love.graphics.newProgram()
blur:attachShader(
    love.graphics.newShader('vertex', love.filesystem.read("null.vs"))
    love.graphics.newShader('fragment', love.filesystem.read("blur.fs")))
blur:link()

blursize = 5
blur:uniform('size', 'int', blursize)
blur:uniform('step', 'float', 1 / love.graphics.getWidth(), 1 / love.graphics.getHeight())

--------------------
-- in love.draw()
blur:use()
-- draw stuff
blur:unuse()
-- draw hud

--------------------
-- in love.keypressed(key)
if key == "kp+" then
    blursize = blursize + 1
    blur:uniform('size', 'int', blursize)
elseif key == "kp-" then
    blursize = math.max(blursize  - 1, 1)
    blur:uniform('size', 'int', blursize)
end
print(blur:uniform('size', 'int'))
The new patch is attached to this post.
Attachments
shaders_v1.1.patch.txt
(24.2 KiB) Downloaded 188 times
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
ljdp
Party member
Posts: 209
Joined: Sat Jan 03, 2009 1:04 pm
Contact:

Re: Shaders and FBOs

Post by ljdp »

So how would I make alpha masks with this?
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Shaders and FBOs

Post by vrld »

ljdp wrote:So how would I make alpha masks with this?
You would need a texture (sampler) uniform to hold the alpha information. The fragment shader then looks at the mask and sets the fragments alpha accordingly. The same way you would do bumpmapping and such. The shader could look like this (not tested):

Code: Select all

uniform sampler2D tex0;
uniform sampler2D alphaMask;

void main(void)
{
    vec2 uv = gl_TexCoord[0].st;
    if (texture2D(alphaMask, uv).a > 0)
        gl_FragColor = texture2D(tex0, uv);
    else
        gl_FragColor = vec4(0.0);
}
(not sure if this is what you want. If you want this, you will need an fbo and then check for foreground color there)
However, the patch does not handle sampler uniforms and since it apparently has no chance to be included in 0.7, I did not work on it lately.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
ljdp
Party member
Posts: 209
Joined: Sat Jan 03, 2009 1:04 pm
Contact:

Re: Shaders and FBOs

Post by ljdp »

Hmm, I managed to get the effect I want with glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_ALPHA )

If I render objects into a fbo with the blend mode set to that, then draw the fbo ontop of my scene then only the scene under the objects gets drawn.

Example:
Screen shot 2010-08-08 at 20.30.51.png
Screen shot 2010-08-08 at 20.30.51.png (94.39 KiB) Viewed 4159 times

Code: Select all

-- Initialization
function love.load()
	
	-- Load background picture.
	picture = love.graphics.newImage('picture.png')
	
	-- Load radial gradient image for hole.
	hole = love.graphics.newImage('hole.png')
	
	-- Create 100px size font.
	bigFont = love.graphics.newFont( 100 )
	
	-- Create the fbo object for the hole.
	hole_buffer = love.graphics.newFbo( love.graphics.getWidth(), love.graphics.getHeight() )
end

-- Logic
function love.update(dt)
end

function hole_render()
	local mx, my = love.mouse.getPosition()
	
	-- Set draw vars.
	-- Sets the blend mode to: glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_ALPHA )
	love.graphics.setBlendMode('hole')
	love.graphics.setFont( bigFont )
	love.graphics.setColor( 255, 255, 255, 255 )
	
	-- Draw
	love.graphics.draw( hole, mx, my, 0, 1, 1, 100, 100 )
	love.graphics.print( 'hello world', 100, 300 )
	
	-- Draw frames per second.
	love.graphics.print( love.timer.getFPS(), 100, 20 )
end

-- Scene Drawing
function love.draw()

	-- Render into the hole buffer.
	hole_buffer:render( hole_render )
	
	-- Set draw vars.
	love.graphics.setColor(255,255,255,255)
	
	-- Draw the background picture
	love.graphics.draw( picture, 0, 0 )
	
	-- Draw the hole.
	love.graphics.draw( hole_buffer, 0, 0 )
	
end
Does the fbo have a background layer or something? If i draw an fbo ontop of something the stuff underneath is hidden.
User avatar
nevon
Commander of the Circuloids
Posts: 938
Joined: Thu Feb 14, 2008 8:25 pm
Location: Stockholm, Sweden
Contact:

Re: Shaders and FBOs

Post by nevon »

This so needs to find its way into Löve.
Post Reply

Who is online

Users browsing this forum: No registered users and 165 guests