float noise(vec3 p) {
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 * 2.);
}
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.));
// effect 1:
// return d + (noise(p + vec3(.0,iTime * 0.2, .0)) + noise(p * 3.) * .15) * .25 * (p.y) ;
// effect 2:
return d + (noise(p + vec3(.0,iTime * 0.2, .0)) + noise(p * 13.) * 2.15) * .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; // eps can affect border significantly
vec3 p = org;
bool glowed = false;
for(int i=0; i<16; i++) {
d = scene(p) + eps;
p += d * dir;
if( d > eps ) {
if(flame(p) < .0)
glowed=true;
if(glowed)
glow = float(i)/12.; // it's essential that max(glow) > 1.
}else break;
}
return vec4(p, pow(glow - 0.42, 1.5));
}
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(0.1,.05,.1,0.1), vec4(0.1,.5,0.,0.1), p.y * .008 + .04);
fragColor = mix(vec4(0.), col, pow(glow*2.,4.));
}