闲暇时看纸鱼实况,看到游戏中有个这样的效果:
视频链接,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游戏特效-仿《黑暗欺骗》模型消融消失效果相关推荐

  1. Unity Shader人物发光特效

    Unity Shader人物发光特效 写在前面 效果 实现方法 项目地址 写在后面 写在前面 当人物被击中或则有任务引导提升时,人物身上将会有发光特效,这里我自己实现一下. 效果 实现方法 核心思想就 ...

  2. Unity Shader 之 实现简单的动态过场切换图片的效果

    Unity Shader 之 实现简单的动态过场切换图片的效果 目录 Unity Shader 之 实现简单的动态过场切换图片的效果 一.简单介绍

  3. 【unity shader】unity游戏特效-仿《幽灵特警》生命扫描仪索敌效果(运用深度、相交算法、CommandBuffer)

    街机游戏<幽灵特警>第一关有个这样的效果: 嗯,透视挂hhhh,关键很炫. 来做个吧. 第一步,做"墙" 仔细观察GIF可见,这个效果像是一堵向前跑的墙,撞到无生命物体 ...

  4. 【Unity Shader】UI特效在RawImage上使用运行良好,但是在Image上则不是预期效果的问题

    疑惑 在最开始用shader做UI特效的时候,或多或少会遇到这样的问题,就是用RawImage能得到预期效果,而用Image很有可能就得不到预期效果,关键原因还是UV的差异引起的. 简单说下RawIm ...

  5. Unity Shader:Unity网格(1)---顶点,三角形朝向,法线,uv,以及双面渲染三角形

    1,顶点 顶点是网格最基础的组成部分,可通过mesh.vertices获取和赋值.mesh.vertices是一个Vector3的数组,每个Vector3代表了此顶点在世界空间中的位置每个Vector ...

  6. Unity Shader unity文档学习笔记(十一):战争迷雾核心算法

    核心算法 非常简单 主要就是把一个点的世界坐标转换到贴图的UV坐标 给整个场景一个大的plane 加上写的shader 摄像机位置调成plane的正上方 Shader "Unlit/FogR ...

  7. Unity Shader unity文档学习笔记(十七):径向模糊 实现类似冲锋时的速度感

    实现思路:离中心点越远的像素 模糊效果越明显 UV偏移的量越大 shader // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'Uni ...

  8. Unity Shader着色器优化

    对游戏开发者而言,着色器长久以来就是游戏开发中的重要部分,在Unity中编写并实现着色器的过程直观且高效,优秀的着色器还可以创造非常精美的游戏画面,同时保证极高的性能.今天将由Unity的技术工程师张 ...

  9. 【Unity Shader实例】 水体WaterEffect(一) 设计

    Unity Shader 水体效果实现的设计 在设计水体效果的实现方案之前,我们先参考一下大神们写好的精彩的例子,比如DCG Water Shader的效果,这也是我们努力的目标. 好!~ 现在开始实 ...

最新文章

  1. SpringCloud:入门介绍
  2. 在网站推广的道路中同样的起点,知乎豆瓣却走上了不相交的两条路
  3. lightningJS之动画
  4. excel常用公式整理
  5. 超文本传输协议及HTTP包
  6. high-speed A/D performance metrics and Amplifie...
  7. Spring MVC-视图解析器(View Resolverr)-内部资源视图解析器(Internal Resource View Resolver)示例(转载实践)...
  8. 腾讯回应封杀质疑;王思聪评社交软件;董明珠连任格力董事长;| 极客头条...
  9. 20201219:力扣219周周赛题解
  10. C# ChartControl
  11. eviews9.0详细安装步骤
  12. gps高斯utm_经纬度与高斯坐标及经纬度与UTM坐标互转
  13. 判断一个double类型的数是不是整数
  14. VMware如何安装windows10教程
  15. 比人工更智能更有趣的植物识别--形色
  16. IOM计算机组成原理,计算机组成原理设计教案.doc
  17. 青春、情动、永恒的经典——岩井俊二
  18. 《Linux命令行与shell脚本大全》笔记
  19. 钣金行业mes解决方案,缩短产品在制周期
  20. 产品经理的职责 产品规划 产品设计 推导研发 职责误区

热门文章

  1. NPN型三极管的工作原理
  2. Android aab文件签名过程
  3. JS实现浏览器打印、打印预览
  4. vivo商城促销系统架构设计与实践-概览篇
  5. iphone11夜景模式怎么开
  6. 对两种类型的蘑菇图像进行识别与分类——使用SVM分类器(matlab)
  7. 关于迅盘Turbo Memory的ReadyDrive功能被禁用的思考
  8. 看雪2w3w安卓高级研修Frida原理学习
  9. 委派模式(Delegate)
  10. jQuery事件委派