前言
本章用shader简单实现火焰,感谢Kerry大佬的教学

一、采样噪声图
//用平移uv的方法采用噪声图
float2 panner=-1.0*_Time.y * _NoiseSpeed + i.uv_noise;
float noiseTex=tex2D(_NoiseMap,panner).r;
panner是混合一个可以平移的uv,噪声图仅alpha通道处理,故只求r即可

噪声图

二、采样渐变图
//采样渐变图
float gradientTex=tex2D(_Gradient,i.uv).r;
//alpha通道进行插值混合,混合渐变图,只让噪声下边显示(SoftNess进行软边缘处理)
float finalAlpha=smoothstep((noiseTex-_SoftNess),noiseTex,gradientTex);
渐变图

通过smoothstep与噪声图做插值,让渐变图可以下部分显示更多,而上部分显示更少,从而模拟火焰大致样貌,另外也可以让火焰边缘显得更加柔和,_SoftNess正是控制这一部分

若_SoftNess=0

三.火焰颜色
代码如下
//火焰颜色部分处理
float gradientEnd=(1.0-gradientTex)*_GradientEnd;//获取外火焰的alpha
float4 mainColor=_FireColor*_EmissIntensity;//主颜色
float endColor=_EndMiss*gradientEnd*noiseTex;//外火焰颜色//分界明显,多乘一个noise
float4 finalColor=float4(mainColor.r,(mainColor.g+endColor),mainColor.b,finalAlpha)*col;//总颜色/col为mainTex颜色
由于外焰和内焰颜色不一样,故分开取色,_EndMiss为外火焰强度,外火焰多乘一个noiseTex是为了让进行扰动不让分层太明显

四、火焰形状
代码如下
//火焰形状
float noiseDisturbance=(noiseTex*_Offset.x+_Offset.y)*_NoiseIns*0.01*gradientEnd;//噪声扰动,让形状不那么平整
float2 uv_shape=i.uv+noiseDisturbance;
float shape=tex2D(_FireShape,uv_shape).r;
finalColor.a=finalAlpha*shape;
形状图

听过调整_Offset和_NoiseIns可以调出合适的形状
大功告成

总代码
Shader "Unlit/Fire_Code"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_FireColor("FireColor",Color)=(0,0,0,0)
_EmissIntensity("EmissIntensity",float)=0
_NoiseMap("NoiseMap",2D)="white"{}
_NoiseSpeed("NoiseSpeed",float)=0
_Gradient("Gradient",2D)="white"{}
_GradientEnd("GradientEnd",float)=0
_EndMiss("EndMiss",float)=0
_SoftNess("SoftNess",float)=0
_FireShape("FireShape",2D)="white"{}
_NoiseIns("NoiseIns",float)=0
_Offset("Offset",vector)=(0,0,0,0)
}
SubShader
{
Tags { "RenderType" = "Transparent" "Queue" = "Transparent" }
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float2 uv_noise:TEXCOORD1;
float4 pos : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _FireColor;
float _EmissIntensity;
sampler2D _NoiseMap;
float4 _NoiseMap_ST;
float _NoiseSpeed;
sampler2D _Gradient;
float _GradientEnd;
float _EndMiss;
float _SoftNess;//软边缘强度
sampler2D _FireShape;
float _NoiseIns;
vector _Offset;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv_noise = TRANSFORM_TEX(v.texcoord, _NoiseMap); // 噪声纹理坐标变换
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
//用平移uv的方法采用噪声图
float2 panner=-1.0*_Time.y * _NoiseSpeed + i.uv_noise;
float noiseTex=tex2D(_NoiseMap,panner).r;
//采样渐变图
float gradientTex=tex2D(_Gradient,i.uv).r;
float gradientEnd=(1.0-gradientTex)*_GradientEnd;
//alpha通道进行插值混合,混合渐变图,只让噪声下边显示(SoftNess进行软边缘处理)
float finalAlpha=smoothstep((noiseTex-_SoftNess),noiseTex,gradientTex);
//火焰颜色部分处理
float4 mainColor=_FireColor*_EmissIntensity;
float endColor=_EndMiss*gradientEnd*noiseTex;//分界明显,多乘一个noise
float4 finalColor=float4(mainColor.r,(mainColor.g+endColor),mainColor.b,1.0)*col;
//火焰形状
float noiseDisturbance=(noiseTex*_Offset.x+_Offset.y)*_NoiseIns*0.01*gradientEnd;//噪声扰动,让形状不那么平整
float2 uv_shape=i.uv+noiseDisturbance;
float shape=tex2D(_FireShape,uv_shape).r;
finalColor.a=finalAlpha*shape;
//return float4(col.xyz,finalAlpha);
return finalColor;
}
ENDCG
}
}
}
本想贴一张ASE连连看,太糊了就算了😓
2319

被折叠的 条评论
为什么被折叠?



