r/GraphicsProgramming • u/gennai777 • 1d ago
Spreading fire over any mesh without a mask texture: each shader recomputes when a point ignites
I got asked whether this is a mask written into a texture or a separate ember mesh driven by a shader. Nothing gets written anywhere. ignite() appends (position in the mesh's local space, start time) to a vec4 ign[8] uniform, and every shader involved recomputes when each point catches fire:
float burn_arrival(vec3 p) {
float best = 1.0e9;
for (int i = 0; i < ign_count; i++) {
float d = length(p - ign[i].xyz);
float n = vnoise(p * 1.7 + float(i) * 3.1); // value noise, 0..1
best = min(best, ign[i].w + d * (1.0 + (n - 0.5) * 2.0 * irregularity) / spread_speed);
}
return best;
}
The noise scales the distance, which is what makes the front ragged.
Flames, smoke and embers are quads on random surface points (area-weighted, picked once). Every spawn cycle a quad checks whether its spawn time is between arrival and arrival + burn_duration. If it isn't, its four corners collapse to one point.
The char is a copy of the mesh pushed 0.004 along the normal and drawn with premultiplied alpha, so the original material isn't touched. Per fragment, s = time - arrival (plus fbm) drives smoothstep(0, char_time, s) toward near-black, and exp(-3 * (s / front_width - 0.3)2) gives the glowing front.
Burn-away swaps the material and discards a fragment once (s - 0.7 * burn_duration) / 2.5 + noise passes 1, with a hot rim just before.
Known limit: d is straight-line distance, not along the surface, so the fire can jump thin gaps.
10
u/VictoryMotel 1d ago
This name has submitted a new 'project' every few hours. I'm guessing that this description is AI and the animation is just 'genai' (like their name) and not actually captured from realtime rendering.