|
大家好,我是老莫,今天分享一下溶解效果的制作方法。
首先定义clip和color属性
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color",Color) =(1,1,1,1)
_Clip("Clip",Range(0,1)) = 0
因为我们要做片段舍弃,所以将Clip运算放在片段着色器中
X代表一个数值,当X<0时,则舍弃掉此片段.
括号中的X就是我们要舍弃掉的片段值,当X<0时,该片段舍弃
只有当x&amp;amp;amp;amp;amp;amp;lt;0,片段才会舍弃
当X为某个数值时,只能实现所有像素的取舍,那么我们想要部分像素舍弃,达到溶解效果,就需要这样一张噪波图。
网上随意找一张噪波图即可
这样做的原理是,噪波图中数值代表了一个Range(0,1),任何一个像素都被限制在这个范围内,并且随机分布,此时我们将噪波图减去一个Range(0,1),就可以控制最终的值了。
属性面板添加一个-DissolveTex,在片段着色器采样它,然后使用采样后的图减去Clip值
fixed4 tex = tex2D(_MainTex,i.uv);
fixed4 dissolveTex = tex2D(_DissolveTex,i.uv);
clip(dissolveTex-_Clip);
不同Clip值所产生的的效果
现在对该效果进行优化,增加一个溶解边缘
我们需要这样一张贴图 _RampTex
PS中随便制作一个即可
我们做这张图的目的在于,将_DissolveTex中从0到1(黑到白)与_RampTex中从左到右对应,听起来有点莫名其妙,慢慢往下看。
使用_DissolveTex采样上图
fixed4 tex = tex2D(_MainTex,i.uv);
fixed4 dissolve = tex2D(_DissolveTex,i.uv);
fixed4 ramptex = tex2D(_RampTex,dissolve);
clip(dissolve-_Clip);
fixed4 c = tex * _Color+ramptex;
return c;
创建一个平面可以更直观地看到效果,请注意现在我们已完成了_DissolveTex中从0到1(黑到白)与_RampTex中从左到右对应。但是目前边缘没有随着溶解的值变化,这里我们需要用到unity内置函数smoothstep。
如果 x 比min 小,返回 0;如果 x 比max 大,返回 1;如果 x 处于范围 [min,max]中,则返回 0 和 1 之间的值(按值在min和max间的比例取平滑值)。
smoothstep(min,max,x)
我们将_Clip设为最小值,再配合_Clip值变化,就可以使溶解边缘始终都是从_RampTex的最左边开始采样
fixed4 tex = tex2D(_MainTex,i.uv);
fixed4 dissolve = tex2D(_DissolveTex,i.uv);
fixed4 ramptex = tex2D(_RampTex,smoothstep(_Clip,1,dissolve));
clip(dissolve-_Clip);
fixed4 c = tex * _Color+ramptex;
这时我们的溶解边缘正确了,但是_RampTex覆盖了主纹理.
在上一步中,我们将最小值设为_Clip,得以控制边缘,现在我们把最大值设为_Clip+0.1,这样使得我们只在_clip 和_clip+0.1之间采样_RampTex
clip=0.2
划重点
现在我们实现了溶解效果,基本了解了原理,但是以上方法计算量较大(smoothstep),现在我们讲讲如何优化。首先我们看一下smoothstep 的原理
float smoothstep (float min, float max, float x)
{
float t = saturate ((x - min) / (max - min));
return t * t * (3.0 - (2.0 * t));
}
其中return t * t *(3.0-(2.0* t));是为了使最终值平滑,运算量太大,我们可以把这一步省掉,直接手写差值,使用saturate
fixed4 tex = tex2D(_MainTex,i.uv);
fixed4 dissolveTex = tex2D(_DissolveTex,i.uv);
clip(dissolveTex-_Clip);
fixed dissolvevalue = saturate(dissolveTex-_Clip)/(_Clip+0.1-_Clip);
fixed4 ramptex = tex2D(_RampTex,dissolvevalue);
fixed4 c = tex * _Color+ramptex;
return c;
到这里unity shader中的溶解效果就完成了,收工。
最后附上源码
Shader &#34;Unlit/rongjie&#34;
{
Properties
{
_MainTex (&#34;Texture&#34;, 2D) = &#34;white&#34; {}
_Color (&#34;Color&#34;,Color) =(1,1,1,1)
_Clip(&#34;Clip&#34;,Range(0,1)) = 0
_DissolveTex(&#34;DissolveTex&#34;,2D) = &#34;white&#34;{}
_RampTex (&#34;RampTex&#34;,2D) = &#34;white&#34;{}
}
SubShader
{
Tags { &#34;RenderType&#34;=&#34;Opaque&#34; }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include &#34;UnityCG.cginc&#34;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
sampler2D _MainTex;
sampler2D _DissolveTex;
sampler2D _RampTex;
float4 _MainTex_ST;
fixed4 _Color;
float _Clip;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 tex = tex2D(_MainTex,i.uv);
fixed4 dissolveTex = tex2D(_DissolveTex,i.uv);
clip(dissolveTex-_Clip);
fixed dissolvevalue = saturate(dissolveTex-_Clip)/(_Clip+0.1-_Clip);
fixed4 ramptex = tex2D(_RampTex,dissolvevalue);
fixed4 c = tex * _Color+ramptex;
return c;
}
ENDCG
}
}
} |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|