MIASMA - potato-grade atmospheric horror
Minecraft 1.20.1 / Forge / Embeddium + Oculus


WHAT IT IS
----------
A deliberately tiny shaderpack. No shadow pass, no composite passes, no
deferred pass, no normal/specular maps, no bloom, no SSAO, no reflections,
no noise textures. One 8-bit colour buffer, seven programs, one fullscreen
grading pass. On most machines it costs a few frames over no shaders at all,
and the heavy distance fog means you can drop to 5-8 chunks and have it read
as atmosphere instead of a hardware limitation.

Look: desaturated, crushed, sick-grey. Torches are small orange pools, sky
light is thin and cold, the sky itself is just the fog dome, no sun, no moon,
no stars. Vignette, fine film grain and a very slow "dread pulse" on top.


INSTALL
-------
1. Forge for 1.20.1
2. Embeddium  (0.3.x or newer)
3. Oculus     (matching Embeddium version - it's the Forge port of Iris)
4. Drop Miasma.zip into  .minecraft/shaderpacks/  (do NOT unzip it)
5. Options > Video Settings > Shaders > Miasma

Oculus is what actually loads the shader; Embeddium alone can't. If Oculus
refuses to start, you have an Embeddium/Oculus version mismatch - that pairing
is the usual cause of crashes on 1.20.1, not the shaderpack.


RECOMMENDED SETTINGS (for maximum frames)
-----------------------------------------
Video Settings:
  Render Distance      5 - 8 chunks   (the fog hides the edge completely)
  Simulation Distance  5
  Graphics             Fast
  Smooth Lighting      On (it's free, it's baked into vertex colours)
  Clouds               Off  (they're 100% fogged out anyway - pure waste)
  Entity Shadows       Off
  Particles            Decreased / Minimal
  Biome Blend          Off or 1
  Mipmap Levels        2  (lower = less texture cache pressure)
  Brightness           Moody, if you can stand it

Embeddium > Performance:
  Use Vertex Compression    On
  Chunk Update Threads      default
  Fog Occlusion / Culling   On, all of it


TUNING
------
Everything is in the in-game shader options screen (four tabs), or you can
edit shaders/lib/settings.glsl directly.

The knobs that matter most:
  FOG_DENSITY    - the whole point of the pack. 3.5 default. 6+ is oppressive,
                   2.0 lets you actually see where you're going.
  FOG_START      - blocks before fog begins. Raise to ~16 if it feels like
                   your face is in it.
  FOG_FLOOR      - keeps night fog from going pure black, so trees and mobs
                   still show as silhouettes.
  AMBIENT        - set to 0.000 for genuinely lightless caves.
  SATURATION     - 0.42 default. Drop to 0.10 for near-monochrome.
  SUN_MOON_VISIBLE - off by default. Turn on if the empty sky bothers you.


HOW IT STAYS CHEAP
------------------
- All lighting is computed per-vertex, not per-pixel. Minecraft's vertex
  density is high enough that this is visually near-identical.
- No lightmap texture fetch at all; block/sky light is read straight from
  the vertex lightmap coordinates.
- Fog is one exponential-squared term evaluated per-vertex, one lerp per pixel.
- colortex0 is RGB16F so torchlight can overshoot 1.0 and feed bloom.
- No shadow programs exist, so Oculus skips the entire shadow render - that
  is the single biggest saving here (it's normally a second pass over all
  geometry).
- Seven programs total. Everything else falls back through the standard
  chain (terrain/hand/water/particles/weather -> textured_lit -> textured
  -> basic).


=====================================================================
 WHY YOUR GPU USAGE DROPPED AND YOUR FPS WENT DOWN
=====================================================================

Low GPU usage is the symptom, not the cause. There is no such thing as
a "GPU utilisation script" in a shaderpack - a shader only ever adds
work, it can never make the rest of the game run faster.

What is actually happening on a 5090:

  Without shaders, Embeddium's renderer is already so cheap on the GPU
  that Minecraft is bottlenecked by your CPU / the driver's draw-call
  submission. Turning Oculus on ADDS CPU work: it rebuilds chunk
  geometry with a fatter vertex format (normals, midblock, block IDs),
  runs extra render stages, and pushes more state changes per frame.
  So the CPU side gets slower while the GPU side stays trivial. Result:
  fewer frames AND lower GPU usage at the same time. Making the shader
  cheaper cannot fix that, because the shader was never the bottleneck.

  Worse, once utilisation falls low enough the card drops into a low
  power state and downclocks, which makes frametimes spikier than the
  raw numbers suggest.

Fixes, in order of how much they actually matter:

  1. NVIDIA Control Panel -> Manage 3D Settings -> add javaw.exe (and
     your launcher's java binary):
        Power management mode      = Prefer maximum performance
        Low Latency Mode           = On (not Ultra)
        Vertical sync              = Off
        Threaded optimization      = On
     "Prefer maximum performance" alone fixes most of the downclocking.

  2. Remove every framerate cap: in-game Max Framerate = Unlimited,
     VSync off, and no cap in the launcher / RTSS / NVIDIA app.

  3. Give the GPU something to do that does not cost CPU: raise your
     RESOLUTION, not your render distance. Enable DLDSR (2.25x) in the
     NVIDIA app and run Minecraft at the higher desktop resolution.
     Render distance costs CPU; resolution is pure GPU. This is the
     single best way to spend a 5090 on Minecraft.

  4. CPU-side mods for Forge 1.20.1: ModernFix and FerriteCore. They
     cut startup and memory churn, which is where the frametime spikes
     come from. Allocate 6-8 GB, no more - a larger heap means longer
     GC pauses, not more frames.

  5. Turn the GPU LOAD options in this pack up (see below). They will
     not give you frames back, but they spend the idle GPU time on
     picture quality instead of leaving the card asleep.

=====================================================================
 GPU LOAD TAB
=====================================================================

Everything in this tab is pure fragment-shader work. Zero extra render
passes, zero extra buffers, so it adds nothing to the CPU side that is
already limiting you.

  VL_STEPS        The big dial. Raymarched volumetric mist, N samples
                  per pixel. Cost is exactly linear. 16 = default,
                  64 = thick and smooth, 128-256 = deliberately
                  wasteful, which is the point. Multiply by VL_OCTAVES.
  BLOOM_SAMPLES   Spiral gather taps per pixel. 24 default, 128 max.
  VL_OCTAVES      Noise layers per step. This multiplies VL_STEPS cost,
                  so 64 steps x 4 octaves is 256 noise evaluations per
                  pixel per frame.

To find your ceiling: turn on the F3 screen, raise VL_STEPS until your
frametime starts climbing, then back off one notch. If VL_STEPS 256 at
4K still does not move your frametime, you are hard CPU-bound and no
shader setting will change your framerate.

=====================================================================
 RENDER DISTANCE CURTAIN
=====================================================================

Fog is now two terms instead of one:

  - exponential-squared atmospheric fog on true (spherical) distance,
    same as before
  - a hard curtain on HORIZONTAL distance, ramping from
    FOG_WALL_START to FOG_WALL_END as a fraction of your render
    distance, forced to full opacity at the end point

Horizontal is the correct axis because chunk loading is cylindrical -
using spherical distance leaves the chunk edge visible when you look
along the ground. With the defaults (0.62 -> 0.90) everything past 90%
of your render distance is solid fog, so unloaded chunks, popping chunk
borders and the void behind them are never visible, exactly like vanilla
fog. The sky dome is painted the same colour, so there is no seam where
the curtain meets the horizon.

If you still catch a glimpse of an unloaded edge, lower FOG_WALL_END to
0.82. If it feels too tight, raise FOG_WALL_START toward 0.78.

=====================================================================
 v3 FIXES
=====================================================================

1. CRUSHED BLACKS ("too dark even at max gamma")

   This was a real bug, not a taste setting. The contrast step was
   pivoted at 0.5:  c = (c - 0.5) * 1.18 + 0.5
   which subtracts a flat 0.09 from every channel. Anything below about
   0.076 clamped to pure zero. Cave lighting lives entirely below 0.076,
   so it was being deleted, and the Brightness slider could not bring it
   back because the shader never read the Brightness slider at all.

   Fixed three ways:
     - Contrast is now an S-curve that pins 0 and 1 in place and cannot
       clip anything.  CONTRAST is now 0..1 strength, not a multiplier.
     - MIN_LIGHT is a new light floor multiplied by the vanilla
       Brightness slider, so the slider finally does something. Moody
       still gives true blackness; Bright is usable.
     - BLACK_LIFT raises shadows without touching highlights.
   Also: gentler torch falloff (2.6 instead of 4), gentler sky light
   falloff (2 instead of 3), and brighter moonlight.

   If it is still too dark: raise MIN_LIGHT first, then BLACK_LIFT.
   If it is now too bright: drop MIN_LIGHT to 0.000 and set the vanilla
   Brightness slider to Moody.

2. CAVE FOG

   Two things were fogging your caves. Both are gone by default:
     - The volumetric mist ran everywhere. It is now gated on how much
       sky your eyes can actually see, so it stops at the cave mouth.
       Turn VL_INDOORS on if you want it back.
     - The distance fog kept full brightness underground. It is now
       scaled by CAVE_FOG_BRIGHTNESS (default 0.05) when you are
       indoors or underground, so caves go black rather than grey. Set
       it to 0.00 for no cave fog whatsoever.
   The transition follows eyeBrightnessSmooth, so it fades over about a
   second as you walk out of a cave instead of popping.

3. NETHER AND END

   The pack now ships real per-dimension programs in shaders/world-1/
   and shaders/world1/. Both dimensions have zero sky light, so the
   old lighting model had literally nothing to work with beyond torch
   range - that is why the End was a black screen with a dragon health
   bar in it.

     NETHER_AMBIENT  warm red-brown ambient fill, plus fog brightness
                     boosted (NETHER_FOG_MUL) and the mist height
                     falloff disabled so the murk is uniform under the
                     ceiling instead of thinning out above y=74.
     END_AMBIENT     cold violet ambient fill.

   Both dimensions skip the cave-fog dimming, since "underground" is
   meaningless there - they are always fully fogged.

   If Oculus on your setup ignores the world-1 / world1 folders, the
   base shaders still load normally and you just lose the per-dimension
   ambient. Check the log for "world-1" if the Nether still looks flat.

=====================================================================
 KNOWN / BY DESIGN
=====================================================================
- No shadows. You asked for none.
- Water is flat and murky, not reflective. Reflections need a deferred pass.
- Volumetric mist is outdoors only by default. VL_INDOORS turns it on
  everywhere.
- The sky is a flat dome. That is intentional; a gradient would betray the
  fog wall's distance.
- Distant Horizons is not supported (no DH programs).
