"ZTest Less Infinity" or equivalent?

Hello,

I have a pretty simple question about the ZTest instruction in ShaderLab. According to the Documentation the only valid parameters are { Less | Greater | LEqual | GEqual | Equal | NotEqual | Always } - however, I found that “Never” also works and leads to the shader never being rendered.

What I’m looking for is a setting that would only render the shader if at the current fragment position nothing has been written to the depth buffer (something like “ZTest Less [some constant]”). Is this possible and if not is there a reason for its absence?

No. Because it’s not supported by hardware.

Render a mesh to the depth buffer only and test against that in later queues.

Alright, good to know.

This sadly won’t work in my scenario, but in this specific case it’s not really an issue and I’ll get over it. I was mainly interested in the details of this limitation, so thanks for clearing this up for me.

How does Unity’s skybox work? It renders after solid geometry for all pixels with “initial” depth.
The only way I can think of would be rendering it at the far clipping plane which would work for a cubemapped skybox, however not for the regular one.

I want to use a skybox for my second render pass where the depth of the first pass should be utilized.

Do you just want to render it behind everything else in the scene? Is this for your sky package?

My “sky” layer uses this:
Zwrite Off
Offset 0, 100000
Blend One One

And “stars” layer uses an offset of 2000000. Not correct obviously but setting it much higher apparently causes problems, as expected.

Is this good practice? I have no idea but it is working. It may not be what you want to do though.

one of the possible tricks (though you will need to setup stuff yourself) is to tweak proj matrix
search google for “eric lengyel infinite projection” (the pdf in question should be among first results)

Haha, I found exactly this paper during my own research. Thanks to Alexey I gave it another go, so here it is - a little script to set up an infinite projection matrix (Rendering is not clipped beyond far plane) - just add script to camera:

using UnityEngine;
using System.Collections;

public class InfiniteProjection : MonoBehaviour {

	void Start () {
	
        float a = 1/camera.aspect;
        float n = camera.nearClipPlane;
		
	//focal length
	float e = 1 / ((Mathf.Tan(camera.fieldOfView*Mathf.Deg2Rad)/2) );
			
	//infinite projection matrix
        Matrix4x4 m = new Matrix4x4();
		
	//1st column
	m[0, 0] = e;
        m[1, 0] = 0;
        m[2, 0] = 0;
        m[3, 0] = 0;
		
	//2nd column
        m[0, 1] = 0;
        m[1, 1] = e/a;
        m[2, 1] = 0;
        m[3, 1] = 0;
		
	//3rd column
        m[0, 2] = 0;
        m[1, 2] = 0;
        m[2, 2] = Mathf.Epsilon-1;
        m[3, 2] = -1;
		
	//4th column
        m[0, 3] = 0;
        m[1, 3] = 0;
        m[2, 3] = (Mathf.Epsilon-2)*n;
        m[3, 3] = 0;	
		
	camera.projectionMatrix = m;
				
	}
}

The projection differs a bit from Unity’s regular projection, don’t know where that is coming from.

I still don’t understand how Unity’s skybox is calculated and rendered as it is a single shader with 6 passes…