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实现物体被遮挡描边
之前在网上看到物体遮挡描边的功能,自己也拿来实现了一番.算作第一篇博客的开篇. 先贴出几张效果图,也是个人思路和方案的改进路线吧. ////////////////////////////////// ...
随机推荐
- 使用第三方框架vapor和swift 搭建本地服务器
在网上看到一篇教程,使用vapor搭建服务端,自己记录下来备忘本文主要记录以下几点 1.配置好Vapor 2.用Swift写GET,POST方法,返回JSON数据 3.配置本地服务器,编译运行在浏览器 ...
- java问题排查可能用到的一些命令
1. jmap查询jvm内存使用情况 -heap :打印jvm heap的情况 -histo: 打印jvm heap的直方图.其输出信息包括类名,对象数量,对象占用大小. -histo:live : ...
- 6.Counting Point Mutations
Problem Figure 2. The Hamming distance between these two strings is 7. Mismatched symbols are colore ...
- 在AndroidStudio不能找到so文件问题:couldn't find libweibosdkcore.so
解决步骤已经写到我的公众号,二维码在下面. 欢迎观看我的CSDN学院课程,地址:http://edu.csdn.net/course/detail/2877 本人联系方式: 更多精彩分享,可关注我的微 ...
- linux笔记_防止ddos攻击
一.什么是DoS攻击 DoS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻击,其目的是使计算机或网络无法提供正常的服务.最常见的DoS攻击有计算机网络带宽攻 ...
- 《C与指针》第十三章练习
本章例程 13.1类型无关的链表查找 #include <stdio.h> #include "node.h" Node *search_list(Node *node ...
- 关于js代码中与或运算符||&&的妙用
看bootstrap时看到如下一行JavaScript代码产生了疑惑. return window.pageYOffset || e.scrollTop ||在这里的作用是什么呢? 首先明确概念,在j ...
- id生成策略 id工具类
import java.util.Random; /** * 各种id生成策略 * <p>Title: IDUtils</p> * <p>Description: ...
- 如何让Notepad++添加Python运行方式.精讲
原文来自金石开的文章,欲知详情请点击他昵称. 名为cncyber的博友,在此感谢他. 全部省略.正确命令是在原文的回复里,在此复制贴上: cmd /k cd /d "$(CURRENT_DI ...
- SDK Manager 中 没有 Support Library怎么弄?
SDK Manager 中 没有 Support Library怎么弄?求大神帮忙 百度上面说的基本都试了,依旧没有弄出来 点击"Packages" > "Show ...