Difference between revisions of "love.graphics.newShader"

(Created page)
 
m (Edited example)
Line 24: Line 24:
 
=== Arguments ===
 
=== Arguments ===
 
{{param|string|pixelcode|The pixel shader code, or a filename pointing to a file with the code.}}
 
{{param|string|pixelcode|The pixel shader code, or a filename pointing to a file with the code.}}
{{param|string|pixelcode|The vertex shader code, or a filename pointing to a file with the code.}}
+
{{param|string|vertexcode|The vertex shader code, or a filename pointing to a file with the code.}}
 
=== Returns ===
 
=== Returns ===
 
{{param|Shader|shader|A Shader object for use in drawing operations.}}
 
{{param|Shader|shader|A Shader object for use in drawing operations.}}
Line 71: Line 71:
  
 
Pixel shader code is run for every pixel on the screen that a drawn object touches, and is used to produce the color that will be blended onto the screen at that pixel, often by reading from an image. Pixel shaders are sometimes called fragment shaders.
 
Pixel shader code is run for every pixel on the screen that a drawn object touches, and is used to produce the color that will be blended onto the screen at that pixel, often by reading from an image. Pixel shaders are sometimes called fragment shaders.
 +
 +
The <code>varying</code> keyword can be used to set a value in the vertex shader and have it interpolated in between vertices and passed down to the pixel shader.
 +
 +
Vertex and Pixel shader code can be combined into one file or string if you wrap the vertex-specific code in <code>#ifdef VERTEX .. #endif</code> and the pixel-specific code in <code>#ifdef PIXEL .. #endif</code>.
  
 
== Examples ==
 
== Examples ==
 
Create a shader using vertex and pixel shader code which behaves as if no shader is set.
 
Create a shader using vertex and pixel shader code which behaves as if no shader is set.
=== pixel shader code: ===
 
<source lang="glsl">
 
vec4 effect( vec4 color, Image texture vec2 texture_coords, vec2 screen_coords )
 
{
 
    vec4 texcolor = Texel(texture, texture_coords);
 
    return texcolor * color;
 
}</source>
 
=== vertex shader code: ===
 
<source lang="glsl">
 
vec4 position( mat4 mvp_matrix, vec4 vertex_position )
 
{
 
    return mvp_matrix * vertex_position;
 
}
 
</source>
 
=== lua code: ===
 
 
<source lang="lua">
 
<source lang="lua">
 
function love.load()
 
function love.load()
 +
    local pixelcode = [[
 +
        vec4 effect(vec4 color, Image texture vec2 texture_coords, vec2 screen_coords)
 +
        {
 +
            vec4 texcolor = Texel(texture, texture_coords);
 +
            return texcolor * color;
 +
        }
 +
    ]]
 +
 +
    local vertexcode = [[
 +
        vec4 position( mat4 mvp_matrix, vec4 vertex_position )
 +
        {
 +
            return mvp_matrix * vertex_position;
 +
        }
 +
    ]]
 +
 
     shader = love.graphics.newShader(pixelcode, vertexcode)
 
     shader = love.graphics.newShader(pixelcode, vertexcode)
 
end
 
end
Line 100: Line 104:
 
     -- draw more things
 
     -- draw more things
 
end
 
end
 +
</source>
 +
 +
 +
Access the pre-transformed vertex position in the pixel shader with the <code>varying</code> keyword.
 +
=== vertex shader code ===
 +
<source lang="glsl">
 +
varying vec4 vpos;
 +
 +
vec4 position( mat4 mvp_matrix, vec4 vertex_position )
 +
{
 +
    vpos = vertex_position;
 +
    return mvp_matrix * vertex_position;
 +
}
 +
</source>
 +
=== pixel shader code ===
 +
<source lang="glsl">
 +
varying vec4 vpos;
 +
 +
vec4 effect(vec4 color, Image texture vec2 texture_coords, vec2 screen_coords)
 +
{
 +
    vec4 texcolor = Texel(texture, texture_coords + vpos.xy);
 +
    return texcolor * color;
 +
}
 +
</source>
 +
 +
 +
Combine the above example into one string or file with the help of <code>#ifdef</code>.
 +
<source lang="glsl">
 +
varying vec4 vpos;
 +
 +
#ifdef VERTEX
 +
vec4 position( mat4 mvp_matrix, vec4 vertex_position )
 +
{
 +
    vpos = vertex_position;
 +
    return mvp_matrix * vertex_position;
 +
}
 +
#endif
 +
 +
#ifdef PIXEL
 +
vec4 effect(vec4 color, Image texture vec2 texture_coords, vec2 screen_coords)
 +
{
 +
    vec4 texcolor = Texel(texture, texture_coords + vpos.xy);
 +
    return texcolor * color;
 +
}
 +
#endif
 
</source>
 
</source>
  

Revision as of 06:21, 15 August 2013

Available since LÖVE 0.9.0
It has been renamed from love.graphics.newPixelEffect.

Creates a new Shader object for hardware-accelerated vertex and pixel effects. A Shader contains either vertex shader code, pixel shader code, or both.

Vertex shader code must contain at least one function, named position, which is the function that will produce transformed vertex positions of drawn objects in screen-space.

Pixel shader code must contain at least one function, named effect, which is the function that will produce the color which is blended onto the screen for each pixel a drawn object touches.

Function

Synopsis

shader = love.graphics.newShader( code )

Arguments

string code
The pixel shader or vertex shader code, or a filename pointing to a file with the code.

Returns

Shader shader
A Shader object for use in drawing operations.

Function

With this variant, the pixelcode and vertexcode arguments can be in any order.

Synopsis

shader = love.graphics.newShader( pixelcode, vertexcode )

Arguments

string pixelcode
The pixel shader code, or a filename pointing to a file with the code.
string vertexcode
The vertex shader code, or a filename pointing to a file with the code.

Returns

Shader shader
A Shader object for use in drawing operations.

Shader Language

Shaders are not programmed in Lua, but by using a special shader language instead. The shader language is basically GLSL 1.20 (specs) with a few aliases added for existing types:

GLSL LÖVE shader language
float number
sampler2D Image
uniform extern
texture2D(tex, uv) Texel(tex, uv)

Pixel Shader Function

Synopsis

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

Arguments

vec4 color
The drawing color set with love.graphics.setColor or the per-vertex Geometry color.
Image texture
The texture of the image or canvas being drawn.
vec2 texture_coords
Coordinates of the pixel relative to the texture. The y-axis of canvases are inverted. Coordinates (1,1) would be the top right corner of the canvas.
vec2 screen_coords
Coordinates of the pixel on the screen. Pixel coordinates are not normalized (unlike texture coordinates)

Returns

vec4 output_color
The color of the pixel.

Vertex Shader Function

Synopsis

vec4 position( mat4 mvp_matrix, vec4 vertex_position )

Arguments

mat4 mvp_matrix
The transformation matrix affected by love.graphics.translate and friends combined with the orthographic projection matrix.
vec4 vertex_position
The raw un-transformed position of the current vertex.

Returns

vec4 output_pos
The final transformed position of the current vertex.

Notes

Vertex shader code is run for every vertex drawn to the screen (for example, love.graphics.rectangle will produce 4 vertices) and is used to transform the vertex positions from their original coordinates into screen-space, as well as to send information such as per-vertex color and texture coordinate values to the pixel shader.

Pixel shader code is run for every pixel on the screen that a drawn object touches, and is used to produce the color that will be blended onto the screen at that pixel, often by reading from an image. Pixel shaders are sometimes called fragment shaders.

The varying keyword can be used to set a value in the vertex shader and have it interpolated in between vertices and passed down to the pixel shader.

Vertex and Pixel shader code can be combined into one file or string if you wrap the vertex-specific code in #ifdef VERTEX .. #endif and the pixel-specific code in #ifdef PIXEL .. #endif.

Examples

Create a shader using vertex and pixel shader code which behaves as if no shader is set.

function love.load()
    local pixelcode = [[
        vec4 effect(vec4 color, Image texture vec2 texture_coords, vec2 screen_coords)
        {
            vec4 texcolor = Texel(texture, texture_coords);
            return texcolor * color;
        }
    ]]

    local vertexcode = [[
        vec4 position( mat4 mvp_matrix, vec4 vertex_position )
        {
            return mvp_matrix * vertex_position;
        }
    ]]

    shader = love.graphics.newShader(pixelcode, vertexcode)
end

function love.draw()
    love.graphics.setShader(shader)
    -- draw things
    love.graphics.setShader()
    -- draw more things
end


Access the pre-transformed vertex position in the pixel shader with the varying keyword.

vertex shader code

varying vec4 vpos;

vec4 position( mat4 mvp_matrix, vec4 vertex_position )
{
    vpos = vertex_position;
    return mvp_matrix * vertex_position;
}

pixel shader code

varying vec4 vpos;

vec4 effect(vec4 color, Image texture vec2 texture_coords, vec2 screen_coords)
{
    vec4 texcolor = Texel(texture, texture_coords + vpos.xy);
    return texcolor * color;
}


Combine the above example into one string or file with the help of #ifdef.

varying vec4 vpos;

#ifdef VERTEX
vec4 position( mat4 mvp_matrix, vec4 vertex_position )
{
    vpos = vertex_position;
    return mvp_matrix * vertex_position;
}
#endif

#ifdef PIXEL
vec4 effect(vec4 color, Image texture vec2 texture_coords, vec2 screen_coords)
{
    vec4 texcolor = Texel(texture, texture_coords + vpos.xy);
    return texcolor * color;
}
#endif

See Also


Other Languages