The rendered frame
Both games draw a frame the same way: shadow maps, a G-buffer of the scene’s opaque surfaces, screen-space passes over
it (ambient occlusion, the sun’s shadow mask, reflections), deferred light into two light targets (diffuse and specular),
a composite with the albedo, volumetric fog, the sky and forward surfaces, effects, motion vectors and temporal
anti-aliasing, glow, exposure, bloom and a tone-mapping look-up into a 10-bit picture, then the interface. The renderer’s
own passes are the programs of the gxrenderershader and gxposteffect bundles;
the scene’s draws are the materials’ programs. Observed
The order and targets below come from one frame of each game recorded in GPU execution order (every draw, dispatch, clear and copy of the frame with its programs and bindings): Sekiro 1.06 at 1920x1080 at the Ashina Castle gate, Elden Ring 1.17.2 at 2560x1440 at night at the Stormveil gate. Programs are named by matching their bytecode with the bundles’. Observed
The passes
Section titled “The passes”| # | Pass (programs) | Sekiro | Elden Ring | Confidence |
|---|---|---|---|---|
| 1 | Shadow casters, GXRend_CopyShadowMapDepth between maps |
R16 4096x2048 and four R16 4096x4096 | D16 atlases: 6144x4096, 8192x4096, 4096x4096 | Observed |
| 2 | G-buffer: the scene’s opaque materials | targets as on G-buffer: RGB10A2, RGBA8, RGBA8, RGBA8, RGBA16F; depth D32S8 | RGB10A2, RGBA8, RGBA8 sRGB, RG8, RGBA16F; depth D32S8 | Observed |
| 3 | Depth reductions: DepthScale2x2OutputDepth |
one level | two levels, then DownSampleDepth16CS (compute) to a 160x90 RG32F tile map and a 1x1 |
Observed |
| 4 | Ambient occlusion: ScreenSpaceAO2_WithNormal, _SeparatedReProj (temporal), _BilateralUpScale |
half resolution, up to full | the same, to R8 | Observed |
| 5 | Sun shadow mask: GXScreenSpaceCascadedShadow_PCF9, GXRend_CompositeShadowMask |
splits 10 / 50 / 200 m, fades 2 / 10 / 40 m; plus a view-space shadow volume (GXViewSpaceShadowVolume_*) and two blurs |
neither the volume nor the blurs among the named programs | Observed |
| 6 | Screen-space reflections: GXSsrConvertDepth, GXSsrNew, then GXSsrTexDownScale / GXSsrTexBlur2 |
RGBA16F, half resolution, 6 mips | a prepass of programs not named in the recording, then the down-scale and blur chain, five levels | Observed |
| 7 | Environment-map regions: one box draw per region, GXEnvMapRegion[Box][DiffSpc] and variants |
61 regions in the frame | 64 | Observed |
| 8 | Sun: GXLightAcc_DDirLightShadowed1 |
after GXLightDeferredAOWithSsr |
after GXLightDeferredAOWithSsr |
Observed |
| 9 | Point and spot lights: GXLightOrganize<N> (compute, tile lists) then a tiled light pass |
GXLightOrganize16, GXRend_TileBasedLighting |
GXLightOrganize8 and GXRend_TileBasedLighting, and GXLightAcc_DPointLightShadowed1 for a shadowed point light |
Observed |
| 10 | GXLightCmbAlbedo, GXSssBlurX / Y, GXLightComposite |
into R11G11B10F | then OutputColor |
Observed |
| 11 | Volumetric fog: GXVolumetricFog_DirLightShadowReproj, _WriteInScatteringPreShadowed, a dispatch per local light, _SolveVolumetricFog, _SceneComposite |
froxels 120x72x16 | 144x88x36, plus _DirLightShadowPostFilter; then GXFogVolume_* fog volumes at half resolution |
Observed |
| 12 | Sky and forward surfaces | the sky’s materials (below), depth-only and blended material draws | before pass 11: an OutputColor fill and the sky shell at depth 0 (below), among forward draws |
Observed |
| 13 | Effects, distortion, half-resolution particles with SampleBilateralDepthBlurTwo |
Observed | ||
| 14 | Motion vectors MotionBlurWriteCMBVelocity, then StencilAndMotionVectorPreprocess, TempAA[StencilMask], SharpenFilter |
Observed | ||
| 15 | Glow: EmissiveToGlowPS, Sample13Weight down, GlowCompositeSinglePS up |
6 levels | 7 levels | Observed |
| 16 | Exposure: ToneMap_ColorToLuminancePS (64x64), ToneMap_ScaleLuminancePS (16, 4, 1), ToneMap_AdaptedLuminancePS (1x1 with the previous frame’s) |
RG32F | the same, after ToneMap_DownSample2x2PS |
Observed |
| 17 | Tone curve and grading: ToneMap_WriteReinhardExToneMappingTablePS (1024x1 R16F), a 16³ look-up |
ToneMap_Blend2Dto3DLUTCS, RGBA32F |
ToneMap_Copy2Dto3DLUTCS, RGBA16F |
Observed |
| 18 | Bloom: ToneMap_BrightPassTemporalPS, ToneMap_BloomGaussBlurPS chain, …CompositeUpScalePS, …CompositeSinglePS |
Observed | ||
| 19 | ToneMap_TabledToneMapLUTPS into RGB10A2 |
then ToneMap_PostOETFPS |
Observed | |
| 20 | Interface, GXSimple_BlendUI_SDR2SDR_F to the back buffer |
Scaleform draws | Observed |
Across recorded frames
Section titled “Across recorded frames”Over more recorded frames (Sekiro: 9 frames of 3 sessions at 1920x1080; Elden Ring: 7 frames of 2 sessions at 2560x1440): Observed
- Every full-screen draw of Sekiro binds one 3-vertex buffer, a triangle over the screen: positions (−1, 1, 1, 1), (3, 1, 1, 1), (−1, −3, 1, 1) with texture coordinates (0, 0), (2, 0), (0, 2). Observed · Sekiro
- Targets sized from the view round up: 1080 / 16 gives 68 rows in Sekiro, and Elden Ring’s bloom chain is 80x45, 40x23, 20x12, 10x6. Observed
- The tiled light lists: Elden Ring’s
GXLightOrganize8writes 1,382,400 bytes atu0(345,600 words) and 43,264 atu1(3,600 records of 12 bytes); Sekiro’sGXLightOrganize16writes 522,240 bytes atu0. Observed - The last tone-map step’s target is RGB10A2 in Sekiro’s nine frames and in five Elden Ring frames of one session, and RGBA8 in two frames of another Elden Ring session; the scene targets of both are 2560x1440, and the RGBA8 session ran on a display that reported 8 bits per colour channel with advanced colour (HDR) supported and off. What chooses the format is not shown. Observed · Elden Ring · 7 Elden Ring frames of 2 sessions Unknown
- Elden Ring draws the shadows of local lights into a 4096x4096 R16 atlas in 64x64 regions (26 in one frame), which
GXLightAcc_DPointLightShadowed1reads att7. It is there in the 2 of 7 frames that have shadowed point lights. Observed · Elden Ring - Elden Ring runs the screen-space reflection chain and
DeferredAOWithSsronly in the frames that drawM[Water](5 of 7). Observed · Elden Ring - Elden Ring’s
GXEnvMapRegion_CopyCubeToCubeLerpwrites an 8-mip 128x128 R11G11B10F cube throughu0tou7, and the region variant[LerpDiff]reads it att25. Observed · Elden Ring Its program writesuk only inside size >> k, from the source cubes at level k, souk is mip k. Inferred · Elden Ring · from the program - Elden Ring’s
ToneMap_AdaptedLuminancePSwrites one RG32F 1x1 target and reads another att4that no recorded frame writes. Observed · Elden Ring - The order of fog and sky differs: Sekiro composites the volumetric fog (
GXVolumetricFog_SceneComposite) before its sky draws, while Elden Ring draws its sky’s cloud shell (M[Clouds9]with an_FwdSdwprogram) before its fog composite. Observed
The forward or G-buffer rule decides which sky materials are drawn
forward. In both games the sky’s colour comes from forward programs: Elden Ring’s G-buffer variants of its skysphere and cloud
materials (M[Sky9]_Gbuf, M[DistantClouds]_001_Gbuf, M[Clouds5]_Gbuf, M[Atmosphere][Clouds]_001_Gbuf) write no colour,
only a normal (normal * 0.5 + 0.5 in target 0) and alpha words, every colour lane being the constant 0 (M[Sky9] samples no
texture). Observed · Elden Ring · the programs translated and read, for the tile m60_42_36_00
Pre-exposure
Section titled “Pre-exposure”The scene constants cbSceneParam carry SC_PreExposure and SC_InvPreExposure. Both are 1 in every program of the
recorded Sekiro frame, and in all 50 distinct cbSceneParam contents the Elden Ring frame binds (and its loading frame).
Observed So in these frames neither game scales its light targets by a pre-exposure factor through this constant.
Elden Ring’s cbSceneParam also carries SC_SceneExposure and SC_InvSceneExposure (offsets 1152 and 1156, reciprocal):
37.696 at night at the Stormveil gate and 19.886 in a loading frame. Observed · Elden Ring None of the 96 programs
that declare cbSceneParam in the gxrenderershader, gxposteffect, gxffxshader, gxshader, gxdecal and grass bundles
reads them: the 72 that read that row
read only SC_PreExposure, by their DXIL. Observed · Elden Ring The scene exposure is therefore a value of the
CPU side, which a light packer can apply to the records it writes. Inferred · Elden Ring
Sekiro
Section titled “Sekiro”The sky is not a pass of its own. It is drawn as material draws (programs of the materials’ shader bundles), in one
command list right after the volumetric fog’s composite, into both light targets with depth testing: boxes
(GXSimple_Transform_V) that write neither colour nor depth, the dome (M[Sky]_SkyDome_Ver2, 1,824 indices), the moon
(M[Moon], a quad of 6 indices), the far mountains (M[LandScape]_FarMountain) and the cloud layer
(M[LandScape]_CloudFog, 60,324 indices), in two recorded frames of the sunset sky. Observed · Sekiro The
dome, the moon, the far mountains and the cloud layer draw with the same states: blended by the source alpha
(SRC_ALPHA, INV_SRC_ALPHA), the depth tested with GREATER_EQUAL (the depth is reversed) and written, back faces
culled. Observed · Sekiro The dome’s pixel program reads the sun’s direction from cbLight, FC_GlobalTime, the
camera, the volumetric fog and 37 material values of its own, per its resource definitions; no separate sun-disc draw is
in the frame. Observed · Sekiro These draws are in pass 0 (Fwd), not the shadowed forward pass, by a breakpoint on
the running game’s pass id (see bundles). Observed · Sekiro
None of the map pieces the layouts of the nine maps place draws a material whose
name or definition names the sky or the moon (every map piece model of each layout read, a positive control finding
1,590 pieces with AMSN materials). Observed · Sekiro The sky is a map of its own, m89_00_00_99, whose layout
places at the origin one dome per sky state (map pieces m900000 to m900095, materials M[Sky]_SkyDome_<state>:
morning, afternoon, evening, night, past night, dawn, dark clouds, storm, fog, cloud sea, fire, and two night domes with
a cloud layer), one ring of far mountains per state (m900100 to m900200, M[LandScape]_FarMtn_<state>) and the moon,
the object o005900. Observed · Sekiro Each dome is 12.6 km across (±6,293.6 m) and spans −1,191.2 m to 3,000 m
in height, 1,824 indices. Observed · Sekiro m10_00_00_00, m11_01_00_00 and m17_00_00_00 keep domes of their
own (±6,000 m, 0 to 3,000 m) that their layouts do not place. Observed · Sekiro In the recorded frame the dome
draw’s index and vertex data are byte for byte those of the m89_00_00_99 morning, evening and night domes, which share
their geometry. Observed · Sekiro The draw drew the evening dome: its material constants (cbMtdParam) equal
M[Sky]_SkyDome_Evening’s parameters on all 37 fields, a colour being its stored value raised to the power 2.2 and
multiplied by its -Intensity parameter, in nine recorded frames of one save at the 18:00 lighting; the next closest state
(dawn) matches 28 fields. Observed · Sekiro Each of those frames draws one dome and no blend of two.
Observed · Sekiro
The game’s executable loads the sky map’s 27 models and the moon’s object from a fixed list of paths whatever the area.
Observed · Sekiro Its run-time code moves the sky map’s parts every frame: each part whose enabled flag is set
gets the world matrix “translation (camera x, 0, camera z) times the part’s own transform”, and the moon is then placed
at a distance the in-game step stores as 25.0 when it is built (a debug value, Moon Distance, can change it), read from
the decrypted code of the running game. Inferred · Sekiro The part’s enabled flag is set only by the engine’s
enable-entity call, by entity id, in the same code. Inferred · Sekiro The layout puts every dome, ring and the
moon in draw group 0, so draw groups do not pick the state. Observed · Sekiro
In the running game the sky map’s 27 parts are one block of map parts, and one dome and one ring are enabled among them. At an
Ashina Castle scene, read twice 40 s apart, two of the 27 have bit 0x200 set in the 32-bit word at part +0x14C (0x04043E00
against 0x04043C00 on the other 25): the dome m900020_0000 (entity 8904020) and the ring m900120_0000 (entity 8904021), the
ring’s number being the dome’s plus 100. Observed · Sekiro · one scene, two readings So the game shows a sky by enabling one
dome and its ring, not by choosing among drawn domes when it renders. Inferred · Sekiro m900020 is the evening dome.
Observed · Sekiro
What chooses the sky
Section titled “What chooses the sky”Event 100 of common.emevd (initialised by instruction 6 of common event 50) chooses the sky and the environment volumes
from four story flags, 9800 to 9803. After branches for particular maps and flags (one for map 10 selects environment 0), it
takes the first of these that holds: Observed · Sekiro · the installed script, read instruction by instruction
| Flags 9800 to 9803 | Part group enabled (2012:1) |
2003:80 environment |
|---|---|---|
| all off | 8907000 | 1 |
| 9800 on, the rest off | 8907010 | 2 |
| 9800 and 9801 on, 9802 and 9803 off | 8907020 | 3 |
| 9800 to 9802 on, 9803 off | 8907030 | 4 |
| all on | 8907050 | 5 |
The third branch also clears flag 9810 and sets animation 4 on the sky object 8901000. 2012:1 takes the group, not a part:
the one call for group 8907020 enables the evening dome (entity 8904020) and its ring (8904021); in a run of the game from a cold
start, all 29 calls the script made reached those parts. Observed · Sekiro · 29 of 29 calls, one run The sky therefore
follows the story’s world state, not the clock hour. Inferred · Sekiro The environment number of 2003:80 is the
package suffix of the environment volumes the frame draws: the evening branch’s 3 goes with _03 below. Inferred · Sekiro
Irradiance volumes
Section titled “Irradiance volumes”The walls’ diffuse ambient comes from volumes, not from the light set. Each of m11_01’s six packages
m11_01_00_00_envmap_00 to _05.tpf.dcx holds 580 textures: 464 BC7 (DXGI 98, package code 102) single-mip volume textures
and 116 cube maps, the volumes being 116 complete groups GIIV<nnnn>_<ss>_W, _X, _Y and _Z, and every one of the 107
EnvironmentMapEffectBox regions of the layout has a group in every package (9 groups more are not placed).
Observed · Sekiro · all six packages, read with an independent reader The four volumes of a group usually share one
grid, but not always: six groups of m11_00 (packages 01 and 05: groups 0250, 0300, 0307 and 0323) mix sizes, 0250_05 having
X, Z and W of 40 × 20 × 36 and Y of 64 × 36 × 60. Every group of m11_01, and every group of the _03 packages, shares one grid.
Observed · Sekiro · the DDS headers of the m11_00, m11_01 and m11_02 packages
In a frame at the evening lighting, every one of the 1,524 volume textures the game created matched, byte for byte, a GIIV
texture of the packages, and each of the 61 GXEnvMapRegion draws bound the four volumes X, Y, Z and W of one group
of package _03, in that order, including regions of the neighbouring maps m11_00 and m11_02. Observed[one frame, the
uploads hooked]{games=“sekiro”} The neighbouring maps’ regions draw in an m11_01 frame: the region draws of one frame
included m11_00’s box 000 (centre (102.4, 583, 8.69), 13,520 × 1,600 × 13,439 m) and m11_02’s (centre (−8.5, −67.3, −62.5),
10,000 × 1,250 × 10,000 m) beside m11_01’s own; a drawn centre is the layout’s position plus half the box’s height.
Observed · Sekiro · one frame
The diffuse region program decodes each coefficient texel as (rgb − 0.5) × 2 × 2^((a − 0.5) × 20), takes per colour channel
the dot product of a coefficient row with (n, 1), clamps it at 0 and multiplies by the pre-exposure; it scales by its
diffuse colour scale (1) and does not read g_envMapColorScale, and it samples the volumes trilinearly at level 0, clamped,
at a position offset along the normal. Observed · Sekiro · the program’s disassembly
Environment-map regions
Section titled “Environment-map regions”Each EnvironmentMapEffectBox region of a layout is one box draw of a GXEnvMapRegion program, which adds the region’s
diffuse and specular light. In one recorded frame of m11_01 at 18:00 (61 region draws, each matched to its box by
g_envMapDrawAreaExtents and the translation of g_envMapWorld, the box’s position plus half its height) the programs were
[Box][DiffSpc] 42 times, [Box][DiffSpcPcc] 9, [Stencil] 5, [Box][Diff] 3 and [Box][SpcPcc] 2. Observed · Sekiro · one frame
The box’s type data chooses the program and supplies its constants. The names are SoulsFormats’ for the type data’s words. Observed · Sekiro · 61 region draws of one frame
| Type data | Use | Confidence |
|---|---|---|
UnkT08 |
1: parallax-corrected specular (the Pcc programs); 1 on all 11 Pcc draws, 0 on the other 50 |
Observed · Sekiro |
UnkT09 |
90 on the reflection boxes below; the region’s priority | Inferred · Sekiro |
UnkT24 (i32 at 0x24) |
0 diffuse and specular ([DiffSpc], [DiffSpcPcc], [Stencil]), 1 diffuse only ([Diff]), 2 specular only ([SpcPcc]): 56, 3 and 2 draws |
Observed · Sekiro |
UnkT28 (f32 at 0x28) |
g_envMapDiffuseColorScale, bit for bit on 61 of 61 draws |
Observed · Sekiro |
UnkT2C (f32 at 0x2C) |
g_envMapColorScale, the specular cube’s scale, bit for bit on the 58 draws whose program reads it |
Observed · Sekiro |
The three diffuse-only draws are each map’s whole-map box Env_Box000, and the two specular-only ones m11_01’s and m11_00’s
Env_Box900. m11_01’s boxes 900 to 917, named 映りこみ用 (“for reflections”), have priority 90 and UnkT08 1, and
m11_00 and m11_02 have one each. Observed · Sekiro Of m11_01’s 107 boxes, 87 store 0 in UnkT24, 2 store 1, 17
store 2, and Env_Box902 stores 258 (0x102), whose 0x100 bit has no known meaning. Observed · Sekiro Lighting four
recorded wall points from the irradiance volumes of the 89 boxes that store 0 or 1, leaving out the specular-only boxes, gives the
frame’s four packed R11G11B10 irradiance words bit for bit. Observed · Sekiro · four points of one frame
For a parallax-corrected region, g_envMapMatPccObb is the box itself (g_envMapWorld) on all 11 draws, and
g_envMapRegionPccOrigin (cb3 byte 288) is the position of the environment point of the same number (Env_Point<id>) bit for
bit on all 7 of m11_01’s. Observed · Sekiro · one frame g_envMapInterpRatio is 0 on every draw, and g_envMapFadeRate
1.0 on 59 (0.468 and 0.324 on the others). Observed · Sekiro · one frame
The region’s specular cube (t25) is <map>_GILM<id>_<package> in the same environment package as its irradiance volumes: a
BC6H_UF16 (DXGI 95) cube of 128 × 128 with 7 levels, one per coefficient group. Package _03 of m11_01 holds 116, their ids
those of its 116 GIIV groups one for one; every package of m11_00 (1 to 5) holds 55 and every one of m11_02 20.
Observed · Sekiro · the packages listed with an independent reader All 61 draws bind such a cube at t25. Observed · Sekiro · one frame
The program, by its disassembly: Observed · Sekiro · the programs’ disassembly
- It writes specular to
o0and diffuse too1, both with one alpha. Withlocal = g_envMapInvWorld × Pandedge = min((1 − |local|) × g_envMapDrawAreaExtents), a pixel withedge < 0writes 0 with alpha 0; otherwisealpha = smoothstep(saturate(edge × g_envMapInvFadeDistance)) × g_envMapFadeRate. - The reflection is
r = 2(n·v)n − v,vthe unit vector to the eye andnthe G-buffer normal (× 2 − 1, normalised). - A
Pccprogram moves the ray into the unit box (q = g_envMapMatInvPccObb × P,dits rotation ofr), takes per axis|(1 − q) / d|whered > 0,|(1 + q) / d|whered < 0and 5,000 otherwise, the least of theset, and the exit pointq + t d. If any coordinate of the exit lies outside±(1 + 1e-4 t)the specular is 0 (the alpha stays); otherwise the cube is sampled alongg_envMapMatPccObb × exit − g_envMapRegionPccOrigin. The other programs sample alongr. - The cube is sampled (
SS_WrapLinear) at levelmin(6.5 − 6.5 × gloss, 6),glossbeingg_GBuffer1.x(t3).o0is the texel timesg_envMapColorScaletimes the pre-exposure (cb8[62].z);o1is the volumes’ irradiance timesg_envMapDiffuseColorScaletimes the pre-exposure.
GXLightDeferredAOWithSsr then applies ambient occlusion and the ambient BRDF: Observed · Sekiro · the program’s disassembly
AO = t32.x × t32.y(g_ShadowTexture), and the diffuse out isAOtimes the diffuse sum.(A, B)isg_AmbientBRDFTexture(t39).rg, sampledSS_ClampLinearat (min(|n·v|, 1),gloss) withnin view space, andenvBRDF = GBuffer3.rgb² × A + B(t5).- The specular sum (
t7) timesenvBRDFis blended with the screen-space reflections (t44, sampled at level5 × saturate((1 − gloss) × cb0[20].w + cb0[21].x)) byk = min(saturate(max(f0) × 10 − cb0[20].z), depth fade):AO × (spec × (1 − k × ssr.a) + envBRDF × ssr.rgb × k).
GXLightComposite adds that to the diffuse light times the albedo. Observed · Sekiro · the program’s disassembly
The ambient BRDF table is data of the executable, not of a texture file. The renderer’s setting AmbientBRDF LUT (LUT Type)
names five tables, R8G8_OLD_256, R8G8_UE4_128, R8G8_UE4_256, R8G8_UE4_512 and R16G16_UE4_256, and each has a loader that
copies its table out of .rdata into a new texture. R16G16_UE4_256 is 0x40000 bytes at VA 0x143114D30 of the 1.06 executable
(SHA-256 637aca52…8b856; file offset 0x3114130, the section being stored unencrypted), a 256 × 256 R16G16_UNORM texture
with a row pitch of 1,024; the table’s SHA-256 is aebecda11cf0543a67b87c1585dff816226e33e46653983cbb46cc945ef532fb. The
renderer’s set-up creates all five and makes R16G16_UE4_256 the current one whenever it exists, and the setting is bound to that
same pointer, so only the parameter editor changes it. Observed · Sekiro · read from the decrypted code and the executable file
All three recorded frames bind a format-35 (R16G16_UNORM) texture at t39, the only R16G16 type. Observed · Sekiro · three frames
That the bound texels are that table’s bytes is not yet read back from the running game. Inferred · Sekiro
Tone curve
Section titled “Tone curve”The tone curve, colour matrix, vignette and grading look-up, with Sekiro’s recorded constants, are on exposure, tone curve and colour grading.
Volumetric fog
Section titled “Volumetric fog”GXVolumetricFog_SolveVolumetricFog runs as 15 × 9 × 1 groups of 8 × 8 × 1 threads. It integrates the 16 slices of
120 × 72 froxels from two R32_UINT targets that pack density and blue, and red and green, as half floats, and writes slices
0 to 15 in RGBA16F, the accumulated end in slice 16 and, with EnableAnalyticalFog 0, a neutral (0, 0, 0, 1) in slice 17: a
120 × 72 × 18 volume, which the sky draw reads. Before it run the sun’s shadow reprojection, the in-scattering and one dispatch
per local point light (four in the frame). Observed · Sekiro · one frame, the program’s disassembly How its constants
come from the draw parameters is on GPARAM.
The in-scattering dispatch (GXVolumetricFog program 2fce80b2c53e19ff) gives each froxel the density
fixedDensity + heightDensity × H(h), with h the world height times the height factor and the height distribution, and
H(h) = exp(−|h|) for h ≥ 0, 2 − exp(−|h|) below. Computed from the dispatch’s constant buffer and narrowed toward zero to
f16, it gives the density half of all 138,240 froxel words of the 120 × 72 × 16 grid bit for bit. Observed · Sekiro · one frame
In the solve, the recorded slice 16 repeats slice 15. An emulation of the solve on the recorded inputs, with fused arithmetic and
narrowing toward zero, gives 622,048 of its 622,080 half-words; the other 32 are not explained. Observed · Sekiro · one frame
The moon o005900 is a 10 by 10 quad with the material M[Moon] (masked by the texture m99_Moon_3m), skinned whole to
the second of its two bones, with a skeleton and animations of its own; the recorded moon draw’s vertex and index data are
byte for byte its model’s. Observed · Sekiro
A map’s _farmodel param (FAR_MODEL_PARAM_ST) names placed parts by parts group, not the sky.
Observed · Sekiro
The dome and the far mountains follow the camera across the ground and keep their height: their object matrices are the identity rotation at the camera’s horizontal position and height 0. Observed · Sekiro
The moon follows the light: in both frames its quad’s object matrix places it 25.0 units from the camera exactly along the
light set’s direction towards its first directional light (0, 0.4226, −0.9063), with its rotation built from the same
direction so that it faces the camera. Observed · Sekiro The quad is 10 by 10 units (corners at ±5 in its own x
and y), its normal its own −z, and its vertices select the second of the draw’s two object matrices, whose z axis is that
direction, whose y axis is the world’s up made perpendicular to it, and whose x axis completes a right-handed frame.
Observed · Sekiro So the moon moves with the light set’s Angle0 over the day. Inferred · Sekiro
Group 8907020 holds the evening dome and its ring; which domes the other four groups enable, and what the map and flag branches before the table choose, were not read from the layouts.
Elden Ring
Section titled “Elden Ring”The sky is a family of assets, AEG096 (82 asset binders): skyspheres 53 to 86 km across (aeg096_010 to _016,
_101, _102), cloud layers (_400 and up), the aurora (_201), a rainbow (_200) and pieces of the Erdtree, drawn by
the sky material families (M[Sky3] to M[Sky9], M[Clouds…], M[Atmosphere][Clouds]_…, M[DistantClouds]_…) whose
materials are named Field_Skysphere_…. Observed · Elden Ring They are placed by the areas’ _99 maps: the
open world’s m60_00_00_99 places 38 of them. Observed · Elden Ring
The sky’s forward draws do not share one render state. With a GreaterEqual depth test in each, the recorded draws of the
Stormveil gate set:
| Pixel program | Colour blend | Depth write | Confidence |
|---|---|---|---|
M[Sky9]_FwdSdw |
off | on | Observed · Elden Ring · three recorded draws |
M[Clouds5]_FwdSdw |
source alpha, one minus source alpha; alpha One, Zero | on | Observed · Elden Ring · three recorded draws |
M[DistantClouds]_001_FwdSdw |
the same | off | Observed · Elden Ring · three recorded draws |
M[Clouds9]_FwdSdw |
the same as M[Clouds5] |
on, at depth 0 (below) | Observed · Elden Ring · three draws of three other frames |
The materials of Field_Skysphere_10, Clouds400, Clouds410 and Clouds411 state the matching
blend mode (0 for M[Sky9], 2 for the two cloud families)
and, for the distant clouds, a flag that turns depth writes off. Observed · Elden Ring · those four materials
The sky in the frame
Section titled “The sky in the frame”The sky is drawn where nothing else is: into the pixels whose depth is still 0 after the G-buffer, the far end of the
reversed depth. In three recorded frames at the Stormveil gate at about 8 h (the camera at three places up to 9.3 m apart,
2560x1440), the sky is two draws between GXLightComposite and the volumetric fog’s composite:
Observed · Elden Ring · three frames
OutputColor(vertex programScreenSpaceQuadShaderZ), one full-screen triangle at the depthcbVtxParam.g_vtxParam.x, 0, with the depth testGreaterEqual, no depth write and no blending, right after the composite: it writescbColor.g_fillColor, (0.013840831, 0.013840831, 0.013840831, 0.5019608) in all three frames, into the scene target wherever the depth is 0. Observed · Elden Ring · three frames- Among the forward draws, one draw of the cloud shell
M[Clouds9](6,336 indices over 1,220 vertices; the same vertex and index bytes in all three frames), a dome ±43,104 m across and −8,000 to 18,076 m high in its own frame. Observed · Elden Ring · three frames
The shell lands exactly on the sky’s pixels: its draw changes every one of the 197,950 pixels at depth 0 and no other pixel of
the scene target, and leaves the depth target as it was. Observed · Elden Ring · one frame, the targets read back before and after the draw
It does so through its own copy of cbSceneParam, whose depth rows (register 18, FC_MatrixProj’s, and register 26,
VC_MatrixViewProj’s) are 0; every other register of its 2,016 bytes equals the next forward draw’s. Its vertex program
writes SV_Position = VC_MatrixViewProj × (world − SC_CameraPos), so every vertex has depth 0 and passes the GreaterEqual
test only where nothing was drawn. Among the 641 to 870 draws of each frame that bind cbSceneParam at b8, it is the only one
with those rows 0. Observed · Elden Ring · three frames, and the vertex program’s DXIL The shell therefore needs no
real distance and never hides scenery, whatever its size. Inferred · Elden Ring
None of these frames draws an M[Sky9] skysphere or another cloud layer, in the G-buffer or forward: the fill colour and
the shell are the whole sky. Observed · Elden Ring · three frames After them the volumetric fog’s composite and the
half-resolution fog volumes change almost every sky pixel (197,701 and 192,634 of the 197,950), then the half-resolution
effects’ composite (SampleBilateralDepthBlurTwo3) and the temporal anti-aliasing, whose sharpened result
(SharpenFilter) is written back; no other material (M[…]) draw writes them. Observed · Elden Ring · one frame, the scene target read back after each pass
The shell follows the camera across the ground and keeps its height. Its object matrix (cbObjMatrix[0], repeated as
cbInstanceData[0].mWorld) is the identity rotation at (camera x, −16, camera z): its x and z equal SC_CameraPos‘s bit for
bit in each frame, while the camera’s height (5.74, 6.61 and 6.99) leaves its y at −16. Observed · Elden Ring · three frames
This is Sekiro’s sky-map placement (translation (camera x, 0, camera z) times the part’s own transform) with the part’s own
height. Inferred · Elden Ring The shell is AEG096_603: the draw’s vertex range (53,680 bytes at offset 22,816 of a
76,544-byte buffer) and its index binding (offset 0, 76,496 bytes) are byte for byte that model’s first vertex buffer and its
whole data block, which no other of the 82 sky binders holds; its
6,336 indices are its first face set, which two other sky models share. Observed[one frame, the same vertex and index bytes as
the three above; the bound ranges’ keys against every sky FLVER’s]{games=“elden-ring”}
Which show depends on the weather: WeatherAssetReplaceParam (1,007 rows) lists, for a _99 map and a weather id, the
assets drawn; every one of m60_00_00_99’s 38 sky assets is listed for some weather, and its 18 weathers list 1 to 27 of
them (weather 0: the clear skysphere aeg096_010 with its clouds and the Erdtree; weather 99: aeg096_102 alone).
Observed · Elden Ring A row (64 bytes, data version 2) is keyed by the sky map, the weather (a WeatherParam id), isFireAsh and
four CreateAssetLimitIds, and lists up to 8 asset ids, AEGnnn_mmm being the number nnn * 1000 + mmm; no key repeats, and
every asset a row names is placed by its sky map’s layout, over all 18 sky maps of the base game.
Observed · Elden Ring · every row, and the 935 layouts of the base game isFireAsh is 0 or 1 in the base game’s rows
and 2 only on the expansion’s maps (m20, m21, m28, m61). Observed · Elden Ring The code that applies the rows
takes 2 as either: it skips a row whose isFireAsh (byte 8) is 0 or 1 and does not equal the game’s current ash state, a byte of
a world-state object (+0xBCD; 0 when the object is absent). Observed · Elden Ring · read from the decrypted code of 2.7.2.0 A row with limits applies only on
maps whose MapDefaultInfoParam row (its id the map’s 8-digit number) has a WeatherCreateAssetLimitId among them: the open
world’s tiles hold 0 to 4, 21, 31, 41 and 42 in the base game and 50 to 75 in the expansion, the legacy dungeons −1; every row of
m60 has limits and no row of a legacy map has. Observed · Elden Ring
The sky maps place more than the rows name: far-view land pieces (m90XXZZ), AEG004 and AEG299 props and the Erdtree
AEG094, 594 parts in m60_00_00_99. Observed · Elden Ring m60_00_00_99’s origin is the centre of the level-2 tile
cell (10, 8): a piece m90XXZZ stands at ((XX − 10) × 1024, 0, (ZZ − 8) × 1024) and its model is centred on its cell (±512),
as the terrain of m60_10_08_02 is centred on its own; a level-0 tile (x, z) has its centre at ((x − 42) × 256 + 128,
(z − 34) × 256 + 128) in that frame. Observed · Elden Ring A legacy dungeon’s sky map mAA_BB_00_99 shares its
dungeon’s frame. Observed · Elden Ring WeatherAssetCreateParam (8 rows) spawns the rainbow between 7 and 16 h and the aurora
between 21 and 3 h, by weather. Observed · Elden Ring Its rows: 0 and 1 the rainbow AEG096_200 (condition 0, on the
change from weather 21 to 0 or to 1, 7 to 16 h), 1000 and 1001 the aurora AEG096_201 (condition 1, after an elapsed time,
21 to 3 h), and 7000 to 7003 AEG050_448 and _449 (condition 0, −2 to 82, a life time of 99,999). Rows of condition 0 set a
transition and rows of condition 1 an elapsed time, so 0 is the transition condition and 1 the elapsed-time one. Inferred · Elden Ring
Every row sets exactly one creation point and one limit (2, 4 or 70). Proven · Elden Ring · the 8 rows
Data version 1. The names are the community param definition's; the bytes it leaves as padding are zero in every row.
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 4 | u32 | AssetId | Proven | |
| 0x4 | 4 | u32 | SlotNo | Unknown | |
| 0x8 | 1 | u8 | CreateConditionType | Inferred | 0 on a weather transition, 1 after an elapsed time |
| 0x9 | 3 | u8[3] = 0 | padding | Proven | |
| 0xC | 2 | s16 | TransitionSrcWeather | Sourced | |
| 0xE | 2 | s16 | TransitionDstWeather | Sourced | |
| 0x10 | 2 | s16 | ElapsedTimeCheckWeather | Sourced | |
| 0x12 | 2 | u8[2] = 0 | padding | Proven | |
| 0x14 | 4 | f32 | ElapsedTime | Sourced | |
| 0x18 | 4 | f32 | CreateDelayTime | Sourced | |
| 0x1C | 4 | u32 | CreateProbability | Sourced | |
| 0x20 | 4 | f32 | LifeTime | Sourced | |
| 0x24 | 4 | f32 | FadeTime | Sourced | |
| 0x28 | 4 | f32 | EnableCreateTimeMin | Sourced | hours: 7 for the rainbow, 21 for the aurora |
| 0x2C | 4 | f32 | EnableCreateTimeMax | Sourced | hours: 16, 3 |
| 0x30 | 8 | s16[4] | CreatePoint0..3 | Sourced | one set per row |
| 0x38 | 4 | s8[4] | CreateAssetLimitId0..3 | Sourced | one set per row: 2, 4 or 70 |
| 0x3C | 4 | u8[4] = 0 | padding | Proven |
The layout reads the base game’s 8 rows with every padding byte zero. Proven · Elden Ring · the 8 rows of the base game’s regulation AssetGeometryParam’s isSkydomeFlag (“treated as a
celestial sphere: follows the player”, by its definition) is set on one asset only, AEG620_002, and no layout part names
one of the 17 PartsDrawParam rows that set isSkydomeDrawPhase (935 layouts read). Observed · Elden Ring
Frame constants
Section titled “Frame constants”In the scene constants cbSceneParam (2,016 bytes, b8 of the sky and light programs) FC_ShadowColor is at byte 544 and
FC_ShadowDir at 560, a unit vector towards the sun in the drawing frame: it agrees within 0.01 with the negated forward
axis of the frame’s orthographic shadow camera. Observed · Elden Ring · one frame at the Stormveil gate cbPerFrame
(b9, 448 bytes, FC_GlobalTime at 432 and FC_TimeOfDay at 436) is bound from a buffer in GPU memory in every draw, not
from an upload heap. Observed · Elden Ring
The deferred sun program’s own buffer repeats two of the scene’s matrices: cbLightAccParam’s g_InvProjMatrix (bytes 0 to
64) is byte for byte cbSceneParam’s FC_MatrixInvProj, and its g_CameraMatrix (bytes 128 to 192) is FC_MatrixInvView, so
these are the inverse projection and the camera’s inverse view, not object matrices. Observed · Elden Ring · one frame at the Stormveil gate
Deferred light
Section titled “Deferred light”The name g_ShadowTexture at t32 does not name one texture. GXLightAcc_DDirLightShadowed1 reads it with an ordinary sample
through s8 at the pixel’s screen position: it is the screen-space shadow mask of pass 5. GXScreenSpaceCascadedShadow_PCF9
reads its t32 with a depth comparison (SampleCmpLevelZero) through s12 at shadow-atlas coordinates: there it is the
cascade atlas. Observed · Elden Ring · the two installed programs’ DXIL, joined by their bytecode to three draws of the Stormveil frame
The sun program’s cbLight holds one constant, FC_DirLight: an array of two light sets, of which each pixel’s G-buffer
selects one. A set’s members, in order, are the directions Vec_0 to Vec_3, the colours Col_0 to Col_3 and the
specular colours Spc_0 to Spc_3 (four floats each), then bLocalLight (four unsigned integers) and FC_SsaoWeight:
224 bytes a set in Elden Ring. Sekiro’s sets put AmbientSH (48 bytes) and AmbientReflection between the specular
colours and bLocalLight: 288 bytes a set. Observed · Elden Ring, Sekiro · the reflection of the installed GXLightAcc_DDirLightShadowed1 pixel program each recorded graph binds
A direction’s w is not part of the direction. In the frames recorded from the running game (nine frames of three
sessions at the Ashina Castle gate), 243 of the 248 draws whose pixel program reads one light set at b5 bind a set
whose Vec_0.w is 1, with Vec_1.w to Vec_3.w at 0.12 or 0.15 or 1. The other 5 bind a set of four equal lights of
colour 1.5 whose every w is 50. Observed · Sekiro · nine recorded frames Elden Ring’s forward lake program
(M[PlacidLake]_FwdSdw) takes the sun’s highlight with a smoothness of sqrt(smoothness * (1 - 0.075 / Vec_0.w)), so a
larger w gives a sharper highlight and a w of 0 none that is a number. Observed · Elden Ring · the installed program’s DXIL
Elden Ring’s Vec_0.w is the light set’s Sharpness0 field, and Vec_1.w its Sharpness1: in frames at the Stormveil gate the
sun program’s cbLight (a 50,432-byte table of 225 sets) holds them equal to the stored values at the clock hour
(light sets of a frame).
Observed · Elden Ring · captures m14 to m17
In the recorded graphs GXLightDeferredAOWithSsr draws the two light targets first, and the sun program blends onto
them; it reads the environment-map regions’ targets, the reflections and the shadow mask. The sun program reads the shadow
mask that GXRend_CompositeShadowMask writes. Elden Ring’s GXRend_TileBasedLighting reads that mask too, after the mask
step has read the ambient occlusion; Sekiro’s tiled program reads the ambient occlusion straight from
ScreenSpaceAO2_BilateralUpScale. GXSssBlurX and Y redraw GXLightCmbAlbedo’s target before GXLightComposite reads
it. Observed · Elden Ring, Sekiro · the recorded graphs of m11_01 (nine frames) and of Elden Ring (five frames)
The tiled point and spot lights are drawn by GXRend_TileBasedLighting in Elden Ring too. Each tile’s 12-byte record from
GXLightOrganize8 holds its light counts in the third word, point lights in the low 16 bits and spot lights in the high 16: the
program adds the two and discards the pixel when the sum is 0, before it walks the tile’s lights. Observed[the installed program’s
DXIL]{games=“elden-ring”} Sekiro’s tiled program reads that word only in a debug branch. Observed · Sekiro · the program’s code
Stencil bit 0x10 marks the pixels the scene’s geometry covers. In the recorded Stormveil frame all 479 G-buffer draws (92
pipeline states, recognised by their four targets’ formats) set a stencil reference with bit 0x10: 16, 18, 50, 80, 88, 144,
210 or 242; 473 of them replace the stencil under write mask 255 and 6 keep it. GXRend_TileBasedLighting and
GXLightComposite test the stencil with mask 0x10 against reference 16, and GXLightCmbAlbedo draws with reference 255.
These three draws have independent blending off, so target 0’s blend state applies to every target they write.
Observed · Elden Ring · one frame In Elden Ring and Sekiro the reference follows the kind of object: 88 on skin (the draws the subsurface blur
selects, by the bit 0x8), 80 on the player’s other parts, and in the Stormveil frame 144 on the other character and 16 to 242 on
the map (see the light-set lane).
Observed · Elden Ring, Sekiro · one frame of each game Which material or draw data chooses a draw’s reference is not
established. Unknown · Elden Ring
Environment-map regions
Section titled “Environment-map regions”Stormveil’s environment packages are m10_00_00_00_envmap_<state>_<tier>_00.tpfbnd.dcx, seven states (00 to 06) in three
tiers (high, middle, low). Each of the 21 holds 640 TPF members of one texture each: 512 GIIV coefficient volumes and 128
GILM reflection cubes, 13,440 textures in all. The volumes are BC7_UNORM true 3-D textures of one level, their size depending
on the group (group 0000: 60 × 44 × 60 in high, 28 × 20 × 28 in middle, 12 × 8 × 12 in low); the cubes are BC6H_UF16 with
six faces and five levels, 128 × 128 in high and 64 × 64 in middle and low. Within a tier the seven states agree in their
members’ names, kinds, sizes, levels and formats. Observed · Elden Ring · the 21 Stormveil packages, read from the installed archives
Elden Ring blends two states in its region draws, where Sekiro’s draw one package’s. Observed · Elden Ring · one frame In a second recorded Stormveil frame, not the one of the pass table:
| Program | Draws | Reads | Confidence |
|---|---|---|---|
GXEnvMapRegion[Box][DiffSpc][Lerp] |
47 | the cubes g_IBLTexture (t25) and g_IBLTexture2 (t26), and two X, Y, Z, W volume groups at t27 to t34 |
Observed · Elden Ring |
GXEnvMapRegion[Box][DiffSpc][LerpDiff] |
9 | the same eight volumes, and one working cube at t25 |
Observed · Elden Ring |
GXEnvMapRegion_CopyCubeToCubeLerp (compute) |
9 dispatches | two source cubes at t0 and t1, at eight levels, writing u0 to u7 |
Observed · Elden Ring |
That the programs read these slots is traced in their DXIL, from each resource handle to its sample, not taken from the
reflection. Observed · Elden Ring · the installed programs’ DXIL The frame has 56 such sampled region draws and 6 stencil
draws. The source cubes are BC6H_UF16, 128 × 128, six faces, five levels; the working cube R11G11B10_FLOAT, 128 × 128, six faces,
eight levels; the coefficient volumes BC7_UNORM 3-D with one level. Observed · Elden Ring · one frame Each [LerpDiff] draw
reads the working cube the dispatch before it has just rewritten. Observed · Elden Ring · one frame
The two region programs shade alike apart from the cube. With [Lerp]’s two cube samples and their blend replaced by one
sample, and [LerpDiff]‘s working-cube sample by the same, the programs keep the same resource registers, constants,
dependencies, branches and output stores, the only other difference two operands of one multiplication in swapped order.
Observed · Elden Ring · the two installed programs’ DXIL, compared in SSA form [LerpDiff] is therefore [Lerp] with
the blend of the two states’ cubes done ahead of it by the compute dispatch. Inferred
Both read the cubes’ highest level from g_envMapMipmapLevelNum0 and 1 (b3 bytes 496 and 500), and all 56 draws hold
(4, 4) there: the source cubes’ five levels counted from 0, not their number. Observed · Elden Ring · one frame The
[LerpDiff] draws hold 4 too, so they read only the first five of the working cube’s eight levels.
Observed · Elden Ring · one frame What a [LerpDiff] region adds then differs from sampling and blending the two
source cubes directly only by the working cube’s R11G11B10 storage and its levels. Inferred
[Lerp] also scales the cube’s contribution by g_ivShLuminance0 and 1; its diffuse output from the coefficient volumes
does not depend on them. Observed · Elden Ring · the program’s DXIL Four of the frame’s values of these constants are
non-zero, and none of them is stored, byte for byte, in any of the 129 environment boxes of Stormveil’s layout or in 194
param tables read from the install, nor equals a decoded volume’s average. Observed[one frame, the installed layout and
params]{games=“elden-ring”} Where the game takes them from is not established. Unknown · Elden Ring
The two states are 05 and 06 of the high tier: by the fingerprints of the uploads, 55 of the 56 draws read those packages’
textures, and 548 of the 550 uploaded inputs are identified uniquely; the other two are GILM0800 cubes whose bytes are the same in
states 00, 03, 04, 05 and 06, so a cube alone does not tell the states apart, while the volumes do. All 56 draws’ b3
g_envMapInterpRatio and all 9 dispatches’ blend rate are the same f32, 0x3EB4E81C (0.35333335). One draw and its 10 inputs
match none of the 21 packages. Observed · Elden Ring · one frame; the uploads fingerprinted, not compared byte for byte
Placing a region
Section titled “Placing a region”The same frame’s region matrices (b3) are 55 boxes of Stormveil’s layout, each within 0.000122 in every one of the 16 floats.
The box’s basis is Ry × Rz × Rx of its rotation, scaled by half its width, height and depth; its centre is its position plus
the box’s local half-height offset turned by that rotation, then the map’s translation into the drawing frame, (88, −16, −16).
The pitched Env_Box253 misses by about 3.165 if the offset is not turned. Observed · Elden Ring · 55 boxes of one frame
The box’s type data at +0x34 is not its probe group: Env_Box002 stores 0 there but binds GIIV and GILM group 0002, and
Env_Box902 binds group 0901, so the box’s name alone is not the group either. Observed · Elden Ring · 55 boxes of one frame
The signed 16-bit word at +0x0A of the type data overrides the group: where it is -1 the box binds the group of its own
number, the digits of its name Env_Box<n>, and otherwise the group the word gives (Env_Box902 stores 901). The rule names
the group of all 55 captured boxes, and over all 129 boxes of Stormveil’s layout it names 128 groups, every one present in
the area’s packages. Observed · Elden Ring · 55 boxes of one frame; the 129 installed boxes No numeric field of the
box’s record, its shape, type data or entity data holds the number of the name on every box (the best on 6 of 129), so the
default comes from the name itself. Observed · Elden Ring · the 129 installed boxes That the game resolves the group
this way on every map is not traced in its code. Inferred · Elden Ring
Byte +0x1A of MapDefaultInfoParam row 10000000 (Stormveil) is 1, and of row 10010000 also 1. Observed · Elden Ring
The community param definition names it IsEnableBlendTimezoneEnvmap, blending environment maps by time of day on the legacy
maps. Sourced · Elden Ring · Paramdex It enables blending; it does not give the schedule from hour to state. The nine
m10_00 GPARAM files (0000 to 0600, 0800, 0900) have time axes offset to 6.5 h with period 24, an empty
EnvironmentConfig group and no Env Map:Editor group, so they hold no state schedule either.
Observed · Elden Ring · the nine files, read from the archives
The ratio is a function of the hour. In the four frames whose cbPerFrame was recorded (FC_TimeOfDay 8.0744, 8.1172, 8.1267
and 8.1294), the g_envMapInterpRatio of every region draw and the lerpRate of every [Lerp] dispatch is (FC_TimeOfDay − 6.5) / 4 (0.39361, 0.40424, 0.40660 and 0.40736), to within 7e-5. Observed · Elden Ring · 4 frames It is the same in a frame’s
draws and dispatches except that one region draw or dispatch of three of the nine frames reads a value 7e-5 lower, so the game
writes it again during the frame. Observed · Elden Ring · 9 frames In the five frames without cbPerFrame the same
formula gives hours of 7.92 to 8.03 from their ratios (0.3553 to 0.3829). Inferred · Elden Ring The 6.5 is the offset of the
file axis of 98 of the 102 draw-parameter files drawn at the gate (looking up an hour),
so the blend runs from 0 to 1 over the 4 hours after that axis’s start; whether the pair of states changes at its end is not
in any frame. Inferred · Elden Ring
The pair stays the same while the ratio moves. The textures bound to the region programs’ environment slots (t25 to t34)
are the same contents in the three frames with ratios 0.3553 to 0.3829 (542 or 543 of 543) and in the three with 0.4042 to 0.4074
(518 of 519), and 480 of them are in both groups; a ratio rising by 0.05 across them changes no cube or volume.
Observed · Elden Ring · 7 frames with first-use contents, the cubes and volumes’ content keys The two states are therefore
held while the ratio rises over this hour. Inferred · Elden Ring
The ratio at the gate follows (hour − 6.5) / 4 (above). The code that picks the two states for an hour (which pair outside
6.5 to 10.5 h, and where the ratio starts again), the rule that picks a tier on PC and where the formula’s 6.5 and 4 come from
are not established: all ten frames are within 7.9 to 8.2 h in one area. The probe-group rule above fits Stormveil but has not
been followed in the executable or checked on another map.
Far tiles
Section titled “Far tiles”The overworld far tiles (m60_<x>_<z>_02, and the _12 alternates) have environment packages whose probe groups no
box of the tile’s layout names: groups 0900 to 0959, each GIIV volume 84 × 84 × 84 in high, with a GILM cube
beside it. 48 far tiles have such a package, all of them m60: 46 _02 tiles, of which 32 hold one group and 14 hold
two (the second numbered 0946 to 0959), and m60_11_09_12 (one group, 0920) and m60_11_13_12 (two, 0924 and
0953, as m60_11_13_02). Observed[every m60 and m61 far tile name, _02 and _12, state 05 high, read from
the installed archives]{games=“elden-ring”} The Shadow of the Erdtree far tiles (m61) have none in high: m61_10_10_02’s
packages, for one, come in the middle tier only (states 00 to 06). Read from the best tier each far tile
installs, 67 far tiles have packages, 47 with one group, 19 with two and one with four, and 10 have none. The 19 more
than at high include m61_10_10_02, m61_10_11_02, m61_10_12_02 and m61_12_10_02 with two groups
(0900 to 0905 under 0916 to 0922) and m61_13_10_02 with four (0910, 0918, 0921 and 0922).
Observed · Elden Ring · every m60 and m61 far tile name, at the best tier each installs No recorded frame
draws one of them. Observed[the recorded Elden Ring
frames]{games=“elden-ring”}
Their volumes line up with the ground. Decoded, a W coefficient is dark in texels inside the terrain and bright in open
air. Against the highest collision surface of the far tile’s 16 small tiles and the ring around them, the volume
separates buried from open texels (those more than 1.5 rows from the surface) best when its columns run along +X, its
slices along +Z and its rows up +Y, centred on the far tile’s origin and spanning the tile’s 1,024 m (12.19 m texels).
Spans from 1,021 to 1,033 m score within 0.0001 of the best, so the volume spans the tile edge to edge.
Observed · Elden Ring · four far tiles with relief: m60_08_10, 08_11, 09_10 and 11_09
The vertical placement is known less well. With one bottom and row height shared by every tile, the second group’s rows stacked on the first’s, the mean area under the ROC curve over twelve tiles is 0.971 at rows of 13.25 m from 105 m below the origin. Bottoms from -120 to -80 m with rows of 12.75 to 13.625 m score within 0.001 of that, while flipping X or Z, spans 2.5 % narrower or wider, a shift of two texels, the bottom 40 m higher or lower, rows 10 % shorter or taller, or cubic texels all score worse. Observed[twelve far tiles, eight with two groups: m60_08_10, 08_11, 09_10, 11_09, 10_12, 10_13, 11_12, 11_13, 12_12, 12_13, 13_13 and 13_14]{games=“elden-ring”} The tiles disagree within that range: the six one-group tiles checked, taken alone, separate best with rows of 14 m from -75 m (pooled, 0.996), and the lower group of a two-group tile separates worst (0.81 to 0.99 per tile). Observed[the same twelve tiles, and m60_10_14 and 10_15]{games=“elden-ring”} The lower groups sit under high ground, where cliffs and overhangs make a highest-surface height field a poor label of buried and open, which would explain their scores without a different placement. Inferred · Elden Ring
Where a tile has two groups, the second continues the first directly above it. Stacked with the lower-numbered group at
the bottom, the two volumes separate buried from open texels at 0.902 to 0.997, and swapped at 0.079 to 0.699, on each
of the 14 _02 tiles, whose terrain reaches 22 to 1,969 m. Letting the upper group take a bottom and row height of its
own gains 0.0008 and moves its bottom 38 m down, within the uncertainty of the stack.
Observed · Elden Ring · all 14 _02 far tiles with two groups, at the shared placement above
The m61 tiles stack the same way. On the four with two groups, the lower-numbered group at the bottom separates at 0.73
to 0.995 and swapped at 0.36 to 0.46; on m61_13_10_02, 0910 under 0918 separates at 0.984 and swapped at 0.779,
while swapping 0918 with 0921, or 0921 with 0922, leaves 0.984 unchanged.
Observed · Elden Ring · the five m61 far tiles with more than one group, at the shared placement above The upper
three of that tile lie wholly above its ground, where the measure has no buried texels to rank, so it cannot tell their
order. Inferred · Elden Ring
None of the ten recorded frames holds a far tile’s volume: of the BC7 3-D textures of each frame’s resource list, none is 84 on all three sides, and the volumes the region draws bind are boxes of the area, at most 132 × 112 × 64. Observed · Elden Ring · the resources of 10 frames at the Stormveil gate A frame at the gate does not draw them, so the captures cannot show how a far tile’s groups are placed or drawn. Observed · Elden Ring
The boxes above are fitted to the volumes’ contents; the code that places these groups, whether the height range is one constant or depends on the tile, and whether they are drawn with the region programs, a fade, colour scales or a priority, is not traced. Which state blend and tier a far tile uses is the open question above. A frame that draws a far tile (at a place on the open world’s tiles, not the Stormveil gate) is missing.
The glow pass (15 above) spreads the effects’ second target. Every effect draw whose node blooms writes a 2560 × 1440 R11G11B10_FLOAT target beside the colour (effect shader programs), and after the effects four programs turn it into light the tone map adds: Observed[18 frames of 4 sessions at 2560 × 1440, the programs translated and their constants read]{games=“elden-ring”}
| Step | Program | What it does | Constants |
|---|---|---|---|
| 1 | EmissiveToGlowPS |
to 1280 × 720: one bilinear tap at each texel’s centre (the mean of the four under it), colour times alpha (1, the target having none); a texel with a NaN channel is 0 | none |
| 2 | Sample13Weight, 7 passes |
halves each level, the size rounded up, down to 10 × 6 (640 × 360, 320 × 180, 160 × 90, 80 × 45, 40 × 23, 20 × 12, 10 × 6): 13 bilinear taps, each offset in texels of the level written, times its weight | g_avSampleOffsets below, the same in every pass |
| 3 | GlowCompositeSinglePS, 6 passes |
from 10 × 6 up to 640 × 360, each level adds its bilinear upsample of the level below times g_GlowScaleOffset.x (blend one + one) |
1.2 |
| 4 | GlowCompositeSinglePS, last pass |
the 1280 × 720 level is replaced (no blend) by the 640 × 360 level’s upsample times g_GlowScaleOffset.x |
0.38711962 |
| 5 | ToneMap_BloomCompositeSinglePS |
adds the 1280 × 720 level to the glare buffer times g_vBloomFinalColor, which is the scene exposure g_ToneMapSceneLumScale in this draw (9.49 to 17.93 in these frames, equal in each) and 0.05 in the draw that adds the bright-pass bloom |
Each tap is at uv + offset × g_vScreenSpaceTexCoordScale, the reciprocal of the written level’s size, clamped half a texel of
the level read inside its edge. Observed · Elden Ring · the program’s code The 13 taps, their weights summing to 1:
Observed · Elden Ring · cbSampleOffset of every Sample13Weight draw in 18 frames
| Taps | Offset (texels of the level written) | Weight |
|---|---|---|
| 1 | (0, 0) | 0.09818182 |
| 2 | (±0.5, 0.707106) | 0.06747935 |
| 2 | (±1, 0) | 0.059550285 |
| 2 | (±0.5, −0.7071006) | 0.06747961 |
| 4 | (±0.5, ±0.23570226) | 0.08427146 |
| 2 | (0, ±0.47140452) | 0.08785695 |
The constants 1.2 and 0.38711962 are the same in all 18. Observed · Elden Ring Every level is R11G11B10_FLOAT like the glow target, each store rounding toward zero. Run as described on the glow target read back from a captured frame, with the levels in that format, steps 1 and 2 give the game’s half-size level and all seven halvings bit for bit; each climbing step, run on the game’s own levels, is exact in the median texel and off by at most one R11G11B10 step; and the whole chain gives the game’s 1280 × 720 result exact in the median texel, within 2.5 % at the 95th percentile and 99.8 % of its total. Observed[one frame’s targets, reproduced pass by pass by an independent implementation]{games=“elden-ring”} The same chain with half-float levels comes out 6 % brighter in red and green and 12 % in blue: the format’s rounding is part of the result. Observed · Elden Ring · the same frame
0.38711962 is 5 / (1 + 1.2 + … + 1.2⁶), so a glow target of one even value v comes out as 5 v, the largest levels weighing most
(the 10 × 6 level 1.156 of it, the 640 × 360 level 0.387). Inferred · Elden Ring · the arithmetic fits to 8 digits
ToneMap_TabledToneMapLUTPS takes the scene times the scene exposure plus the glare buffer times g_GlareLuminance.x (1), so the
glow lands in the scene’s own light units, added after exposure is metered: the meter (ToneMap_DownSample2x2PS and the
luminance passes) and the bright pass read the scene target without it. Observed[the programs’ code and bindings in one
frame; the factor equal to the scene exposure in all 18]{games=“elden-ring”}
Exposure
Section titled “Exposure”Elden Ring’s exposure meter and the scale the CPU derives from it are on exposure, tone curve and colour grading.
In nine more recorded frames at the gate (the camera at five places, its height 5.74 to 8.19 m, looking from 20° below the
horizon to 40° above it, at about 8 h) the shell’s object matrix is again the identity rotation with x and z equal to
SC_CameraPos’s bit for bit and y −16. Observed · Elden Ring · 9 frames; the tenth holds no constants Of the 1,872 to 2,768
draws of each frame that bind both cbObjMatrix and cbSceneParam, the shell is the only one whose matrix sits at the camera’s
x and z, and in every frame exactly one of the scene-constant contents bound has registers 18 and 26 zero.
Observed · Elden Ring · 9 frames None of the ten frames, the three that look up at the sky included, draws an M[Sky9]
skysphere or another cloud layer: the fill and the shell are the whole sky at this hour and place. Observed[10 frames, the
programs of every draw named]{games=“elden-ring”}
The cloud shell M[Clouds9] follows the camera at a fixed height (above), in every frame that holds constants. Whether the
skysphere M[Sky9] and the cloud layers drawn in night frames are placed the same way and take the same depth-0 scene
constants is not shown: no recorded frame draws one (all ten are at the Stormveil gate at about 8 h). How a weather’s list
combines with the _99 map’s own placements is not established.