This is an image of the effect:
The purpose of the shader applied to the walls is to allow the special effect to work only on certain objects (walls), just in case I wanted some walls to completely obstruct the view.
Both shaders are fairly simple, they react to light (multiple lights as well), however, they don't cast shadows.
The walls shader simply uses a stencil buffer, like so:
Pass
{
Stencil
{
Ref 4
Comp always
Pass replace
}
// rest of the code for rendering
}
This lets the gpu know the all the pixels used to draw the object with this shader are given the value 4 in the stencil buffer.
Then, we have the character shader. I wrote two draw calls: one that renders the character normally and the other that renders a single color, which is the white color we see when the character is behind the wall.
The first pass goes like this:
Pass
{
Tags{"Queue" = "Geometry" "RenderType"="Opaque"}
ZWrite off
ZTest Always
Blend One OneMinusSrcAlpha
Stencil
{
Ref 4
Comp equal
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
// apply fog
return _MaskedColor;
}
}
This always draws a white color (or whatever color the variable _MaskedColor is set to) for each pixel of the character model. Notice how the fragment function simply returns a color
(_MaskedColor) which, in our case, is white. It is possible change the color in the inspector of the material.
(_MaskedColor) which, in our case, is white. It is possible change the color in the inspector of the material.
The second pass:
Pass
{
Tags{"LightMode" = "ForwardBase"}
ZWrite on
ZTest LEqual
{
Tags{"LightMode" = "ForwardBase"}
ZWrite on
ZTest LEqual
// rest of the code for texture and lighting rendering
}
Basically, the gpu will render the texture and lighting color whenever the object is in front of other object (ZTest LEqual), overriding the white color of the previous pass.
No comments:
Post a Comment