-- 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
#Stencils for Portal Location Indicators
1 messages · Page 1 of 1 (latest)
no matter what I do
It either render or don't render completely
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?
yeah
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?
i think kinda
like it's something that used in comparison and do various logic depending on it
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
yes, i saw it in wiki
(they made it, it is very helpful)
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"
Does this explanation clarify the Reference Value's purpose at all?
in terms of flow and general logic yes
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
The moment you call render.ClearStencil(), all Stencil Values are 0 for every pixel
After that line of code, all Stencil Values are 0
during enabled render.SetStencilEnable?
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
so depth value is 8-bit too?
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
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
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
well, I just need to see it in play and realize it
like always
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
after playing with stencil values
now it makes sense
and cam.IgnoreZ(true) for 2 call
only missing is $nocull parameter
Nice work, stencils are a pain in the ass to understand properly