Back to Devlog
    v0.8.8
    RendererJanuary 4, 2026Release notes

    What Carmack Said About Fog

    Per-face fog detection from the BSP effects lump, and a note on why the obvious global-fog implementation does not work.

    Commands

    text
    fog on [r] [g] [b] [density]      fog off
    fog color <r> <g> <b>             fog density <value>
    fog linear <start> <end>          fog status

    Per-face fog detection reads effectIndex from each BSP face, looks up fogParms from the Effects lump, stores the parameters in mesh metadata, and logs how many meshes were fog-affected on load.

    The Research Notes

    Three findings, recorded because each one invalidates an assumption:

    1. 1.Q3 does not render fog brush geometry as meshes. The fog volume is not

    drawn.

    1. 1.Fog is per-face, keyed off face.effectIndex.
    2. 2.A fog brush has only one visible surface — the other five sides have null

    normals.

    Then the algorithm, attributed in the changelog itself:

    text
    Algorithm (confirmed by Carmack): determine whether the camera is inside or
    outside the volume, calculate fog depth per vertex for faces inside, then render
    as an extra pass with a gradient texture.

    What Landed And What Did Not

    Detection and per-face parameter reading landed, with BspFogVolume and a docs/BSP_FOG_VOLUMES_PLAN.md that marks Phase 1 complete and Phases 2 and 3 as documented future work.

    The volumetric pass did not land here. The commands did, which is why this post can say "here is the plan, and here is the part that is real" without guessing.

    Known Issues: none stated.