Difference between revisions of "Tutorial:Introduction to Shaders"

m (vec4 color = ... throws an error about redefining "color". Changed variable name to "c".)
(fixed an error in the example code)
Line 8: Line 8:
 
function love.draw()
 
function love.draw()
 
     love.graphics.setShader(shader)
 
     love.graphics.setShader(shader)
     love.graphics.rectangle(0, 0, 100, 100)
+
     love.graphics.rectangle("fill", 0, 0, 100, 100)
 
     love.graphics.setShader()
 
     love.graphics.setShader()
 
end
 
end

Revision as of 21:02, 6 June 2014

This is a simple and basic tutorial explaining the basics of shaders. Here is a small example:

function love.load()
    shader = love.graphics.newShader("shader.fs")
end

function love.draw()
    love.graphics.setShader(shader)
    love.graphics.rectangle("fill", 0, 0, 100, 100)
    love.graphics.setShader()
end

The most important thing to remember when writing your shader is that the entry point is not the same as in pure GL. It's modified in LOVE.

vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )

So instead of setting gl_FragCoord, you'd return the vec4 for the pixel color. Your texture coordinates are supplied for you, as well as the current texture, the system-wide current color setting, and the screen coordinate position of the current pixel. In pure GL, you'd supply your own uniform values for that stuff.

You can also send data to the shader in the form of uniform variables, like I mentioned above:

shader:send(name, value[s])

The value can be a number or a table of numbers for a vec2/3/4. Or more numbers for a matrix. Full list here.

If you're looking for a big repository of shaders already written for LOVE, you're out of luck as far as I know. There is, however, a "share a shader" thread. That's the closest you can get right now.

If you don't know how shaders work, you can think of them as a small program that the graphics processor runs for each pixel. When you draw a rectangle, OpenGL transforms those coordinates into pixels on the screen (rasterization) and then runs those pixels through your shader. It's a very fast and efficient way to make modifications to images on the fly, and modern photorealistic or otherwise graphics would be nearly impossible (extremely impractical) without them.

The effect function in your shader returns a vec4 that represents the color you want to choose for the current pixel. There are a many functions built-in for math and for reading from textures. Here's a sample effect that'd simply draw a black and white texture.

vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
{
    vec4 c = Texel(texture, texture_coords); // This reads a color from our texture at the coordinates LOVE gave us (0-1, 0-1)
    return vec4(vec3(1.0, 1.0, 1.0) * (max(c.r, max(c.g, c.b))), 1.0); // This just returns a white color that's modulated by the brightest color channel at the given pixel in the texture. Nothing too complex, and not exactly the prettiest way to do B&W :P
}

-- Source: [1]

See Also

Other Languages