Garry's Mod Wiki

Revision Difference

render.SetStencilWriteMask#561571

<function name="SetStencilWriteMask" parent="render" type="libraryfunc"> <description> Sets the unsigned 8-bit write bitflag mask that will be bitwise ANDed with any value that is written to the Stencil Buffer.⤶ Sets the unsigned 8-bit (`byte`) bitflag mask that will be bitwise ANDed with all values as they are written to the Stencil Buffer⤶ ⤶ This can be considered a "niche" Stencil function as it is not required for many Stencil use-cases.⤶ ⤶ This is a companion function to <page>render.SetStencilTestMask</page> which modifies Stencil Buffer values as they are read.⤶ For more detailed information on the Stencil system, including usage examples, see the <page text="Stencils Render Reference">render_stencils</page> page </description> <realm>Client and Menu</realm> <args> <arg name="mask" type="number">The mask bitflag.</arg>⤶ <arg name="bitMask" type="number">⤶ The 8-bit (`byte`) mask ⤶ Set to `255` to make no change to written Stencil Buffer values.⤶ </arg>⤶ </args> </function> ⤶ <example>⤶ <description>A brief demonstration of masks (from ⤶ [Lex's Stencil Tutorial](https://github.com/Lexicality/stencil-tutorial)).</description>⤶ <code>⤶ hook.Add( "PostDrawOpaqueRenderables", "Stencil Tutorial Example", function()⤶ --[[⤶ To understand this tutorial you need to already understand the basics⤶ of binary and bitwise operations.⤶ ⤶ It would also help to understand hexadecimal notation, since Lua⤶ doesn't have a bitmask input, but I will include binary notation in⤶ comments to help.⤶ --]]⤶ ⤶ -- Reset everything to known good⤶ render.SetStencilWriteMask( 0xFF )⤶ render.SetStencilTestMask( 0xFF )⤶ render.SetStencilReferenceValue( 0 )⤶ render.SetStencilCompareFunction( STENCIL_ALWAYS )⤶ render.SetStencilPassOperation( STENCIL_KEEP )⤶ render.SetStencilFailOperation( STENCIL_KEEP )⤶ render.SetStencilZFailOperation( STENCIL_KEEP )⤶ render.ClearStencil()⤶ ⤶ -- Enable stencils⤶ render.SetStencilEnable( true )⤶ -- Force everything to fail⤶ render.SetStencilCompareFunction( STENCIL_NEVER )⤶ -- Save all the things we don't draw⤶ render.SetStencilFailOperation( STENCIL_REPLACE )⤶ ⤶ -- Set the reference value to 00011100⤶ render.SetStencilReferenceValue( 0x1C )⤶ -- Set the write mask to 01010101⤶ -- Any writes to the stencil buffer will be bitwise ANDed with this mask.⤶ -- With our current reference value, the result will be 00010100.⤶ render.SetStencilWriteMask( 0x55 )⤶ ⤶ -- Fail to draw our entities.⤶ for _, ent in ipairs( ents.FindByClass( "prop_physics" ) ) do⤶ ent:DrawModel()⤶ end⤶ ⤶ -- Set the test mask to 11110011.⤶ -- Any time a pixel is read out of the stencil buffer it will be bitwise ANDed with this mask.⤶ render.SetStencilTestMask( 0xF3 )⤶ -- Set the reference value to 00011100 & 01010101 & 11110011⤶ render.SetStencilReferenceValue( 0x10 )⤶ -- Pass if the masked buffer value matches the unmasked reference value⤶ render.SetStencilCompareFunction( STENCIL_EQUAL )⤶ ⤶ -- Draw our entities⤶ render.ClearBuffersObeyStencil( 0, 148, 133, 255, false )⤶ ⤶ -- Let everything render normally again⤶ render.SetStencilEnable( false )⤶ end )⤶ </code>⤶ ⤶ </example>⤶ ⤶ ⤶ <example>⤶ <description>A somewhat more complicated mask example (from ⤶ [Lex's Stencil Tutorial](https://github.com/Lexicality/stencil-tutorial)).</description>⤶ <code>⤶ hook.Add( "PostDrawOpaqueRenderables", "Stencil Tutorial Example", function()⤶ --[[⤶ To understand this tutorial you need to already understand the basics⤶ of binary and bitwise operations.⤶ ⤶ It would also help to understand hexadecimal notation, since Lua⤶ doesn't have a bitmask input, but I will include binary notation in⤶ comments to help.⤶ --]]⤶ ⤶ -- Reset everything to known good⤶ render.SetStencilWriteMask( 0xFF )⤶ render.SetStencilTestMask( 0xFF )⤶ render.SetStencilReferenceValue( 0 )⤶ render.SetStencilCompareFunction( STENCIL_ALWAYS )⤶ render.SetStencilPassOperation( STENCIL_KEEP )⤶ render.SetStencilFailOperation( STENCIL_KEEP )⤶ render.SetStencilZFailOperation( STENCIL_KEEP )⤶ render.ClearStencil()⤶ ⤶ -- Enable stencils⤶ render.SetStencilEnable( true )⤶ ⤶ -- Only write to the upper 4 bits of the stencil buffer⤶ render.SetStencilWriteMask( 0xF0 )⤶ -- Wipe the stencil buffer to be 0001111. This is not affected by the write mask.⤶ render.ClearStencilBufferRectangle( 0, 0, ScrW(), ScrH(), 0x0F )⤶ ⤶ -- Always fail⤶ render.SetStencilCompareFunction( STENCIL_NEVER )⤶ -- Don't read any bits from the stencil buffer⤶ render.SetStencilTestMask( 0x00 )⤶ -- When an operation fails, read the current value from the stencil buffer, add⤶ -- one to it and then write it back to the buffer⤶ -- This is not affected by the test mask, but it is affected by the write mask⤶ -- This means we will read 00001111, then write 00010000.⤶ -- However, due to the write mask, this won't affect the last four bits already⤶ -- in the buffer, resulting in 00011111.⤶ render.SetStencilFailOperation( STENCIL_INCR )⤶ ⤶ -- Add something interesting to the stencil buffer⤶ for _, ent in ipairs( ents.FindByClass( "prop_physics" ) ) do⤶ ent:DrawModel()⤶ end⤶ ⤶ -- Go back to reading the full value from the stencil buffer⤶ render.SetStencilTestMask( 0xFF )⤶ -- Set the reference value to 00011111⤶ render.SetStencilReferenceValue( 0x1F )⤶ -- Render the result⤶ render.SetStencilCompareFunction( STENCIL_EQUAL )⤶ render.ClearBuffersObeyStencil( 0, 148, 133, 255, false )⤶ ⤶ -- Let everything render normally again⤶ render.SetStencilEnable( false )⤶ end )⤶ </code>⤶ </example>