【unity shader】unity游戏特效-仿《黑暗欺骗》模型消融消失效果
闲暇时看纸鱼实况,看到游戏中有个这样的效果:
视频链接,UP主:薄海纸鱼
卧槽,放慢再看一遍:
可以看到,玩家在惹怒Boss后,所有的椅子瞬间消失,Boss战还未开打就已经逼格拉满了。给玩家留下震撼的印象以及实力差所带来的压抑和绝望。
太帅了!这个效果我也想要!
实现思路
仔细观察椅子消失瞬间:
想要实现这个效果有三个要求:
一是要剔除片元来达到物体消融的效果。
二是在剔除片元的操作里设定剔除的条件。
三是在剔除的边缘上颜色高亮
看完了冯乐乐女神的书,我们就知道解决第一个问题需要用到的就是clip函数,该函数可以剔除指定的片元
clip(x)
///相当于下面这句
if(x < 0)
{discard;
}
ok,上代码:
Shader "Unlit/DirectionalDissolve"
{Properties{_MainTex ("Texture", 2D) = "white" {}_DissolveDirection ("消融方向",Vector) = (0,0,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 objPos : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;half4 _DissolveDirection;v2f vert (appdata v){v2f o;//v.vertex.xyz += v.normal * saturate(sin(_Time.w)) * 10;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.objPos = v.vertex;//mul(unity_ObjectToWorld,v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);return col;}ENDCG}}
}
这里最好开Cull off,否则正面剔除一半时玩家会发现后面早空了。
可以看见关键代码在这两句
half dis = i.objPos.y - _DissolveDirection.y;
clip(dis);
clip()剔除掉我们不需要的片元。而dis的那句话是用物体对象的模型坐标的y轴与我们给的一个三维矢量的y轴进行相减计算,轴上相减的结果小于0的部分片元就会被剔除掉。
还可以拓展成下面这样:
half3 dis = i.objPos.xyz - _DissolveDirection.xyz;
half discardCondition = * dis.y;
clip(discardCondition);
如果想要左右方向的消除,就把dis.y改为x即可。
但要注意,这个是利用的模型坐标系进行计算。如果一个模型(假设是人体模型)。他模型坐标系的Y轴不是向上而是向前。那你就不能用y轴上的计算来实现从头到脚的顺序消失。
你可以考虑用世界坐标系解决,世界坐标系XYZ轴方向是不会变的,但同样会引入新的问题——物体所在的位置会影响计算结果。这个问题我目前还没有比较好的解决方法,看看以后有没有好兄弟来帮个忙。
OK,这是目前的效果:
emmmmmm,其实我想要你们从头的方向开始消失,而不是脚。。。
Shader "Unlit/DirectionalDissolve"
{Properties{..._InverseDir("反向",Range(-1,1)) = 1}...fixed _InverseDir;...fixed4 frag (v2f i) : SV_Target{half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = _InverseDir * dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);return col;}ENDCG}}
}
这里我用了一个笨办法,引入一个新int属性,用1和-1来控制消融的方向;想要反方向?乘个负一就好。
OK,前两个问题搞定了,现在需要解决高亮的问题了。
咱们前面不是利用两个矢量相减计算吗?小于0的部分被剔除掉了。那我们就再设定一个小于某值但大于0的范围,相减结果在这个范围内的,返回的颜色值要发生改变。
效果如下:
if(discardCondition < _Width)
{ return fixed4(1,1,1,1); }
图中的_width值设为0.1,fixed4(1,1,1,1)代表输出白色。
我这里用了if,但这种语句是不建议用在shader里的,GPU上做这种逻辑判断是非常非常奢侈的。
可惜目前没有想出更好的办法,只能先把问题放在这了。
最终代码:
Shader "Unlit/DirectionalDissolve"
{Properties{_MainTex ("Texture", 2D) = "white" {}_DissolveDirection ("消融方向",Vector) = (0,0,0,0)_InverseDir("反向",Range(-1,1)) = 1[HDR]_Color ("颜色",Color) = (1,1,1,1)_Width ("宽度",Range(0.0,1.0)) = 0.1}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 objPos : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;half4 _DissolveDirection;fixed _InverseDir;fixed4 _Color;fixed _Width;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.objPos = v.vertex;return o;}fixed4 frag (v2f i) : SV_Target{//_DissolveDirection.y = sin(_Time.y);half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = _InverseDir * dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);if(discardCondition < _Width){ return _Color * col; }return col;}ENDCG}}
}
最终效果:
2021/8/15 更新:
在网上找到了puppet_master大佬的文章,他的文章深度和广度真的不是我这种萌新能比的。
参考文章链接,作者:puppet_master
这是看过他的文章后改进的代码:
Shader "Unlit/DirectionalDissolve"
{Properties{_MainTex ("Texture", 2D) = "white" {}_DissolveDirection ("消融方向",Vector) = (0,0,0,0)_InverseDir("反向",Range(-1,1)) = 1[HDR]_Color ("颜色",Color) = (1,1,1,1)_Width ("宽度",Range(0.0,1.0)) = 0.1}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 objPos : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;half4 _DissolveDirection;fixed _InverseDir;fixed4 _Color;fixed _Width;v2f vert (appdata v){v2f o;//v.vertex.xyz += v.normal * saturate(sin(_Time.w)) * 10;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.objPos = v.vertex;//mul(unity_ObjectToWorld,v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{_DissolveDirection.y = sin(_Time.y);half3 dis = i.objPos.xyz - _DissolveDirection.xyz;half discardCondition = _InverseDir * dis.y;clip(discardCondition);fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 col = fixed4(texColor.rgb,1.0);//if(discardCondition < _Width)//{ return _Color * col; }//return col;//更好的办法fixed t = saturate(sign(_Width - discardCondition));return (1 - t) * col + t * _Color * col;}ENDCG}}
}
其中,sign函数长这样:
当x>0,sign(x)=1;
当x=0,sign(x)=0;
当x<0, sign(x)=-1;
它用这里是为了保证颜色边界鲜明。如果没有sign函数的处理它会变成这样:
(这里的材质参数宽度值为0.35,颜色的边界都如此不明显。而前面的图宽度值仅为0.1)
【unity shader】unity游戏特效-仿《黑暗欺骗》模型消融消失效果相关推荐
- Unity Shader人物发光特效
Unity Shader人物发光特效 写在前面 效果 实现方法 项目地址 写在后面 写在前面 当人物被击中或则有任务引导提升时,人物身上将会有发光特效,这里我自己实现一下. 效果 实现方法 核心思想就 ...
- Unity Shader 之 实现简单的动态过场切换图片的效果
Unity Shader 之 实现简单的动态过场切换图片的效果 目录 Unity Shader 之 实现简单的动态过场切换图片的效果 一.简单介绍
- 【unity shader】unity游戏特效-仿《幽灵特警》生命扫描仪索敌效果(运用深度、相交算法、CommandBuffer)
街机游戏<幽灵特警>第一关有个这样的效果: 嗯,透视挂hhhh,关键很炫. 来做个吧. 第一步,做"墙" 仔细观察GIF可见,这个效果像是一堵向前跑的墙,撞到无生命物体 ...
- 【Unity Shader】UI特效在RawImage上使用运行良好,但是在Image上则不是预期效果的问题
疑惑 在最开始用shader做UI特效的时候,或多或少会遇到这样的问题,就是用RawImage能得到预期效果,而用Image很有可能就得不到预期效果,关键原因还是UV的差异引起的. 简单说下RawIm ...
- Unity Shader:Unity网格(1)---顶点,三角形朝向,法线,uv,以及双面渲染三角形
1,顶点 顶点是网格最基础的组成部分,可通过mesh.vertices获取和赋值.mesh.vertices是一个Vector3的数组,每个Vector3代表了此顶点在世界空间中的位置每个Vector ...
- Unity Shader unity文档学习笔记(十一):战争迷雾核心算法
核心算法 非常简单 主要就是把一个点的世界坐标转换到贴图的UV坐标 给整个场景一个大的plane 加上写的shader 摄像机位置调成plane的正上方 Shader "Unlit/FogR ...
- Unity Shader unity文档学习笔记(十七):径向模糊 实现类似冲锋时的速度感
实现思路:离中心点越远的像素 模糊效果越明显 UV偏移的量越大 shader // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'Uni ...
- Unity Shader着色器优化
对游戏开发者而言,着色器长久以来就是游戏开发中的重要部分,在Unity中编写并实现着色器的过程直观且高效,优秀的着色器还可以创造非常精美的游戏画面,同时保证极高的性能.今天将由Unity的技术工程师张 ...
- 【Unity Shader实例】 水体WaterEffect(一) 设计
Unity Shader 水体效果实现的设计 在设计水体效果的实现方案之前,我们先参考一下大神们写好的精彩的例子,比如DCG Water Shader的效果,这也是我们努力的目标. 好!~ 现在开始实 ...
最新文章
- SpringCloud:入门介绍
- 在网站推广的道路中同样的起点,知乎豆瓣却走上了不相交的两条路
- lightningJS之动画
- excel常用公式整理
- 超文本传输协议及HTTP包
- high-speed A/D performance metrics and Amplifie...
- Spring MVC-视图解析器(View Resolverr)-内部资源视图解析器(Internal Resource View Resolver)示例(转载实践)...
- 腾讯回应封杀质疑;王思聪评社交软件;董明珠连任格力董事长;| 极客头条...
- 20201219:力扣219周周赛题解
- C# ChartControl
- eviews9.0详细安装步骤
- gps高斯utm_经纬度与高斯坐标及经纬度与UTM坐标互转
- 判断一个double类型的数是不是整数
- VMware如何安装windows10教程
- 比人工更智能更有趣的植物识别--形色
- IOM计算机组成原理,计算机组成原理设计教案.doc
- 青春、情动、永恒的经典——岩井俊二
- 《Linux命令行与shell脚本大全》笔记
- 钣金行业mes解决方案,缩短产品在制周期
- 产品经理的职责 产品规划 产品设计 推导研发 职责误区