![v2-8c63dd50de523de2f84b32f1b4678936_1440w.jpg?source=172ae18b](http://img-01.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-8c63dd50de523de2f84b32f1b4678936_1440w.jpg?source=172ae18b)
=========源文件下载群========
QQ群:818511955
=========================
最近在知乎上看到很多聊unity后期特效的文章。
自己研究了一下,做出了很多效果。
今天开一个新坑,做个系列教程。
欢迎大家,观看和讨论。
=======下面进入正文=======
先看最终效果
![v2-e22b86e204178776ab8f75a1e442826a_b.gif](http://img-03.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-e22b86e204178776ab8f75a1e442826a_b.gif)
镜头特效的作用流程是:
在摄像机上挂载一个引入Shader的C#程序。
=====C#程序中渲染特效结构====
OnRenderImage(渲染输入,渲染输出)
{
Graphics.Blit(渲染输入,渲染输出,特效材质球);
}
==============
使用Shader驱动GPU渲染输出。
![v2-99f0d3c33c8a0ffd85b292b89e985126_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-99f0d3c33c8a0ffd85b292b89e985126_b.jpg)
首先要在摄像机上添加一个C#程序。
![v2-deba37b7eddc1163af31abe11878f83e_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-deba37b7eddc1163af31abe11878f83e_b.jpg)
在启动程序中,我预先确定用来处理图像的Shader名称。
![v2-efb15e1af2dbfaf8768a37ee0cc7ac68_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-efb15e1af2dbfaf8768a37ee0cc7ac68_b.jpg)
在 OnRenderImage()渲染处理是系统默认函数。
使用Graphics.Blit()引入Shader和渲染图像。
![v2-60b99a765dd30b1064560a9c01c4d166_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-60b99a765dd30b1064560a9c01c4d166_b.jpg)
C#中预先定义好将要使用的“马赛克尺寸”变量。
使用Material.SetInt()传入材质的“_TileSize”变量
![v2-000f641727e8286907d2e28504a44593_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-000f641727e8286907d2e28504a44593_b.jpg)
CRLuo_CameraFX_Mosaic_Base.cs 代码
using
======CameraFXShader_Mosaic_Base.shader
源代码
//材质的路径与名称
自定义材质球名称与参数,注意与上面CS文件中使用的材质路径,名称与参数一致。
![v2-6081420d6775e30147dc8950790897f8_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-6081420d6775e30147dc8950790897f8_b.jpg)
参数中我们定义了 _MainTex 主贴图(名称一定不要改),用来接收渲染图片。
使用_TileSize来定义马赛克尺寸(像素个数)。(一个数据是方形的,可以定义两个数据来保存长/宽)
并且在Pass(渲染片段)程序中正确的载入变量。
![v2-105d87183ad5878a803fc8bc4a9e29cb_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-105d87183ad5878a803fc8bc4a9e29cb_b.jpg)
最后就是核心的,效果实现部分:
![v2-9f9c9dd94197f52a7806f843979fc3b4_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-9f9c9dd94197f52a7806f843979fc3b4_b.jpg)
_ScreenParams是系统默认保存屏幕尺寸的二维变量
屏幕尺寸/马赛克像素尺寸=屏幕的横竖需要X,Y块马赛克
二维数据除以一维数据,相当于每个二维数据被除(X,Y)/A=(X/A,Y/A)
//获取马赛克块数量 = 屏幕像素个数/块的像素个数
float2 TileSum = _ScreenParams / _TileSize;
===========================
要想看懂接下来的内容,
我们需要知道,到底在对什么操作。
![v2-9413e02183f339b7f0aa383327fb32c0_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-9413e02183f339b7f0aa383327fb32c0_b.jpg)
UV的0~1与贴图的0~1一一对应,如果我们使用程序重新定义一个UV坐标,然后就可以通过UV与贴图一一对应的关系,得到UV修改后的贴图。
=============================
原始i.UV的范围就是0~1,与输出图像一一对应。
![v2-a205029ef31571c66e85980d483fd230_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-a205029ef31571c66e85980d483fd230_b.jpg)
使用 i.UV(原始UV数据)*块数,使得UV从0~1,放大到0~X。
![v2-9216ddd80a646efa32bb706c8a43ceef_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-9216ddd80a646efa32bb706c8a43ceef_b.jpg)
然后使用,ceil()向上取整函数得到 1,2,3,4,5~X的UV分布。
![v2-15b625be682caea2b43ec9e7b411be86_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-15b625be682caea2b43ec9e7b411be86_b.jpg)
结果除以块数,把UV约束回0~1范围,这时每块儿中UV数据相同。
![v2-686d83c3efd9455e8d10a83e4b330073_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-686d83c3efd9455e8d10a83e4b330073_b.jpg)
//整理UV,让一个马赛克块儿中的UV统一为一个数据
随后应用UV数据给渲染图像
//把整理后的UV结果赋给渲染图像,获得马赛克画面。
![v2-b69d50b912f6f2bb0d4bf2669430aba1_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=57ca76fb-8e2e-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-b69d50b912f6f2bb0d4bf2669430aba1_b.jpg)
输出图像结果
//输出图像 = 马赛克图像;
=====本节完======
谢谢观看。