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
时间: 2024-10-09 09:02:27

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

Unity Shaders and Effects Cookbook (4-6)震撼的实时反射 动态立方图系统

昨天逛街的时候看到太平鸟里面摆了个金属的米老鼠,于是职业病犯了,一直在想金属的颜色是什么,这个反射该怎么写,想不出来-- 今天正好看到动态反射立方图系统这一节,看完觉得很别扭,因为书上介绍的是事先踩点生成Cubemap的方式而不是实时的.于是到官方文档找到实时反射的代码,做了一个比较花俏的场景,运行之后吃了一大惊,实时反射是如此的震撼.. 第四章第一节第二节介绍了创建Cubemap,然后学习了如何使用. Unity Shaders and Effects Cookbook (4-1)(4-2)静

Unity Shaders and Effects Cookbook (4-3)遮罩反射

今天看完了4.3小节,Unity3d 中的遮罩反射,这一节内容比较少. 如果大家对Unity Shader 感兴趣的白菜,那么推荐大家购买一本 Unity 着色器和屏幕特效开发秘笈 .这本书写的浅显易懂,很适合入门. 当看完这本书,大概了解 Shader 的用处的时候,再去看更高级的 Shader 教程也可以. 京东图书连接 http://item.jd.com/1338728578.html 转自http://blog.csdn.net/huutu http://www.thisisgame.

Unity Shaders and Effects Cookbook (4-4)在Cubemap 上使用 法线贴图 (法线贴图与反射)

法线贴图 在之前学习过了,我们使用法线贴图在低分辨率的模型上 模拟 高分辨率的效果. Unity中 通过 UnpackNormal 函数 来使用法线贴图. 之前学习法线贴图的记录 Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图 这一节讲的是 在Cubemap 上使用法线贴图.模拟凹凸效果. 最终效果如图 一起来做吧. 首先搭建好场景,和上一节一样. 导入法线贴图 创建材质 .Shader . 复制上一节的 Shader 就行.然后修改成下面的内

Unity Shaders and Effects Cookbook (3-6) 创建各向异性高光类型(Anisotropic) 模拟金属拉丝效果

这一次学习各向异性高光类型,名字真拗口,Anisotropic 这个英文单词也很拗口. 各向异性是模拟物体表面 沟槽方向性的高光反射类型,他会修改或延伸垂直方向上的高光. 比如模拟金属拉丝的效果,就可以使用各向异性来模拟. 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 首先需要准备一张各向异性 的法线贴图,代表各向异性镜面高光的方向性. 注意法线贴图导入到Unity之后要在属性面板中勾选类型为 Normal Map. 首先在

Unity Shaders and Effects Cookbook (6-4) GUI 和 透明度

在游戏项目中使用透明最多的地方就是 GUI 了.这一节用一个非常简单的 GUI 例子,来熟悉控制透明物体的渲染顺序. 搭建场景,导入随书资源. 创建着色器 GUI,创建两个Material,一个 GUIBG 用于背景图片,一个 GUIGRP 用于 按钮界面. 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 把创建的Material 分别赋值给 GUIBG 和 GUIGRP. 场景搭建完毕后 效果如下 因为创建的Shader 默认

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

默认情况下,Unity是按照物体与 摄像机 的距离,来决定哪个物体先渲染.远处的物体先渲染,先渲染的物体,就会被都渲染的物体遮挡. Unity 提供了一些默认的渲染队列,比如最先被渲染的是 Background = 1000,然后是 Geometry =2000,一般在编辑器中创建的 物体都是处于 Geometry 这一渲染队列的. 有这么一个场景,里面有两个Sphere,一个远一些,一个近一些. 那么肯定的是,近一些的会遮挡远一些的,这是自然现象.远一些的先渲染. 但是有的时候,需要让远一点的

Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息

这一节看了几次才慢慢的读懂. 首先是这个灰度图,为什么叫灰度图,是因为 这个图片中的 R.G.B 存放的都是同一份数据,打开Unity 来调一下颜色看看 更直观. 可以看到,当 R.G.B 三个值相同的时候,图片是只有黑白,而丢失了其它的颜色的,所以我们叫灰度图. 什么时候用到灰度图? 本文转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 比如说高度图,在这个坐标的点,海拔高,就记作 1,海拔低就记作0 .把这一份数据 同时存储到

Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画

上一节中说了,在 Surface Shader 中,添加顶点函数,我们可以在 顶点函数中获取到 顶点数据,比如顶点颜色.顶点坐标等. 这一节学习获取顶点坐标,并且修改顶点坐标,来实现顶点动画. 简单介绍原理: 在顶点函数中,获取到顶点坐标 vertex,然后,求float offsetY = sin(vertex.x) ,然后将 offsetY 加到 vertex.y 上,这样就把原来的平面 ,变成了 正弦 波浪. 然后再使用之前学过的 内置变量 _Time ,算式变为 float offset

Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用

开始学习第4章 - 着色器的反射 看完了1.2节,来记录一下.反射主要是利用了 Cubemap 立方体贴图. 认识Cubemap 立方体贴图,就如同名字所说,在一个立方体上有6张图,就这样认为吧. 假想一下 ,在一个艳丽的房间里,有一个表面是镜子的圆球,那这个圆球表面就反射了房间里面的所有东西,就是一个大号的凸镜. 这是到网上找得一张图,很直观的表达了我的意思-- 注意标题中说的,静态立方体贴图,为什么叫静态,因为这一次使用的立方体贴图是提前生成好的图片,而不是动态生成的. 这又是什么意思呢?