Garry's Mod Wiki

Revision Difference

render.SetStencilWriteMask#528611

<function name="SetStencilWriteMask" parent="render" type="libraryfunc"> <description>Sets the unsigned 8-bit write bitflag mask to be used for any writes to the stencil buffer.</description> <realm>Client</realm> <args> <arg name="mask" type="number">The mask bitflag.</arg> </args> </function> <example> <description>A brief demonstration of masks</description>⤶ <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.SetStencilWriteMask( 0xFF ) render.SetStencilTestMask( 0xFF ) render.SetStencilReferenceValue( 0 ) -- render.SetStencilCompareFunction( STENCIL_ALWAYS ) render.SetStencilCompareFunction( STENCIL_ALWAYS ) render.SetStencilPassOperation( STENCIL_KEEP ) -- render.SetStencilFailOperation( 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( "sent_stencil_test" ) ) do 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 ); 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</description>⤶ <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.SetStencilWriteMask( 0xFF ) render.SetStencilTestMask( 0xFF ) render.SetStencilReferenceValue( 0 ) -- render.SetStencilCompareFunction( STENCIL_ALWAYS ) render.SetStencilCompareFunction( STENCIL_ALWAYS ) render.SetStencilPassOperation( STENCIL_KEEP ) -- render.SetStencilFailOperation( 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( "sent_stencil_test" ) ) do for _, ent in ipairs( ents.FindByClass( "prop_physics" ) ) do ent:DrawModel() end ⤶ ⤶ -- Go back to reading the full value from the stencil buffer⤶ ⤶ -- 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 ); render.ClearBuffersObeyStencil( 0, 148, 133, 255, false ) -- Let everything render normally again render.SetStencilEnable( false ) end ) </code> ⤶ </example></example>