This might sounds newbie description, but I don’t know if this is just the shader thing.
Ok, I have an player and a wall, when the player is in front of the wall, it’s just regular shading. And when the player goes behind the wall, the ghost shape of the player is projected on the wall. I saw this effect in couple of games, the latest one is Torchlight.
Just curious if anybody knows how this can be achieved by shader. thanks.
thank you very much. Another newbie question, is this supposed to be applied to the wall, right ? And how do I make the switch from show-through to no show-through? I actually just start to read the shaderlib manual.
That shader goes on things that you want to appear through walls. The trick is that it has two Pass blocks, one of which uses ZTest LEqual to only draw in front of things, and one which uses ZTest Greater to only draw when it is behind things. Thus for every pixel, the model will be drawn using one pass or the other, but never both. The Queue = Geometry+5 tag makes sure that objects with this shader wait until everything else is drawn so that they can decide whether they are behind or in front of something.
Thanks Daniel, I just tested, it works perfect, when the object under shader is behind something, it’s plotted using a blue color. Awesome. I’m sure this shader can turn into other kool stuff as well.
Daniel, that’s really cool. Thanks for giving me ideas!
Do you have any method to turn objects transparent only when certain meshes go behind them? (e.g. the player character)? I really like this effect in games. Seems like a much more complicated situation, but I’ve seen it a lot, so perhaps there is a common solution?
You mean turning a wall transparent when it blocks the camera’s view of the player? That can be done with a script that casts a ray at the player and modifies the materials of whatever it hits. I believe there was a script in the Goober demo from way back when that did that. I’m not sure if there’s an equivalent script in the Lerpz tutorial.
I figured that was how it needed to be done. But I hadn’t thought of what you posted in this thread, so I didn’t know if there was some shader trick I didn’t know about, to “automate” this.
I’m new to unity and trying to use this code but I keep getting and error on the first lane saying ‘Shader’ unexpected symbol. Any tips on how to fix this? or am I just creating the shader wrong?
I’m trying to use this shader for an object lit by light probes and the model appears black. Does anyone know how to integrate light probe info into this?
If you want to use the shader on 2nd reply for many (semi-) transparent models in the same scene (eg a party of characters going behind a wall at the same time) keep in mind that you are going to run into drawing order problems, since the render queue used is opaque and Unity sorts front-to-back by default in these queues.
For correct transparency, apart from a suitable blend mode, you also need to use a back-to-front sorting render queue (eg Transparent). But if you try to do this with a separate transparent material, the triangles on the back of your model will mess everything up since they will always render because they will pass the “ZTest Greater” depth test (they are occluded by the geometry of the same mesh in front of them).
A solution to this situation is to use stencils: have a stencil-only pre-pass in your opaque shader and “flag” the pixels that will need to be transparent:
Pass {
ZWrite Off //we MUST NOT write to depth buffer (else below passes will also render)!
ZTest Greater //depth test will succeed when geometry is occluded
ColorMask 0 //do not write anything on screen!
Stencil
{
Ref 1 //value that will be written to stencil buffer
Comp Always //stencil test will always succeed
Pass Replace //if depth test succeeds write ref value
}
}
When your transparent material renders later on, perform a stencil test against the same reference value:
Pass
{
ZTest Greater //we still need this as depth test will always happen after stencil test
ZWrite Off //do not write anything to z-buffer (else geometry behind ours won't render)
Blend SrcAlpha OneMinusSrcAlpha //classic transparency blend mode
Stencil
{
Ref 1
Comp Equal //if stencil buffer for this pixel equals our flag value then stencil test succeeds
Pass Keep //do not do anything if depth + stencil tests succeeds (stencil buffer will be cleared anyway next frame)
}
CGPROGRAM
//your shader here
ENDCG
}