diff --git a/README.md b/README.md index 23fcd71..9c7604f 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,7 @@ toward the core (dot ≥ 0.998). -Color attribute wheel: an HSV color wheel disc with a white center fading into a vivid rainbow rim, resting on a dark studio floor +Color attribute wheel: an HSV color wheel disc with a white center fading into a vivid rainbow rim, leaning upright toward the camera on a dark studio floor with a warm light pool behind it diff --git a/docs/gallery/armature-bend/index.html b/docs/gallery/armature-bend/index.html index 7ff2221..dc0a16c 100644 --- a/docs/gallery/armature-bend/index.html +++ b/docs/gallery/armature-bend/index.html @@ -434,8 +434,8 @@

Source

fmat = bpy.data.materials.new("Studio") fmat.use_nodes = True fb = fmat.node_tree.nodes["Principled BSDF"] - fb.inputs["Base Color"].default_value = (0.05, 0.055, 0.065, 1.0) - fb.inputs["Roughness"].default_value = 0.55 + fb.inputs["Base Color"].default_value = (0.03, 0.032, 0.037, 1.0) + fb.inputs["Roughness"].default_value = 0.7 floor_me.materials.append(fmat) floor = bpy.data.objects.new("Floor", floor_me) scene.collection.objects.link(floor) @@ -446,7 +446,7 @@

Source

world = bpy.data.worlds.new("World") world.use_nodes = True - world.node_tree.nodes["Background"].inputs["Color"].default_value = (0.03, 0.033, 0.04, 1.0) + world.node_tree.nodes["Background"].inputs["Color"].default_value = (0.02, 0.021, 0.025, 1.0) scene.world = world def light(name, loc, energy, size, col, rot): @@ -457,9 +457,14 @@

Source

ob.rotation_euler = tuple(math.radians(a) for a in rot) scene.collection.objects.link(ob) - light("Key", (-4.0, -5.0, 6.0), 1500.0, 7.0, (1.0, 0.97, 0.92), (48, 0, -38)) - light("Fill", (5.0, -4.0, 3.0), 500.0, 9.0, (0.75, 0.85, 1.0), (62, 0, 50)) - light("Rim", (0.5, 4.5, 5.0), 900.0, 5.0, (0.55, 0.75, 1.0), (-55, 0, 175)) + # a shaped warm key from the upper left, a faint cool fill so the shadow + # side of each tube stays legible, a cool rim to lift the silhouettes off + # the backdrop, and a warm wedge raking the back wall — the falloff pool + # behind the subjects that the rest of the gallery stages against. + light("Key", (-4.0, -5.0, 6.0), 650.0, 4.5, (1.0, 0.96, 0.9), (48, 0, -38)) + light("Fill", (5.0, -4.0, 3.0), 110.0, 9.0, (0.75, 0.85, 1.0), (62, 0, 50)) + light("Rim", (0.5, 4.5, 5.0), 350.0, 4.0, (0.6, 0.78, 1.0), (-55, 0, 175)) + light("Wedge", (2.5, 3.5, 4.2), 520.0, 6.0, (1.0, 0.76, 0.5), (-72, 0, 195)) cam_data = bpy.data.cameras.new("Cam") cam_data.lens = 45.0 @@ -481,6 +486,9 @@

Source

scene.render.resolution_y = 720 scene.render.image_settings.file_format = 'PNG' scene.render.filepath = path + # AgX (the 4.x/5.x default) desaturates the BoneTint bands toward pastel, + # hiding exactly the weight boundaries the LBS check asserts. + scene.view_settings.view_transform = 'Standard' bpy.ops.render.render(write_still=True) return os.path.exists(path) and os.path.getsize(path) > 0 diff --git a/docs/gallery/assets/armature-bend-hero.webp b/docs/gallery/assets/armature-bend-hero.webp index b69c8a7..1866425 100644 Binary files a/docs/gallery/assets/armature-bend-hero.webp and b/docs/gallery/assets/armature-bend-hero.webp differ diff --git a/docs/gallery/assets/color-attribute-wheel-hero.webp b/docs/gallery/assets/color-attribute-wheel-hero.webp index 405971f..e8867fb 100644 Binary files a/docs/gallery/assets/color-attribute-wheel-hero.webp and b/docs/gallery/assets/color-attribute-wheel-hero.webp differ diff --git a/docs/gallery/color-attribute-wheel/index.html b/docs/gallery/color-attribute-wheel/index.html index 113fd03..7ecbea0 100644 --- a/docs/gallery/color-attribute-wheel/index.html +++ b/docs/gallery/color-attribute-wheel/index.html @@ -244,11 +244,15 @@

Source

"""Vertex coords and per-vertex (h, s, v) in the same order as vidx().""" coords = [(0.0, 0.0, 0.0)] hsv = [(0.0, 0.0, 1.0)] # center: fully desaturated, white + # the hue origin is rotated off the picture horizontal: red is the + # perceptually sharpest hue transition, and the 0/360-degree wrap reads + # as a seam artifact when it lies level in frame + angle0 = math.radians(-52.0) for r in range(1, RINGS + 1): radius = R_OUTER * r / RINGS sat = min(1.0, (r / RINGS) * 1.4) for s in range(SEGMENTS): - angle = 2.0 * math.pi * s / SEGMENTS + angle = angle0 + 2.0 * math.pi * s / SEGMENTS coords.append((radius * math.cos(angle), radius * math.sin(angle), 0.0)) hsv.append((s / SEGMENTS, sat, 1.0)) return coords, hsv @@ -360,7 +364,11 @@

Source

if "Emission Color" in bsdf.inputs: # Principled gained built-in emission in 4.x+ nt.links.new(attr_node.outputs["Color"], bsdf.inputs["Emission Color"]) bsdf.inputs["Emission Strength"].default_value = 0.12 - bsdf.inputs["Roughness"].default_value = 0.62 + # fully matte: any specular component reflects the wall/floor horizon as + # a hard line across the disc face + bsdf.inputs["Roughness"].default_value = 0.85 + if "Specular IOR Level" in bsdf.inputs: + bsdf.inputs["Specular IOR Level"].default_value = 0.0 # The step AI code most often skips: the attribute must actually be wired # into the shader, not just present on the mesh. @@ -385,8 +393,11 @@

Source

if mat is None: return False obj.data.materials.append(mat) - obj.location = (0.0, 0.0, 0.55) - obj.rotation_euler = (math.radians(14), 0.0, math.radians(12)) + # stand the disc up toward the camera like an easel: the wheel is the + # subject, so it should present nearly face-on and fill the frame instead + # of lying foreshortened on the floor. + obj.location = (0.0, 0.0, 1.34) + obj.rotation_euler = (math.radians(52), 0.0, math.radians(10)) floor_me = bpy.data.meshes.new("Floor") bm = bmesh.new() @@ -424,9 +435,15 @@

Source

# a bright soft key from above reads the hue ring clearly; a low cool fill # keeps the shadow side legible; a faint warm rim separates the disc edge # from the dark backdrop without washing out the attribute colors. - light("Key", (-2.0, -3.0, 5.5), 380.0, 11.0, (1.0, 0.98, 0.96), (58, 0, -28)) - light("Fill", (4.5, -2.5, 1.6), 140.0, 9.0, (0.78, 0.86, 1.0), (68, 0, 55)) + light("Key", (-2.0, -3.0, 5.5), 320.0, 8.0, (1.0, 0.98, 0.96), (58, 0, -28)) + light("Fill", (4.5, -2.5, 1.6), 90.0, 9.0, (0.78, 0.86, 1.0), (68, 0, 55)) light("Rim", (0.5, 3.6, 2.2), 170.0, 4.0, (1.0, 0.78, 0.55), (-70, 0, 175)) + # a warm wedge raking the back wall — the falloff pool behind the subject + # the rest of the gallery stages against. + # placed between the disc and the back wall so it can only rake the wall: + # from any position in front, its grazing terminator draws a hard line + # across the flat disc face. + light("Wedge", (2.0, 5.2, 3.6), 220.0, 6.0, (1.0, 0.76, 0.5), (-68, 0, 190)) aim = bpy.data.objects.new("Aim", None) aim.location = obj.location @@ -435,7 +452,7 @@

Source

cam_data = bpy.data.cameras.new("Cam") cam_data.lens = 50.0 cam = bpy.data.objects.new("Cam", cam_data) - cam.location = (0.0, -7.4, 3.6) + cam.location = (0.0, -8.0, 2.4) con = cam.constraints.new('TRACK_TO') con.target = aim con.track_axis = 'TRACK_NEGATIVE_Z' diff --git a/docs/gallery/grease-pencil-rosette/index.html b/docs/gallery/grease-pencil-rosette/index.html index 6fb8d4a..ef5eba9 100644 --- a/docs/gallery/grease-pencil-rosette/index.html +++ b/docs/gallery/grease-pencil-rosette/index.html @@ -4,18 +4,18 @@ grease-pencil-rosette — Examples — Blender Developer Tools - + - + - +