AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Blender Texture

skill-max-786-claude-3d-harness-blender-texture · by MAX-786

>

— No reviews yet
0 installs
0 views
— view→install

Install

$ agentstack add skill-max-786-claude-3d-harness-blender-texture

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-max-786-claude-3d-harness-blender-texture)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 4d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Blender Texture? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Skill: Blender Texture & Materials

Sei un esperto di materiali e texturing in Blender con bpy + node tree. Ricevi una richiesta ($ARGUMENTS) e produci materiali realistici di qualità professionale.


Connessione — MCP

MCP (porta 9876 — PREFERITO):

mcp__Blender__execute_blender_code(code="import bpy\n# ...\nresult={'ok':True}")
mcp__Blender__get_screenshot_of_window_as_image()
mcp__Blender__render_viewport_to_path(output_path="/out.png")

Helper universali (copia nel blocco che esegui)

import bpy

def set_input(node, *names, value):
    """Imposta input per nome — gestisce rename tra versioni Blender."""
    for name in names:
        if name in node.inputs:
            node.inputs[name].default_value = value
            return True
    return False

def link(links, from_node, from_sock, to_node, to_sock):
    links.new(from_node.outputs[from_sock], to_node.inputs[to_sock])

def new_mat(name):
    """Crea materiale pulito con use_nodes=True, nodes svuotati."""
    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    mat.node_tree.nodes.clear()
    return mat, mat.node_tree.nodes, mat.node_tree.links

def apply_mat(obj_name, mat):
    """Assegna mat allo slot 0 dell'oggetto."""
    ob = bpy.data.objects.get(obj_name)
    if ob:
        ob.data.materials.clear()
        ob.data.materials.append(mat)

Sezione 1 — UV Unwrap

1.1 Smart UV Project (raccomandato per oggetti complessi)

import bpy

def smart_uv(obj_name, angle_limit=66, margin=0.02):
    ob = bpy.data.objects[obj_name]
    bpy.context.view_layer.objects.active = ob
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.uv.smart_project(
        angle_limit   = angle_limit,
        island_margin = margin,
        scale_to_bounds = True
    )
    bpy.ops.object.mode_set(mode='OBJECT')
    uv = ob.data.uv_layers.active
    return uv.name if uv else None

1.2 Angle-Based Unwrap (superfici organiche)

def unwrap_angle(obj_name, margin=0.02):
    ob = bpy.data.objects[obj_name]
    bpy.context.view_layer.objects.active = ob
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    # Mark seam automatico prima di unwrap
    bpy.ops.mesh.mark_seam(clear=True)  # rimuovi seam precedenti
    bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=margin)
    bpy.ops.object.mode_set(mode='OBJECT')

1.3 Cube Projection (muri, pavimenti, superfici piane)

def cube_project(obj_name, cube_size=1.0):
    ob = bpy.data.objects[obj_name]
    bpy.context.view_layer.objects.active = ob
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.uv.cube_project(cube_size=cube_size)
    bpy.ops.object.mode_set(mode='OBJECT')

1.4 UV Layer aggiuntivo (baking separato)

def add_uv_layer(obj_name, name="UVBake"):
    ob = bpy.data.objects[obj_name]
    ob.data.uv_layers.new(name=name)
    ob.data.uv_layers.active = ob.data.uv_layers[name]
    # Fai unwrap con Smart Project su questo layer
    smart_uv(obj_name)

Sezione 2 — Materiali Procedurali

TABELLA VALORI DI RIFERIMENTO — Materiali Comuni

> Regola: Metallic è sempre 0 o 1 — nessun valore intermedio (le cose sono o metallo o non-metallo). > Regola: Mai Base Color = (0,0,0) puro. Anche i materiali più scuri riflettono qualcosa. Minimo: 0.02–0.03.

| Materiale | Base Color (lineare) | Roughness | Metallic | Specular IOR | Note | |-----------|---------------------|-----------|----------|--------------|------| | Plastica matte nera | (0.025, 0.025, 0.030) | 0.50–0.65 | 0 | 0.25 | + noise su roughness | | Plastica semi-gloss | (0.03, 0.03, 0.04) | 0.35–0.50 | 0 | 0.30 | consumer electronics | | Vetro screen (spento) | (0.005, 0.006, 0.012) | 0.01–0.03 | 0 | 0.50 | quasi mirror | | Porcellana bianca | (0.955, 0.940, 0.896) | 0.08–0.12 | 0 | 0.55 | coat 0.2 | | Legno chiaro | (0.55, 0.38, 0.22) | 0.65–0.80 | 0 | 0.10 | + grain texture | | Legno scuro | (0.12, 0.07, 0.04) | 0.70–0.85 | 0 | 0.10 | + grain texture | | Metallo lucido | (0.95, 0.95, 0.95) | 0.05–0.15 | 1 | — | alluminio, acciaio | | Metallo spazzolato | (0.80, 0.80, 0.80) | 0.30–0.45 | 1 | — | + anisotropy | | Oro | (1.00, 0.78, 0.28) | 0.10–0.25 | 1 | — | colore giallo caldo | | Gomma | (0.02, 0.02, 0.02) | 0.90–1.00 | 0 | 0.05 | molto matte | | Vetro trasparente | (0.92, 0.95, 0.98) | 0.00–0.05 | 0 | 0.50 | transmission=1, IOR=1.52 | | Carta | (0.85, 0.83, 0.78) | 0.90–1.00 | 0 | 0.05 | no specular | | Tessuto cotone | (base a scelta) | 0.85–0.95 | 0 | 0.05 | + fuzz/sheen | | Pelle umana | (0.77, 0.52, 0.40) | 0.60–0.75 | 0 | 0.35 | SSS obbligatorio |


Pattern noise-roughness — Anti "CG-Clean Look"

La roughness uniforme è il segnale più riconoscibile del "CG pulito". Aggiungere micro-variazione con Noise Texture rompe l'uniformità sintetica e rende qualsiasi superficie più reale.

def add_roughness_noise(nodes, links, bsdf,
                        base_roughness=0.50,
                        variation=0.08,
                        scale=80.0,
                        detail=4.0):
    """
    Aggiunge micro-variazione di roughness tramite Noise → ColorRamp → Roughness.

    base_roughness: valore centrale (es. 0.50 per plastica matte)
    variation:      ±variazione attorno alla base (0.05–0.10 è sottile, 0.15+ è visibile)
    scale:          frequenza spaziale del noise (60–120 per micro-texture, 5–20 per macro)
    detail:         ottave del noise (2–4 per plastica, 6–8 per roccia)

    Esempi:
      Plastica matte:    base=0.50, variation=0.08, scale=80
      Plastica semi-gloss: base=0.40, variation=0.05, scale=100
      Legno:             base=0.70, variation=0.15, scale=20, detail=6
      Metallo spazzolato: base=0.35, variation=0.10, scale=60
    """
    noise = nodes.new("ShaderNodeTexNoise")
    noise.inputs["Scale"].default_value    = scale
    noise.inputs["Detail"].default_value   = detail
    noise.inputs["Roughness"].default_value = 0.6
    noise.inputs["Distortion"].default_value = 0.0
    noise.location = (-400, -200)

    ramp = nodes.new("ShaderNodeValToRGB")
    lo = max(0.0, base_roughness - variation)
    hi = min(1.0, base_roughness + variation)
    ramp.color_ramp.elements[0].position = 0.35
    ramp.color_ramp.elements[0].color    = (lo, lo, lo, 1.0)
    ramp.color_ramp.elements[1].position = 0.65
    ramp.color_ramp.elements[1].color    = (hi, hi, hi, 1.0)
    ramp.location = (-200, -200)

    links.new(noise.outputs["Fac"], ramp.inputs["Fac"])
    links.new(ramp.outputs["Color"], bsdf.inputs["Roughness"])
    return noise, ramp

# Uso rapido su un materiale esistente:
def apply_roughness_noise_to(mat, base_roughness=0.50, variation=0.08, scale=80.0):
    """Aggiunge noise-roughness a un materiale già esistente."""
    nt = mat.node_tree
    bsdf = next((n for n in nt.nodes if n.type == 'BSDF_PRINCIPLED'), None)
    if bsdf:
        add_roughness_noise(nt.nodes, nt.links, bsdf,
                            base_roughness, variation, scale)

Pattern base: Principled BSDF

mat, nodes, links = new_mat("MyMat")

out  = nodes.new("ShaderNodeOutputMaterial"); out.location = (600, 0)
bsdf = nodes.new("ShaderNodeBsdfPrincipled"); bsdf.location = (200, 0)
links.new(bsdf.outputs["BSDF"], out.inputs["Surface"])

bsdf.inputs["Base Color"].default_value  = (0.8, 0.3, 0.1, 1.0)
bsdf.inputs["Roughness"].default_value   = 0.6
bsdf.inputs["Metallic"].default_value    = 0.0
set_input(bsdf, "Specular IOR Level", "Specular", value=0.5)

# Per plastica: aggiungi subito noise-roughness
add_roughness_noise(nodes, links, bsdf, base_roughness=0.5, variation=0.08)

2.1 mat_porcelain — Porcellana / Ceramica

def mat_porcelain(name="Porcelain", color=(0.955, 0.940, 0.896)):
    mat, nodes, links = new_mat(name)
    out  = nodes.new("ShaderNodeOutputMaterial"); out.location = (600, 0)
    bsdf = nodes.new("ShaderNodeBsdfPrincipled");  bsdf.location = (200, 0)
    links.new(bsdf.outputs["BSDF"], out.inputs["Surface"])

    # Micro-variazione noise (2%) via ShaderNodeMix RGBA
    noise = nodes.new("ShaderNodeTexNoise"); noise.location = (-400, 100)
    noise.inputs["Scale"].default_value    = 12.0
    noise.inputs["Detail"].default_value   = 2.0
    noise.inputs["Roughness"].default_value= 0.5

    mix = nodes.new("ShaderNodeMix"); mix.data_type = "RGBA"
    mix.location = (-100, 100)
    mix.inputs[6].default_value = (*[c * 0.97 for c in color], 1.0)  # scuro
    mix.inputs[7].default_value = (*[c * 1.01 for c in color], 1.0)  # chiaro
    links.new(noise.outputs["Fac"], mix.inputs[0])
    links.new(mix.outputs[2], bsdf.inputs["Base Color"])

    bsdf.inputs["Roughness"].default_value = 0.08
    set_input(bsdf, "IOR", value=1.52)
    set_input(bsdf, "Coat Weight", "Clearcoat", value=0.2)
    set_input(bsdf, "Coat Roughness", "Clearcoat Roughness", value=0.05)
    set_input(bsdf, "Specular IOR Level", "Specular", value=0.55)
    return mat

# NOTA ShaderNodeMix RGBA:
#   inputs[0]  = Factor (Fac)
#   inputs[6]  = Color A  (NON inputs[1])
#   inputs[7]  = Color B  (NON inputs[2])
#   outputs[2] = risultato Color  (NON outputs[0])
# ShaderNodeMixRGB è DEPRECATO in Blender 4.x/5.x — non usare.

2.2 mat_organic — Materiale organico con SSS + Noise + Fresnel

def mat_organic(name="Organic",
                base_color=(0.65, 0.05, 0.05),
                roughness_range=(0.50, 0.72),
                sss=0.18, sss_radius=(0.92, 0.10, 0.10),
                bump_strength=0.35, bump_dist=0.008,
                glossy_ior=1.38, glossy_rough=0.06):
    """
    Stack: Noise→ColorRamp→Principled + Noise→Bump + Glossy→Fresnel→Mix
    Usato per: muscoli, frutta, skin, radici, tessuti biologici.
    """
    mat, nodes, links = new_mat(name)

    # Coordinate
    tc  = nodes.new("ShaderNodeTexCoord"); tc.location = (-1100, 0)
    mp  = nodes.new("ShaderNodeMapping");  mp.location = (-900, 0)
    mp.inputs["Scale"].default_value = (1.2, 1.2, 1.0)
    links.new(tc.outputs["Object"], mp.inputs["Vector"])

    # Noise colore
    nc = nodes.new("ShaderNodeTexNoise"); nc.location = (-680, 250)
    nc.inputs["Scale"].default_value     = 6.0
    nc.inputs["Detail"].default_value    = 5.0
    nc.inputs["Roughness"].default_value = 0.65
    nc.inputs["Distortion"].default_value= 0.25
    links.new(mp.outputs["Vector"], nc.inputs["Vector"])

    ramp = nodes.new("ShaderNodeValToRGB"); ramp.location = (-430, 250)
    try:    ramp.color_ramp.color_space = "RGB"
    except: ramp.color_ramp.color_mode  = "RGB"   # Blender 5.x rinomina
    c = base_color
    ramp.color_ramp.elements[0].color = (c[0]*0.55, c[1]*0.55, c[2]*0.55, 1.0)
    ramp.color_ramp.elements[1].color = (*c, 1.0)
    links.new(nc.outputs["Fac"], ramp.inputs["Fac"])

    # Noise rugosità
    nr = nodes.new("ShaderNodeTexNoise"); nr.location = (-680, -50)
    nr.inputs["Scale"].default_value = 18.0
    links.new(mp.outputs["Vector"], nr.inputs["Vector"])
    rr = nodes.new("ShaderNodeValToRGB"); rr.location = (-430, -50)
    rr.color_ramp.elements[0].color = (*[roughness_range[0]]*3, 1.0)
    rr.color_ramp.elements[1].color = (*[roughness_range[1]]*3, 1.0)
    links.new(nr.outputs["Fac"], rr.inputs["Fac"])

    # Bump
    nb = nodes.new("ShaderNodeTexNoise"); nb.location = (-680, -350)
    nb.inputs["Scale"].default_value     = 22.0
    nb.inputs["Detail"].default_value    = 8.0
    nb.inputs["Roughness"].default_value = 0.55
    links.new(mp.outputs["Vector"], nb.inputs["Vector"])
    bump = nodes.new("ShaderNodeBump"); bump.location = (-180, -300)
    bump.inputs["Strength"].default_value = bump_strength
    bump.inputs["Distance"].default_value = bump_dist
    links.new(nb.outputs["Fac"], bump.inputs["Height"])

    # Principled BSDF
    bsdf = nodes.new("ShaderNodeBsdfPrincipled"); bsdf.location = (80, 120)
    links.new(ramp.outputs["Color"], bsdf.inputs["Base Color"])
    links.new(rr.outputs["Color"],   bsdf.inputs["Roughness"])
    links.new(bump.outputs["Normal"],bsdf.inputs["Normal"])
    set_input(bsdf, "Subsurface Weight", "Subsurface", value=sss)
    try:    bsdf.inputs["Subsurface Radius"].default_value = sss_radius
    except: pass
    set_input(bsdf, "Specular IOR Level", "Specular", value=0.28)

    # Glossy (strato umido)
    glossy = nodes.new("ShaderNodeBsdfGlossy"); glossy.location = (80, -200)
    glossy.inputs["Roughness"].default_value = glossy_rough
    links.new(bump.outputs["Normal"], glossy.inputs["Normal"])

    # Fresnel → Mix
    fresnel = nodes.new("ShaderNodeFresnel"); fresnel.location = (80, -380)
    fresnel.inputs["IOR"].default_value = glossy_ior
    mix = nodes.new("ShaderNodeMixShader"); mix.location = (380, 0)
    links.new(fresnel.outputs["Fac"],   mix.inputs["Fac"])
    links.new(bsdf.outputs["BSDF"],     mix.inputs[1])
    links.new(glossy.outputs["BSDF"],   mix.inputs[2])

    out = nodes.new("ShaderNodeOutputMaterial"); out.location = (620, 0)
    links.new(mix.outputs["Shader"], out.inputs["Surface"])
    return mat

2.3 mat_metal — Metallo PBR

def mat_metal(name="Metal", color=(0.8, 0.8, 0.85), roughness=0.15):
    mat, nodes, links = new_mat(name)
    out  = nodes.new("ShaderNodeOutputMaterial"); out.location = (400, 0)
    bsdf = nodes.new("ShaderNodeBsdfPrincipled");  bsdf.location = (0, 0)
    links.new(bsdf.outputs["BSDF"], out.inputs["Surface"])

    bsdf.inputs["Base Color"].default_value  = (*color, 1.0)
    bsdf.inputs["Metallic"].default_value    = 1.0
    bsdf.inputs["Roughness"].default_value   = roughness
    set_input(bsdf, "Specular IOR Level", "Specular", value=0.5)

    # Anisotropia leggera per look brushed
    if "Anisotropic" in bsdf.inputs:
        bsdf.inputs["Anisotropic"].default_value = 0.3
    return mat

2.4 mat_glass — Vetro

def mat_glass(name="Glass", color=(0.95, 0.98, 1.0), roughness=0.02, ior=1.45):
    mat, nodes, links = new_mat(name)
    mat.blend_method = "BLEND"  # Eevee transparency
    out  = nodes.new("ShaderNodeOutputMaterial"); out.location = (400, 0)
    bsdf = nodes.new("ShaderNodeBsdfPrincipled");  bsdf.location = (0, 0)
    links.new(bsdf.outputs["BSDF"], out.inputs["Surface"])

    bsdf.inputs["Base Color"].default_value  = (*color, 1.0)
    bsdf.inputs["Roughness"].default_value   = roughness
    set_input(bsdf, "IOR", value=ior)
    set_input(bsdf, "Transmission Weight", "Transmission", value=1.0)
    return mat

2.5 mat_leather — Cuoio / Pelle

def mat_leather(name="Leather", color=(0.25, 0.10, 0.05), roughness=0.75):
    mat, nodes, links = new_mat(name)
    out  = nodes.new("ShaderNodeOutputMaterial"); out.location = (600, 0)
    bsdf = nodes.new("ShaderNodeBsdfPrincipled");  bsdf.location = (200, 0)
    links.new(bsdf.outputs["BSDF"], out.inputs["Surface"])

    # Voronoi per pori del cuoio
    vc = nodes.new("ShaderNodeTexVoronoi"); vc.location = (-500, 200)
    vc.inputs["Scale"].default_value    = 80.0
    vc.inputs["Randomness"].default_value = 0.8
    noise = nodes.new("ShaderNodeTexNoise"); noise.location = (-500, -100)
    noise.inputs["Scale"].default_value = 12.0
    noise.inputs["Detail"].default_value = 6.0

    # Mix Voronoi + Noise per bump complesso
    mix_h = nodes.new("ShaderNodeMix"); mix_h.data_type = "FLOAT"
    mix_h.location = (-200, 100); mix_h.inputs[0].default_value = 0.4
    links.new(vc.outputs["Distance"],   mix_h.inputs[4])  # A (float)
    links.new(noise.outputs["Fac"],     mix_h.inputs[5])  # B (float)

    bump = nodes.new("ShaderNodeBump"); bump.location = (-20, 0)
    bump.inputs["Strength"].default_value = 0.5
    bump.inputs["Distance"].default_value = 0.003
    links.new(mix_h.outputs[1], bump.inputs["Height"])  # output[1] = float

    # Colore con leggera variazione noise
    cr = nodes.new("ShaderNodeValToRGB"); cr.location = (-200, -200)
    cr.color_ramp.elements[0].color = (*[c*0.7 for c in c

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [MAX-786](https://github.com/MAX-786)
- **Source:** [MAX-786/claude-3d-harness](https://github.com/MAX-786/claude-3d-harness)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.