Skip to content

Commit a65973b

Browse files
TMHSDigitalclaude
andcommitted
fix(examples): give the swatch-grid gold something to reflect
Render path only. The mirror gold reflected the near-black world and read as a black ball; a reflection-only sky (Light Path Is Glossy Ray) now gives it a warm overhead gradient while camera and diffuse rays still see the dark stage. The backdrop moves in behind the spheres so they cast contact shadows. Six-region pixel check and exit codes unchanged on all three binaries. Also refreshes the gallery alts and index for both examples. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
1 parent 8e40035 commit a65973b

8 files changed

Lines changed: 76 additions & 13 deletions

File tree

9.82 KB
Loading
14.9 KB
Loading

‎docs/gallery/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ <h1>Examples and Showcase</h1>
343343
<div class="grid" id="grid">
344344
<article class="card" data-tags="materials rendering">
345345
<a class="card-media" href="swatch-grid/" tabindex="-1" aria-hidden="true">
346-
<img src="assets/swatch-grid-hero.webp" alt="Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white." loading="lazy" decoding="async" />
346+
<img src="assets/swatch-grid-hero.webp" alt="Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white." loading="lazy" decoding="async" />
347347
</a>
348348
<div class="card-body">
349349
<h2><a href="swatch-grid/">swatch-grid</a></h2>
@@ -354,7 +354,7 @@ <h2><a href="swatch-grid/">swatch-grid</a></h2>
354354
</article>
355355
<article class="card" data-tags="animation">
356356
<a class="card-media" href="turntable/" tabindex="-1" aria-hidden="true">
357-
<img src="assets/turntable-hero.webp" alt="A bronze monkey head (Suzanne) turned three-quarters on a dark studio floor." loading="lazy" decoding="async" />
357+
<img src="assets/turntable-hero.webp" alt="A smooth copper monkey head (Suzanne) turned three-quarters on a black turntable with a brushed metal platter." loading="lazy" decoding="async" />
358358
</a>
359359
<div class="card-body">
360360
<h2><a href="turntable/">turntable</a></h2>

‎docs/gallery/swatch-grid/index.html‎

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
<meta property="og:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/swatch-grid-hero.webp" />
1717
<meta property="og:image:width" content="1280" />
1818
<meta property="og:image:height" content="720" />
19-
<meta property="og:image:alt" content="Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white." />
19+
<meta property="og:image:alt" content="Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white." />
2020
<meta property="og:site_name" content="Blender Developer Tools" />
2121
<meta name="twitter:card" content="summary_large_image" />
2222
<meta name="twitter:title" content="swatch-grid — Examples — Blender Developer Tools" />
2323
<meta name="twitter:description" content="Procedural Principled materials — metal and dielectric, the emission pattern, and the cross-version set_specular shim." />
2424
<meta name="twitter:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/swatch-grid-hero.webp" />
25-
<meta name="twitter:image:alt" content="Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white." />
25+
<meta name="twitter:image:alt" content="Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white." />
2626
<style>
2727
/* fonts are deployed by the landing build (docs/fonts/) */
2828
@font-face { font-family: 'Barlow Condensed'; font-weight: 600; font-display: swap;
@@ -268,8 +268,8 @@ <h1>swatch-grid</h1>
268268
<p>Procedural Principled materials — metal and dielectric, the emission pattern, and the cross-version set_specular shim.</p>
269269
</header>
270270
<main id="main">
271-
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white.">
272-
<img src="../assets/swatch-grid-hero.webp" alt="Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white." width="1280" height="720" />
271+
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white.">
272+
<img src="../assets/swatch-grid-hero.webp" alt="Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white." width="1280" height="720" />
273273
</button>
274274
<p class="zoom-hint">Rendered headless by the example itself — click to zoom.</p>
275275
<div class="callout"><span class="tag">witnesses</span> EEVEE engine-id mapping: BLENDER_EEVEE on 5.x, BLENDER_EEVEE_NEXT on 4.2–4.5.</div>
@@ -294,6 +294,8 @@ <h2>Run</h2>
294294
# GPU-less / CI hosts: render the pixels with Cycles (CPU). The EEVEE id is still
295295
# asserted; only the final pixels use Cycles.
296296
blender --background --python swatch_grid.py -- --output swatch.png --engine cycles --samples 16 --width 960</code></pre>
297+
<h2>Staging</h2>
298+
<p>The backdrop stands 0.16 behind the spheres, so each casts a soft contact shadow. It used to stand 1.58 behind them, and the grid floated. The world is a reflection-only sky: glossy rays see a warm overhead gradient above a dark horizon, and camera and diffuse rays see the dark stage. The mirror-finish gold otherwise reflected the near-black world and rendered as a black ball with two light-card glints. Sphere positions, materials, the camera and the six-region pixel check are unchanged; <code>verify_png</code> still reads six distinct regions on 4.5.11, 5.1.2 and 5.2.1.</p>
297299
<h2>Exit codes</h2>
298300
<p>Per-script sequential checks. <code>9</code> is a valid check code; there is no rule against it. <code>10</code> is the shared framing helper.</p>
299301
<div class="table-wrap"><table><thead><tr><th scope="col">Code</th><th scope="col">Meaning</th></tr></thead><tbody><tr><td>0</td><td>Success</td></tr><tr><td>1</td><td>Uncaught exception (FATAL wrapper)</td></tr><tr><td>2</td><td>argparse / usage</td></tr><tr><td>3</td><td>Distinct swatch colors ≠ 6 (<code>--same-base</code> lands here); also render not six distinct regions</td></tr><tr><td>4</td><td><code>--output</code> produced no file</td></tr><tr><td>5</td><td>Wrong-era EEVEE engine id was accepted</td></tr><tr><td>10</td><td>Gallery framing violation</td></tr></tbody></table></div>
@@ -463,7 +465,10 @@ <h2>Source</h2>
463465
wmat, _ = make_principled(<span class="s">&quot;Studio&quot;</span>, (<span class="n">0.03</span>, <span class="n">0.032</span>, <span class="n">0.037</span>, <span class="n">1</span>), <span class="n">0.0</span>, <span class="n">0.7</span>)
464466
wall_me.materials.append(wmat)
465467
wall = bpy.data.objects.new(<span class="s">&quot;Wall&quot;</span>, wall_me)
466-
wall.location = (<span class="n">0.0</span>, <span class="n">2.5</span>, <span class="n">0.0</span>)
468+
<span class="c"># just behind the spheres (0.16 clear of their backs) so each casts a</span>
469+
<span class="c"># soft contact shadow and reads as mounted; at y=2.5 they hung 1.58 in</span>
470+
<span class="c"># front of the backdrop with nothing under them</span>
471+
wall.location = (<span class="n">0.0</span>, <span class="n">1.08</span>, <span class="n">0.0</span>)
467472
wall.rotation_euler = (math.radians(<span class="n">90</span>), <span class="n">0.0</span>, <span class="n">0.0</span>)
468473
bpy.context.collection.objects.link(wall)
469474

@@ -492,7 +497,29 @@ <h2>Source</h2>
492497
bpy.data.objects[<span class="s">&quot;WedgeL&quot;</span>].rotation_euler = (math.radians(-<span class="n">56</span>), <span class="n">0.0</span>, math.radians(<span class="n">190</span>))
493498
world = bpy.data.worlds.new(<span class="s">&quot;W&quot;</span>)
494499
world.use_nodes = <span class="k">True</span>
495-
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="n">0</span>].default_value = (<span class="n">0.02</span>, <span class="n">0.021</span>, <span class="n">0.025</span>, <span class="n">1</span>)
500+
nt = world.node_tree
501+
bg = nt.nodes[<span class="s">&quot;Background&quot;</span>]
502+
bg.inputs[<span class="n">0</span>].default_value = (<span class="n">0.02</span>, <span class="n">0.021</span>, <span class="n">0.025</span>, <span class="n">1</span>)
503+
<span class="c"># A reflection-only sky: glossy rays see a warm overhead gradient over a</span>
504+
<span class="c"># dark horizon, every other ray the dark stage. The mirror-finish gold</span>
505+
<span class="c"># otherwise reflected the near-black world and rendered as a black ball</span>
506+
<span class="c"># with two light-card glints. Diffuse and camera rays are unchanged, so</span>
507+
<span class="c"># the stage stays dark.</span>
508+
path = nt.nodes.new(<span class="s">&quot;ShaderNodeLightPath&quot;</span>)
509+
coord = nt.nodes.new(<span class="s">&quot;ShaderNodeTexCoord&quot;</span>)
510+
sep = nt.nodes.new(<span class="s">&quot;ShaderNodeSeparateXYZ&quot;</span>)
511+
nt.links.new(coord.outputs[<span class="s">&quot;Generated&quot;</span>], sep.inputs[<span class="n">0</span>])
512+
sky = nt.nodes.new(<span class="s">&quot;ShaderNodeValToRGB&quot;</span>)
513+
sky.color_ramp.elements[<span class="n">0</span>].position = <span class="n">0.0</span>
514+
sky.color_ramp.elements[<span class="n">0</span>].color = (<span class="n">0.02</span>, <span class="n">0.021</span>, <span class="n">0.025</span>, <span class="n">1</span>)
515+
sky.color_ramp.elements[<span class="n">1</span>].position = <span class="n">0.7</span>
516+
sky.color_ramp.elements[<span class="n">1</span>].color = (<span class="n">0.70</span>, <span class="n">0.63</span>, <span class="n">0.55</span>, <span class="n">1</span>)
517+
nt.links.new(sep.outputs[<span class="s">&quot;Z&quot;</span>], sky.inputs[<span class="s">&quot;Fac&quot;</span>])
518+
pick = nt.nodes.new(<span class="s">&quot;ShaderNodeMixRGB&quot;</span>)
519+
pick.inputs[<span class="n">1</span>].default_value = (<span class="n">0.02</span>, <span class="n">0.021</span>, <span class="n">0.025</span>, <span class="n">1</span>)
520+
nt.links.new(sky.outputs[<span class="s">&quot;Color&quot;</span>], pick.inputs[<span class="n">2</span>])
521+
nt.links.new(path.outputs[<span class="s">&quot;Is Glossy Ray&quot;</span>], pick.inputs[<span class="n">0</span>])
522+
nt.links.new(pick.outputs[<span class="n">0</span>], bg.inputs[<span class="n">0</span>])
496523
bpy.context.scene.world = world
497524

498525

@@ -648,7 +675,7 @@ <h2>Source</h2>
648675
</main>
649676
<dialog class="lightbox" id="lightbox" aria-label="Full-size render">
650677
<button class="lightbox-close" type="button" autofocus>Close</button>
651-
<img src="../assets/swatch-grid-hero.webp" alt="Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white." />
678+
<img src="../assets/swatch-grid-hero.webp" alt="Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white." />
652679
</dialog>
653680
<footer>
654681
<div class="statusbar">

‎examples/gallery.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"name": "swatch-grid",
1010
"dir": "examples/swatch-grid",
1111
"teaches": "Procedural Principled materials — metal and dielectric, the emission pattern, and the cross-version set_specular shim.",
12-
"alt": "Six material spheres in two rows: black glossy, copper metal, red, blue, flat orange emission and white.",
12+
"alt": "Six material spheres in two rows against a dark backdrop: mirror gold, brushed copper, red, blue, flat orange emission and white.",
1313
"witnessesFix": "EEVEE engine-id mapping: BLENDER_EEVEE on 5.x, BLENDER_EEVEE_NEXT on 4.2–4.5.",
1414
"hero": "docs/gallery/assets/swatch-grid-hero.webp",
1515
"preview": "examples/swatch-grid/preview.webp",
@@ -22,7 +22,7 @@
2222
"name": "turntable",
2323
"dir": "examples/turntable",
2424
"teaches": "A slotted-actions Z-rotation turntable keyed through the cross-version channelbag path (get_channelbag_for_slot).",
25-
"alt": "A bronze monkey head (Suzanne) turned three-quarters on a dark studio floor.",
25+
"alt": "A smooth copper monkey head (Suzanne) turned three-quarters on a black turntable with a brushed metal platter.",
2626
"witnessesFix": "Slotted-actions boundary: ensure-helper channelbag on 5.x, strip.channelbag on 4.4/4.5.",
2727
"hero": "docs/gallery/assets/turntable-hero.webp",
2828
"preview": "examples/turntable/preview.webp",

‎examples/swatch-grid/README.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ blender --background --python swatch_grid.py -- --output swatch.png
3434
blender --background --python swatch_grid.py -- --output swatch.png --engine cycles --samples 16 --width 960
3535
```
3636

37+
## Staging
38+
39+
The backdrop stands 0.16 behind the spheres, so each casts a soft contact
40+
shadow. It used to stand 1.58 behind them, and the grid floated. The world is
41+
a reflection-only sky: glossy rays see a warm overhead gradient above a dark
42+
horizon, and camera and diffuse rays see the dark stage. The mirror-finish
43+
gold otherwise reflected the near-black world and rendered as a black ball
44+
with two light-card glints. Sphere positions, materials, the camera and the
45+
six-region pixel check are unchanged; `verify_png` still reads six distinct
46+
regions on 4.5.11, 5.1.2 and 5.2.1.
47+
3748
## Exit codes
3849

3950
Per-script sequential checks. `9` is a valid check code; there is no rule

‎examples/swatch-grid/preview.webp‎

8.45 KB
Loading

‎examples/swatch-grid/swatch_grid.py‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ def build_scene(mats):
153153
wmat, _ = make_principled("Studio", (0.03, 0.032, 0.037, 1), 0.0, 0.7)
154154
wall_me.materials.append(wmat)
155155
wall = bpy.data.objects.new("Wall", wall_me)
156-
wall.location = (0.0, 2.5, 0.0)
156+
# just behind the spheres (0.16 clear of their backs) so each casts a
157+
# soft contact shadow and reads as mounted; at y=2.5 they hung 1.58 in
158+
# front of the backdrop with nothing under them
159+
wall.location = (0.0, 1.08, 0.0)
157160
wall.rotation_euler = (math.radians(90), 0.0, 0.0)
158161
bpy.context.collection.objects.link(wall)
159162

@@ -182,7 +185,29 @@ def build_scene(mats):
182185
bpy.data.objects["WedgeL"].rotation_euler = (math.radians(-56), 0.0, math.radians(190))
183186
world = bpy.data.worlds.new("W")
184187
world.use_nodes = True
185-
world.node_tree.nodes["Background"].inputs[0].default_value = (0.02, 0.021, 0.025, 1)
188+
nt = world.node_tree
189+
bg = nt.nodes["Background"]
190+
bg.inputs[0].default_value = (0.02, 0.021, 0.025, 1)
191+
# A reflection-only sky: glossy rays see a warm overhead gradient over a
192+
# dark horizon, every other ray the dark stage. The mirror-finish gold
193+
# otherwise reflected the near-black world and rendered as a black ball
194+
# with two light-card glints. Diffuse and camera rays are unchanged, so
195+
# the stage stays dark.
196+
path = nt.nodes.new("ShaderNodeLightPath")
197+
coord = nt.nodes.new("ShaderNodeTexCoord")
198+
sep = nt.nodes.new("ShaderNodeSeparateXYZ")
199+
nt.links.new(coord.outputs["Generated"], sep.inputs[0])
200+
sky = nt.nodes.new("ShaderNodeValToRGB")
201+
sky.color_ramp.elements[0].position = 0.0
202+
sky.color_ramp.elements[0].color = (0.02, 0.021, 0.025, 1)
203+
sky.color_ramp.elements[1].position = 0.7
204+
sky.color_ramp.elements[1].color = (0.70, 0.63, 0.55, 1)
205+
nt.links.new(sep.outputs["Z"], sky.inputs["Fac"])
206+
pick = nt.nodes.new("ShaderNodeMixRGB")
207+
pick.inputs[1].default_value = (0.02, 0.021, 0.025, 1)
208+
nt.links.new(sky.outputs["Color"], pick.inputs[2])
209+
nt.links.new(path.outputs["Is Glossy Ray"], pick.inputs[0])
210+
nt.links.new(pick.outputs[0], bg.inputs[0])
186211
bpy.context.scene.world = world
187212

188213

0 commit comments

Comments
 (0)