unity shader 人物走入草丛,草的晃动的草丛特效特效怎么做

后使用快捷导航没有帐号?
只需一步,快速开始
查看: 1185|回复: 12
Unity界面UI特效怎么实现扭曲效果
TA的其他好贴
马上注册,加入CGJOY,享用更多功能,让你轻松玩转CGJOY。
才可以下载或查看,没有帐号?
本帖最后由 不易 于
17:39 编辑
最近在弄界面的效果,遇到一个问题,因为手游项目 所以都没有用到特殊脚本和shader ,但是玩过几款手游(如:聚爆里面的刀光)里面有用到过扭曲shader,想问长得帅的人 &&这些手游为什么可以用这些shader,要注意哪些。。。
还有就是 炉石传说 里面的金色卡牌特效,那个效果是不是Unity扭曲Shader,竟然用的这么肆无忌惮&&。。。如果炉石传说的特效师看到一定要回答我啊~~
(3.16 MB, 下载次数: 9)
17:25 上传
就是那根!!!舌头
(3.14 MB, 下载次数: 3)
17:37 上传
这尼玛这个人都在扭动
我这个就是炉石的效果,是个插件 只是一张图直接做的效果,没有粒子,没有UV,不是序列,我只能说红米跑起来没一点问题,方法是偏程序的告诉你你也不会
这个效果很好用啊,咋不科普出来,&
手游里面用的扭曲shader是经过优化的。并不是说手游里面就一定不能用扭曲的shader,主要还是要看程序优化的能力。shader这方面还是程序说的算,如果公司程序能力不够强的话,特效限制很多,很多shader都不能用。你说的这种效果在u3d中用shader 或者用序列图来实现吧。
序列图少的话 还能接受,一般需要的很多,,,就GG 了&
/forum.php?mod=viewthread&tid=160508&shareuid=320278
我这个就是炉石的效果,是个 ...
这个效果很好用啊,咋不科普出来,
能分享下插件名吗?&
没办法科普,因为是公司买的炉石插件,我又不能给你&
手游里面用的扭曲shader是经过优化的。并不是说手游里面就一定不能用扭曲的shader,主要还是要看程序优化的 ...
序列图少的话 还能接受,一般需要的很多,,,就GG 了
这些效果不难,过些天我出教程讲下
等银神出教程啊~~~~&
坐等银神出教程了&
大神你可一定要讲啊,我们等着看&
这些效果不难,过些天我出教程讲下
大神你可一定要讲啊,我们等着看
本帖最后由 你不懂我的美 于
19:46 编辑
这个效果很好用啊,咋不科普出来,
没办法科普,因为是公司买的炉石插件,我又不能给你
其他办法就是正常做出来然后模型遮挡但是 你也清楚很烧资源 不烧资源的 让你们公司给你去买插件吧
这些效果不难,过些天我出教程讲下
& &坐等银神出教程了
每天在加班加点的做,做好了分享给大家哈&
坐等银神出教程了
每天在加班加点的做,做好了分享给大家哈
拭目以待~~~~~~~~&
动画师的生存手册
Powered by【Shader】通过Shader实现森林树木随风摆动效果 - 游戏开发,移动开发技术干货分享 - 泰课在线 - 国内专业的Unity在线学习平台|Unity3d培训|Unity教程|Unity教程 Unreal 虚幻 AR|移动开发|美术CG|UI平面设计|前端开发 - Powered By EduSoho
【Shader】通过Shader实现森林树木随风摆动效果
作者:yangyy753
原文链接:
大家首先可以想象一下这样的场景:场景中有一大片森林,我想让这片森林的树木有微风轻轻吹拂而缓缓摆动的效果,应该要怎么实现呢?
A:给每棵树加个动画,让动画来控制摆动
方案A如果在树木少的情况下还是属于可接受范围的,而且用美术童鞋做的动画来控制树木摆动会显得更真实更生动。不过注意,当是&森林&的时候,这一动起来,CPU估计就吃不消了,若是美术童鞋为了让树木更生动,加的是骨骼动画,那CPU和DrawCall将会爆表!
B:用代码控制树木位移来实现
方案B当然不可能是每棵树挂个脚本,那对性能是极大的浪费。若是直接控制整片森林的位移,首先是要把整片森林形成一个整体,然后是用代码每帧循环地去控制位移。虽然能达到摆动,但是动起来会非常的怪异,很难达到理想的效果,大神们可以去尝试一下。
C:使用Unity自带的Tree和WindZone
方案C不失为一个好方法,能够实现很真实的效果。不过使用Unity自带的Tree有很多美术上的限制,而且配置Tree和Wind Zone也是非常麻烦,性能也有一定的消耗。有时候当我们只需要实现简单的摆动功能,就会显得有些得不偿失,性价比不是很高。
总而言之,方案各式各样,种类繁多,选中最适合自己的那一个才重要。综上所述,要实现符合简单、仿真、高性能的三大条件,通过Shader的帧动画变换UV采样贴图来实现效果,将是一个不错的选择。
简要说一下原理:一个贴图具体如何被映射到模型的表面是根据模型定点的UV值来决定的。假设不修改的话,一个平面的左下角的UV是(0,0),右上角是(1,1)。然后,根据时间计算出当前帧贴图上相应的UV位置,按照这个位置取贴图中取出对应颜色。其实模型顶点本身的UV信息没变,只是把它传递给我们的UV信息进行加工,获取我们想要的位置上的像素。好的,不多说了,直接上代码吧:
[AppleScript] 纯文本查看 复制代码
Shader &Consume/Leaf Swing&
Properties {
_MainTex (&Base (RGB)&, 2D) = &white& {}
_Pos(&Position&,Vector) =(0,0,0,0)
_Direction(&Direction&,Vector) =(0,0,0,0)
_TimeScale(&TimeScale&,float) = 1
_TimeDelay(&TimeDelay&,float) = 1
&RenderType&=&Opaque&
&Queue&=&Transparent&
#pragma surface surf Lambert vertex:vert alpha
sampler2D _MainT
half _TimeS
half _TimeD
struct Input
half2 uv_MainT
void surf (Input IN, inout SurfaceOutput o)
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.
o.Alpha = c.a;
void vert (inout appdata_full v)
half dis = distance(v.vertex ,_Pos) ;
half time = (_Time.y + _TimeDelay) * _TimeS
v.vertex.xyz += dis * (sin(time) * cos(time * 2 / 3) + 1) * _Direction.//核心,动态顶点变换
FallBack &Transparent/Cutout/VertexLit&
从以上代码我们可以进行这几个参数的配置,位移量:_Pos、方向:_Direction、时间尺度:_TimeScale、延迟时间:_TimeDelay。只要森林的所有树木叶子材质统一使用以上Shader,就能做到微风轻摆的效果,赶紧试试吧~
Ricky Yang个人原创,版权所有,转载注明,谢谢。
后发表看法
Unity3D技术交流1群
工作时间: 9:00 - 17:00
北京客服: 010 -
广州客服: 020 -当前位置: >
Shader基础知识
时间: 22:19 来源:互联网 作者:脚印 浏览:
1.Unity中配备了强大的阴影和材料的语言工具称为ShaderLab,以程式语言来看,它类似于CgFX和Direct3D的效果框架语法,它描述了材质所必须要的一切咨询,而不仅仅局限于平面顶点/像素着色。2.在Unity3D中创建一个Shader:Assets&-&&Create&-&&Shader3.创建了Shader就可以应用到各个材质Material中,创建材质:Assets&-&&Create&-&&Material。然后就可以在材质的Inspector面板中,shader下拉框中可以找到新增加的shader4.Rendering&Paths是Unity3D中一个重要的概念,中文翻译就是“渲染通道”。它可以很大程度上影响光线和阴影的渲染效果,但具体要依赖于具体的游戏内容和硬件设备,以及平台。Unity3D中有三种渲染通道类型,从高到低分别为:Deferred&Lighting,Forward&Rendering,Vertex&Lit。如果平台或设备显卡不能支持高级别的通道类型,Unity3D会自动选择稍微低一些的类型。//Unity3D教程手册:5.如何设置渲染通道:在Edit&-&&Project&Setting&-&&Player中Inspector面板下面,三种发布类型里都有一个渲染通道的设置。另外,每个摄像机的Inspector面板中,也都有一个渲染通道Rendering&Path的设置。6.渲染通道与shader的关系。Deferred&Lighting通道类型不关心有多少个光源会影响它,每个物体一般都会绘制两次;类似地,Vertex&Lit&只绘制一次。所以对于这两种类型来说,shader对表现效果的改变大多在于多重纹理方面。Forward&通道类型的表现效果要取决于shader和场景中的光源。它有两种基本的计算方式Vertex-Lit&和&Pixel-Lit。可以翻译为逐顶点渲染法和逐像素渲染法吧应该,对应着D3D中的顶点着色和像素着色过程。Vertex-Lit&用于对网格模型表面顶点进行光照计算,一次性将所有光源的影响都计算在内,所以无论场景中有多少个光源,这种方式绘制的物体只绘制一次。Pixel-Lit&会计算每个像素上面最终的光照,因此一个物体必须先呗绘制一次来获得环境光和主方向光的光照信息,再绘制一次来获得其他每个额外的光源信息。应用Pixel-Lit的物体的大小也会影响绘制的效率,越大的物体,绘制越慢。Vertex-Lit&的开销大于Pixel-Lit,但是Pixel-Lit可以提供很多非常好的效果。7.Unity3D中的shader是通过改变那些直接影响游戏对象的材质来使用的。8.一个shader可以被应用于多个材质中,但一个材质只能应用一个shader。9.一些shader被写入了Unity3D底层里,一部分作为内建shader被放置于standard&assets里,可供用户使用。&
(责任编辑:脚印)
免责声明:Unity之家部分内容来源于互联网,如有侵权,请联系我们,本站将立即进行处理。
猜你也喜欢看这些 ??????
其他类型的Unity特效 ??????&&国之画&&&&&&
版权所有 京ICP备号-2
迷上了代码!【浅墨Unity3D Shader编程】之八 Unity5新版Shader模板源码解析&运动模糊(径向模糊)屏幕特效的实现
博客专家
【浅墨Unity3D Shader编程】之八 Unity5新版Shader模板源码解析&运动模糊(径向模糊)屏幕特效的实现
【Unity3D】
【Unity3D】【Shader】
本系列文章由&出品,转载请注明出处。&& 文章链接: 作者:毛星云(浅墨)&& &微博:
本文工程使用的Unity3D版本: 5.2.1& && & &概要:本文对Unity5中全新的三种Shader模板的源码进行了解析,然后还讲解了运动模糊屏幕特效的实现方法。前言时隔9个月,终于有了一些稍微空闲的时间,可以进行一些更新了。鉴于以后可以用来写博客的时间肯定不会非常充裕,个人觉得再讲Shader的基础写法比较拖节奏,所以最好是把力气用在刀刃上,在有时间更新的时候,主要讲一些更加前沿、实用的技巧,以及进阶一些的Shader的写法。&另外,从本次开始,每次更新的标题也就不取那么主题化了(比如之前的暗黑城堡、静谧之秋之类的)。人老了,渐渐文艺不起来了,还是实在一点好。:D&好的,就交代这么多。接下来就按新的风格试着写几次。。&&看一组程序截图之后,便开始我们的正文。如下图,一份运动模糊屏幕特效的效果对比。原始场景效果图:&开启运动模糊特效后的场景效果图:&&图先就上这两张。文章末尾有更多的运行截图,并提供了源工程的下载。先放出可运行的exe下载,如下:&&好的,正文开始。一、Unity5中新的Shader体系简析&Unity5和之前的书写模式有了一定的改变。Unity5时代的Shader Reference官方文档也进一步地变得丰满。&主要需要了解到的是,在原来的Unity中,若想要新建一个Shader源文件,不考虑compute shader的话,仅有一种Shader模板供选择。而自从Unity5.1起(好像是Unity5.1)想在Unity5.1之后的版本中新建Shader,【右键在Project窗口中单击】-&【Create】,会出现如下的四个选项:而由于暂时不考虑compute shader。所以,新版Unity中有三种基本的Shader模板分别为:Standard Surface Shader标准表面着色器Unlit Shader 无灯光着色器Image Effect Shader 图像特效着色器&&二、Unity5中新的Shader模板源码解析&&下面,对Unity5中三种基本Shader模板进行逐行注释与思路解析。可以点击跳转到Github,查看详细注释好的三种Shader模板的源码。&2.1 标准表面着色器(Standard Surface Shader)模板源码解析&在Unity中,我们若要实现新的表面着色器时,可以根据这个模板,进行一步添加子着色器和新的参数与特性。这个Shader模板的脉络很清晰,先是定义一些属性,然后在SubShader中设置渲染模式,层次细节LOD的值,然后开启一个CG编程语言模块,写一些编译指令#pragma,声明一下变量让属性值在CG块中可见,定义输入结构,然后填充一下表面着色函数即可。注意:专门强调一句,SurfaceShader不能使用Pass,一使用就报错,我们直接在SubShader中实现和填充代码就可以了。Standard Surface Shader模板详细注释的Shader代码如下:&Shader &浅墨Shader编程/Volume8/Surface Shader模板&
//------------------------------------【属性值】------------------------------------
Properties
_Color(&Color&, Color) = (1,1,1,1)
_MainTex(&Albedo (RGB)&, 2D) = &white& {}
_Glossiness(&Smoothness&, Range(0,1)) = 0.5
_Metallic(&Metallic&, Range(0,1)) = 0.0
//------------------------------------【唯一的子着色器】------------------------------------
//【注意:Surface Shader不能使用Pass,直接在SubShader中实现即可】
//渲染类型设置:不透明
Tags{&RenderType& = &Opaque& }
//细节层次设为:200
//===========开启CG着色器语言编写模块===========
//编译指令:告知编译器表明着色函数的名称为surf
//Standard表示光照模型为Unity标准版光照模型
//fullforwardshadows表示在正向渲染路径中支持所有阴影类型
#pragma surface surf Standard fullforwardshadows
//编译指令: 指定着色器编译目标为Shader Model 3.0
#pragma target 3.0
//变量的声明
sampler2D _MainT
//表面输入结构体
struct Input
float2 uv_MainT//纹理坐标
//变量的声明
//--------------------------------【表面着色函数】-----------------------------
//输入:表面输入结构体
//输出:Unity内置的SurfaceOutputStandard结构体
//SurfaceOutputStandard原型如下:
struct SurfaceOutputStandard
// 漫反射颜色
// 切线空间法线
// 金属度;取0为非金属, 取1为金属
// 光泽度;取0为非常粗糙, 取1为非常光滑
// 遮挡(默认值为1)
//---------------------------------------------------------------------------------
void surf(Input IN, inout SurfaceOutputStandard o)
//【1】漫反射颜色为主纹理对应的纹理坐标,并乘以主颜色
fixed4c = tex2D(_MainTex, IN.uv_MainTex) * _C
//【2】将准备好的颜色的rgb分量作为漫反射颜色
o.Albedo= c.
//【3】金属度取自属性值
o.Metallic= _M
//【4】光泽度也取自属性值
o.Smoothness= _G
//【5】将准备好的颜色的alpha分量作为Alpha分量值
o.Alpha= c.a;
//===========结束CG着色器语言编写模块===========
//备胎为漫反射
FallBack&Diffuse&
}&接着来看Unity5的第二种Shader模板,无灯光着色器(Unlit Shader)模板。2.2 无灯光着色器(Unlit Shader)模板源码解析&Unlit Shader,简单来说,就是直接采用漫反射纹理,不考虑场景中的任何灯光效果。使用无灯光着色器的话,也就不能使用任何镜面或者法线效果了。Unlit系的Shader基本原理和其他Shader无异,但是计算量更小,更快速,更高效。而在Unity内置的各种着色器中,有如下的四种是Unlit系的:&好的,已经稍微解释了下什么是Unlit Shader。下面一起看一下Unity为我们提供的无灯光着色器模板的代码:&Shader &浅墨Shader编程/Volume8/无灯光着色器(Unlit Shader)模板&
//------------------------------------【属性值】------------------------------------
Properties
_MainTex(&Texture&, 2D) = &white& {}
//------------------------------------【唯一的子着色器】------------------------------------
//渲染类型设置:不透明
Tags{ &RenderType&=&Opaque& }
//细节层次设为:100
//--------------------------------唯一的通道-------------------------------
//===========开启CG着色器语言编写模块===========
//编译指令:告知编译器顶点和片段着色函数的名称
#pragma vertex vert
#pragma fragment frag
//着色器变体快捷编译指令:雾效。编译出几个不同的Shader变体来处理不同类型的雾效(关闭/线性/指数/二阶指数)
#pragma multi_compile_fog
//包含头文件
#include&UnityCG.cginc&
//顶点着色器输入结构
struct appdata
float4 vertex : POSITION;//顶点位置
float2 uv : TEXCOORD0;//纹理坐标
//顶点着色器输出结构
struct v2f
float2 uv : TEXCOORD0;//纹理坐标
UNITY_FOG_COORDS(1)//雾数据
float4 vertex : SV_POSITION;//像素位置
//变量声明
sampler2D _MainT
float4 _MainTex_ST;
//--------------------------------【顶点着色函数】-----------------------------
//输入:顶点输入结构体
//输出:顶点输出结构体
//---------------------------------------------------------------------------------
v2f vert (appdata v)
//【1】实例化一个输入结构体
//【2】填充此输出结构
//输出的顶点位置(像素位置)为模型视图投影矩阵乘以顶点位置,也就是将三维空间中的坐标投影到了二维窗口
o.vertex= mul(UNITY_MATRIX_MVP, v.vertex);
//【3】用UnityCG.cginc头文件中内置定义的宏,根据uv坐标来计算真正的纹理上对应的位置(按比例进行二维变换)
o.uv= TRANSFORM_TEX(v.uv, _MainTex);
//【4】用UnityCG.cginc头文件中内置定义的宏处理雾效,从顶点着色器中输出雾效数据
UNITY_TRANSFER_FOG(o,o.vertex);
//【5】返回此输出结构对象
//--------------------------------【片段着色函数】-----------------------------
//输入:顶点输出结构体
//输出:float4型的像素颜色值
//---------------------------------------------------------------------------------
fixed4 frag (v2f i) : SV_Target
//【1】采样主纹理在对应坐标下的颜色值
fixed4 col = tex2D(_MainTex, i.uv);
//【2】用UnityCG.cginc头文件中内置定义的宏启用雾效
UNITY_APPLY_FOG(i.fogCoord,col);
//【3】返回最终的颜色值
//===========结束CG着色器语言编写模块===========
}不难分析得到,无灯光着色器是一种顶点&片段着色器,这边模板给出的是单子着色器,单通道的写法。&并且,无灯光着色器中使用了一些UnityCG.cginc头文件中内置的宏,比如说TRANSFORM_TEX、UNITY_TRANSFER_FOG、UNITY_APPLY_FOG。接下来分别把这三个宏简单解释一下。2.2.1 TRANSFORM_TEX宏TRANSFORM_TEX宏的定义为:#define TRANSFORM_TEX(tex,name) (tex.xy *name##_ST.xy + name##_ST.zw)其位于UnityCG.cginc(Unity5.2.1版本)的第266行。其可以根据uv坐标来计算真正的纹理上对应的位置(按比例进行二维变换),组合上上文中定义的float4 _MainTex_ST,便可以计算真正的纹理上对应的位置。<span style="font-family:Microsoft YaHfont-size:18color:#.2 UNITY_TRANSFER_FOG宏&UNITY_TRANSFER_FOG宏的作用是从顶点着色输出雾数据。在UnityCG.cginc(Unity5.2.1版本)的第772行起,具体定义如下:&#if (SHADER_TARGET & 30) ||defined(SHADER_API_MOBILE)
//手机端或者Shader Mode 2.0: 计算每个顶点的雾效因子
#define UNITY_TRANSFER_FOG(o,outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.fogCoord =unityFogFactor
//Shader Mode 3.0和PC和游戏机: 计算每像素的雾距离,和每像素的雾效因子
#define UNITY_TRANSFER_FOG(o,outpos) o.fogCoord = (outpos).z
#endif2.2.3 UNITY_APPLY_FOG宏&UNITY_APPLY_FOG宏的定义稍微有些长,从UnityCG.cginc(Unity 5.2.1版本)的第787行起:&#if defined(FOG_LINEAR) || defined(FOG_EXP)|| defined(FOG_EXP2)
#if(SHADER_TARGET & 30) || defined(SHADER_API_MOBILE)
//mobile or SM2.0: fog factor was already calculated per-vertex, so just lerp thecolor
#defineUNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_FOG_LERP_COLOR(col,fogCol,coord)
//SM3.0 and PC/console: calculate fog factor and lerp fog color
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_CALC_FOG_FACTOR(coord);UNITY_FOG_LERP_COLOR(col,fogCol,unityFogFactor)
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol)
#ifdef UNITY_PASS_FORWARDADD
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,fixed4(0,0,0,0))
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,unity_FogColor)
#endif可以发现,UNITY_APPLY_FOG宏的作用是从顶点着色器中输出雾效数据,将第二个参数中的颜色值作为雾效的颜色值,且在正向附加渲染通道(forward-additive pass)中,自动设置纯黑色(fixed4(0,0,0,0))的雾效。其在定义中借助了UNITY_APPLY_FOG_COLOR宏,而我们也可以使用UNITY_APPLY_FOG_COLOR来指定特定颜色的雾效。&&&2.3 图像特效着色器(Image Effect Shader) 模板源码解析&这里的图像特效一般指的就是屏幕图像特效,在Camera加上各种滤镜,比如说屏幕溅血,像素化,色调的调整,画面模糊等效果。其也是一个顶点&片段着色器,且一般主要的操作集中在片段着色函数中。Unity为我们提供的模板,经过详细注释后的源码如下:&Shader &浅墨Shader编程/Volume8/图像特效Shader模板&
//------------------------------------【属性值】------------------------------------
Properties
_MainTex(&Texture&, 2D) = &white& {}
//------------------------------------【唯一的子着色器】------------------------------------
//关闭剔除操作
//关闭深度写入模式
ZWrite Off
//设置深度测试模式:渲染所有像素.等同于关闭透明度测试(AlphaTestOff)
ZTest Always
//--------------------------------唯一的通道-------------------------------
//===========开启CG着色器语言编写模块===========
//编译指令:告知编译器顶点和片段着色函数的名称
#pragma vertex vert
#pragma fragment frag
//包含头文件
#include&UnityCG.cginc&
//顶点着色器输入结构
struct appdata
float4 vertex : POSITION;//顶点位置
float2 uv : TEXCOORD0;//一级纹理坐标
//顶点着色器输出结构(v2f,vertex to fragment)
struct v2f
float2 uv : TEXCOORD0;//一级纹理坐标
float4 vertex : SV_POSITION;//像素位置
//--------------------------------【顶点着色函数】-----------------------------
//输入:顶点输入结构体
//输出:顶点输出结构体
//---------------------------------------------------------------------------------
//顶点着色函数
v2f vert (appdata v)
//【1】实例化一个输入结构体
//【2】填充此输出结构
//输出的顶点位置(像素位置)为模型视图投影矩阵乘以顶点位置,也就是将三维空间中的坐标投影到了二维窗口
o.vertex= mul(UNITY_MATRIX_MVP, v.vertex);
//输入的UV纹理坐标为顶点输出的坐标
//【3】返回此输出结构对象
//变量的声明
sampler2D _MainT
//--------------------------------【片段着色函数】-----------------------------
//输入:顶点输出结构体
//输出:float4型的像素颜色值
//---------------------------------------------------------------------------------
fixed4 frag (v2f i) : SV_Target
//【1】采样主纹理在对应坐标下的颜色值
fixed4 col = tex2D(_MainTex, i.uv);
//【2】将颜色值反向
//【3】返回最终的颜色值
//===========结束CG着色器语言编写模块===========
}&2.4 Shader模板中文注释格式调整版替换其实可以将Unity5中自带的上述三个着色器模板,替换成上文中贴出来的、经过详细注释和格式调整的Shader模板,这样在每次新建Shader时,就已经得到了具有很高可读性的Shader模板了,非常便捷。一定要吐槽的是,Unity5.2.1自带的三个Shader模板的缩进和空格完全是混用的,导致在通过他们新建出来的Shader里面写代码的时候,格式非常混乱,十分影响新版Unity中Shader的编码体验。很明显,准备此Shader模板的Unity开发人员的编码习惯有点欠缺,得在这里点名批评,轻喷一下。&浅墨在一发现他们格式有问题的时候就马上替换掉了,所以现在在Unity中写Shader代码的体验是非常棒的。这边也教大家如何替换掉自带的3个模板。Unity中Shader模板的位置是…Unity\Editor\Data\Resources\ScriptTemplates,比如说Unity安装在D:\ProgramFiles\路径下,整体路径就是:D:\ProgramFiles\Unity\Editor\Data\Resources\ScriptTemplates。在此路径下的3个txt,即为对应的三个Shader模板文件:83-Shader__Standard SurfaceShader-NewSurfaceShader.shader.txt84-Shader__UnlitShader-NewUnlitShader.shader.txt85-Shader__Image EffectShader-NewImageEffectShader.shader这边已经将调整好格式,详细注释的三种模板准备好了,下载之后,找到上面提到的…Unity\Editor\Data\Resources\ScriptTemplates目录。替换掉对应的3个txt文件即可。需要注意的是,如果你想自己DIY Shader模板,需要将txt保存为UTF-8编码格式,否则可能会出现乱码。替换的模板下载地址在这里:&&另外还有一个小细节可以提一下。如果你安装了两个或者两个以上的Unity5.1之后版本的Unity,如果你替换你当前使用的Unity路径下的模板文件后,新建的模板文件没有改变的话,你试着将所有的Unity5.1之后版本的路径下的这三个模板文件都进行替换,应该就可以实现想要的替换效果。浅墨的机器上就是同时存在Unity5.2.1和Unity5.2.0,然后使用Unity5.2.1,替换掉Unity5.2.1路径下的三个模板文件后,并没有发生变换。之后我按图索骥,替换了Unity 5.2.0版路径下的三个模板文化,才使得替换的模板文件生效。这估计是Unity多版本共存时,自身的一个小bug。 &&&&三、运动模糊屏幕特效的实现&&关于运动模糊特效,如果把握要要点的话,实现起来其实比较简单,就是一个脚本文件配合一个Shader,便可以实现较为出色的运动模糊特效。而其中的脚本文件用于控制Shader中的外部参数。也就是说一个屏幕特效通常分为两部分来实现:Shader实现部分脚本实现部分&下面我们对运动模糊屏幕特效的实现分别进行简单的描述。&可以点击跳转到Github,查看详细注释好的运动模糊屏幕特效的实现源码。&3.1 Shader实现部分先看一下Shader代码的写法,因为基本上已经逐行注释,就不花时间和笔墨仔细讲解了,详细注释的代码如下:Shader &浅墨Shader编程/Volume8/运动模糊特效标准版&
//------------------------------------【属性值】------------------------------------
Properties
_MainTex(&主纹理 (RGB)&, 2D) = &white& {}
_IterationNumber(&迭代次数&, Int)=16
//------------------------------------【唯一的子着色器】------------------------------------
//--------------------------------唯一的通道-------------------------------
//设置深度测试模式:渲染所有像素.等同于关闭透明度测试(AlphaTest Off)
ZTest Always
//===========开启CG着色器语言编写模块===========
//编译指令: 指定着色器编译目标为Shader Model 3.0
#pragma target 3.0
//编译指令:告知编译器顶点和片段着色函数的名称
#pragma vertex vert
#pragma fragment frag
//包含辅助CG头文件
#include &UnityCG.cginc&
//外部变量的声明
uniform sampler2D _MainT
uniform float _V
uniform float _Value2;
uniform float _Value3;
uniform int _IterationN
//顶点输入结构
struct vertexInput
float4 vertex : POSITION;//顶点位置
float4 color : COLOR;//颜色值
float2 texcoord : TEXCOORD0;//一级纹理坐标
//顶点输出结构
struct vertexOutput
half2 texcoord : TEXCOORD0;//一级纹理坐标
float4 vertex : SV_POSITION;//像素位置
fixed4 color : COLOR;//颜色值
//--------------------------------【顶点着色函数】-----------------------------
// 输入:顶点输入结构体
// 输出:顶点输出结构体
//---------------------------------------------------------------------------------
vertexOutput vert(vertexInput Input)
//【1】声明一个输出结构对象
vertexOutput O
//【2】填充此输出结构
//输出的顶点位置为模型视图投影矩阵乘以顶点位置,也就是将三维空间中的坐标投影到了二维窗口
Output.vertex = mul(UNITY_MATRIX_MVP, Input.vertex);
//输出的纹理坐标也就是输入的纹理坐标
Output.texcoord = Input.
//输出的颜色值也就是输入的颜色值
Output.color = Input.
//【3】返回此输出结构对象
//--------------------------------【片段着色函数】-----------------------------
// 输入:顶点输出结构体
// 输出:float4型的颜色值
//---------------------------------------------------------------------------------
float4 frag(vertexOutput i) : COLOR
//【1】设置中心坐标
float2 center = float2(_Value2, _Value3);
//【2】获取纹理坐标的x,y坐标值
float2 uv = i.texcoord.
//【3】纹理坐标按照中心位置进行一个偏移
//【4】初始化一个颜色值
float4 color = float4(0.0, 0.0, 0.0, 0.0);
//【5】将Value乘以一个系数
_Value *= 0.085;
//【6】设置坐标缩放比例的值
float scale = 1;
//【7】进行纹理颜色的迭代
for (int j = 1; j & _IterationN ++j)
//将主纹理在不同坐标采样下的颜色值进行迭代累加
color += tex2D(_MainTex, uv * scale + center);
//坐标缩放比例依据循环参数的改变而变化
scale = 1 + (float(j * _Value));
//【8】将最终的颜色值除以迭代次数,取平均值
color /= (float)_IterationN
//【9】返回最终的颜色值
//===========结束CG着色器语言编写模块===========
可以发现,这是一个单子着色器、单通道的顶点&片段着色器,顶点着色函数vert中基本上都是写的比较中规中矩的代码,精髓之处在于片段着色器frag中,用一个for循环,将像素颜色按照一条直线(uv * scale + center)进行了迭代采样累加,最终将采样的颜色的总和除以采样次数,得到了想要实现的运动模糊效果。&&3.2 脚本实现部分&脚本文件的实现方面,如下的即个点是要提出来专门讲一下的,即Shader文件的获取方法和OnRenderImage函数、Blit函数。&3.2.1 Shader文件的获取&Shader文件的获取可以使用Shader.Find函数实现。需要注意,Shader.Find函数参数应该和Shader代码中的名称一致,也就是下面的代码框架中xxx的值,而不是Shader的文件名:Shader &xxxx&
}举个例子,脚本代码如果是这样:CurShader = Shader.Find (&浅墨Shader编程/Volume8/运动模糊特效标准版&);&那么获取到的Shader,文件名是任意的,但Shader代码框架肯定是这样:&Shader &浅墨Shader编程/Volume8/运动模糊特效标准版&
}3.2.2 OnRenderImage函数与Blit函数OnRenderImage()函数是MonoBehaviour中提供的一个可供我们重写的函数,它在unity完成所有图片的渲染后被调用。所以我们想实现屏幕特效,主要依靠它来实现。而OnRenderImage函数的函数原型是:void OnRenderImage(RenderTexture sourceTexture,RenderTexture destTexture);另外,我们需要配合一个Graphics.Blit函数,实现从源纹理到目标渲染纹理的拷贝过程,其原型如下三种:public static void Blit(Texture source,RenderTexture dest);
public static void Blit(Texture source,RenderTexture dest, Material mat, int pass = -1);
public static void Blit(Texture source,Material mat, int pass = -1);其中。第一个参数,Texture类型的source,原始纹理。第二个参数,RenderTexture类型的dest,目标渲染纹理,若为null,表示直接将原始纹理拷贝到屏幕之上。第三个参数,Material类型的mat,使用的材质(其实也就是Shader),根据不同材质的准备,就是在这里实现后期的效果的。第四个参数,int类型的pass,有默认值 -1,表示使用所有的pass。用于指定使用哪一个pass。&说个题外话,其实在很久之前的Win32 API游戏编程中,同样原理和相似用途的Blit函数用得太多了。&好的,最后看一下实现屏幕特效的核心代码,如下:&
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
//着色器实例不为空,就进行参数设置
if (CurShader != null)
//设置Shader中的外部变量
material.SetFloat(&_IterationNumber&, IterationNumber);
material.SetFloat(&_Value&, Intensity);
material.SetFloat(&_Value2&, OffsetX);
material.SetFloat(&_Value3&, OffsetY);
material.SetFloat(&_Value4&, blurWidth);
material.SetVector(&_ScreenResolution&, new Vector4(sourceTexture.width, sourceTexture.height, 0.0f, 0.0f));
//拷贝源纹理到目标渲染纹理,加上我们的材质效果
Graphics.Blit(sourceTexture, destTexture, material);
//着色器实例为空,直接拷贝屏幕上的效果。此情况下是没有实现屏幕特效的
//直接拷贝源纹理到目标渲染纹理
Graphics.Blit(sourceTexture, destTexture);
}& & & & & & &&&最后看一下详细注释后的脚本完整实现代码:using UnityE
using System.C
[ExecuteInEditMode]
public class MotionBlurEffects : MonoBehaviour
//-------------------变量声明部分-------------------
#region Variables
public Shader CurS//着色器实例
private Vector4 ScreenR//屏幕分辨率
private Material CurM//当前的材质
[Range(5, 50)]
public float IterationNumber = 15;
[Range(-0.5f, 0.5f)]
public float Intensity = 0.125f;
[Range(-2f, 2f)]
public float OffsetX = 0.5f;
[Range(-2f, 2f)]
public float OffsetY = 0.5f;
public static float ChangeV
public static float ChangeValue2;
public static float ChangeValue3;
public static float ChangeValue4;
#endregion
//-------------------------材质的get&set----------------------------
#region MaterialGetAndSet
Material material
if (CurMaterial == null)
CurMaterial = new Material(CurShader);
CurMaterial.hideFlags = HideFlags.HideAndDontS
return CurM
#endregion
//-----------------------------------------【Start()函数】---------------------------------------------
// 说明:此函数仅在Update函数第一次被调用前被调用
//--------------------------------------------------------------------------------------------------------
void Start()
//依此赋值
ChangeValue = I
ChangeValue2 = OffsetX;
ChangeValue3 = OffsetY;
ChangeValue4 = IterationN
//找到当前的Shader文件
CurShader = Shader.Find(&浅墨Shader编程/Volume8/运动模糊特效标准版&);
//判断是否支持屏幕特效
if (!SystemInfo.supportsImageEffects)
//-------------------------------------【OnRenderImage()函数】------------------------------------
// 说明:此函数在当完成所有渲染图片后被调用,用来渲染图片后期效果
//--------------------------------------------------------------------------------------------------------
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
//着色器实例不为空,就进行参数设置
if (CurShader != null)
//设置Shader中的外部变量
material.SetFloat(&_IterationNumber&, IterationNumber);
material.SetFloat(&_Value&, Intensity);
material.SetFloat(&_Value2&, OffsetX);
material.SetFloat(&_Value3&, OffsetY);
material.SetVector(&_ScreenResolution&, new Vector4(sourceTexture.width, sourceTexture.height, 0.0f, 0.0f));
//拷贝源纹理到目标渲染纹理,加上我们的材质效果
Graphics.Blit(sourceTexture, destTexture, material);
//着色器实例为空,直接拷贝屏幕上的效果。此情况下是没有实现屏幕特效的
//直接拷贝源纹理到目标渲染纹理
Graphics.Blit(sourceTexture, destTexture);
//-----------------------------------------【OnValidate()函数】--------------------------------------
// 说明:此函数在编辑器中该脚本的某个值发生了改变后被调用
//--------------------------------------------------------------------------------------------------------
void OnValidate()
//将编辑器中的值赋值回来,确保在编辑器中值的改变立刻让结果生效
ChangeValue4 = IterationN
ChangeValue = I
ChangeValue2 = OffsetX;
ChangeValue3 = OffsetY;
//-----------------------------------------【Update()函数】------------------------------------------
// 说明:此函数在每一帧中都会被调用
//--------------------------------------------------------------------------------------------------------
void Update()
if (Application.isPlaying)
IterationNumber = ChangeValue4;
Intensity = ChangeV
OffsetX = ChangeValue2;
OffsetY = ChangeValue3;
//找到对应的Shader文件
#if UNITY_EDITOR
if (Application.isPlaying != true)
CurShader = Shader.Find(&浅墨Shader编程/Volume8/运动模糊特效标准版&);
//-----------------------------------------【OnDisable()函数】---------------------------------------
// 说明:当对象变为不可用或非激活状态时此函数便被调用
//--------------------------------------------------------------------------------------------------------
void OnDisable()
if (CurMaterial)
DestroyImmediate(CurMaterial);
&3.3 关于如何使用此特效使用方面的话比较简单,把脚本文件拖到主摄像机上面,效果就出来了。脚本文件中有如下这些参数可以调整,得到不同的模糊效果:Iteration Number- 迭代次数Intensity - 模糊强度Offset X - X方向上的偏移Offset Y - Y方向上的偏移四、最终的效果展示&这边贴几张场景的效果图和使用了屏幕特效后的效果图。需要注意的是,本次的场景效果,除了类似CS/CF的FPS游戏的控制系统以外,还可以使用键盘上的按键【F】,开启或者关闭运动模糊特效。正如下图所展示的:&下面放几张测试截图。&首先,Unity5中,导出的exe使用了新的片头Logo,质感不错,好评:&&城镇中的原始效果:&&运动模糊后的效果:&&海港原始效果:&海港运动模糊后的效果:&&城镇草丛前的效果:&城镇草丛前运动模糊后的效果:&沙滩原始效果:&沙滩运动模糊后的效果:&海面原始效果:&海面运动模糊后的效果:&&五、后记&本来准备这次更新再稍微剖析一下Unity5中主推的Standard Shader的写法思路的,但发现这篇博文的篇幅已经有点长了,那么,StandardShader就留到下次更新再讲。本次的更新大致如此,以后的更新依然是安排在每周一,最近一段时间尽量保证每周都更。最后,感谢各位捧场,我们下周再见。附: 本博文相关下载链接清单&
我的热门文章
&#xe60e;21
即使是一小步也想与你分享

我要回帖

更多关于 口袋妖怪晃动的草丛 的文章

 

随机推荐