CNA-GAP-032: PbrEffect limits: one punctual light per draw, and no back-face normal flip for double-sided materials outside EasyGL

CNA snapshot c1c316b9  ·  Known Issues › Functional gaps  ·  source links pinned to c1c316b9

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit c1c316b9; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

PbrEffect takes one punctual light, and only EasyGL's PBR programs reverse the normal of a double-sided material's back face (GSC-0010); every other PBR renderer lights the back face with the front normal.

Identifier
CNA-GAP-032
Category
Functional gap
Subsystem
Graphics & renderers
Status
Narrowed (partially fixed; describes only what survives)
Verified against
CNA c1c316b9 (c1c316b9c7a846ce8002809c151fcd1af14942c9)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
PbrEffect::setPunctualLightEXT; PbrEffect/SkinnedPbrEffect doubleSided on renderers other than EasyGL

Expected behaviour

glTF 2.0 reverses the normal of a back face of a double-sided material before lighting.

Actual behaviour at TARGET

PbrEffect.hpp holds a single PunctualLightEXT (“Supplies one punctual light and its shadow”). The doubleSided mapping in gltf-limitations.md selects CullNone; PbrEffect and SkinnedPbrEffect pass the material's flag as GpuDrawParams::pbrDoubleSided (IGraphicsRenderer.hpp), which only EasyGL reads: its PBR programs flip N, T and B on a back face. VULKAN, SDL_GPU, WEBGPU, DIRECTX9/11 and METAL ignore it, so their back faces are lit with the front normal.

Fixed since first recorded: the back-face flip on EasyGL (GSC-0010, a1414a1b0). The entry's two limits of CNA-generated environment cubes and shadow casters do not apply at this snapshot: CNA ships no environment-cube or shadow-map generator, and an application supplies those textures to the PbrEffect receivers itself.

Source locations

Evidence

Checked by reading at c1c316b9 (the front-facing search was a grep of all of modules/); not executed. The original limits were reported by the living-room-simulator sample @ 2bf3f56b against an earlier CNA revision and re-established individually.

Re-verified at b0e97bb1: PbrEffect.hpp still holds one PunctualLightEXT. pbrDoubleSided is read only in EasyGLRenderer.cpp (GSC-0010, a1414a1b0); the other PBR renderers bind the PBR maps but never read the flag. Not executed.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

EasyGL_Pbr_DoubleSided (easygl_pbr_double_sided_test.cpp) lights a double-sided back face on EasyGL; no other renderer has such a test, and no test draws two punctual lights.

Regression test

A back-face lighting pixel test per PBR renderer; a two-punctual-light draw once that limit is lifted.

Blast radius

glTF scenes with double-sided foliage or cloth on renderers other than EasyGL, or several punctual lights per object.

Workaround

Duplicate double-sided geometry with flipped normals on renderers other than EasyGL; split draws per punctual light.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.