Unity Shaders and Effects Cookbook (D-1) 设置 ZTest 来实现遮挡半透效果

Posted _Captain

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shaders and Effects Cookbook (D-1) 设置 ZTest 来实现遮挡半透效果相关的知识,希望对你有一定的参考价值。

在游戏里面经常看到这样的效果,英雄走到障碍物后面,但是我们能够透过障碍物看到英雄的身体,好像我们有了透视眼一般。


都是套路。

其实是程序猿在显示英雄模型的时候,画了两次。

一次是被遮挡的部分用半透明的样子画了一遍。

另一次是没有遮挡的部分画了一遍。


下面在Unity中来实现。

首先新建材质 、Shader、场景。

搭建好场景,一个Cube、一个Capsule


好了,现在是最正常不过的情况了,Capsule被Cube 挡住了。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

下面修改一下 Shader。

Shader "CookBookShaders/Cover Translucent" 
	Properties 
		_MainTex ("Base (RGB)", 2D) = "white" 
	
	SubShader 
		Tags  "RenderType"="Opaque"
		LOD 200
		
		ZWrite On
		ZTest greater  //Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off 默认是LEqual 如果要绘制的像素的Z值 小余等于深度缓冲区中的值,那么就用新的像素颜色值替换。这里使用 Greater,代表如果当前要渲染的像素 Z值大于 缓冲区中的Z,才渲染,也就是后面的物体覆盖了前面的。
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input 
			float2 uv_MainTex;
		;

		void surf (Input IN, inout SurfaceOutput o) 
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		
		ENDCG
	 
	FallBack "Diffuse"


只是在 CGPROGRAM 之前加了两句话,设置了两个东西

ZWrite On
ZTest greater

ZWrite 代表是否将深度写入深度缓冲中,默认是 On

ZTest   代表通过通过判断深度,来决定当前像素的颜色是否写入颜色缓冲,即是否要用当前像素颜色替换掉之前的像素颜色。

取值有以下几种:

Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off

默认是LEqual 如果要绘制的像素的Z值 小余等于深度缓冲区中的值,那么就用新的像素颜色值替换。

这里使用 Greater,代表如果当前要渲染的像素 Z值大于 缓冲区中的Z,才渲染,也就是后面的物体覆盖了前面的。


现在得到如下效果:


这就是第一次的绘制,把后面的Capsule 覆盖掉了前面的Cube。


那下面开始第二次绘制,也就是没有被遮挡的。

既然是没有被遮挡的,那只要按照最普通的方法就可以了,

Shader "CookBookShaders/Cover Translucent" 
	Properties 
		_MainTex ("Base (RGB)", 2D) = "white" 
	
	SubShader 
		Tags  "RenderType"="Opaque"
		LOD 200
		
		ZWrite On
		ZTest greater  //Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off 默认是LEqual 如果要绘制的像素的Z值 小余等于深度缓冲区中的值,那么就用新的像素颜色值替换。这里使用 Greater,代表如果当前要渲染的像素 Z值大于 缓冲区中的Z,才渲染,也就是后面的物体覆盖了前面的。
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input 
			float2 uv_MainTex;
		;

		void surf (Input IN, inout SurfaceOutput o) 
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		
		ENDCG
		
		//上面设置了ZTest greater后,只有被遮挡的地方才渲染出来。所以下面把没有遮挡的地方渲染出来。
		ZWrite On
		ZTest LEqual  //Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off 默认是LEqual 如果要绘制的像素的Z值 小余等于深度缓冲区中的值,那么就用新的像素颜色值替换。这里使用 Greater,代表如果当前要渲染的像素 Z值大于 缓冲区中的Z,才渲染,也就是后面的物体覆盖了前面的。
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input 
			float2 uv_MainTex;
		;

		void surf (Input IN, inout SurfaceOutput o) 
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		
		ENDCG
	 
	FallBack "Diffuse"

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

现在效果是这样的


看起来像是Capsule 在 Cube前面了,Shader实现的效果就是这个,但是我们不能用这个放到游戏中,因为会产生很多误解的。。。

我们来把被遮挡的这一部分,设置为透明,实现类似于LOL 躲草丛的效果。

下面要修改第一次绘制的代码,把它变为透明。


既然要做透明,那么要加上 alpha 的tag才行,然后设置 Alpha。

最终修改如下

Shader "CookBookShaders/Cover Translucent" 
	Properties 
		_MainTex ("Base (RGB)", 2D) = "white" 
	
	SubShader 
		Tags  "RenderType"="Opaque"
		LOD 200
		
		ZWrite On
		ZTest greater  //Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off 默认是LEqual 如果要绘制的像素的Z值 小余等于深度缓冲区中的值,那么就用新的像素颜色值替换。这里使用 Greater,代表如果当前要渲染的像素 Z值大于 缓冲区中的Z,才渲染,也就是后面的物体覆盖了前面的。
		CGPROGRAM
		#pragma surface surf Lambert alpha 
		//加上alpha让被遮挡的这部分透明显示

		sampler2D _MainTex;

		struct Input 
			float2 uv_MainTex;
		;

		void surf (Input IN, inout SurfaceOutput o) 
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = 0.5f; //设置Alpha为0.5
		
		ENDCG
		
		//上面设置了ZTest greater后,只有被遮挡的地方才渲染出来。所以下面把没有遮挡的地方渲染出来。
		ZWrite On
		ZTest LEqual  //Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off 默认是LEqual 如果要绘制的像素的Z值 小余等于深度缓冲区中的值,那么就用新的像素颜色值替换。
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input 
			float2 uv_MainTex;
		;

		void surf (Input IN, inout SurfaceOutput o) 
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		
		ENDCG
	 
	FallBack "Diffuse"


最终效果 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn


示例工程下载:

http://pan.baidu.com/s/1pKT17sf


以上是关于Unity Shaders and Effects Cookbook (D-1) 设置 ZTest 来实现遮挡半透效果的主要内容,如果未能解决你的问题,请参考以下文章

Unity Shaders and Effects Cookbook (6-2) 透明裁剪着色器

Unity Shaders and Effects Cookbook (6-1) 使用 alpha 参数的 半透明着色器

Unity Shaders and Effects Cookbook (6-3) 修改渲染队列Queue 来 修改渲染顺序

Unity Shaders and Effects Cookbook (7-3) 在地形中使用顶点颜色做混合

Unity Shaders and Effects Cookbook (D-2) Cull Back背面剔除 -- 模型半边不可见

Unity Shaders and Effects Cookbook (5-1)LitSphere lighting model