This is how I created a realistic candle flame in Unity.The image shows the out put.
1.Create a plane like the following image (Vertices are numbered accordingly) using a 3d modelling software.
2. Color the vertices as the following list before exporting to FBX
vertex # color(R,G,B)
1,2 0,0,0
3,4 51,51,51
5,6 102,102,102
7,8 153,153,153
9,10 204,204,204
11,12 255,255,255
3.Import the FBX to unity ,position and scale appropriately,attach a flame texture
The following image shows my flame in unity. Please note the coordinate system of the flame.
4.Create a Shader with following code and attached to the flame material.
The coordinate system in the Shader is the coordinate system of the flame object
Shader "MyShader/flame"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_Depth ("Depth", Range(-1,1)) = 1
_High ("High", Range(0,0.5)) = 0.5
}
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
LOD 200
CGPROGRAM
#pragma surface surf OffModel alpha vertex:vert
sampler2D _MainTex;
half _Depth;
half _High;
half4 LightingOffModel (SurfaceOutput s, half3 lightDir, half atten)
{
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
struct Input
{
float2 uv_MainTex;
};
void vert (inout appdata_full v,out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input,o);
if(v.color.r<0.1)
{
v.vertex.y -=_Depth*2.8;
v.vertex.x -=_High*5.5;
}
else if(v.color.r<0.3)
{
v.vertex.y -=_Depth*1.8;
v.vertex.x -=_High*4.2;
}
else if(v.color.r<0.5)
{
v.vertex.y -=_Depth*1;
v.vertex.x -=_High*3;
}
else if(v.color.r<0.7)
{
v.vertex.y -=_Depth*0.4;
v.vertex.x -=_High*1.8;
}
else if(v.color.r<0.9)
{
v.vertex.x -=_High;
}
}
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Mobile/Diffuse"
}
5.Give life to the flame by sending inputs from the smartphone accelerometer to the flame Shader
void OnGUI () {
m_Y = Input.acceleration.y;
m_X = Input.acceleration.x;
m_Y+=1;
m_Y/=4;
//m_Material is the material of the flame
m_Material.SetFloat("_Depth",m_X);
m_Material.SetFloat("_High",m_Y);
}
A sample project which uses this technique (which I’ve already written about the notification plugin in a previous post): https://play.google.com/store/apps/details?id=com.myuselesswork.taskburner&hl=en
