Skip to main content
The game draws its smoke, and you can’t take it away. What you can do is draw what it hides: when a wall or a doorway is behind smoke, outline it. Two pieces of the frame make this easy:
  • frame.smokeTable has every cloud’s center and bounds this frame.
  • frame.worldDepth is the depth of the map alone. No players, and none of the cheat’s smoke boxes, so the outlines follow the real walls.

Step 1: How much smoke is in the way

For each pixel, take the ray from your eye to the wall behind it and measure how much of it runs through a cloud. A cloud is roughly an ellipsoid, so treat it as one inside its bounds: a ray against a stretched sphere is a quadratic, no marching. Keep this function in a string, SMOKE_BEFORE, for the shader in step 2:
Bounds are a rough shape. For the exact one, mark the voxels into a grid with a compute pass and march it, like the gpu-showcase script does. The ellipsoid is good enough to start.

Step 2: The map from its depth

Where enough smoke is in the way, rebuild the map from worldDepth: four neighbouring pixels give the normal, and jumps or bends in depth are edges.
Post-projection depth changes linearly across a flat surface on screen, so its second difference is zero on a wall and spikes at a corner. That’s the whole edge detector.

Step 3: Wiring it up

Record this every frame, smoke or not. The smoke buffers and worldDepth are only filled while some recording uses them; frame.smokeCount reads 0 until yours does.

Tuning

  • Smoke needed is how many units of smoke the ray must cross before anything shows. Raise it if the outlines pop up at the cloud’s thin edges.
  • Swap worldDepth for solidDepth and players hide the outlines behind them, while the smoke still doesn’t.
  • Draw players in the smoke with scene.player and an xray material: that part is already done for you.