Difference between revisions of "love.graphics.stencil"
m |
(Updated for 11.0) |
||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | {{newin|[[0.10.0]]|100|type=function|text= | + | {{newin|[[0.10.0]]|100|type=function|text=Together with [[love.graphics.setStencilTest]], it has replaced [[love.graphics.setStencil]]}} |
− | Draws geometry | + | Draws geometry as a stencil. |
− | The | + | The geometry drawn by the supplied function sets invisible stencil values of pixels, instead of setting pixel colors. The stencil buffer (which contains those stencil values) 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. |
− | + | Stencil values are integers within the range of [0, 255]. | |
+ | |||
+ | |||
+ | {{notice|1=Starting with version [[11.0]], a stencil buffer must be set or requested in [[love.graphics.setCanvas]] when using stencils with a Canvas. <code>love.graphics.setCanvas{canvas, stencil=true}</code> is an easy way to use an automatically provided temporary stencil buffer in that case.}} | ||
== Function == | == Function == | ||
=== Synopsis === | === Synopsis === | ||
<source lang="lua"> | <source lang="lua"> | ||
− | love.graphics.stencil( stencilfunction, | + | love.graphics.stencil( stencilfunction, action, value, keepvalues ) |
</source> | </source> | ||
=== Arguments === | === Arguments === | ||
− | {{param|function|stencilfunction|Function which draws the stencil | + | {{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| | + | {{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. Has no effect with other stencil actions. 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. | ||
+ | |||
+ | == Notes == | ||
+ | It is possible to draw to the screen and to the stencil values of pixels at the same time, by using [[love.graphics.setColorMask]] inside the stencil function to enable drawing to all color components. | ||
+ | |||
== Examples == | == Examples == | ||
=== Drawing circles masked by a rectangle === | === Drawing circles masked by a rectangle === | ||
Line 23: | Line 33: | ||
function love.draw() | function love.draw() | ||
− | -- draw a rectangle | + | -- 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) |
− | + | -- Only allow rendering on pixels which have a stencil value greater than 0. | |
− | love.graphics.setStencilTest( | + | love.graphics.setStencilTest("greater", 0) |
− | love.graphics.setColor( | + | love.graphics.setColor(1, 0, 0, 0.45) |
love.graphics.circle("fill", 300, 300, 150, 50) | love.graphics.circle("fill", 300, 300, 150, 50) | ||
− | love.graphics.setColor(0, | + | love.graphics.setColor(0, 1, 0, 0.45) |
love.graphics.circle("fill", 500, 300, 150, 50) | love.graphics.circle("fill", 500, 300, 150, 50) | ||
− | love.graphics.setColor(0, 0, | + | love.graphics.setColor(0, 0, 1, 0.45) |
love.graphics.circle("fill", 400, 400, 150, 50) | love.graphics.circle("fill", 400, 400, 150, 50) | ||
− | love.graphics.setStencilTest( | + | love.graphics.setStencilTest() |
end | end | ||
</source> | </source> | ||
Line 63: | Line 73: | ||
function love.draw() | function love.draw() | ||
− | love.graphics.stencil(myStencilFunction) | + | love.graphics.stencil(myStencilFunction, "replace", 1) |
− | love.graphics.setStencilTest( | + | love.graphics.setStencilTest("greater", 0) |
love.graphics.rectangle("fill", 0, 0, 256, 256) | love.graphics.rectangle("fill", 0, 0, 256, 256) | ||
− | love.graphics.setStencilTest( | + | love.graphics.setStencilTest() |
+ | end | ||
+ | </source> | ||
+ | === Allow drawing everywhere except where multiple circles intersect === | ||
+ | <source lang="lua"> | ||
+ | local function myStencilFunction() | ||
+ | -- Draw four overlapping circles as a stencil. | ||
+ | love.graphics.circle("fill", 200, 250, 100) | ||
+ | love.graphics.circle("fill", 300, 250, 100) | ||
+ | love.graphics.circle("fill", 250, 200, 100) | ||
+ | love.graphics.circle("fill", 250, 300, 100) | ||
+ | end | ||
+ | |||
+ | function love.draw() | ||
+ | -- Each pixel touched by each circle will have its stencil value incremented by 1. | ||
+ | -- The stencil values for pixels where the circles overlap will be at least 2. | ||
+ | love.graphics.stencil(myStencilFunction, "increment") | ||
+ | |||
+ | -- Only allow drawing in areas which have stencil values that are less than 2. | ||
+ | love.graphics.setStencilTest("less", 2) | ||
+ | |||
+ | -- Draw a big rectangle. | ||
+ | love.graphics.rectangle("fill", 0, 0, 500, 500) | ||
+ | |||
+ | love.graphics.setStencilTest() | ||
end | end | ||
</source> | </source> | ||
The [[love.graphics.setStencilTest]] wiki page includes more examples. | The [[love.graphics.setStencilTest]] wiki page includes more examples. | ||
+ | |||
== See Also == | == See Also == | ||
* [[parent::love.graphics]] | * [[parent::love.graphics]] | ||
Line 76: | Line 111: | ||
* [[love.graphics.clear]] | * [[love.graphics.clear]] | ||
[[Category:Functions]] | [[Category:Functions]] | ||
− | {{#set:Description=Draws geometry | + | {{#set:Description=Draws geometry as a stencil.}} |
− | {{#set:Sub-Category= | + | {{#set:Sub-Category=Drawing}} |
== Other Languages == | == Other Languages == | ||
{{i18n|love.graphics.stencil}} | {{i18n|love.graphics.stencil}} |
Latest revision as of 00:07, 4 April 2018
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 invisible stencil values of pixels, instead of setting pixel colors. The stencil buffer (which contains those stencil values) 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.
Stencil values are integers within the range of [0, 255].
Starting with version 11.0, a stencil buffer must be set or requested in love.graphics.setCanvas when using stencils with a Canvas. love.graphics.setCanvas{canvas, stencil=true} is an easy way to use an automatically provided temporary stencil buffer in that case.
|
Contents
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. Has no effect with other stencil actions. 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.
Notes
It is possible to draw to the screen and to the stencil values of pixels at the same time, by using love.graphics.setColorMask inside the stencil function to enable drawing to all color components.
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(1, 0, 0, 0.45)
love.graphics.circle("fill", 300, 300, 150, 50)
love.graphics.setColor(0, 1, 0, 0.45)
love.graphics.circle("fill", 500, 300, 150, 50)
love.graphics.setColor(0, 0, 1, 0.45)
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
Allow drawing everywhere except where multiple circles intersect
local function myStencilFunction()
-- Draw four overlapping circles as a stencil.
love.graphics.circle("fill", 200, 250, 100)
love.graphics.circle("fill", 300, 250, 100)
love.graphics.circle("fill", 250, 200, 100)
love.graphics.circle("fill", 250, 300, 100)
end
function love.draw()
-- Each pixel touched by each circle will have its stencil value incremented by 1.
-- The stencil values for pixels where the circles overlap will be at least 2.
love.graphics.stencil(myStencilFunction, "increment")
-- Only allow drawing in areas which have stencil values that are less than 2.
love.graphics.setStencilTest("less", 2)
-- Draw a big rectangle.
love.graphics.rectangle("fill", 0, 0, 500, 500)
love.graphics.setStencilTest()
end
The love.graphics.setStencilTest wiki page includes more examples.
See Also
Other Languages
Dansk –
Deutsch –
English –
Español –
Français –
Indonesia –
Italiano –
Lietuviškai –
Magyar –
Nederlands –
Polski –
Português –
Română –
Slovenský –
Suomi –
Svenska –
Türkçe –
Česky –
Ελληνικά –
Български –
Русский –
Српски –
Українська –
עברית –
ไทย –
日本語 –
正體中文 –
简体中文 –
Tiếng Việt –
한국어
More info