G-buffer shading classes
The material shader packs both a normal and a shading class into the G-buffer. The lighting pass uses the class to interpret other channels, so the same output component does not always mean metalness or emission. Observed · material writers and deferred consumer
Normals are octahedrally encoded. The two projected components are quantized to nine bits; their low eight bits occupy o1.x/y, while high bits and a normal sign share o1.z with the class. Observed · writer and consumer disassembly
| Output | Class 1, ordinary surface | Classes 3–5, terrain/vegetation family | Confidence |
|---|---|---|---|
| o0.rgb | Base colour | Base colour | Observed |
| o0.w | Perceptual roughness | Perceptual roughness | Observed |
| o1.xyz | Packed world normal and class | Packed world normal and class | Observed |
| o1.w | Metalness | Ambient occlusion | Observed |
| o2.xy | Motion vector | Motion vector | Observed |
| o2.z | Emissive scalar, commonly exposure-divided | Specular occlusion | Observed |
| o2.w | Pass-dependent alpha | Translucency | Observed |
| o3.x | AO | Family-specific additional output | Observed |
Tex1’s forward shader establishes the roughness convention: it clamps the stored roughness to at least .045 and squares it to obtain GGX alpha. Metalness drives F0=lerp(.04,albedo,metalness) and diffuse albedo*(1-metalness). This discriminates roughness from the older SpecGloss label. Observed · forward program arithmetic
| Template | Class | Checked class-writing permutations | Confidence |
|---|---|---|---|
| Tex1_TerrainBlend | 3 | 20 | Proven · every class-writing permutation and control-flow path |
| Clutters_Grass | 4 | 8 | Proven · every class-writing permutation and control-flow path |
| Tex1_Leaves | 5 | 32 | Proven · every class-writing permutation and control-flow path |
| Bark | 5 | 8 | Proven · every class-writing permutation and control-flow path |
| Tex1_Rocks | 5 | 8 | Proven · every class-writing permutation and control-flow path |
These programs do not write class 1; the deferred non-metal branch uses F0 .04 rather than reading their o1.w as metalness. TerrainBlend’s class-writing permutations never read its material property labelled Metalness. Other permutations with UAV atomics belong to the fragment-recording pass and do not establish an alternative shading class for an ordinary G-buffer draw. Observed · all listed class writers and consumer
In those five templates the other o1-writing permutations (16, 8, 8, 2 and 2 of them) increment a structured u6 counter with imm_atomic_iadd and store a record to u7; their o0 is cb1[85] or a t70 record, o1.xyz a normal and o1.w zero, with no class byte. Observed · every o1-writing permutation of the five templates
The class literal
Section titled “The class literal”The class is a literal in the program, not a value it computes. The shader builds o1.z’s byte by inserting the normal’s sign
at bit 0 and adding its two high bits with weights 2 and 4. It then adds the literal 8 for class 1, 24 for class 3 or 32
for class 4, and writes the byte divided by 255. The class is therefore byte >> 3, and no normal can change it.
Observed · the packing code of the saved permutations below The water atlases’ bytes 48 and 80 (classes 6 and 10, on
Water surfaces) follow the same rule. Inferred
| Templates | Class | Checked permutation | Confidence |
|---|---|---|---|
| Tex1_SkinningSupported, Tex1_TeamColoured, Tex2, Tex2_TintBFromShaderConstants, Tex2_Graffiti_Mode, Grounds, Road, Hero_Ice, IceBrick, Tex1_UniqueNormalGradient, Tex1_Screen, Screens, Screens_Simple, SHD_UNLIT_UndergroundBox, Tex1_FakeRiver | 1 | ps_400000 of each |
Observed · one permutation per template |
| Decals1_Graffiti, Tex1_Graffiti_Mode_DecalFX | 1 | the cut-out permutations ps_404004 and ps_404000 |
Observed · one permutation per template |
| Outskirt | 3 | ps_400000 |
Observed · one permutation |
| SHD_Nat_Veg_Grass_AO | 4 | ps_400000 |
Observed · one permutation |
In these, class 1 has o1.w metalness, o2.z the albedo-scaled emission and o3.x the occlusion of all light. Outskirt writes o1.w = 1 (its AO) and o2.zw = (1, 0), and Grass_AO o1.w = 1, o2.z = .2 and o2.w = 0; neither writes metalness or emission. Observed · the same permutations A valid class does not mean that every input of these programs is a material value: the video and state branches of the screen templates, for example, read run-time state. Observed
Its target and UAV writes are established, but the full downstream use is not. Unknown