I apologize if this thread is a bit large, but I’m just trying to get a grip on stencils, so I’m spitballing as much information as I can to make sure I’m heading in the right direction.
Essentially, I’m trying to recreate this effect but with stencils. The original method physically moves the player’s position under the floor, which could be quite problematic, and if the player spawns on a floor (which is the ceiling for the room below it), their model would be visible from below. As a result, I took to giving a shot at stencils to attempt to recreate this effect, but without actually moving the player’s model. The CalcView and CalcViewModelView hooks are all finished, as well as making the players invisible while the view is still shifting.Now the last step is to get the stencils to render properly, and the part I’m having trouble with.
So I start by enabling the stencil, setting the write and test mask to 255 (to avoid any problems with other stencils screwing with my ones), and I give my stencil a reference value of 1. Next I want to generate a cube with Hell in it (little easter egg so that players who can look down quickly will see), so I start by setting my compare function to STENCIL_ALWAYS and the pass operation to STENCIL_REPLACE, as I want my hole stencil to always replace the pixels that are on the floor of the map with the reference value 1, and I finally draw the hole using a 3D2D cam. Now I want to create a small cube with hell in it, so I set my compare function to STENCIL_EQUAL, as I only want my hell to render INSIDE the hole. Afterwards I render multiple boxes which are all given seperate textures to create a makeshift hell. All is good from here.
Something like this:
[img_thumb]http://www.kyle93.co.uk/i/b9fd4.png[/img_thumb]
Now this is the part where I’m kind of lost. Essentially, I want to render a model of the player’s model, crawling it’s way out of hell, but to only be visible both outside and inside my hole. I don’t want the model to be visible below the floor where the player spawns, but at the same time be visible inside the hole. I can’t seem to get both of these conditions to work together. Essentially, something like this:
[img_thumb]http://www.kyle93.co.uk/i/a25cb.png[/img_thumb]
Any ideas? Getting this to work with multiple conditions seems to be still a mystery to me.
Here’s the code I have so far. I am drawing the stencil on top of the sawblade model for testing purposes
[lua]
/-----------------------------------------------------
Custom render.Model func
-----------------------------------------------------/
function render.ModelCustom( mdl, pos, ang, animation, animationspeed, scale )
local ent = ClientsideModel( mdl, RENDERGROUP_OTHER )
if ( !IsValid( ent ) ) then return end
ent:SetModel( mdl )
ent:SetNoDraw( true )
ent:SetPos( pos )
ent:SetAngles( ang )
ent:ResetSequence( ent:LookupSequence( animation ) )
ent:SetModelScale(scale)
ent:SetCycle( (CurTime()-math.floor(CurTime()))*animationspeed )
ent:DrawModel()
ent:Remove()
end
/-----------------------------------------------------
Stencil
-----------------------------------------------------/
local comp = 1
local pass = 1
local fail = 1
local zfail = 1
hook.Add( “PostDrawOpaqueRenderables”, “SpookyPlayerSpawningStencils”, function()
for k, v in pairs( ents.GetAll() ) do
if v:GetModel() == "models/props_junk/sawblade001a.mdl" then//if v:GetNWFloat("DoSpawnAnim") > CurTime() then
local angle = Angle(0, 0, 0)
local scale = 48
local pos = v:GetPos()-Vector(scale/2,-scale/2,0)
render.SetStencilEnable( true )
render.SetStencilWriteMask( 255 )
render.SetStencilTestMask( 255 )
/*-----------------------------------------------------
Make the hole
-----------------------------------------------------*/
render.SetStencilReferenceValue( 1 )
render.SetStencilCompareFunction( STENCIL_ALWAYS )
render.SetStencilPassOperation( STENCIL_REPLACE )
cam.Start3D2D( pos, angle, scale )
surface.SetDrawColor( Color( 0, 0, 0, 255 ) )
surface.DrawRect( 0, 0, 1, 1 )
cam.End3D2D()
/*-----------------------------------------------------
Draw Hell
-----------------------------------------------------*/
render.SetStencilCompareFunction( STENCIL_EQUAL )
cam.IgnoreZ( true )
render.SetMaterial(Material("models/misc/cube_left.png"))
render.DrawBox( pos,angle,Vector(-1,-scale,-scale),Vector(0,0,0),Color(255,255,255,255),true)
render.SetMaterial(Material("models/misc/cube_right.png"))
render.DrawBox( pos,angle,Vector(scale,-scale,-scale),Vector(scale+1,0,0),Color(255,255,255,255),true)
render.SetMaterial(Material("models/misc/cube_center.png"))
render.DrawBox( pos,angle,Vector(0,0,-scale),Vector(scale,1,0),Color(255,255,255,255),true)
render.SetMaterial(Material("models/misc/cube_back.png"))
render.DrawBox( pos,angle,Vector(0,-scale-1,-scale),Vector(scale,-scale,0),Color(255,255,255,255),true)
render.SetMaterial(Material("models/misc/cube_bot.png"))
render.DrawBox( pos,angle,Vector(0,-scale,-scale),Vector(scale,0,-scale+1),Color(255,255,255,255),true)
cam.IgnoreZ( false )
/*-----------------------------------------------------
Draw player crawling out of hell
-----------------------------------------------------*/
render.SetStencilCompareFunction( STENCIL_GREATEREQUAL )
render.SetStencilPassOperation( STENCIL_REPLACE )
render.SetStencilFailOperation( STENCIL_DECR )
render.SetStencilZFailOperation( STENCIL_ZERO )
//if GetViewEntity() != LocalPlayer() then // Don't draw the model for the player spawning.
render.ModelCustom("models/Kleiner.mdl",pos+Vector(scale/2,-scale/2,-25),angle,"ragdoll",1, 1)
//end
render.SetStencilEnable( false )
end
end
end )
[/lua]
I’m certain it has something to do with the increment functions but I’m just not quite putting my finger on it.
This code is ALMOST there but it doesn’t render the model if it’s too close to the floor(image 3) and it also leaves some gaps in the model due to the rendering of the hole(image 2). It also creates some weird artifacts if I put my mouse looking at where the hole is supposed to be(image 4).
[lua]
render.SetStencilCompareFunction( STENCIL_GREATEREQUAL )
render.SetStencilPassOperation( STENCIL_REPLACE )
render.SetStencilFailOperation( STENCIL_DECR )
render.SetStencilZFailOperation( STENCIL_ZERO )
[/lua]