ZTesting to get one object to always show on top of another?

I have some eyes that are inside of the head object (sphere) which would normally be obstructed. I want the eyes to be rendered after the head so they appear on top. The eyes should then be in normal flow so they are behind any other objects that are closer.

I’m still pretty clueless when it comes to shaderlab. What I’ve played with so far is the ZTest parameter along with render queues. Render queues from my understanding won’t work because the eyes don’t pass the depth check.

So then I played with the ZTest parameter in the shader. I made a copy of the Transparent/Diffuse shader and tried all of the available ZTest options. ZTest Greater essentially does what I need, but it then obviously renders on top of everything as shown:

Is it possible to get the Eyes to always render in front of the head object only? Is there a better way to do this?

Thanks for any advice.

You’re almost there, but you need renderqueues too. First render the head, then the eyes (using ZTest Always) and finally everything else.

Ah! I was scared to move the eyes out of the Transparent render queue (because they transparent), but I went ahead and put them in the geometry queue and et Voila!

Head = Geometry - 20
Eyes = Geometry - 10

Thanks again Daniel.

Ok, so I’ve always had a problem with this solution, now it’s about time that I get it sorted.

The render queues worked to get the eyes to show on top of the face, but the problem is that the eyes show on top of ANY face.

Here is an image to illustrate.

Even though the second and third heads are behind the first, the eyes render on top. Is it possible to have the eyes obscured by faces that are closer to the camera even though the eyes have a higher render queue? In fact, the eyes render on top of the terrain.

I have a sneaking suspicion that it has to do with ZTest, but I’ve tried different ZTest values from the reference manual but haven’t found a solution yet.

Here are the relevant parts of the shaders.

Face:

Shader "Toon/Lighted-20" {
	Properties {
		...
	}

	SubShader {
		Tags { "Queue"="Geometry-20" "RenderType"="Opaque" }

Eyes:

Shader "Transparent/Nolighting-10" {
Properties {
	...
}

SubShader {
	Tags {"Queue"="Geometry-10" "IgnoreProjector"="True" "RenderType"="Transparent"}
	ZTest Always

So I finally took the time to dig in and learn more about shaders and now I see that what I want to do is probably not possible because the eyes are simply in a higher render queue. I did however find a solution that works in the context of my game which involves putting different characters in different queues so the overlap is never visible.

What would be very helpful is to be able to set a variable that I could use to add to the Queue (+10 or -12 etc…) as needed without having to write a new shader every time I need something in a different queue. Is something like that possible?

What I think you’ll want to use is the offset.

Offset allows you to make an object render closer or further away from the camera, without it actually moving and changing shape.

One problem is it can mess up deferred rendering because it relies on the depth buffer, but as your eyes are black I doubt that would matter.

Another thing you could try is using a projector to project the face onto the sphere, and then parent it to the sphere. That way if you look at the face side on it will curve around the face realistically. Make sure to adjust the near and far planes so it only projects onto the sphere another nothing else.