понедельник, 16 декабря 2019 г.

Fire shader

In this post you will find a fire shader for Unity 3D and a set of textures for it.


In order to use the shader in your project you need to create material and choose "My/FireShader" as your shader.

Create a file "Fire.shader", copy&paste the code of the shader into the file. Place the file into the assets catalog of your project.

The code of the shader. 

Shader "My/FireShader"
{
    Properties
    {
        _FireTexture("Fire Texture", 2D) = "white" {}
        _FireAlpha("Fire Alpha", 2D) = "white" {}
        _SurfaceDistortion("Surface Noise", 2D) = "white" {}
        _SurfaceNoise("Surface Noise 2", 2D) = "white" {}
        
        _DistortionSpeed("Noise Speed", Float) = 1
        _DistortCoordFactor("Noise Coord Factor", Float) = 1
        _DistortUVFactor("Noise UV Factor", Float) = 0.2
        
        _NoiseSpeed("Noise 2", Float) = 0.05
        _NosieUVFactor("Noise 2 UV Factor", Float) = 0.2
        
        _HighlightAlphaCutoff("Highlight Alpha Cutoff", Range(0,1)) = 0.9
        _HighlightFactor("Highlight Factor", Range(0, 2)) = 0.45
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" }
        GrabPass { "_BackgroundTexture" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            //Parameters
            float _DistortionScale;
            float _DistortUVFactor;
            float _DistortionSpeed;
            float _DistortCoordFactor;
            float _NoiseSpeed;
            float _NosieUVFactor;
            float _HighlightAlphaCutoff;
            float _HighlightFactor;

            //Textures
            sampler2D _FireTexture;
            sampler2D _FireAlpha;
            sampler2D _SurfaceDistortion;
            sampler2D _SurfaceNoise;
            sampler2D _BackgroundTexture;
            
            //For TRANSFORM_TEX
            float4 _SurfaceDistortion_ST;
            float4 _SurfaceNoise_ST;

            struct v2f
            {
                float4 grabPos : TEXCOORD0;
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD1;
                float2 noiseuv : TEXCOORD2;
                float2 distortuv : TEXCOORD3;
            };
            
            struct appdata
            {
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;
            };

            v2f vert(appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.grabPos = ComputeGrabScreenPos(o.pos);
                o.uv = v.uv;
                o.distortuv = TRANSFORM_TEX(v.uv, _SurfaceDistortion);
                o.noiseuv = TRANSFORM_TEX(v.uv, _SurfaceNoise);
                return o;
            }
            
            half4 SampleNoiseTexture(sampler2D _tex, float2 uv1, float2 uv2)
            {
                return ( (tex2D(_tex, uv1) * 2 - 1) + (tex2D(_tex, uv2) * 2 - 1) ) * 0.5;
            }

            half4 frag(v2f i) : SV_Target
            {
                //Calculate tex coords
                half4 distortionValue = SampleNoiseTexture(
                    _SurfaceDistortion, 
                    i.distortuv + float2(0, - _Time.y * _DistortionSpeed), 
                    i.distortuv -float2(0.5, 0.5 - _Time.y * _DistortionSpeed * 0.1));
                
                //Noise
                half4 noiseValue = SampleNoiseTexture(
                    _SurfaceNoise, 
                    i.noiseuv + float2(0, - _Time.y * _NoiseSpeed), 
                    i.noiseuv + -float2(0.5, 0.5 - _Time.y * _NoiseSpeed * 0.1));
                
                //Distortion
                half2 distortUV = half2(
                    distortionValue.x * _DistortUVFactor + noiseValue.x * _NosieUVFactor,
                    distortionValue.x * _DistortUVFactor * 0.2 + noiseValue.x * _NosieUVFactor * 0.2);
                    
                //Textures
                half4 fireColor = tex2D(_FireTexture, 
                    clamp(i.uv + distortUV, half2(0.01,0.01), half2(0.99,0.99)));
                half4 fireAlpha = tex2D(_FireAlpha, 
                    clamp(i.uv + distortUV, half2(0.01,0.01), half2(0.99,0.99)));
                half4 backColor = tex2Dproj(_BackgroundTexture, 
                    i.grabPos + (distortionValue * _DistortCoordFactor * fireAlpha.x));
                
                //Add light
                half4 colorAdd = half4(0,0,0,0);
                if(fireAlpha.x > _HighlightAlphaCutoff) {
                    colorAdd.xyz = (noiseValue + 0.5).xyz * 
                        (fireAlpha.x - _HighlightAlphaCutoff) * (1 / (1-_HighlightAlphaCutoff));
                    colorAdd *= _HighlightFactor;
                }
                
                //Mix result color
                half4 mixedColor = 
                    fireColor * fireAlpha + 
                    backColor * (1 - fireAlpha) + 
                    colorAdd;
                
                return mixedColor;
            }
            ENDCG
        }

    }
}


Texture of fire and smoke. Semitransparency texture. Two noise textures for a burning effect.


In the next picture you can see the material parameters that I have used.




In order to make the final picture look better I have added an effect called Bloom, as well as particles to imitate sparks.


   



The code and textures in this blog post are under the CC0 license. You can use them for free. No attribution/credits needed.


If this information was useful for you, you can support me by having a look at my game on Steam.




If you don't want to miss future shaders you may follow me on twitter.




Комментариев нет:

Отправить комментарий