Esfog_UnityShader教程_遮挡描边(原理篇)
咳咳,有段时间没有更新了,最近有点懒!把不少精力都放在C++身上了。闲言少叙,今天要讲的可和之前的几篇有所不同了,这次是一个次综合应用.这篇内容中与之前不同主要体现在下面几点上.
1.之前我们写的都是只用一个Shader来实现某些效果,而这次我们要使用多个Shader结合起来发挥作用。
2.之前我们只是写的都是纯Shader代码,没有涉及到客户端的C#脚本(你爱用JS也可).而这次也要使用到。
3.这篇教程涉及到的代码量也是之前是之前的几倍了.
4.总的来说之前的都是比较简单的,而这篇就有了些难度了。
不过不要怕,我们先讲解实现的原理,因为这个教程内容比较多,所以只能抽出一篇来单独讲原理了,建议看这篇教程的同学,最好能有基本的UnityShader基础,不妨去看看我的前几篇教程,在后面讲解代码中我不会事无巨细的都讲到,直跳比较重点的地方进行说明。
好了进入正题,什么是遮挡描边呢?直接上图吧。

如上图, 在很多游戏中,特别是3D游戏中,当我们的角色被一些墙体或者其它物体挡着的时候,为了让玩家清楚的看到角色当前身处的位置,就需要把角色被遮挡部分的外轮廓描出来(上图中的绿色边框)。这就是我们要实现的"遮挡描边"。大家可以联想一下自己玩过的游戏看看有没有这种情况。
重要概念
在讲解具体原理之前,我们要先了解几个比较重要的概念:
1.后期处理:有点类似于影音方面后期处理的意思,在这里指的就是,当摄像机把当前帧渲染完毕之后,我们不是直接把图像映射到屏幕上,而是利用我们的代码来对原图像进行处理,把处理后的显示在屏幕上。游戏中非常多的效果都通过后期处理实现的,比如Bloom效果,运动模糊效果等等。我们这篇说的"遮挡描边"也算作是后期处理。
2.深度缓冲:对于一款3D游戏,要将三维世界里摄像机看到的部分展示到二维的屏幕上,除了要展示物体本身的颜色,还要处理物体的前后关系。而在我们的显存里有两个缓冲区(和具体显卡架构有关,这里只是举个例子)来分别用来保存游戏的画面和物体的前后关系。我们把它们分别称作颜色缓冲区和深度缓冲区。颜色缓冲区你可以理解为他是一个二维数组,里面的一个元素对应着屏幕的一个像素点的颜色(还会附带一些其他信息)。深度缓冲区也可以理解为一个二维数组,里面存放着屏幕像素上每一个点所对应场景中物体上的点距离相机的距离。在渲染流程中深度缓冲非常重要的,如果没有它,也就没有了物体间的前后关系,我们在屏幕上看到的可能是杂乱的图像了。
3.深度图:深度图适合深度缓冲相关联的一个概念,深度缓冲是由操作系统通过显卡API来控制的,而我们使用引擎的时候也只能通过引擎提供的有限的API来读写利用深度缓冲来实现一些效果。那当我们需要利用深度缓冲来做一些特殊效果的时候就要抓狂了,别急我们可以通过制定一个相机,让它把渲染的图像不是显示到屏幕上,而是显示到一张我们设定好的二维图片上,我们在通过我们写的Shader来让它把这个相机所拍摄到物体的深度信息保存到这个二维图片(它现在就是深度图了)上,而不是颜色信息。这样在接下来的处理用我们就可以利用这个深度图来做一下事情了。
原理
有了上面的一些概念我们就来了解一下实现的原理(当然了,实现遮挡描边的方法很多,而每一款游戏需要的效果也不尽相同,这里的方法仅供参考):
大体上可以分四个大步骤:(下面的两张图片,在游戏中玩家是看不到的,开发人员也是看不到的,全部都是在代码中处理的,这里显示出来只是为了让大家能更好的理解一下)
1.获得一共只包含我们要进行遮挡描边处理的物体(在我们的例子中,就是上图的那个士兵)深度信息的深度图。对于我们的例子,这一步的结果如下图,粗看起来是一片红,但是大家细看右边你会看到那个士兵的.至于为什么图像这么偏红,大家可以想想,我在下篇中会说明。

2.通过比较判断主摄像机(就是你在Game窗口看到的图像所用到的摄像机)的深度信息和我们第一步中获得到的深度图信息,来界定出我们要处理的物体的哪些部分被挡住了。并对被遮挡全部涂上描边颜色。如下图

3.把被遮挡部分分别进行一次左右,上下方向的拉伸一像素.这个就不用图了基本和上面的图一样,只是上下左右都多了一个像素,所以看起来不明显。
4.最后把除了我们在第三步中额外绘制的一像素外轮廓以外,对角色的被遮挡部分还使用原来的颜色(就是墙本身的颜色)。效果就是本文一开始放的那个图片了。
涉及到的一些API
这样我们就实现了遮挡描边,不过上面只是比较笼统的概括,有很多细节需要注意。具体的代码实现我会在下次的教程中进行具体讲解,这里我先把需要设计到的一些Unity知识列出来,很多内容都可以通过Unity的官方API文档查到,大家可以自己先了解一下然后试着实现一下遮挡描边。这样看下一次教程的时候会效果更好:
1.在Unity进行后处理需要涉及到的一些API,有 OnRenderImage(...),RenderTexture.GetTemporary,RenderTexture.ReleaseTemporary,Graphics.Blit,RenderWithShader.
2.在C#脚本中对Shader进行传值设计到的一些API,如Shader.SetGlobalXXX(),Shader.Find,Material.SetXXX().
3.相机的深度模式,和Unity提供给我们的一个默认深度图.Camera.depthTextureMode,_CameraDepthTexture等.
好了关于遮挡描边的原理篇基本就讲完了,怎么样是不是和之前几篇的内容有很多不同,这篇内容也只是做了一个抛砖引玉,只是希望大家能了解一下渲染中的几个重要概念,然后自己去做一些扩展,比如说深度缓冲和深度图,他们两个能够实现的效果远远不只是"遮挡描边"。更多神奇的功能还等待大家自己一起去探索。另外我会在近期完成"实现篇"的,这段时间大家不妨自己动手试着写写看,没准在我发下一篇之前,聪明的你啊已经搞定了呢!!!
尊重他人智慧成果,欢迎转载,请注明作者esfog,原文地址 http://www.cnblogs.com/Esfog/p/CoverOutline_Shader.html
Esfog_UnityShader教程_遮挡描边(原理篇)的更多相关文章
- Esfog_UnityShader教程_遮挡描边(实现篇)
在上一篇中,我们基本上说明了遮挡描边实现的一种基本原理.这一篇中我们将了解一下基于这种原理的具体实现代码.本篇中的内容和前几篇教程相比,相对比较难一些,建议先有一些基本的Unity的C#脚本编程经验 ...
- Esfog_UnityShader教程_镜面反射SpecularReflection
系列教程第四篇,本来打算昨天写的,有些小偷懒就今天写了,这一期我们来讨论一下关于镜面反射的基本原理和具体代码.这一篇是承接着上一篇<Esfog_UnityShader教程_漫反射DiffuseR ...
- Esfog_UnityShader教程_前言
很多人在学习Unity的时候对Shader都是一知半解,作为刚入职半年的新人接触Shader的时间也并不长,正因为是新人才能体会到学习Shader时候所遇到的困难和迷茫,无奈于资料不好找,网上难得的几 ...
- Esfog_UnityShader教程_漫反射DiffuseReflection
这篇是系列教程的第三篇,最近工作比较紧,所以这个周六周日就自觉去加了刚回来就打开电脑补上这篇,这个系列的教程我会尽量至少保证一周写一篇的.如果大家看过我的上一篇教程<Esfog_UnitySha ...
- Esfog_UnityShader教程_逐帧动画
有段日子没出这个系列的新文章了,今天就拿一个比较常见也比较基础的利用改变Shader来改变不断调整UV实现播放逐帧动画的小功能.很久没写了就当练练手了.在新版本的Unity中早就已经集成了Sprite ...
- Esfog_UnityShader教程_溶解效果Dissolve
溶解效果在游戏中是很常见的,比如在一些神话或者魔法世界中,一些NPC角色在剧情需要时候会身体会渐渐的消失掉.甚至有一些更炫的,比如用火焰喷射器把目标燃尽.这些都可以用到溶解效果.这篇文章主要是讲解一下 ...
- Spring_MVC_教程_快速入门_深入分析
Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门 资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...
- Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04
摘自: http://www.cnblogs.com/kinglau/p/3796164.html http://www.powerxing.com/install-hadoop/ 当开始着手实践 H ...
- UnityShader实现物体被遮挡描边
之前在网上看到物体遮挡描边的功能,自己也拿来实现了一番.算作第一篇博客的开篇. 先贴出几张效果图,也是个人思路和方案的改进路线吧. ////////////////////////////////// ...
随机推荐
- 简单的射击游戏HTML+JS实现
一直想自己写一个游戏玩,时间和精力都不太允许,最近几天刚好有空闲时间,就琢磨了这个小游戏. 刚开始想着计算图片重叠事件,然后让炮弹和飞机消失,傻乎乎写了一天,越整越乱.今天一大早晕过来了,改用数组以后 ...
- Halcon pick_and_place_scara_stationary_cam.hdev程序学习
此示例显示如何基于由SCARA手眼校准确定的校准信息,使用SCARA机器人执行拾取和放置应用程序. 在第一步骤中,根据模型图像定义形状模型. 然后,基于该形状模型,在每个图像中搜索对象. 对于一个选定 ...
- apache https 伪静态
今天很是郁闷,配置了一个https成功了,但是伪静态不成功,经过多方面查看资料终于配置成功了: <VirtualHost *:443> DocumentRoot /var/www/juba ...
- ajaxpro 异步调用
AjaxPro一般默认是同步调用,异步调用只需要在方法后面加一个callback函数,直接取value属性即可.例如: MyNameSpace.Page1.getOtherConfig("A ...
- Access 数据库连接 字符串
<!--Microsoft.Practices.EnterpriseLibrary.Data.dll 操作引用程序集--> <connectionStrings> <ad ...
- 如何通过WPS 2013 API 将Office(Word、Excel和PPT)文件转PDF文件
1. 描述 PDF 文件是一种便携文件格式,是由Adobe公司所开发的独特的跨平台文件格式.PDF文件以PostScript语言图象模型为基础,无论在哪种打印机上都可保证精确的颜色和准确的打印效果,即 ...
- Lua学习---Lua的控制结构
前言 由于之前有c/c++.javascript基础,所以学Lua的时候喜欢拿来和前面的语言比较,这里主要和C比较 1.if...else Lua的if语句格式: if 条件 then 条件成立,运行 ...
- DHTMLX-Form
DHTMLX-Form dhtmlxForm提供了一个标准形式与一些有用的补充,如不同风格,使用的数据从客户端和服务器端,与其他dhtmlx组件的集成.验证等. 例子 <!DOCTYPE htm ...
- Zedboard安装桌面系统ubuntu及opencv(1)
最近一直在搞板子,想帮Zedboard安装一个opencv谁知道困难重重,而且网络几乎没有任何资料可以参考,只有陆佳华的<嵌入式软硬件协同设计实战指南>可以参考. 但是这本书讲得不清不楚, ...
- 【学】React的学习之旅1
React的学习之旅1 单标签要有斜杠代表结束 用React.createClass()方法时,赋值后的组件名称首字母一定要大写 一定要先定义组件,再用ReactDOM.render调用 组件里ren ...