#Stencils for Portal Location Indicators

1 messages · Page 1 of 1 (latest)

dim gull
#
-- Render portal ghost
if not PortalRendering.Rendering then
    render.SetStencilWriteMask( 255 )
    render.SetStencilTestMask( 255 )
    render.SetStencilReferenceValue( 0 )
    render.SetStencilCompareFunction( STENCIL_ALWAYS )
    render.SetStencilPassOperation( STENCIL_KEEP )
    render.SetStencilFailOperation( STENCIL_KEEP )
    render.SetStencilZFailOperation( STENCIL_KEEP )
    render.ClearStencil() -- Set the Stencil Value to 0 for all pixels

    render.SetStencilEnable( true )

    render.SetStencilReferenceValue( 0 )
    render.SetStencilCompareFunction( STENCIL_ALWAYS )
    render.SetStencilZFailOperation( STENCIL_REPLACE )

    render.SetMaterial(dummyBlue)
    render.OverrideColorWriteEnable(true, false)
    cam.PushModelMatrix(self.RENDER_MATRIX)
        renderMesh:Draw()
    cam.PopModelMatrix()    
    render.OverrideColorWriteEnable(false, false)

    render.SetStencilCompareFunction(STENCIL_EQUAL)

    cam.PushModelMatrix(self.RENDER_MATRIX)
        renderMesh:Draw()
    cam.PopModelMatrix()

    render.SetStencilEnable(false)
end
balmy peak
#

no matter what I do
It either render or don't render completely

dim gull
#

Let's "walk" through the code step by step and see where the issue/confusion is

#

Do you understand that each pixel in the Render Target has color, alpha, stencil, and depth values?

balmy peak
#

yeah

dim gull
#

Great!

#

When you call render.ClearStencil(), the Stencil Value for all pixels becomes 0. The color, alpha, and depth channels are all unchanged.

#

Do you understand what the Stencil Reference Value is and what its purpose is?

balmy peak
#

i think kinda
like it's something that used in comparison and do various logic depending on it

dim gull
#

Let's make sure you understand 100%

#

Your explanation sounds like you have the right idea in mind

#

While the Stencil system is enabled, each pixel affected by a Draw Operation undergoes an identical logical flow

#

This is the flow, starting from the top

balmy peak
#

yes, i saw it in wiki

inner spear
#

(they made it, it is very helpful)

dim gull
#

The Reference Value is used in the "Did this pixel pass the Compare Function" step, which is the first check each pixel undergoes

#

The pixel's current Stencil Value is compared against the Reference Value. If the relationship between pixel's Stencil Value and the Reference Value matches the relationship currently configured in the Compare Function (Greater than, less than, equal to, etc.) then that pixel continues down the "Yes" path to "Is this pixel's depth less than the draw operation's depth?" whereas if they do not match, the pixel continues down the "No" path to "Perform Fail Operation"

dim gull
balmy peak
#

in terms of flow and general logic yes

dim gull
#

In what way(s) does it not make sense?

#

Are you unsure of its practical application?

balmy peak
#

i mean

  • current stencil value is previous modified stencil value or after render.ClearStencil()?

but anyway I need to understand that on practical example
like play with it

dim gull
#

The moment you call render.ClearStencil(), all Stencil Values are 0 for every pixel

#

After that line of code, all Stencil Values are 0

balmy peak
#

during enabled render.SetStencilEnable?

dim gull
#

Yes, but not only during render.SetStencilEnable

#

That setting enables and disables the Stencil system, but it does not modify the Stencil Values

#

You cannot predict what state the Stencil Values will be in when your draw code is called. Some previous addon may have made crazy changes to them, so you must start each Stencil-based draw operation by cleaning up the Stencil Values

#

After you run render.ClearStencil, and all Stencil Values are set to 0, you have the following code:

render.SetStencilReferenceValue( 0 )
render.SetStencilCompareFunction( STENCIL_ALWAYS ) -- Pixels ALWAYS pass the Compare Function and move directly to "Is this pixel's depth less than the draw operation's depth" which is configured by render.SetStencilZFailOperation
render.SetStencilZFailOperation( STENCIL_REPLACE ) -- If a pixel is occluded because it is behind something, REPLACE the pixel's current Stencil Value (All pixels are 0 because of render.ClearStencil) with the currently configured Reference Value (The reference value is 0)
#

Logically, this will always result in every pixel's Stencil Value being 0. Any pixel which fails the Depth Test (StencilZFailOperation) will have its current Stencil Value (0) replaced with the Reference value (Also 0) which results in no change

#

Instead, you should use a Reference Value other than 0 so that those pixels which are occluded will have a different Stencil Value

#

The goal in this step is to ensure that the pixels you want to draw on have a specific, known Stencil Value that differentiates them from the pixels you do not want to draw on

balmy peak
#

so depth value is 8-bit too?

dim gull
#

I believe so. Depth is more difficult to directly interact with than color, alpha, and stencil values

#

You are essentially relying on the built-in depth system to handle determining if a pixel is occluded or visible

#

It's handled on your behalf

balmy peak
#

only what I don't understand is right now
depth here referred as one bit
like fully blocked or fully visible?

#

transparent glass = fully visible
wall = fully blocked

dim gull
#

A pixel is either visible or not visible. That determination is a boolean true/false value. The rendering system uses an 8-bit image called the Depth Buffer to make that true/false determination

#

So the Depth Buffer is 8 bit, but visibility BASED on the Depth Buffer is true/false

balmy peak
#

well, I just need to see it in play and realize it
like always

dim gull
#

That is always the best way to learn

#

I recommend that you create a very, very simple version of a Stencil and play around with that

#

Only after you understand that simple code should you attempt to apply that understanding to your problem

#

Attempting to learn within your addon's logic can be confusing and make learning hard

balmy peak
#

yeah

#

anyway thanks for taking the time to explain this

dim gull
#

No problem. I hope it helps you

#

If you make something be sure to post about it!

balmy peak
#

after playing with stencil values
now it makes sense

#

and cam.IgnoreZ(true) for 2 call

#

only missing is $nocull parameter

inner spear
#

Nice work, stencils are a pain in the ass to understand properly