196 lines
11 KiB
Markdown
196 lines
11 KiB
Markdown
# MinecraftPT — Path Traced Shader Pack
|
||
## Design & Architecture Documentation
|
||
|
||
MinecraftPT is an original, from-scratch implementation of a high-quality
|
||
path-traced Minecraft shader pack, designed by studying the architecture of the
|
||
IterationRP shader pack (see `study/architecture.md`). It targets OptiFine and
|
||
Iris (OpenGL 4.30 compute required; `iris.features.required=CUSTOM_IMAGES`).
|
||
|
||
All code in this pack is original work. The architecture follows the same
|
||
deferred + voxelized path-tracing class of techniques, implemented with our own
|
||
algorithms and data layouts.
|
||
|
||
---
|
||
|
||
## 1. Frame pipeline (program chain)
|
||
|
||
```
|
||
begin1.csh CausticsTex_CS -> generate caustics normal field (pixelData2D)shadow.vsh/gsh/fsh Shadow+Voxelizer -> render shadow map AND voxel atlas into shadowcolor0/1
|
||
composite3.csh VoxelData_Copy_CS -> 2D atlas -> 3D voxelData3D (RGBA16) + sparse markers
|
||
composite3_a.csh SkyImage_CS -> precompute sky panorama (skyBox2D)
|
||
composite4.csh IRC_CS -> update 3D irradiance cache (RGBA16F)
|
||
composite4_a.csh SH_TRACING_CS -> SH sky tracing for ambient
|
||
composite5.fsh DiffuseTracing_FS -> 1 diffuse path ray/pixel @ half res (colortex6+10)
|
||
composite10.fsh DiffuseTemporal_FS -> temporal accumulation -> colortex7
|
||
composite11.fsh DiffuseVariance_FS -> luminance moments -> colortex8
|
||
composite12..15.fsh DiffuseSpatial x4 -> edge-avoiding a-trous @ steps 1,2,4,8
|
||
composite20.fsh Sky_Overworld_FS -> sky into HDR background (colortex12)
|
||
composite25.fsh Soild_FS -> MAIN lighting: gbuffer + PT diffuse/spec + sun/held/emissive
|
||
composite40.fsh WaterRefraction_FS -> water refraction pass
|
||
composite42.fsh SpecularTracing_FS -> GGX reflection ray @ half res (colortex9)
|
||
composite44.fsh SpecularTemporal_FS -> temporal accumulation -> colortex11
|
||
composite46..47.fsh SpecularSpatial x2 -> edge-avoiding filter
|
||
composite50.fsh Translucent_FS -> glass/water/particle composite
|
||
composite51.fsh Volumetric_FS -> volumetric fog + water fog
|
||
composite53.fsh Dof_FS -> depth of field (option)
|
||
composite65.fsh TAA -> temporal AA (writes colortex12 + 13 history)
|
||
composite67.fsh MotionBlur_FS -> camera motion blur (option)
|
||
composite70..73.csh Bloom compute -> downsample x2 + axial blur X/Y
|
||
composite72_a..75.csh RTWSM compute -> importance analysis/blur/collapse/warp build
|
||
composite74.csh Exposure_CS -> auto exposure (SSBO)
|
||
composite76.fsh Bloom_FS -> bloom composite
|
||
composite79.csh DepthCopy_CS -> depthtex0 -> prevDepth2D (for next frame)
|
||
composite80.fsh Final_FS -> tonemap + color grade -> colortex0
|
||
final.vsh/fsh -> present colortex0 to screen
|
||
```
|
||
|
||
Dimension variants: `world1/` (Nether) and `world-1/` (End) override the entry
|
||
points with `DIMENSION_NETHER` / `DIMENSION_END`; the loader falls back to the
|
||
root programs for anything not overridden.
|
||
|
||
## 2. Buffer layout
|
||
|
||
| Buffer | Format | Res | Content |
|
||
|---|---|---|---|
|
||
| colortex0 | RGBA16 | full | solid albedo.rgb + emissive.a |
|
||
| colortex1 | RGBA16 | full | world normal (oct, xy) + vertex normal (oct, zw) |
|
||
| colortex2 | RGBA16 | full | spec.r (roughness) .g (metalness) .b (sss) .a (matID/255) |
|
||
| colortex3 | RGBA16 | full | lightmap.rg + parallaxShadow.b + spare |
|
||
| colortex4 | RGBA16 | full | translucent albedo.rgb + alpha.a |
|
||
| colortex5 | RGBA16 | full | translucent normal.xy + matID.a + rough.b |
|
||
| colortex6 | RGBA16F | half | noisy diffuse PT (current) |
|
||
| colortex7 | RGBA16F | half | diffuse PT history (temporal output) |
|
||
| colortex8 | RGBA16F | half | diffuse variance |
|
||
| colortex9 | RGBA16F | half | noisy specular PT (current) |
|
||
| colortex10 | RG16F | half | motion vectors (half-res pixels) |
|
||
| colortex11 | RGBA16F | half | specular PT history |
|
||
| colortex12 | RGBA16F | full | HDR scene (composite output) |
|
||
| colortex13 | RGBA16F | full | TAA history |
|
||
| colortex14 | R16F | 1x1 | exposure |
|
||
| colortex15 | RGBA16F | 1/4 | bloom pyramid |
|
||
| depthtex0 | R32F | full | scene depth |
|
||
| shadowcolor0 | RGBA16 | SxS | shadow map (right region) |
|
||
| shadowcolor1 | RGBA16 | SxS | voxel atlas (left region) |
|
||
|
||
Images: voxelData3D (RGBA16 3D), irradianceCache3D/Alt (RGBA16F 3D),
|
||
skyBox2D (RGBA16F panorama), prevDepth2D (R32F half), rtwImportance2D (R32F),
|
||
rtwWarp1D (RG16), pixelData2D (RG16F caustics field).
|
||
|
||
Custom textures: atlas2D (block atlas), atlasSpecular2D (LAB PBR spec atlas),
|
||
CloudNoise3D (128³ RGBA8), CloudDetailedNoise3D (32³ RGB8), noise.png
|
||
(blue-noise dither), ripple.png.
|
||
|
||
## 3. Voxelization (shadow pass)
|
||
|
||
The world is rendered once from the shadow camera into a square S×S framebuffer
|
||
(S = 2·W, W = voxelWidth per resolution, e.g. 4096/8192/12288/16384):
|
||
|
||
- **Voxel atlas** (bottom-left, [0,W)² texels): the geometry shader emits, per
|
||
triangle, an extra triangle positioned at the voxel's atlas texel
|
||
(`VoxelTexel_From_VoxelCoord` linear packing
|
||
`n = x + y·Rx + z·Rx·Ry; texel = (n mod W, floor(n/W))`), with z encoding
|
||
block-shape info. The fragment shader writes shadowcolor1 =
|
||
`(midTexCoord, voxelID, pack(textureRes, skylight))`.
|
||
- **Shadow map** (right square [W,2W)×[0,W)): the same triangle is re-emitted
|
||
after `ShiftShadowNdcPos` (maps shadow NDC square into the right region,
|
||
aspect-preserving) plus the RTWSM warp offset. The FS writes
|
||
shadowcolor0 = (albedo.rgb, depth.a).
|
||
|
||
Block ID encoding: full blocks `id+1000`, cutout shapes `1000-id`, empty
|
||
markers in .z (0.91/0.71/0.61 for 8³/4³/2³ empty cells) computed by
|
||
VoxelData_Copy_CS via shared-memory atomic occupancy reduction (sparse tracing).
|
||
|
||
## 4. Path tracing
|
||
|
||
All rays march the 3D voxel grid with Amanatides–Woo DDA
|
||
(`PackRay`, per-axis `totalStep`, sparse-skip on empty markers):
|
||
|
||
- **Shadow rays** (ShadowTracing): up to 64 steps; penumbra from
|
||
distance-to-occluder weighting; used for sun direct light.
|
||
- **Diffuse** (DiffuseTracing_FS): cosine-weighted hemisphere sample per pixel,
|
||
bounce: light spheres (torches etc.) + full-block/cutout hit shading
|
||
(albedo from atlas, direct sun via shadow ray, skylight from voxel.w,
|
||
one IRC bounce).
|
||
- **Specular** (SpecularTracer): GGX importance-sampled reflection direction,
|
||
traced; hit shading + sky sampling on miss/escape (`SampleSkyBox` from the
|
||
precomputed panorama); light spheres contribute.
|
||
- **IRC** (IRC_CS / SH_TRACING_CS / SampleIRC): 3D irradiance cache grid
|
||
(PT_IRC_RESOLUTION³), updated by tracing few rays per cell toward the sky
|
||
with SH-weighted accumulation, trilinearly sampled with normal bias as cheap
|
||
indirect diffuse.
|
||
|
||
## 5. Denoiser
|
||
|
||
- **Temporal**: reproject previous frame by motion vectors (+jitter), validate
|
||
with prevDepth2D, neighborhood clamp (min/max 3×3), blend by accumulation
|
||
count (`PT_DIFFUSE_TEMPORAL_MAX_ACCUM`), history-fix option.
|
||
- **Variance**: luminance moments over 3×3 to steer firefly handling.
|
||
- **Spatial**: edge-avoiding A-trous passes; weights combine luminance, depth
|
||
and normal similarity; diffuse 4 levels (steps 1,2,4,8), specular 2 levels.
|
||
|
||
## 6. Lighting composite (Soild_FS)
|
||
|
||
Per pixel: gbuffer decode -> direct sun (GetSunlight: voxel shadow tracing,
|
||
optionally warped shadow map) + block light (lightmap, colored) + IRC ambient
|
||
+ held light (torch/flashlight with short shadow ray) + emission (gbuffer.a) +
|
||
denoised PT diffuse (colortex7) + denoised PT specular (colortex11) with
|
||
reflection strength, plus analytic GGX direct specular (NDF/geometry/Fresnel).
|
||
Transparent pass (Translucent_FS) handles water (fresnel + refraction color),
|
||
glass (fresnel tint), particles.
|
||
|
||
## 7. Sky / atmosphere / clouds / volumetrics
|
||
|
||
- Analytic Rayleigh/Mie atmosphere (`PrecomputedAtmosphere.glsl`): sun/sky
|
||
irradiance from camera altitude + sun elevation; sky radiance per direction
|
||
with sun disk, sunset tint, horizon haze, night sky. Sky panorama
|
||
(SkyImage_CS) renders a 3:2 cubemap cross into skyBox2D for PT sky sampling.
|
||
- End sky: stars, planet, accretion disc (EndSky).
|
||
- Planar clouds: FBM 2D density, coverage/density by weather, sun+sky lighting.
|
||
- Volumetric fog (Volumetric_FS): height-based two-layer density + 3D noise,
|
||
ray marched with jitter, sun phase in-scattering, cloud shadow modulation;
|
||
underwater fog variant.
|
||
- Water: Gerstner-ish multi-octave waves (WaterWaves), caustics field
|
||
(CausticsTex_CS analytic wave normal field), refraction pass, deep-water tint.
|
||
|
||
## 8. Post-processing
|
||
|
||
Auto exposure (log-average luminance, temporal smoothing, EV), bloom (2-level
|
||
downsample + axial blur X/Y + composite), TAA (jittered accumulation with
|
||
neighborhood clamp and subpixel sharpening), motion blur (per-pixel velocity,
|
||
shutter angle), DOF (CoC + bokeh gather, cat's eye option), final tonemap
|
||
(ACES/AGX/filmic/vanilla), color grading (white/black point, saturation, gamma,
|
||
tone hue shifts), blue-noise dithering, gamma output.
|
||
|
||
## 9. RTWSM (warped shadow map)
|
||
|
||
BackwardAnalysis computes per-texel importance from shadow depth proximity and
|
||
gradient; BlurImportance smooths it; CollapseImportance + BuildingWarp build a
|
||
1D cumulative warp curve per row (rtwWarp1D); SampleWarp redistributes shadow
|
||
map coordinates toward high-importance texels, applied both when rendering the
|
||
shadow map (GS) and when sampling it.
|
||
|
||
## 10. Per-frame lighting constants\r?\n\r?\nNo shared SSBO is used (for maximum loader compatibility). Per-frame lighting\r?\nvalues (sun direction, sun/moon/sky irradiances, cloud irradiances, fog factors)\r?\nare computed inline by `Lib/BasicFunctions/LightingConstants.glsl` — cheap\r?\nfunctions of the sun angle and camera altitude using the analytic atmosphere\r?\nmodel. Auto-exposure is computed by Exposure_CS into a 1x1 R16F image\r?\n(exposureTex) that the final pass samples.\r?\n
|
||
## 11. File map
|
||
|
||
```
|
||
shaders/
|
||
shaders.properties program chain, buffers, images, GUI
|
||
block.properties block -> ID mapping (material system)
|
||
entity.properties entity -> ID mapping
|
||
item.properties held item light levels
|
||
begin1.csh shadow.* final.* gbuffers_*.vsh/fsh composite*.fsh/csh
|
||
world1/ world-1/ Nether/End overrides
|
||
Lib/ all implementation code (see tree above)
|
||
texture/ noise.png, CloudNoise bins, ripple.png
|
||
lang/ en_us / zh_cn
|
||
scripts/ generate_textures.js (regenerates textures)
|
||
```
|
||
|
||
## 12. Tuning notes
|
||
|
||
- Default: PT_VOXEL_RESOLUTION 8006 (256×192×256, 128-block radius, S=8192),
|
||
half-res tracing, 8-frame temporal accumulation, IRC 32³.
|
||
- For weaker GPUs: 8004 (S=4096), PT_HALF_RES stays on, reduce
|
||
PT_DIFFUSE_TEMPORAL_MAX_ACCUM, VFOG_QUALITY.
|
||
- For high end: 12006/16008, SKYBOX_RESOLUTION 128, DOF on, motion blur on.
|