咳咳,有段时间没有更新了,最近有点懒!把不少精力都放在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教程_遮挡描边(原理篇)的更多相关文章

  1. Esfog_UnityShader教程_遮挡描边(实现篇)

     在上一篇中,我们基本上说明了遮挡描边实现的一种基本原理.这一篇中我们将了解一下基于这种原理的具体实现代码.本篇中的内容和前几篇教程相比,相对比较难一些,建议先有一些基本的Unity的C#脚本编程经验 ...

  2. Esfog_UnityShader教程_镜面反射SpecularReflection

    系列教程第四篇,本来打算昨天写的,有些小偷懒就今天写了,这一期我们来讨论一下关于镜面反射的基本原理和具体代码.这一篇是承接着上一篇<Esfog_UnityShader教程_漫反射DiffuseR ...

  3. Esfog_UnityShader教程_前言

    很多人在学习Unity的时候对Shader都是一知半解,作为刚入职半年的新人接触Shader的时间也并不长,正因为是新人才能体会到学习Shader时候所遇到的困难和迷茫,无奈于资料不好找,网上难得的几 ...

  4. Esfog_UnityShader教程_漫反射DiffuseReflection

    这篇是系列教程的第三篇,最近工作比较紧,所以这个周六周日就自觉去加了刚回来就打开电脑补上这篇,这个系列的教程我会尽量至少保证一周写一篇的.如果大家看过我的上一篇教程<Esfog_UnitySha ...

  5. Esfog_UnityShader教程_逐帧动画

    有段日子没出这个系列的新文章了,今天就拿一个比较常见也比较基础的利用改变Shader来改变不断调整UV实现播放逐帧动画的小功能.很久没写了就当练练手了.在新版本的Unity中早就已经集成了Sprite ...

  6. Esfog_UnityShader教程_溶解效果Dissolve

    溶解效果在游戏中是很常见的,比如在一些神话或者魔法世界中,一些NPC角色在剧情需要时候会身体会渐渐的消失掉.甚至有一些更炫的,比如用火焰喷射器把目标燃尽.这些都可以用到溶解效果.这篇文章主要是讲解一下 ...

  7. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

  8. Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04

    摘自: http://www.cnblogs.com/kinglau/p/3796164.html http://www.powerxing.com/install-hadoop/ 当开始着手实践 H ...

  9. UnityShader实现物体被遮挡描边

    之前在网上看到物体遮挡描边的功能,自己也拿来实现了一番.算作第一篇博客的开篇. 先贴出几张效果图,也是个人思路和方案的改进路线吧. ////////////////////////////////// ...

随机推荐

  1. SVN更新报错

    将服务器SVN文件更新到本地是出现下图错误 报错中已经提示可以通过clean up来清理,若直接执行release lock,则不会解决问题. 原因:本地的项目中存在过期的工作副本 解决办法:选择该文 ...

  2. nohup使用(转)

    在启动weblogic的时候我们经常看到如下的命令: nohup ./startWebLogic.sh >out.log 2>&1 & 其中 0.1.2分别代表如下含义:  ...

  3. Ubuntu下安装boost

    今天开始安装配置Ubuntu开发环境(Ubuntu 12.04).在干活之前就预计到会遇到很多问题,但是没想到一开始就卡壳,可能是linux中各种包的依赖关系太复杂了,决定写个帖子记录一下,免得以后再 ...

  4. 王爽<汇编语言>实验十

    实验十 3.数值显示(以下程序附带测试程序) ;名称: dtoc ;功能: 将dword型数据转变为表示十进制数的字符串,字符串以0为结尾 ;参数: (ax)=dword型数据低字 ; (dx)=dw ...

  5. 你应该知道的那些Android小经验

    原文出处:http://jayfeng.com/ 做Android久了,就会踩很多坑,被坑的多了就有经验了,闲暇之余整理了部分,现挑选一些重要或者偏门的“小”经验做个记录. 查看SQLite日志 ad ...

  6. Ext.Net 学习随笔 003 Panel基本使用

    Panel() 1.使用Content和Html属性设置Panel内容 前台View代码 @(X.Panel() .ID("panel1") .Width() .Height() ...

  7. kuangbin_SegTree I (HDU 1540)

    做完D之后我信誓旦旦以为之后就只剩一个二维就能攻克线段树了 看来也跟图论一样全是模板嘛 然后我打开了I题一眼看下去似乎直接用线段树记录sum然后跟区间长度比较然后处理一下实现也不难 两个小时后:特么的 ...

  8. SolrCloud分布式集群部署步骤

    Solr及SolrCloud简介 Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成 ...

  9. .Net Office开源组件

    1.NPOI NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目.使用 NPOI 你就可以在没有安装 Office 或者相应环 ...

  10. 国内最新Unity3D视频教程合辑

    麦子学院最新Unity3D视频教程上线啦,此为现目前国内最全.最新Unity3D教程,分享给广大小伙伴,希望对大家学习Unity3D有帮助: 第一阶段:Unity3D概要及入门 零基础学C#开发 Un ...