Shader消散特效(如回城)

在很多游戏中能够看到消散,燃烧等特效。

如:

所以今天写简单的消散特效的shader代码!!!

(学习的庄懂的视频学到的,强烈新手学习庄懂视频)

 

 

第一步思考:我们能看到什么!

我们能够看到网格的消散,这个消散过程中:

第一:网格的偏移,我们可以简单的用顶点向法线方向的偏移,所以我们需要先有一张网格遮罩的贴图。

第二:有些前面一点的网格提前消散,所以我们需要模型网格随机灰度遮罩。

第三:第二张图中可以看到这不是一个同一高度一起消散的,说明有弧度,这里我们用模型面坡度遮罩实现。

然后节约采样次数,所以可以合并在一张图中。

第二步如何写:

首先获取定义2张贴图,和控制参数:

        [Header(Effect)]
        _EffMap01   ("特效纹理1",2D) = "gray"{}
        _EffMap02   ("特效纹理2",2D) = "gray"{}
        [HDR]_EffCol     ("特效颜色",Color) = (0,0,0,0)
        _EffParams  ("X:波密度 Y:波速度 Z:混乱度 W:消散强度",vector) = (0.03,3.0,0.3,2.5)



        uniform sampler2D _EffMap01;
        uniform sampler2D _EffMap02 ;  
        uniform float3 _EffCol;
        uniform float4 _EffParams;  

其中第一张图就是前面制作的网格相关的贴图,后者就是noise扰动图。

然后我们先写出顶点动画:

float4 CyberpunkAnim(float noise,float mask,float3 normal,inout float3 vertex){
                //锯齿波
                float baseMask = abs(frac(vertex.y * _EffParams.x - _Time.x * _EffParams.y) - 0.5) * 2.0;
                
                //返回值
                return baseMask;
            }

 两张图看不出是什么波,这里用锯齿波后面能够控制强度能够多次显示,好看点。

为什么锯齿波这么写!!

f(x) = abs(frac(x))

 然后这个波的值域在[0,1]之间 所以直接输出这个的话

出现了严重锯齿感,没有缓慢的起伏的效果所以

f(x) = frac(x)-0.5

值域控制在[-0.5,0.5]之间 

f(x) = abs(frac(x)-0.5) * 2

值域就能控制在[0,1]并且锯齿感消除了,有了明显的起伏

 

 加上时间速度和强度的配合就有了简单的波动的效果了。

为了让我们的波不那么连续,我们控制了白的时间是黑的2倍。

baseMask = min(1.0,baseMask * 2.0);

 f(x) = min(1.0,(abs(frac(x)-0.5) * 2) * 2)

相当于原本值域[0,1]变成了[0,2]然后y=1来截取了这个图形 所以值域还是在[0,1]之间。

                //noise偏移锯齿波
                baseMask += (noise - 0.5) * _EffParams.z;

在顶点处理阶段先采样了noise扰动图 记住noise 区间也在[0,1]想要偏移方向正确 控制到[-0.5,0.5]之间。

较为关键的地方:

                //smoothstep出各级Mask
                float4 effectMask = float4(0,0,0,0);
                effectMask.x = smoothstep(0.0,0.9,baseMask);
                effectMask.y = smoothstep(0.2,0.7,baseMask);
                effectMask.z = smoothstep(0.4,0.5,baseMask);

smoothstep(a, b, x)

 f(x) = smoothstep(0.2,0.7,x) 

 

 smoothstep会给我们一个很平滑的过程。小于前者则为0,大于后者则为1,中间就是3a^2-2a^3。

然后3个作为rgb通道的控制,也是一个显示范围。

                //顶点色遮罩
                effectMask.w = mask;
                //顶点动画
                vertex.xz += normal.xz * (1.0-effectMask.y) * _EffParams.w * mask;

最后就是顶点向法线方向的偏移,前面2张图能看出就是波动范围内才有偏移,然后用了g通道的范围,其他范围都可以看自己的需求了,还有消散强度。不要忘记底座是没有消散的所以要使用上遮罩。

最后就是贴上网格图来控制咯!

                float3 _EffMap01_var = tex2D(_EffMap01, i.uv1).xyz;
                float meshMask = _EffMap01_var.x;
                float faceRandomMask = _EffMap01_var.y;
                float faceSlopeMask = _EffMap01_var.z;

采样网格贴图,并且获取xyz通道内容。x:网格遮罩,y:模型网格随机灰度遮罩。 z:模型面坡度遮罩。

                // 获取EffectMask
                float smallMask = i.effectMask.x;
                float midMask = i.effectMask.y;
                float bigMask = i.effectMask.z;
                float baseMask = i.effectMask.w;

 获取顶点动画返回的各通道值。xyz:三个范围大小,w:底座遮罩。

// 计算Opacity
    float midOpacity= saturate(floor(min(faceRandomMask, 0.999999) + midMask));
    float bigOpacity= saturate(floor(min(faceSlopeMask, 0.999999) + bigMask));
    float opacity = lerp(1.0, min(bigOpacity, midOpacity), baseMask);

 前两行是分别是模型网格随机灰度遮罩用和中范围的叠加,模型面坡度遮罩和大范围的叠加。

最后进行了2者实现的判定,和控制底座遮罩。

// 叠加自发光
    float meshEmitInt = (bigMask - smallMask) * meshMask;
    meshEmitInt = meshEmitInt * meshEmitInt;
    float3 emission = _EffCol * meshEmitInt * baseMask;

 

最后就是自发光,前面是控制自发光的范围在大范围和小范围之间,这一块我来显示特效自发光颜色。

 

你好!关于UnityShader消散效果,我可以给你一些指导。 在Unity中,你可以使用自定义的Shader来实现消散效果。消散效果通常基于一个纹理,并且通过渐变将纹理逐渐消除。 首先,你需要创建一个自定义的Shader。在Shader的片段着色器中,你可以使用插值的纹理坐标来获取纹理颜色。然后,可以根据需要添加一些控制消散效果的参数。 接下来,你可以使用一个控制器(比如时间或距离)来改变纹理坐标,从而实现纹理的渐变效果。通过改变纹理坐标,你可以将纹理从中心点向四周逐渐消失。 以下是一个简单的示例代码,用于实现基本的消散效果: ```csharp Shader "Custom/DissolveShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _DissolveAmount ("Dissolve Amount", Range(0, 1)) = 0 } SubShader { Pass { Tags { "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float _DissolveAmount; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag(v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); col.a *= smoothstep(_DissolveAmount - 0.1, _DissolveAmount + 0.1, i.uv.x); return col; } ENDCG } } } ``` 在这个示例代码中,_DissolveAmount 参数控制了消散的程度。你可以根据需要调整这个值来实现不同的效果。 希望这些信息对你有所帮助!如果你有任何其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值