nx_sdfrender_sss_gate.nx source
↩ module page · 325 lines · 19764 B
1// nx_sdfrender_sss_gate.nx -- THE PRE-INTEGRATED-NORMAL HALF of Penner 2011, gated. [@penner2011]
2// /compare/graphics row: "RENDER: pre-integrated SSS bound to baked normals" -- the rung that stops
3// the clay read. The CURVATURE half (sr_sss_preint over N.L x curvature) already shipped and is pinned
4// by nx_sdfrender_gate's T6; this gate owns the half that binds the shader to the BAKED NORMAL MAP:
5// each colour channel lit by its own blur of DETAIL->GEOMETRIC normal, so fine relief SCATTERS.
6//
7// ★2026-08-25, THE SAMPLING RUNG: the mechanism above shipped bound to the baked map's CONSTANTS while
8// the DETAIL normal was still a procedural stand-in (mat_height through a hand-picked 10/16 gain). Its
9// reach was MEASURED at 18 against the law's 51, so the blur was competing with a signal of a different
10// width. sdf_shade_ray now samples the BAKED MAP'S OWN HEIGHT FIELD -- literally the same rlf_noise3 the
11// baker calls -- and the gain is the law instead of a number. T4/T9/T10 are that rung; T3's derivation
12// and the whole curvature half are unchanged and still pinned.
13//
14// WHY THESE TEETH AND NOT A PICTURE DIFF: a render diff moves for a hundred reasons. Every tooth here
15// is a property of the arithmetic that the WRONG implementations provably cannot satisfy --
16// * a PLAIN BLUR softens all three channels equally -> dies at T6 (neg-control, bite-proven)
17// * a RED TINT raises red's level, not its contrast -> dies at T1 (neg-control, bite-proven)
18// * the PRE-RUNG shader (wrap only) -> dies at T6, which measures it AS THE CONTROL
19// * a dialled-in constant -> dies at T3/T9 (derivation + the law's gain)
20// * a LOOK-ALIKE field of the shader's own -> dies at T4 (the baker's field, cross-checked)
21// * the retired 10/16 gain -> dies at T9 (neg-control, bite-proven)
22// T5 alone is NOT sufficient and that is measured, not assumed: a uniform blur PASSES T5 (the wrap
23// already orders the channels) and FAILS T6. T6 is the load-bearing tooth for the MECHANISM, and its
24// bar is not a magic number -- it is the SHIPPED wrap-only path, called at runtime as the incumbent
25// control. T10 is the load-bearing tooth for the REACH, and its bar is the RETIRED procedural path,
26// also called at runtime. Neither bar is ever a constant.
27// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26).
28import "nx_syscalls.nx"
29import "nx_gate_verdict.nx"
30import "nx_relief_lib.nx"
31import "nx_sdfrender.nx"
32import "nx_nxa_texbake_lib.nx"
33
34const SG_PK: i64 = 1024 // the (wR,wG,wB) packing radix used by sr_sss_preint_n
35const SG_PK2: i64 = 1048576 // = SG_PK*SG_PK, the blue field's shift
36const SG_PERMIL: i64 = 1000
37const SG_TINT: i64 = 1 // a ONE-UNIT red tint: the smallest possible level change
38const SG_CH_R: i64 = 0
39const SG_CH_G: i64 = 1
40const SG_CH_B: i64 = 2
41const SG_CURV_STEP: i64 = 64 // curvature sweep step (0..SSS_CURV_MAX inclusive)
42const SG_NDL_STEP: i64 = 32 // N.L sweep over the full -SSS_N_FULL..SSS_N_FULL range
43
44func sg_chan(v: i64, ch: i64) -> i64 {
45 if ch == SG_CH_R { return v % SG_PK }
46 if ch == SG_CH_G { return (v / SG_PK) % SG_PK }
47 return v / SG_PK2
48}
49func sg_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
50
51// THE REAL IMPLEMENTATION: per-channel blur, detail -> geometric.
52func sg_pre_real(nd: i64, gd: i64, curv: i64) -> i64 {
53 let br: i64 = sr_sss_blur(SSS_WRAP_R0)
54 let bg: i64 = sr_sss_blur(SSS_WRAP_G0)
55 let bb: i64 = sr_sss_blur(SSS_WRAP_B0)
56 return sr_sss_preint_n(sr_sss_ndl(nd, gd, br), sr_sss_ndl(nd, gd, bg), sr_sss_ndl(nd, gd, bb), curv)
57}
58// THE WRONG ONE -- A PLAIN BLUR: one blur for all three channels.
59func sg_pre_uniform(nd: i64, gd: i64, curv: i64) -> i64 {
60 let u: i64 = sr_sss_blur(SSS_WRAP_R0)
61 return sr_sss_preint_n(sr_sss_ndl(nd, gd, u), sr_sss_ndl(nd, gd, u), sr_sss_ndl(nd, gd, u), curv)
62}
63
64// relief CONTRAST in one channel: the response difference between a relief crest and a relief trough
65// sitting on the SAME coarse surface. This is the quantity the clay read is made of.
66func sg_contrast_real(gd: i64, tilt: i64, curv: i64, ch: i64) -> i64 {
67 return sg_abs(sg_chan(sg_pre_real(gd + tilt, gd, curv), ch) - sg_chan(sg_pre_real(gd - tilt, gd, curv), ch))
68}
69func sg_contrast_uniform(gd: i64, tilt: i64, curv: i64, ch: i64) -> i64 {
70 return sg_abs(sg_chan(sg_pre_uniform(gd + tilt, gd, curv), ch) - sg_chan(sg_pre_uniform(gd - tilt, gd, curv), ch))
71}
72// THE CONTROL: the SHIPPED pre-rung path (wrap only, one normal for all channels).
73func sg_contrast_wrap(gd: i64, tilt: i64, curv: i64, ch: i64) -> i64 {
74 return sg_abs(sg_chan(sr_sss_preint(gd + tilt, curv), ch) - sg_chan(sr_sss_preint(gd - tilt, curv), ch))
75}
76
77// THE DETECTOR T6 IS BUILT ON: does <impl>'s red/blue relief-contrast ratio FAIL to come in strictly
78// under the shipped wrap-only path's ratio? 1 = fails (no real per-channel scattering happened).
79func sg_fails_ratio(cr: i64, cb: i64, wr: i64, wb: i64) -> i64 {
80 if cb <= 0 { return 1 }
81 if wb <= 0 { return 1 }
82 if cr * SG_PERMIL / cb < wr * SG_PERMIL / wb { return 0 }
83 return 1
84}
85// THE DETECTOR T1 IS BUILT ON: at ZERO relief (detail normal == geometric normal), does <impl> deviate
86// from the shipped sr_sss_preint anywhere on the full N.L x curvature grid? 1 = deviates.
87func sg_breaks_identity(tint: i64) -> i64 {
88 var q: i64 = 0 - SSS_N_FULL
89 while q <= SSS_N_FULL {
90 var c: i64 = 0
91 while c <= SSS_CURV_MAX {
92 if sg_pre_real(q, q, c) + tint != sr_sss_preint(q, c) { return 1 }
93 c = c + SG_CURV_STEP
94 }
95 q = q + SG_NDL_STEP
96 }
97 return 0
98}
99
100// ---- THE RETIRED INCUMBENT, KEPT RUNNABLE. Until 2026-08-25 sdf_shade_ray tilted the normal by the
101// PROCEDURAL mesostructure (mat_height central differences, scaled 10/16). Nothing in the shading path
102// calls it now, but it is measured here every run as the BAR for T10: a baseline you cannot re-run is a
103// number, not a control. The five constants below are the retired shader's own, named and mirrored.
104const SG_REACH_N: i64 = 64 // samples along the sweep
105const SG_REACH_STRIDE: i64 = 7 // model-unit stride, coprime with the noise lattices (24/9/5 and 18)
106const SG_MT_HI: i64 = 8201 // the retired shader's +e central-difference offset
107const SG_MT_MID: i64 = 8192
108const SG_MT_LO: i64 = 8183 // ... and its -e offset
109const SG_OLD_GAIN_NUM: i64 = 10 // the RETIRED hand-picked gain. It exists here ONLY as a neg-control.
110const SG_OLD_GAIN_DEN: i64 = 16
111func sg_proc_tilt_max() -> i64 {
112 var mx: i64 = 0
113 var i: i64 = 0
114 while i < SG_REACH_N {
115 let p: i64 = i * SG_REACH_STRIDE
116 let hx: i64 = mat_height(p + SG_MT_HI, SG_MT_MID, SG_MT_MID) - mat_height(p + SG_MT_LO, SG_MT_MID, SG_MT_MID)
117 let t: i64 = sg_abs(hx * SG_OLD_GAIN_NUM / SG_OLD_GAIN_DEN)
118 if t > mx { mx = t }
119 i = i + 1
120 }
121 return mx
122}
123// ---- THE SHIPPED PATH, measured by calling the SHADER'S OWN function over the SAME sweep. One ruler:
124// what this reports is the reach sdf_shade_ray actually has, never a re-derivation of it.
125func sg_baked_tilt_max() -> i64 {
126 var mx: i64 = 0
127 var i: i64 = 0
128 while i < SG_REACH_N {
129 let p: i64 = i * SG_REACH_STRIDE
130 let t: i64 = sg_abs(sr_relief_grad(p, SG_MT_MID, SG_MT_MID, 0))
131 if t > mx { mx = t }
132 i = i + 1
133 }
134 return mx
135}
136
137// ---- FIELD IDENTITY ACROSS THE ORGAN BOUNDARY. 1 = the shader's volumetric sample at <cell> and the
138// baker's per-texel height at atlas resolution <res> are DIFFERENT functions; 0 = they are one function.
139const SG_FIELD_N: i64 = 64
140const SG_FIELD_STRIDE2: i64 = 11 // second-axis stride, coprime with the first and with every lattice
141const SG_NEG_RES: i64 = 4096 // a real atlas resolution whose relief lattice is NOT the shader's
142// the two other whole-body atlas resolutions the baker is PROVEN at -- named so the published atlas
143// ceiling is a statement about REAL bakes rather than three numbers picked to make a point
144const SG_ATLAS_RES_LO: i64 = 1024
145const SG_ATLAS_RES_MID: i64 = 2048
146// a codomain's TOP VALUE sits exactly one below its modulus. Named so T9 ASSERTS that relationship
147// rather than assuming it, since the compiler takes literal const initialisers only.
148const SG_CODOMAIN_GAP: i64 = 1
149func sg_field_differs_at(cell: i64, res: i64) -> i64 {
150 var i: i64 = 0
151 while i < SG_FIELD_N {
152 let ax: i64 = i * SG_REACH_STRIDE
153 let ay: i64 = i * SG_FIELD_STRIDE2
154 if ntb_relief_h(ax, ay, res, i) != rlf_relief_h3(ax, ay, i, cell) { return 1 }
155 i = i + 1
156 }
157 return 0
158}
159// 1 = <g> is NOT the baked map's own angular width, i.e. this gain does not carry the law.
160func sg_gain_breaks_law(g: i64) -> i64 { if g != sr_relief_wrap() { return 1 } return 0 }
161func sg_tilt_old_gain(dh: i64) -> i64 { return dh * SG_OLD_GAIN_NUM / SG_OLD_GAIN_DEN }
162
163func main() -> i64 {
164 let ctr: *i64 = gv_ctr()
165 gv_head("nx_sdfrender_sss_gate -- PRE-INTEGRATED NORMALS bound to the baked normal map (Penner 2011)" as *u8)
166
167 // ---- the fixture. Both numbers are DERIVED, neither is chosen: the relief tilt IS the relief's own
168 // derived angular width, and the coarse surface is the mid-lit one (no channel clamps there, so a
169 // contrast comparison measures the shader and not the clamp).
170 let tilt: i64 = sr_relief_wrap()
171 let gd: i64 = SSS_N_FULL / 2
172 let br: i64 = sr_sss_blur(SSS_WRAP_R0)
173 let bg: i64 = sr_sss_blur(SSS_WRAP_G0)
174 let bb: i64 = sr_sss_blur(SSS_WRAP_B0)
175 gv_puts(" relief_wrap=" as *u8); gv_num(tilt)
176 gv_puts(" blur r/g/b=" as *u8); gv_num(br); gv_puts("/" as *u8); gv_num(bg); gv_puts("/" as *u8); gv_num(bb)
177 gv_puts(" of " as *u8); gv_num(SSS_N_FULL)
178 gv_puts(" (from RLF_RELIEF_UM=" as *u8); gv_num(RLF_RELIEF_UM)
179 gv_puts(" lambda=" as *u8); gv_num(RLF_RELIEF_LAMBDA_UM); gv_puts(")\n" as *u8)
180
181 // T0 THE FIXTURE MUST REACH THE CONDITION BEFORE ANY OUTCOME IS ASSERTED: the relief has to actually
182 // tilt the surface, and it has to move the channels APART, or every tooth below is vacuous.
183 var t0: i64 = 1
184 if tilt <= 0 { t0 = 0 }
185 if sr_sss_ndl(gd + tilt, gd, br) == sr_sss_ndl(gd + tilt, gd, bb) { t0 = 0 }
186 gv_check("T0 fixture-relief-actually-tilts-and-separates-channels" as *u8, t0, ctr)
187
188 // T1 ZERO RELIEF IS BIT-EXACTLY THE SHIPPED SHADER. Flat skin must not move by one unit: this rung
189 // is additive on the coarse surface and only acts where relief exists.
190 var t1: i64 = 0
191 if sg_breaks_identity(0) == 0 { t1 = 1 }
192 gv_check("T1 no-relief-identity-bit-exact-vs-shipped-sr_sss_preint" as *u8, t1, ctr)
193
194 // T2 the blur ordering is the diffusion profile's, and it is bounded.
195 var t2: i64 = 1
196 if br <= bg { t2 = 0 }
197 if bg <= bb { t2 = 0 }
198 if bb <= 0 { t2 = 0 }
199 if br >= SSS_N_FULL { t2 = 0 }
200 gv_check("T2 blur-ordered-red-widest-and-strictly-bounded" as *u8, t2, ctr)
201
202 // T3 THE DERIVATION, PINNED: the relief width is arithmetic over the baked map's constants, not a
203 // dial. Re-derived here from the OWNER's constants and compared with the shipped function.
204 var t3: i64 = 1
205 if tilt != SSS_N_FULL * RLF_TILT_K * RLF_RELIEF_UM / RLF_RELIEF_LAMBDA_UM { t3 = 0 }
206 if tilt <= 0 { t3 = 0 }
207 gv_check("T3 relief-wrap-derived-from-baked-map-not-dialled" as *u8, t3, ctr)
208
209 // T4 ONE OWNER, PROVEN ACROSS THE ORGAN BOUNDARY. This REPLACES the old mirror-equals-baker tooth,
210 // which compared two HAND-COPIED constants -- those copies are gone (nx_relief_lib owns the law), so
211 // that comparison is now structurally incapable of failing, and a vacuous tooth wearing the name of
212 // a drift guard is worse than no tooth at all. What is checked instead is the thing that can still
213 // be got wrong: the field the SHADER samples must be the SAME FUNCTION the BAKER bakes. Pick the
214 // atlas resolution whose relief lattice equals the shader's own cell, then compare the two organs'
215 // heights at the same coordinates. FIXTURE-REACHES-THE-CONDITION first: if that resolution does not
216 // actually produce the shader's lattice, the comparison would be meaningless and the tooth fails.
217 let cell: i64 = sr_relief_cell()
218 let mres: i64 = RLF_BODY_UM * cell / RLF_RELIEF_LAMBDA_UM
219 var t4: i64 = 1
220 if rlf_relief_lat(mres) != cell { t4 = 0 }
221 if sg_field_differs_at(cell, mres) != 0 { t4 = 0 }
222 gv_puts(" shader relief cell=" as *u8); gv_num(cell)
223 gv_puts(" == baker lattice at res " as *u8); gv_num(mres)
224 gv_puts(" (lat=" as *u8); gv_num(rlf_relief_lat(mres)); gv_puts(")\n" as *u8)
225 gv_check("T4 shader-field-IS-the-bakers-field-same-hash-same-lattice" as *u8, t4, ctr)
226
227 // T5 THE ANTI-CLAY PROPERTY: relief contrast strictly ordered red < green < blue. The fine relief is
228 // scattered away in red and kept in blue -- which is what skin does and what clay does not.
229 let cr: i64 = sg_contrast_real(gd, tilt, 0, SG_CH_R)
230 let cg: i64 = sg_contrast_real(gd, tilt, 0, SG_CH_G)
231 let cb: i64 = sg_contrast_real(gd, tilt, 0, SG_CH_B)
232 var t5: i64 = 1
233 if cr >= cg { t5 = 0 }
234 if cg >= cb { t5 = 0 }
235 if cr <= 0 { t5 = 0 }
236 gv_puts(" relief contrast r/g/b=" as *u8); gv_num(cr); gv_puts("/" as *u8); gv_num(cg); gv_puts("/" as *u8); gv_num(cb); gv_puts("\n" as *u8)
237 gv_check("T5 relief-contrast-strictly-channel-ordered-r-lt-g-lt-b" as *u8, t5, ctr)
238
239 // T6 THE LOAD-BEARING TOOTH FOR THE MECHANISM: the per-channel NORMAL must buy scattering the wrap
240 // alone did not. The bar is the SHIPPED wrap-only path measured at runtime -- an incumbent control,
241 // not a constant.
242 let wr2: i64 = sg_contrast_wrap(gd, tilt, 0, SG_CH_R)
243 let wb2: i64 = sg_contrast_wrap(gd, tilt, 0, SG_CH_B)
244 var t6: i64 = 0
245 if sg_fails_ratio(cr, cb, wr2, wb2) == 0 { t6 = 1 }
246 gv_puts(" red/blue contrast permil: new=" as *u8); gv_num(cr * SG_PERMIL / cb)
247 gv_puts(" vs wrap-only control=" as *u8); gv_num(wr2 * SG_PERMIL / wb2); gv_puts("\n" as *u8)
248 gv_check("T6 relief-contrast-ratio-strictly-beats-wrap-alone" as *u8, t6, ctr)
249
250 // T7 CURVATURE STILL BITES THROUGH THE NEW PATH: the response must vary with CURVATURE, not only
251 // with N.L. A shader that only reads N.L cannot pass this, and neither can one that dropped the
252 // curvature half while wiring the normal half.
253 let f0: i64 = sg_pre_real(gd, gd, 0)
254 let fc: i64 = sg_pre_real(gd, gd, SSS_CURV_MAX)
255 var t7: i64 = 1
256 if sg_chan(fc, SG_CH_R) <= sg_chan(f0, SG_CH_R) { t7 = 0 }
257 if sg_chan(fc, SG_CH_G) <= sg_chan(f0, SG_CH_G) { t7 = 0 }
258 if sg_chan(fc, SG_CH_B) <= sg_chan(f0, SG_CH_B) { t7 = 0 }
259 gv_check("T7 curvature-still-widens-every-channel-through-the-new-path" as *u8, t7, ctr)
260
261 // T8 NO RESURRECTED BACKLIGHT: fully-away skin stays black at every curvature, relief or not.
262 var t8: i64 = 1
263 var c8: i64 = 0
264 while c8 <= SSS_CURV_MAX {
265 if sg_pre_real(0 - SSS_N_FULL + tilt, 0 - SSS_N_FULL, c8) != 0 { t8 = 0 }
266 if sg_pre_real(0 - SSS_N_FULL - tilt, 0 - SSS_N_FULL, c8) != 0 { t8 = 0 }
267 c8 = c8 + SG_CURV_STEP
268 }
269 gv_check("T8 fully-away-stays-black-under-relief-at-every-curvature" as *u8, t8, ctr)
270
271 // T9 THE GAIN IS THE LAW, NOT A NUMBER. The shader's height-delta -> tilt conversion must turn the
272 // field's FULL SWING into EXACTLY the baked map's angular width, nothing into nothing, and negate
273 // symmetrically. The retired 10/16 gain fails this by construction -- see the neg-control. The last
274 // conjunct pins the codomain to its own unit, since the compiler takes literal const initialisers
275 // only and the two are therefore free to drift in the source.
276 var t9: i64 = 1
277 if sr_relief_tilt(RLF_H_RANGE) != sr_relief_wrap() { t9 = 0 }
278 if sr_relief_tilt(0) != 0 { t9 = 0 }
279 if sr_relief_tilt(0 - RLF_H_RANGE) != 0 - sr_relief_wrap() { t9 = 0 }
280 if RLF_H_RANGE != RLF_UNIT - 1 { t9 = 0 }
281 gv_check("T9 shader-gain-maps-full-swing-to-exactly-the-baked-width" as *u8, t9, ctr)
282
283 // T10 THE REACH ACTUALLY MOVED -- the deliverable of this rung, and the tooth the pre-rung shader
284 // cannot pass. Both paths are measured over the SAME sweep, at runtime: the retired procedural
285 // stand-in (bar) and the shipped baked-field sampler. ANTI-VACUITY: the bar must be non-zero, or
286 // "the new one is bigger" is beating nothing at all.
287 let pt: i64 = sg_proc_tilt_max()
288 let bt: i64 = sg_baked_tilt_max()
289 var t10: i64 = 1
290 if pt <= 0 { t10 = 0 }
291 if bt <= pt { t10 = 0 }
292 gv_puts(" REACH on the N.L axis: retired procedural stand-in=" as *u8); gv_num(pt)
293 gv_puts(" -> SHIPPED baked-field sampler=" as *u8); gv_num(bt)
294 gv_puts(" against the law's " as *u8); gv_num(tilt)
295 gv_puts("\n (both are SWEPT maxima over " as *u8); gv_num(SG_REACH_N)
296 gv_puts(" samples, i.e. LOWER BOUNDS on each path; the shipped path's EXACT peak is pinned by T9\n" as *u8)
297 gv_check("T10 REACH-baked-relief-strictly-exceeds-the-procedural-stand-in" as *u8, t10, ctr)
298
299 // ---- MEASURED, PUBLISHED, AND THE REASON THE SHADER READS THE FIELD RATHER THAN RE-SAMPLING AN
300 // ATLAS. A whole-body atlas clamps the relief lattice to two texels, so the peak tilt it can encode
301 // is full-swing over the two-texel run -- strictly less than the law at every shippable resolution.
302 // Fetching those texels would have handed the shader LESS relief than the stand-in it replaces.
303 gv_puts(" ATLAS CEILING (peak tilt a whole-body atlas can ENCODE) 1024=" as *u8)
304 gv_num(rlf_atlas_tilt_full(SG_ATLAS_RES_LO, SSS_N_FULL))
305 gv_puts(" 2048=" as *u8); gv_num(rlf_atlas_tilt_full(SG_ATLAS_RES_MID, SSS_N_FULL))
306 gv_puts(" 4096=" as *u8); gv_num(rlf_atlas_tilt_full(SG_NEG_RES, SSS_N_FULL))
307 gv_puts(" -- all below the law's " as *u8); gv_num(tilt)
308 gv_puts(", because the texel footprint clamps the lattice.\n" as *u8)
309
310 // ---- NEG-CONTROLS: the wrong implementations, built here and PROVEN to die. A tooth that has only
311 // ever seen the right answer is unverified; gv_bite requires the detector to fire on bad AND stay
312 // silent on good, so a detector that refuses everything cannot score either.
313 let ur: i64 = sg_contrast_uniform(gd, tilt, 0, SG_CH_R)
314 let ub: i64 = sg_contrast_uniform(gd, tilt, 0, SG_CH_B)
315 gv_puts(" neg-control uniform-blur red/blue permil=" as *u8); gv_num(ur * SG_PERMIL / ub)
316 gv_puts(" (passes T5 ordering, must FAIL T6 -- this is why T5 alone is not sufficient)\n" as *u8)
317 gv_bite("neg-control-plain-blur-cannot-beat-wrap-alone" as *u8, sg_fails_ratio(ur, ub, wr2, wb2), sg_fails_ratio(cr, cb, wr2, wb2), ctr)
318 gv_bite("neg-control-red-tint-cannot-pass-zero-relief-identity" as *u8, sg_breaks_identity(SG_TINT), sg_breaks_identity(0), ctr)
319 gv_bite("neg-control-retired-10-16-gain-cannot-carry-the-law" as *u8, sg_gain_breaks_law(sg_tilt_old_gain(RLF_H_RANGE)), sg_gain_breaks_law(sr_relief_tilt(RLF_H_RANGE)), ctr)
320 gv_bite("neg-control-a-different-atlas-lattice-is-a-different-field" as *u8, sg_field_differs_at(cell, SG_NEG_RES), sg_field_differs_at(cell, mres), ctr)
321
322 let rc: i64 = gv_verdict("SDFRENDER-SSS" as *u8, ctr, "pre-integrated NORMALS bound to the baked map: the DETAIL normal is now the baked map's own height field read at the lattice this sampler can resolve, gained by the map's own physical law rather than a picked number, so fine relief scatters per channel (red loses it, blue keeps it) while the coarse surface stays lit; flat skin bit-identical to the shipped shader; the law has ONE declaration that the baker and the renderer both import" as *u8)
323 sys_exit(rc)
324 return rc
325}