4.7 KiB
HLSL Renderer
Aquarium now has a first shader-owned image path.
Current Path
D3D11RenderercompilesRender/Shaders/Aquarium.hlslat startup withVortice.D3DCompiler.- The renderer draws one fullscreen triangle.
- The pixel shader raymarches the Grid heightfield, Self sun, and orbiting planets.
- C# feeds only frame constants: resolution, time, Grid radius, and camera position.
- CultMath is referenced as the CPU-side math grammar. Vortice math stays at the graphics API membrane.
Current Limits
This is still a first image path, not the final renderer. The shader keeps planet broad-phase cheap by avoiding terrain samples inside every planet anchor. Terrain-hugging orbit cups should come back through a real object table or precomputed frame constants, not repeated procedural work inside every SDF sample. That was the tiny furnace. It has been told to sit down.
Ported Renderer Lessons
The first native renderer pass carries the pieces that fit a single HLSL raymarch path:
- body-driven
powerPulseGrid wells - world-space Grid weather with domain warping and filament layers
- stable planet-local displaced SDFs
- material-specific normals so terrain and body shading do not re-evaluate the entire scene six times per visible pixel
Volumetric lighting, brick maps, HDR bloom, and debug controls are not one-pass
pixel-shader jobs. They need engine systems around the shader rather than more
stuffing in AquariumPS.
Deferred Grid Pass
The renderer now has a deferred Grid height target.
Current frame order:
- C# bins Self and planet bounds into a small Grid-space froxel table and uploads fixed primitive id slots as a structured buffer.
GridHeightPSrenders body/gravity height into a 128x128 Grid-spaceR32G32B32A32_Floatrender target.AquariumPSraymarches solids and terrain against that height texture.- Body SDF checks read only the primitive ids binned into the current froxel. Empty froxels skip body SDF work entirely.
- Displaced body SDFs report a noisy hit distance separately from a conservative envelope step distance, so high-frequency surface detail can shape the silhouette without letting rays skip over it. When a ray is inside the conservative envelope but outside the noisy surface, it takes a shell escape step instead of starving on the minimum stride.
- Terrain marching uses heightfield crossing and slope-aware steps instead of
pretending
z - height(xy)is a true Euclidean SDF. Body objects still use SDF distance steps. - Terrain normals sample adjacent Grid texels in world space instead of re-evaluating analytic height per normal tap.
- The Grid target is centered on the camera target; body anchors remain in world space.
- Direct2D/DirectWrite draws overlay text onto the swapchain backbuffer after
the shader image is complete and before
Present. Overlay text is therefore final-pixel UI, not HDR scene material, and should stay out of bloom, tonemapping, and raymarching unless a specific diegetic surface asks for the trouble.
The target currently stores height in .r only. The next useful expansion is to
store packed gradients in .g/.b during the Grid pass so the raymarcher can use
one texture fetch for height and a cheaper normal path when fidelity allows it.
Grid linework is derivative-aware in the final raymarch pass. Cartesian
Gridlines use screen-space fwidth against their world-domain coordinate so
minor and major lines stay the same pixel width across zoom distances. Terrain
height isolines and gradient-angle field lines follow the older Aetheria UI
shader pattern: height contours are derived from the Grid height field, while
angle lines quantize the terrain gradient direction and fade out on flat
surfaces.
Overlay Text
Readable overlay text is handled by DirectWriteOverlay, using DirectWrite for
font layout/rasterization and Direct2D for the final draw. The D3D swapchain uses
B8G8R8A8_UNorm so the same backbuffer can be shared with Direct2D without
format drama. This path is for debug UI, terminal text, inspectors, and future
CultUI overlay surfaces. Diegetic labels that live in the scene still belong in
the renderer as MSDF/SDF billboards.
The overlay owns a private DirectWrite font collection built from bundled Google
Fonts files in Assets/Fonts: Montserrat for thin small-cap display text and
Ubuntu Sans for body/debug copy. The runtime does not depend on those fonts
being installed in Windows.
Startup status text is drawn by the Win32 splash path before D3D exists. That path uses GDI with the same bundled font files registered privately for the process, then reports coarse initialization stages while the renderer creates the device, swapchain targets, shaders, and buffers.