分享一个GLSL转换的火Shader

先看效果:


GLSL代码:

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,iTime*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; vec3p = 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); }void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 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.,.5,.1,1.), vec4(0.1,.5,1.,1.), p.y*.02+.4); fragColor = mix(vec4(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.)); }

转换成的Shader代码:
Shader "Hidden/Fire" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { // No culling or depth Cull Off ZWrite Off ZTest AlwaysPass { 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; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } float noise(float3 p) //Thx to Las^Mercury { float3 i = floor(p); float4 a = dot(i, float3(1., 57., 21.)) + float4(0., 57., 21., 78.); float3 f = cos((p-i)*acos(-1.))*(-.5)+.5; a = lerp(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x); a.xy = lerp(a.xz, a.yw, f.y); return lerp(a.x, a.y, f.z); }float sphere(float3 p, float4 spr) { return length(spr.xyz-p) - spr.w; }float flame(float3 p) { float d = sphere(p*float3(1.,.5,1.), float4(.0,-1.,.0,1.)); return d + (noise(p+float3(.0,_Time.y *2.,.0)) + noise(p*3.)*.5)*.25*(p.y) ; }float scene(float3 p) { return min(100.-length(p) , abs(flame(p)) ); }float4 raymarch(float3 org, float3 dir) { float d = 0.0, glow = 0.0, eps = 0.02; float3p = 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 float4(p,glow); } sampler2D _MainTex; fixed4 frag (v2f i) : SV_Target { float2 v = -1.0 + 2.0 *i.uv ; float3 org = float3(0., -2., 4.); float3 dir = normalize(float3(v.x*1.6, -v.y, -1.5)); float4 p = raymarch(org, dir); float glow = p.w; float4 col = lerp(float4(1.,.5,.1,1.), float4(0.1,.5,1.,1.), p.y*.02+.4); returnlerp(float4(0.,0.,0.,0.), col, pow(glow*2.,4.)); //fragColor = lerp(float4(1.), lerp(float4(1.,.5,.1,1.),float4(0.1,.5,1.,1.),p.y*.02+.4), pow(glow*2.,4.)); } ENDCG } } }

如果你对Unity,Unreal4,人工智能感兴趣,请关注我的公众号,后续会分享更多好玩的东西,你的一个点赞就是我坚持写下去的动力:
【分享一个GLSL转换的火Shader】分享一个GLSL转换的火Shader
文章图片

    推荐阅读