Skip to content

Flag reader placeholder maps instead of guessing them by size - #49

Merged
treeform merged 1 commit into
masterfrom
fix/writer-placeholder-flags
Aug 15, 2026
Merged

Flag reader placeholder maps instead of guessing them by size#49
treeform merged 1 commit into
masterfrom
fix/writer-placeholder-flags

Conversation

@treeform

Copy link
Copy Markdown
Owner

Problem

CI has been red on master since e33ca75 (Aug 11), on both Linux and Windows:

  • Linux — tests.nim(358): fileExists(externalImagePath)
  • Windows — test_ktx2.nim(221): fileExists(externalKtx2ImagePath)

e33ca75 taught writeGLB to skip the 1x1 fill images the reader substitutes for empty texture slots, so exported files don't gain meaningless textures. It detected them by size:

img == nil or (img.width <= 1 and img.height <= 1)

A 1x1 image is indistinguishable from a real texture that small, and both failing tests supply exactly that — a genuine 1x1 base color the caller built. Their textures were silently dropped, so no sidecar image was ever written. The tests predate e33ca75; the commit changed writer behavior without running them.

Fix

The reader is the only thing that creates these fills, so it records the fact rather than leaving the writer to infer it. Each Material texture slot gains a *Placeholder flag, set at the five sites in defaultRuntimeMaterial() and the five per-primitive else branches where the fill is made. The writer consults the flag:

img == nil or placeholder

The flag defaults to false, so hand-built materials keep writing their textures no matter how small — which is what makes the two failing tests pass — while reader placeholders stay out of the output.

hasNormalTexture is left as an additional gate on the normal slot; it is a pre-existing, separately-consumed field (all four renderer backends read it) and out of scope here.

Tests

Adds "placeholder maps are not written back" to tests/tests.nim: reads a glTF whose material declares no textures, asserts all five slots come back flagged, writes it out with iwmExternal, and asserts no sidecar image appears next to the .glb. This covers the behavior e33ca75 introduced but never tested. Verified it fails without the fix:

placeholder written as a texture: tmp/out_placeholder/occlusion.png

Verification

Every step of .github/workflows/build.yml run locally on macOS, all green:

  • nim check src/gltf.nim
  • nim check tests/draco/tests.nim
  • nim r -d:release tests/backend_shaders.nim
  • nim r -d:release tests/draco/tests.nim
  • nim r -d:release tests/tests.nim — including both previously-failing suites
  • nim r -d:release tests/test_ktx2.nim
  • nim c --compileOnly -d:release -d:shadyBinaryShaders -d:useOpenGL for tests/sample_assets.nim and tools/gltf_viewer.nim

One caveat on local runs: the EXT_texture_webp test needs a pixie new enough to have the pure-Nim WebP decoder (treeform/pixie#581). Against an older pixie it fails with Unsupported image file format on a VP8L payload, unrelated to this change; CI installs a current pixie and decodes it fine.

🤖 Generated with Claude Code

writeGLB skipped any material map that was 1x1 or smaller, on the theory
that such images are the 1x1 fills the reader substitutes for empty
texture slots. That guess is wrong for a genuinely 1x1 texture the caller
supplied, which was silently dropped instead of written -- breaking the
external and KTX2 image-mode tests, and CI on master since e33ca75.

The reader is the only thing that creates those fills, so let it say so:
each Material texture slot gains a `*Placeholder` flag, set where the fill
is made, and the writer consults the flag rather than the dimensions. The
flag defaults to false, so hand-built materials keep writing their
textures no matter how small they are.

Adds a test that a material read with no textures round-trips through
writeGLB without gaining any, which e33ca75 changed behavior for but never
covered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@treeform
treeform merged commit f3ab67e into master Aug 15, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant