import bpy
import math

# The ball material setup looks correct. Let me verify the vertex colors are set properly.
ball = bpy.data.objects["BeachBall"]
ca = ball.data.color_attributes["VColor"]

# Check a sample of vertex colors
print("Sample vertex colors:")
for i in range(0, len(ca.data), 200):
    c = ca.data[i].color
    r, g, b, a = c[0], c[1], c[2], c[3]
    label = "white" if r > 0.9 and g > 0.9 and b > 0.9 else \
            "red" if r > 0.8 and g < 0.3 else \
            "blue" if b > 0.8 and r < 0.3 else \
            "yellow" if r > 0.9 and g > 0.8 and b < 0.2 else \
            f"({r:.2f},{g:.2f},{b:.2f})"
    print(f"  Vertex {i}: {label}")

# Also check if the Attribute node needs to use the correct attribute type
# In Blender 4.x, for vertex color attributes, the Attribute node should find it automatically
# Let me try using the Color output directly

# Let me also check: maybe the ball is just very small in the render
# The ball is at (0.4, 0, -0.2) with radius 0.22
# Camera is at (0.3, -0.6, -0.05)
# Distance from camera to ball: sqrt(0.1^2 + 0.6^2 + 0.15^2) = sqrt(0.01+0.36+0.0225) = sqrt(0.3925) ≈ 0.63
# Ball radius 0.22 at distance 0.63, with 38mm lens (FOV ~52°)
# Angular size of ball: 2*atan(0.22/0.63) = 2*19.2° = 38.4°
# That's about 38.4/52 = 74% of the frame width
# The ball should be quite visible!

# But it wasn't detected. Maybe the vertex colors aren't rendering.
# Let me render with a solid color material to test

test_mat = bpy.data.materials.new("BallTestMat")
test_mat.use_nodes = True
test_mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.8, 0.1, 0.1, 1.0)

# Temporarily replace ball material
orig_mat = ball.data.materials[0]
ball.data.materials[0] = test_mat

scene = bpy.context.scene
scene.render.resolution_x = 512
scene.render.resolution_y = 512
scene.cycles.samples = 16
scene.cycles.use_denoising = True
scene.render.filepath = "/tmp/ball_test.png"
bpy.ops.render.render(write_still=True)

# Check for red pixels
img = bpy.data.images.load("/tmp/ball_test.png")
pixels = list(img.pixels)
w, h = img.size

red_count = 0
for y in range(h):
    for x in range(0, w, 2):
        idx = (y * w + x) * 4
        r, g, b = pixels[idx], pixels[idx+1], pixels[idx+2]
        if r > 0.5 and g < 0.3 and b < 0.3:
            red_count += 1
            if red_count == 1:
                print(f"First red pixel at ({x},{y}): R={r:.3f} G={g:.3f} B={b:.3f}")

print(f"Total red pixels: {red_count} (out of {w*h//2} sampled)")

# Restore original material
ball.data.materials[0] = orig_mat

Test ball visibility with solid color material


Code executed successfully: Sample vertex colors:
  Vertex 0: red
  Vertex 200: white
  Vertex 400: red
  Vertex 600: white
  Vertex 800: yellow
  Vertex 1000: blue
  Vertex 1200: red
  Vertex 1400: red
  Vertex 1600: yellow
  Vertex 1800: yellow
Total red pixels: 0 (out of 131072 sampled)