feat: add color-attribute-wheel example#54
Merged
Conversation
Witnesses the modern color-attributes API (mesh.color_attributes.new on the CORNER domain) that AI code routinely swaps for the deprecated vertex_colors alias, and the domain-size trap that follows: a CORNER attribute is sized to loop count, not vertex count, so per-vertex data must be expanded across face corners before writing. Also asserts the Attribute node is actually linked to Base Color, since AI code frequently creates the attribute but forgets to wire it into the shader.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/color-attribute-wheel/— an HSV color wheel disc built withbmesh, colored via the modernMesh.color_attributes.new()API (not the deprecatedvertex_colorsalias).CORNER-domainFLOAT_COLORattribute is sized tolen(mesh.loops), notlen(mesh.vertices)— a domain-size trap AI-generated code hits when it assumes per-vertex sizing. Per-vertex HSV is expanded across face corners with oneforeach_get(loop → vertex index) + oneforeach_set(loop color). The check also assertscolor_attributes.active_colorpoints at it, and that the shaderAttributenode (attribute_type='GEOMETRY') is actually linked to Base Color — a step AI code frequently skips, leaving the mesh gray even though the attribute data is correct.examples/gallery.jsonentry,.cursor-plugin/plugin.jsonexamples array,blender-smoke.ymlcheck-only step (both 4.5 LTS and 5.1), README gallery row + aggregate counts (14 → 15), AGENTS.md/CLAUDE.md example counts, hero/preview webp assets, regenerateddocs/gallery/.Visual notes
Rendered with both EEVEE and Cycles locally (portable Blender 5.1.2 and 4.5.11 LTS on Windows) — pixel-identical composition across engines and Blender versions. Key fix during iteration: Blender's default AgX view transform compresses bright regions toward white, which was hiding the saturation gradient this example exists to show off; the render path now explicitly sets
view_transform = 'Standard'so the rendered colors match the underlying attribute data. Framing uses aTRACK_TOaim empty (matching theswatch-gridlight-aim convention) rather than hand-tuned camera rotation, tilted gently so the disc reads as a wheel rather than foreshortening into an ellipse-dominated shape, on the repo's usual dark-studio floor/wall/three-light rig.Test plan
blender --background --python color_attribute_wheel.py --exits 0 on Blender 5.1.2 (portable, local)--outputrender verified on both engines (EEVEE, Cycles) and both Blender versions; hero/preview pixels visually inspected at full size and thumbnail croppython scripts/build_gallery.pyregenerateddocs/gallery/cleanlyvalidate-countsandvalidate-manifestCI checks passesvalidate.yml,drift-check.yml,blender-smoke.yml(4.5 + 5.1) green on this PR🤖 Generated with Claude Code