Difference between revisions of "love.graphics.stencil"

m
(Updated for the latest API changes)
Line 1: Line 1:
 
{{newin|[[0.10.0]]|100|type=function|text=Together with [[love.graphics.setStencilTest]], it has replaced [[love.graphics.setStencil]]}}
 
{{newin|[[0.10.0]]|100|type=function|text=Together with [[love.graphics.setStencilTest]], it has replaced [[love.graphics.setStencil]]}}
Draws geometry to the stencil buffer.
+
Draws geometry as a stencil.
  
The passed function draws to the (invisible) stencil buffer instead of the regular screen. The stencil buffer acts like a mask or stencil – the geometry of everything drawn to the stencil buffer determines whether pixels in the buffer are 'enabled' or not. When the [[love.graphics.setStencilTest|Stencil Test]] is enabled after [[love.graphics.stencil]] is used, everything drawn after that point will clipped / stencilled out based on whether it intersects what has been drawn to the stencil buffer.
+
The geometry drawn by the supplied function sets the invisible stencil values of pixels, instead of setting pixel colors. The stencil values of pixels can act like a mask / stencil - [[love.graphics.setStencilTest]] can be used afterward to determine how further rendering is affected by the stencil values in each pixel.
  
Each [[Canvas]] has its own stencil buffer.
+
Each [[Canvas]] has its own per-pixel stencil values. Stencil values are within the range of [0, 255].
 
== Function ==
 
== Function ==
 
=== Synopsis ===
 
=== Synopsis ===
 
<source lang="lua">
 
<source lang="lua">
love.graphics.stencil( stencilfunction, keepbuffer )
+
love.graphics.stencil( stencilfunction, action, value, keepvalues )
 
</source>
 
</source>
 
=== Arguments ===
 
=== Arguments ===
{{param|function|stencilfunction|Function which draws the stencil geometry to the stencil buffer.}}
+
{{param|function|stencilfunction|Function which draws geometry. The stencil values of pixels, rather than the color of each pixel, will be affected by the geometry.}}
{{param|boolean|keepbuffer (false)|Whether to preserve the previous contents of the stencil buffer. Note that [[love.graphics.clear]] will also clear the stencil buffer.}}
+
{{param|StencilAction|action ("replace")|How to modify any stencil values of pixels that are touched by what's drawn in the stencil function.}}
 +
{{param|number|value (1)|The new stencil value to use for pixels if the "replace" stencil action is used. Must be between 0 and 255.}}
 +
{{param|boolean|keepvalues (false)|True to preserve old stencil values of pixels, false to re-set every pixel's stencil value to 0 before executing the stencil function. [[love.graphics.clear]] will also re-set all stencil values.}}
 
=== Returns ===
 
=== Returns ===
 
Nothing.
 
Nothing.
 +
 
== Examples ==
 
== Examples ==
 
=== Drawing circles masked by a rectangle ===
 
=== Drawing circles masked by a rectangle ===
Line 23: Line 26:
  
 
function love.draw()
 
function love.draw()
     -- draw a rectangle to the stencil buffer
+
     -- draw a rectangle as a stencil. Each pixel touched by the rectangle will have its stencil value set to 1. The rest will be 0.
     love.graphics.stencil(myStencilFunction)
+
     love.graphics.stencil(myStencilFunction, "replace", 1)
  
    -- enable testing against the contents of the stencil buffer
+
  -- Only allow rendering on pixels which have a stencil value greater than 0.
     love.graphics.setStencilTest(true)
+
     love.graphics.setStencilTest("greater", 0)
  
 
     love.graphics.setColor(255, 0, 0, 120)
 
     love.graphics.setColor(255, 0, 0, 120)
Line 38: Line 41:
 
     love.graphics.circle("fill", 400, 400, 150, 50)
 
     love.graphics.circle("fill", 400, 400, 150, 50)
  
     love.graphics.setStencilTest(false)
+
     love.graphics.setStencilTest()
 
end
 
end
 
</source>
 
</source>
Line 63: Line 66:
  
 
function love.draw()
 
function love.draw()
     love.graphics.stencil(myStencilFunction)
+
     love.graphics.stencil(myStencilFunction, "replace", 1)
     love.graphics.setStencilTest(true)
+
     love.graphics.setStencilTest("greater", 0)
 
     love.graphics.rectangle("fill", 0, 0, 256, 256)
 
     love.graphics.rectangle("fill", 0, 0, 256, 256)
     love.graphics.setStencilTest(false)
+
     love.graphics.setStencilTest()
 
end
 
end
 
</source>
 
</source>
Line 76: Line 79:
 
* [[love.graphics.clear]]
 
* [[love.graphics.clear]]
 
[[Category:Functions]]
 
[[Category:Functions]]
{{#set:Description=Draws geometry to the stencil buffer.}}
+
{{#set:Description=Draws geometry as a stencil.}}
{{#set:Sub-Category=State}}
+
{{#set:Sub-Category=Drawing}}
 
== Other Languages ==
 
== Other Languages ==
 
{{i18n|love.graphics.stencil}}
 
{{i18n|love.graphics.stencil}}

Revision as of 03:52, 15 December 2015

Available since LÖVE 0.10.0
Together with love.graphics.setStencilTest, it has replaced love.graphics.setStencil.

Draws geometry as a stencil.

The geometry drawn by the supplied function sets the invisible stencil values of pixels, instead of setting pixel colors. The stencil values of pixels can act like a mask / stencil - love.graphics.setStencilTest can be used afterward to determine how further rendering is affected by the stencil values in each pixel.

Each Canvas has its own per-pixel stencil values. Stencil values are within the range of [0, 255].

Function

Synopsis

love.graphics.stencil( stencilfunction, action, value, keepvalues )

Arguments

function stencilfunction
Function which draws geometry. The stencil values of pixels, rather than the color of each pixel, will be affected by the geometry.
StencilAction action ("replace")
How to modify any stencil values of pixels that are touched by what's drawn in the stencil function.
number value (1)
The new stencil value to use for pixels if the "replace" stencil action is used. Must be between 0 and 255.
boolean keepvalues (false)
True to preserve old stencil values of pixels, false to re-set every pixel's stencil value to 0 before executing the stencil function. love.graphics.clear will also re-set all stencil values.

Returns

Nothing.

Examples

Drawing circles masked by a rectangle

local function myStencilFunction()
   love.graphics.rectangle("fill", 225, 200, 350, 300)
end

function love.draw()
    -- draw a rectangle as a stencil. Each pixel touched by the rectangle will have its stencil value set to 1. The rest will be 0.
    love.graphics.stencil(myStencilFunction, "replace", 1)

   -- Only allow rendering on pixels which have a stencil value greater than 0.
    love.graphics.setStencilTest("greater", 0)

    love.graphics.setColor(255, 0, 0, 120)
    love.graphics.circle("fill", 300, 300, 150, 50)

    love.graphics.setColor(0, 255, 0, 120)
    love.graphics.circle("fill", 500, 300, 150, 50)

    love.graphics.setColor(0, 0, 255, 120)
    love.graphics.circle("fill", 400, 400, 150, 50)

    love.graphics.setStencilTest()
end

Using an Image as a stencil mask

-- a black/white mask image: black pixels will mask, white pixels will pass.
local mask = love.graphics.newImage("mymask.png")

local mask_shader = love.graphics.newShader[[
   vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) {
      if (Texel(texture, texture_coords).rgb == vec3(0.0)) {
         // a discarded pixel wont be applied as the stencil.
         discard;
      }
      return vec4(1.0);
   }
]]

local function myStencilFunction()
   love.graphics.setShader(mask_shader)
   love.graphics.draw(mask, 0, 0)
   love.graphics.setShader()
end

function love.draw()
    love.graphics.stencil(myStencilFunction, "replace", 1)
    love.graphics.setStencilTest("greater", 0)
    love.graphics.rectangle("fill", 0, 0, 256, 256)
    love.graphics.setStencilTest()
end

The love.graphics.setStencilTest wiki page includes more examples.

See Also


Other Languages