public static class VirtualShadowMapThe virtual shadow map's address space: clipmap levels, pages, and the arithmetic that turns a world position into one.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
Phase 7 of docs/plan/22-virtualized-geometry.md, and the reason it exists at all. A Nanite-class scene defeats cascades: the geometry is detailed enough that the cascade's own resolution becomes the visible limit, and there is no cascade count that fixes it — four maps over a whole frustum is four fixed resolutions, and the one a pixel gets is whichever slice it landed in. A virtual map inverts that: the resolution is chosen per pixel from what that pixel actually needs, and only the pages some pixel asked for are ever allocated or drawn.
Pure arithmetic with no device and no state, on ShadowCascades' terms and for the sharper version of its reason: every way a virtual shadow map goes wrong is a property of these functions. A level chosen one step too coarse is a soft shadow nobody can attribute; a page snapped to the wrong grid is a shadow that crawls when the camera moves; a page index that disagrees between the marking pass and the lookup is a pixel reading another part of the world's depth, which looks like a shadow of something that is not there. All three are assertable without rendering anything.
Snapped to whole pages, not to texels, and that is what makes a page cacheable. A cascade snaps its centre to a texel so the sampling grid does not slide; a clipmap level snaps to a page so that a camera moving less than a page leaves every page's world footprint bit-identical — which is the whole of why a page already drawn does not have to be drawn again. Snapping to a texel would leave the page boundaries sliding and every page stale every frame, which is a virtual shadow map with none of the point of one.
Fields and properties (9)
public const int PageTexelsHow many texels a page is on a side.
public const int PagesPerSideHow many pages a virtual map is on a side.
public const int PagesPerMapHow many pages one virtual map holds.
public const int MaxLevelsThe most maps — clipmap levels plus spot lights — one frame may address.
public const int MaxPagesHow many virtual pages the whole address space holds.
public const int MarkBlockHow many pixels on a side one marking invocation reads.
public const int MarkTileHow many pixels on a side one marking workgroup covers.
public const uint PageAbsentWhat the page table holds for a virtual page with no physical page behind it.
public const float ClipmapNearHow close to the light a clipmap level's box begins.
Methods (19)
public static float WorldTexelSize(float distance, float screenHeightScale, int screenHeight)How many world units one screen texel covers at a distance.
public static float DepthScale(float depthRange)One metre along the light, in a clipmap level's normalised depth.
public static float ExtentOf(int level, float firstExtent)How wide one clipmap level is, in world units.
public static float TexelOf(int level, float firstExtent)How many world units one of a level's texels covers.
public static int LevelFor(float worldTexelSize, float firstExtent, int levels)Which clipmap level a pixel needs, from the world size of its screen texel.
public static float DepthStep(int level, float firstExtent, float depthRange)How far a level's centre moves along the light between refits, in world units.
public static (int Right, int Up, int Light) ClipmapCell(int level, float firstExtent, Vector3 camera, Vector3 lightDirection, float depthRange)Which cell of its own snap grid a level's centre lands in, along the light's basis.
public static Int2 ClipmapOrigin(int level, float firstExtent, Vector3 camera, Vector3 lightDirection, float depthRange)Where a clipmap level's window sits in the light's own endless page grid.
public static Int2 ToroidalOf(Int2 page, Int2 origin)Which toroidal address a window cell holds, for a map with this origin.
public static Int2 GridOf(Int2 toroidal, Int2 origin)ToroidalOf backwards: which window cell an address names.
public static bool PageSurvives(int toroidal, int before, int after)Whether one axis of a toroidal address still means the same world after a slide.
public static Matrix4x4 ClipmapProjection(int level, float firstExtent, Vector3 camera, Vector3 lightDirection, float depth)One clipmap level's orthographic projection, snapped to its own page grid.
public static Vector3 SnapDirection(Vector3 direction, float degrees)A light direction snapped to an angular grid, so a drifting sun refits rarely.
public static (Vector3 Right, Vector3 Up, Vector3 Reference) Basis(Vector3 lightDirection)A light's own basis, which the camera never enters into.
public static bool PageOf(in Matrix4x4 viewProjection, Vector3 world, out Int2 page)Where a world position lands in a map's page grid, and whether it lands in it at all.
public static bool PageSpan(in Matrix4x4 viewProjection, Vector3 center, float radius, out Int2 first, out Int2 last)Which of a map's pages a world-space sphere's shadow can reach.
public static int IndexOf(uint first, Int2 page)A virtual page's index in the global numbering.
public static Int2 AtlasOrigin(int slot, int pagesPerSide)Where a physical page sits in the atlas, in texels.
public static Matrix4x4 PageProjection(in Matrix4x4 viewProjection, Int2 page)The projection that renders one virtual page into the whole of a viewport.
Used by (7)
- VirtualShadowAtlasVixen.Rendering
- VirtualShadowLookupDeviceTestsVixen.Graphics.Golden.Tests
- VirtualShadowMapTestsVixen.Rendering.Tests
- VirtualShadowPageTestsVixen.Rendering.Tests
- VirtualShadowPagesVixen.Rendering
- VirtualShadowRendererVixen.Rendering
- VirtualShadowRendererTestsVixen.Rendering.Tests