If you have ever played games like Assassins Creed, Red Dead Redemption,gta , you would have understood what i am gonna talk. In those games if a character enters fire, you see that burn effect on their skin(which might slowly fade away with time). In general, they usually achieve that results using Shader effects. They have 2 textures for their body skins. One - Normal Texture for the skin and Two - After burn texture( Texture how skins looks after burn). Once you enter the fire, they slowly bring the 2nd texture(After burn texture) onto first, which give you that burn effect on the skin. And slowly after that the bring back the normal texture.
All you need here is to get a noise texture. What exactly is noise texture? This texture has different alpha values in it and we have to use this alpha values to create transparency gradually for our model in unity.
Lets picture this noise texture with blocks as shown below. Each block represents pixel. Each pixel has a value associated with it called "Alpha value". All you have to do is add a condition, which checks texture alpha pixel value with this noise alpha value. If it is greater than certain value(say _dissolveFactor) display that pixel, else return burn Texture co-ordinate value(return tex2D(_TextureBurn, i.texcoorda)) at that fragment.
So in this way by controlling the _dissolveFactor with a script(increasing/decreasing gradually) we can create this burn effect.
half4 frag(vertexOutput i) : COLOR
{
if (tex2D(_NoiseTexture,i.texcoorda).a < _dissolveFactor)
return tex2D(_TextureBurn, i.texcoorda);
else
return tex2D(_Texture,i.texcoorda);
}
Noise Texture:
After Burn Texture:
Full Code:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "ShaderLearning/FireBurn"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_Texture("Basic Texture", 2D) = "white" {}
_TextureBurn("Burn Texture", 2D) = "white" {}
_NoiseTexture("Noise Texture", 2D) = "white" {}
_dissolveFactor("Dissolve Factor", float) = 0.7
}
Subshader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform half4 _Color;
uniform sampler2D _Texture;
uniform sampler2D _TextureBurn;
uniform sampler2D _NoiseTexture;
uniform float4 _Texture_ST;
uniform float _dissolveFactor;
struct vertexInput
{
float4 vertex: POSITION;
float4 texcoorda: TEXCOORD0;
};
struct vertexOutput
{
float4 pos : SV_POSITION;
float4 texcoorda: TEXCOORD0;
};
vertexOutput vert(vertexInput v)
{
vertexOutput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.texcoorda.xy = v.texcoorda + _Texture_ST.wz;
return o;
}
half4 frag(vertexOutput i) : COLOR
{
if (tex2D(_NoiseTexture,i.texcoorda).a < _dissolveFactor)
return tex2D(_TextureBurn, i.texcoorda);
else
return tex2D(_Texture,i.texcoorda);
}
ENDCG
}
}
}
Final Result:
Commentaires