Unity&Shader案例篇—火焰

一、前言

1、效果图如图所示:
2、使用的Unity版本为Unity5.3.3
、制作方法
1、C#部分的代码如下:
using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class CamRendImage : MonoBehaviour {

	[SerializeField]
	private Material m_mat;

	// Use this for initialization
	void Start () {	
	}
	
	// Update is called once per frame
	void Update () {

	}
	void OnRenderImage(RenderTexture src,RenderTexture dest)
	{
		Graphics.Blit (src,dest,m_mat);
	}
	void OnMouseDown()
	{
		
	}
	void OnMouseUp()
	{
		
	}
}
2、Shader代码如下:
Shader "Unlit/Flame"
{
	Properties{
		
    }

    CGINCLUDE    
    #include "UnityCG.cginc"   
    #pragma target 3.0      

    #define vec2 float2
    #define vec3 float3
    #define vec4 float4
    #define mat2 float2x2
    #define mat3 float3x3
    #define mat4 float4x4
    #define iGlobalTime _Time.y
    #define mod fmod
    #define mix lerp
    #define fract frac
    #define texture2D tex2D
    #define iResolution _ScreenParams
    #define gl_FragCoord ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy)

    #define PI2 6.28318530718
    #define pi 3.14159265358979
    #define halfpi (pi * 0.5)
    #define oneoverpi (1.0 / pi)

    vec4 main(in vec2 fragCoord );

    struct v2f {    
        float4 pos : SV_POSITION;    
        float4 scrPos : TEXCOORD0;   
    };              

    v2f vert(appdata_base v) {  
        v2f o;
        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
        o.scrPos = ComputeScreenPos(o.pos);
        return o;
    }  

    fixed4 frag(v2f _iParam) : COLOR0 { 
        vec2 fragCoord = gl_FragCoord;
        return main(gl_FragCoord);
    }  

    float noise(vec3 p) //Thx to Las^Mercury
{
	vec3 i = floor(p);
	vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
	vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
	a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
	a.xy = mix(a.xz, a.yw, f.y);
	return mix(a.x, a.y, f.z);
}

float sphere(vec3 p, vec4 spr)
{
	return length(spr.xyz-p) - spr.w;
}

float flame(vec3 p)
{
	float d = sphere(p*vec3(1.,.5,1.), vec4(.0,-1.,.0,1.));
	return d + (noise(p+vec3(.0,iGlobalTime*2.,.0)) + noise(p*3.)*.5)*.25*(p.y) ;
}

float scene(vec3 p)
{
	return min(100.-length(p) , abs(flame(p)) );
}

vec4 raymarch(vec3 org, vec3 dir)
{
	float d = 0.0, glow = 0.0, eps = 0.02;
	vec3  p = org;
	bool glowed = false;
	
	for(int i=0; i<64; i++)
	{
		d = scene(p) + eps;
		p += d * dir;
		if( d>eps )
		{
			if(flame(p) < .0)
				glowed=true;
			if(glowed)
       			glow = float(i)/64.;
		}
	}
	return vec4(p,glow);
}

vec4 main(in vec2 fragCoord )
{
	vec4 fragColor;
	vec2 v = -1.0 + 2.0 * fragCoord.xy / iResolution.xy;
	v.x *= iResolution.x/iResolution.y;
	
	vec3 org = vec3(0., -2., 4.);
	vec3 dir = normalize(vec3(v.x*1.6, -v.y, -1.5));
	
	vec4 p = raymarch(org, dir);
	float glow = p.w;
	
	vec4 col = mix(vec4(1.0,0.5,0.1,1.0), vec4(0.1,0.5,1.0,1.0), p.y*0.02+0.4);
	
	fragColor = mix(vec4(0,0,0,0), col, pow(glow*2.,4.));
	//fragColor = mix(vec4(1.), mix(vec4(1.,.5,.1,1.),vec4(0.1,.5,1.,1.),p.y*.02+.4), pow(glow*2.,4.));
	return fragColor;
}

    ENDCG    

    SubShader {    
        Pass {    
            CGPROGRAM    

            #pragma vertex vert    
            #pragma fragment frag    
            #pragma fragmentoption ARB_precision_hint_fastest 


            ENDCG    

        }    
    }     
    FallBack Off    
}
将1中的C#脚本赋给主摄像机,然后将附有2中的Shader的材质赋值给C#脚本中的“m_mat”变量。


  • 9
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Unity火焰shader可以通过多种方式实现,下面是其中一种实现方式: 1. 创建一个新的材质,并将其shader设置为“Standard”或“Standard (Specular Setup)”。 2. 在材质的属性面板中添加一个新的纹理,用于表示火焰形状的alpha通道。这个纹理可以是一个黑色背景,中心区域是白色火焰形状的灰度图像。 3. 添加一个新的颜色属性,用于定义火焰的颜色。 4. 在shader中添加以下代码: ``` Shader "Custom/Flame" { Properties { _MainTex ("Flame Texture", 2D) = "white" {} _Color ("Flame Color", Color) = (1,1,1,1) _Speed ("Speed", Range(0, 10)) = 1 _Intensity ("Intensity", Range(0, 5)) = 1 } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent"} LOD 200 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _Color; float _Speed; float _Intensity; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } half4 frag (v2f i) : SV_Target { half4 texColor = tex2D(_MainTex, i.uv); float alpha = texColor.a; float t = _Time.y * _Speed; float sinx = sin(i.uv.x * 20 + t); float siny = sin(i.uv.y * 20 + t + 0.5); float noise = sin(sinx + siny) * 0.5 + 0.5; float intensity = pow(noise, _Intensity); return alpha * _Color * intensity; } ENDCG } } FallBack "Diffuse" } ``` 5. 将这个shader拖到材质中,并将火焰纹理拖到“MainTex”属性中。 6. 调整属性面板中的“Color”、“Speed”和“Intensity”属性,直到得到满意的火焰效果。 这个shader使用了alpha通道纹理来定义火焰形状,并且根据时间和噪声函数来产生火焰动态效果。你可以根据自己的需求和创意来调整shader代码和属性面板中的属性,以得到更加逼真和有趣的火焰效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值