shader_type spatial; render_mode unshaded, cull_disabled; uniform sampler2D fire_tex_1; uniform sampler2D fire_tex_2; uniform sampler2D fire_mask; uniform vec4 inner_color; uniform vec4 outer_color; // fire uniforms uniform float detail_strength = 3.0; uniform float scroll_speed = 1.2; uniform float fire_height = 1.0; uniform float fire_shape = 1.5; uniform float fire_thickness = 0.55; uniform float fire_sharpness = 1.0; uniform float intensity = 1.0; // noise uniforms uniform int noise_octaves = 6; uniform float noise_lacunarity = 3.0; uniform float noise_gain = 0.5; uniform float noise_amplitude = 1.0; uniform float noise_frequency = 1.5; uniform float scale = 1.0; float hash(vec2 p) { p = fract(p * 0.3183099 + vec2(0.1, 0.1)); p *= 17.0; return fract(p.x * p.y * (p.x + p.y)); } float noise(vec2 x) { vec2 p = floor(x); vec2 f = fract(x); float n = hash(p) * (1.0 - f.x) * (1.0 - f.y) + hash(p + vec2(1.0, 0.0)) * f.x * (1.0 - f.y) + hash(p + vec2(0.0, 1.0)) * (1.0 - f.x) * f.y + hash(p + vec2(1.0, 1.0)) * f.x * f.y; return n; } float fbm(vec2 p) { int octaves = noise_octaves; float lacunarity = noise_lacunarity; float gain = noise_gain; float amplitude = noise_amplitude; float frequency = noise_frequency; float total = 0.0; for (int i = 0; i < octaves; i++) { total += noise(p * frequency) * amplitude; frequency *= lacunarity; amplitude *= gain; } return total * 0.5; } float random (vec2 uv) { return fract(sin(dot(uv.xy, vec2(12.9898,78.233))) * 43758.5453123); } void vertex() { VERTEX *= scale; mat4 modified_model_view = VIEW_MATRIX * mat4( INV_VIEW_MATRIX[0], MODEL_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3] ); MODELVIEW_MATRIX = modified_model_view; } void fragment() { vec2 uv = UV; // modified_uv for offset and animating UVs for fire vec2 modified_uv = -uv; modified_uv.x = mod(modified_uv.x, 1.0) - 0.5; modified_uv.y += 0.84; // size vertical // fire noise scroll effect float scroll = scroll_speed * detail_strength * TIME; // sample noise for fire float n = fbm(detail_strength * modified_uv - vec2(0.0, scroll)); // Threshold to create a mask-like edge float mask2 = smoothstep(0.4, 0.6, n); vec3 noise_1 = texture(fire_tex_1, vec2(UV.x, UV.y + TIME * 0.7)).rgb * n; vec3 noise_2 = texture(fire_tex_2, vec2(UV.x, UV.y + TIME * 1.2)).rgb * n; vec3 mask = texture(fire_mask, UV).rgb - 0.2; vec3 col = (noise_1 + noise_2) * mask * mask2; float fire_intensity = intensity - 16.0 * fire_sharpness * pow( max( 0.0, length( modified_uv * vec2((1.0 / fire_thickness) + modified_uv.y * fire_shape, 1.0 / fire_height) ) - n * max(0.0, modified_uv.y + 0.25) ), 1.2 ); float fire_intensity1 = n * fire_intensity * (1.5 - pow(1.0 * uv.y, 14.0)); float alpha = fire_intensity * (1.0 - pow(uv.y, 3.0)); fire_intensity1 = clamp(fire_intensity1, 0.0, 1.0); ALBEDO = vec3(step(0.015, col.r)); ALBEDO *= mix(outer_color.rgb, inner_color.rgb, step(0.15, col.r)) * alpha; ALPHA = step(0.015, col.r) * (alpha * 2.0); } //void light() { // // Called for every pixel for every light affecting the material. // // Uncomment to replace the default light processing function with this one. //}