Shader学习笔记 05 - 2d火焰

2D程序式火焰

火焰通常包括焰心、内焰、外焰,至少要有内焰、外焰的区分,另外有烟,火花,热扭曲之类的效果。html

基本原理很简单,就是使用梯度值(通常是uv.y)截取不断上移的噪声值来造成火焰效果。动画

截取方法能够定值截取,也能够插值截取
1. 定值

参考博客3d

使用step区份内外焰,效果上相似卡通火焰(toon fire)。
imagecode

另外使用偏导数也能够实现相似效果,好处是能加一点抗锯齿效果。orm

参考博客htm

image效果其实差很少blog

2. 插值

噪声值减去递增梯度值便可,结果是颜色变化比较平滑。ci

float gradientValue = 1 - uv.y;
float t = noiseValue + lerp(0, -2, gradientValue);
float3 col = _FireColor.rgb*(1-t);

image

Mask

使用Mask来约束火焰外形的时候,定值截取效果并很差。应该是须要特制下噪声,让火焰集中。get

image

插值的火焰效果就好不少。博客

image

Smoke

烟能够单独制做而后叠加上去,也能够从火焰中截取一部分做为烟雾。

1. 单独制做

与火焰原理相同,一个噪声向上移动,而后须要另加一个噪声与之相差让结果有层次感。

image

相乘结果:

image

修改颜色,加上Mask。

image

最后将结果和合并到火焰上取便可。

2. 截取

既然前面能够截取噪声不一样值区份内外焰,那么天然能够截取一部分做为烟。

直接插值截取效果并很差,比较好的实现参考:

shadertoy

火花、热扭曲

火花使用纯粹的shader实现起来比较麻烦,目前没有找到好的方法,仍是使用粒子效果或者动画。

热扭曲就是简单的uv扭曲。

其余

在一个贴图上是能够模拟出粒子效果。最简单原理参考:

How to Write a Smoke Shader

粒子模拟须要能获取上一渲染结果,在unity中须要建立2个RenderTexture。

private RenderTexture SimTexture;
private RenderTexture buffer;
private Material ParticleSimulationMat;
public Shader ParticleSimulationShader; // 粒子模拟Shader
public Material ObjMat;  // 目标Sprite的Material
Start {
    ParticleSimulationMat = new Material(ParticleSimulationShader)
    SimTexture = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
    buffer = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
}
Update {
    // Graphics.Blit(SimTexture, SimTexture, ParticleSimulationMat) 无效,2019.4 版本
    // 保存渲染结果,ParticleSimulationMat中_MainTex即是上一渲染结果
    Graphics.Blit(SimTexture, buffer, ParticleSimulationMat);
    Graphics.Blit(buffer, SimTexture);
    ObjMat.SetTexture("_SimTexture", SimTexture);
}

shadertoy上有一些不错的火焰模拟,基本上能够经过这个方法移植过来,好比这个:

Smoke and fire

结论

仍是直接使用Unity自带的粒子系统吧。

相关文章
相关标签/搜索