CommunityImagengithub.com

TraX22/blender-modelado-low-poly

Construye modelos y escenas estilizados low-poly en Blender mediante una conexión de Blender (el servidor oficial de BlenderLab): formas facetadas y robustas con pocos polígonos, sombreado plano, una paleta reducida de colores mate, proporciones exageradas y la iluminación suave que requiere este estilo.

¿Qué es blender-modelado-low-poly?

Esta habilidad permite a un agente de IA especializado generar modelos y escenas low-poly en Blender a través del servidor BlenderLab, conectándose directamente con Blender para ejecutar código Python, obtener resúmenes de objetos, tomar capturas de pantalla del viewport y renderizar. El low-poly se define aquí como un estilo artístico, no simplemente un bajo recuento de triángulos: se enfatizan las formas grandes y legibles, los facetados planos visibles, una paleta de colores reducida (6-12 colores) con materiales Principled BSDF mate, proporciones exageradas (paredes gruesas, techos sobredimensionados) y la ausencia de biseles y subdivisiones que suavicen las aristas. La habilidad incluye reglas estrictas como el sombreado plano en todas partes, el uso de cilindros de 6-8 lados, la creación de materiales reutilizables, y un flujo de trabajo paso a paso que comienza con un bloqueo de masas a partir de una imagen de referencia, sigue con la estructura, los detalles secundarios, el rugosidad manual (con variaciones aleatorias de posición y rotación), y finaliza con una comprobación automática mediante la función `final_check`, que analiza el render y detecta problemas de encuadre, brillo, color y silueta. Es adecuada para activos de videojuegos, dioramas, escenas estilizadas o cualquier modelo que busque una apariencia caricaturesca y facetada.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/TraX22/HydraOps-Skills/tree/HEAD/blender-low-poly

Installed? Explore more Imagen skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Modelado low-poly en Blender

Low poly es un estilo, no solo un bajo recuento de triángulos: formas grandes y legibles, facetas planas visibles, unos pocos colores sólidos y proporciones ligeramente exageradas más allá de la realidad. Un modelo realista con menos polígonos no es low poly; es un modelo realista basto.

El bucle de trabajo general (mirar la escena, planificar en partes, una parte por llamada, captura de pantalla después de cada paso, nunca borrar lo que no creaste) está en la habilidad blender-modeling: síguelo. Esta habilidad indica qué es diferente para low poly.

Tu conexión Blender

Trabajas a través de BlenderLab, el servidor oficial de Blender Lab; sus herramientas son blenderlab_…:

  • Lo que hay en la escena: get_objects_summary; un objeto en detalle: get_object_detail_summary (por name). El archivo, guardado o no, y su ruta: get_blendfile_summary_path_info.
  • Ejecuta Python: execute_blender_code. Nada persiste entre llamadas (lleva tus ayudas en cada script); lo que imprime el script regresa, y un diccionario asignado a result regresa como datos. Su guardia rechaza algunos operadores (salir de Blender, restablecimientos de fábrica).
  • Ve el viewport 3D: get_screenshot_of_area_as_image con area_ui_type: "VIEW_3D" (la ventana completa: get_screenshot_of_window_as_image); apúntalo a un objeto: jump_to_view3d_object_by_name.
  • Verifica la API de Python: get_python_api_docs (un identificador como bpy.types.BevelModifier), search_api_docs; el manual: search_manual_docs.
  • Renderizado rápido: render_thumbnail_to_path, render_viewport_to_path; la imagen va a la carpeta temporal de Blender y el resultado da la ruta real.
  • Exportar: código (bpy.ops.export_scene.gltf, bpy.ops.export_scene.fbx).
  • Bibliotecas de activos y generadores 3D: ninguna. Construye el objeto, o pide al usuario un archivo para importar.

Si estas herramientas no están disponibles, detente y dilo: el usuario debe instalar la conexión BlenderLab (Tools → Connections), dársela a este agente, y tener Blender abierto con el servidor del complemento iniciado. No describas el trabajo como hecho si no pudiste hacerlo.

El estilo, como reglas

  1. Sombreado plano en todas partes. Cada cara es un color plano; sin sombreado suave, sin auto smooth. Esto es lo que hace que los facetados se vean.
  2. Pocos segmentos, a propósito. Cilindros de 6-8 lados, conos de 5-6, esferas como icósferas con 1-2 subdivisiones. Un cilindro de 32 lados arruina la apariencia más que cualquier otra cosa.
  3. Sin bisel, sin Subdivision Surface. Redondean los facetados. Para un borde más suave, usa un chaflán de un solo segmento como máximo.
  4. Color sólido, sin texturas. Un material por color, Principled BSDF con Base Color, Roughness 0.8-1.0, Metallic 0, sin brillo especular. Reutiliza materiales: una escena completa normalmente necesita 6-12.
  5. Una paleta deliberada. Elígela antes de modelar: 1-2 colores dominantes, 2-3 de apoyo, 1 acento. Tonos medios ligeramente desaturados, equilibrados entre cálidos y fríos, y dos tonos de cada color principal (claro y oscuro) para variedad entre partes vecinas.
  6. Proporciones robustas y exageradas. Paredes, vigas y troncos más gruesos que en la vida real; techos, puertas y ventanas sobredimensionados; formas cónicas (más anchas en la base, o en la parte superior para un aspecto caricaturesco). Las partes delgadas desaparecen en este nivel de detalle.
  7. Imperfección a mano, en pequeñas dosis. Nada perfectamente alineado: inclina una chimenea 2-4°, varía las tejas en un pequeño porcentaje de su tamaño y en 2-3° de inclinación, mueve los vértices de rocas y terreno al azar. La estructura aún debe leerse: las filas de tejas siguen siendo filas, ninguna pieza girada de lado o levantada de la superficie. Con una semilla aleatoria fija, para que una re-ejecución dé el mismo resultado.
  8. Detalle mediante piezas pequeñas separadas, no mediante subdivisión. Una ventana es un marco de cuatro cajas más un panel; las tejas del techo son filas de pequeñas losas; las piedras son algunos bloques irregulares incrustados en la pared. Cada pieza es simple; la disposición da la riqueza.
  9. Las piezas pueden intersecarse. Las partes low-poly se empujan unas dentro de otras en lugar de soldarse: una viga se hunde en una pared, una roca en el suelo. No gastes esfuerzo en booleanos o uniones limpias.

Flujo de trabajo

  1. Lee la referencia, si la hay: enumera las partes, cuenta lo que se repite (filas de tejas, número de vigas, ventanas por pared), anota las proporciones entre partes como relaciones (altura del techo frente a altura de la pared, ancho frente a altura), y nombra los colores de la paleta. Construye a partir de esa lista. La imagen decide: fija un tamaño y deriva el resto de las relaciones, no inventes tamaños en metros que la imagen contradiga, y no añadas lo que no muestra (una base, accesorios) a menos que se te pida.
  2. Bloqueo primero las masas grandes con cajas y cuñas en las proporciones correctas. Toma una captura de pantalla y compara la silueta: si la silueta está mal, los detalles no la salvarán.
  3. Paleta: crea los materiales una vez, nombrados por lo que colorean (LP_Wall_Light, LP_Roof_Red, LP_Wood_Dark).
  4. Estructura, luego partes secundarias (vigas, marcos, chimenea, escalones), luego pequeños detalles (tejas, piedras, tablones, grietas), luego alrededores (losa de suelo, algunas rocas, matas de hierba).
  5. Rugosidad: los desplazamientos e inclinaciones aleatorios de la regla 7.
  6. Luz y encuadre (abajo), luego coloca la vista en el ángulo de la referencia, captúrala y compara parte por parte: silueta, proporciones, dónde se encuentra cada parte, colores. Corrige.
  7. Termina con final_check, la última llamada de la tarea: la función está abajo, en "La comprobación final". No ves tus renders; mide el render por ti (el modelo aparte del fondo, contra la imagen de referencia cuando tienes su nombre de archivo) e imprime una línea PROBLEM: para lo que está mal. Corrige, ejecútalo de nuevo (como máximo dos rondas) y pon su salida en el informe. Las mediciones que hagas tú mismo no lo reemplazan: una tarea que construye o modifica un modelo no está terminada hasta que esta función se haya ejecutado.

Espera dos o tres rondas de corrección contra la referencia. Di lo que aún difiere.

Tienes un número limitado de rondas de herramientas por tarea (consulta "Tu presupuesto de pasos" en blender-modeling): construye dos o tres partes relacionadas por llamada, captura en los hitos (bloqueo, detalles, final) y pon las partes más visibles primero.

El código para cada receta está en references/low-poly-recipes.md: paleta, sombreado plano, cajas cónicas, techos a dos aguas, filas de tejas, ventanas y puertas, entramados de madera, rocas, árboles, terreno, dispersión y la configuración de iluminación. Ábrelo antes del primer script.

Muchos bloques en un objeto

Hiladas de piedras, almenas, adoquinado, tablones y ladrillos son muchas cajas pequeñas que pertenecen a un solo objeto. Constrúyelos con lp_blocks: termina cada caja en su propio bmesh y solo entonces la añade al objeto. No unas cajas agregando listas de vértices y caras a mano, y no muevas "los últimos N vértices" después de una operación que cambie su número (un chaflán lo hace): las caras terminan en los vértices equivocados y el modelo sale como picos estirados. final_check nombra un objeto roto así; reconstrúyelo, no lo reportes.

import bpy, bmesh
from mathutils import Matrix, Vector

def lp_blocks(name, col, mat, blocks, chamfer=0.03):
    """Muchas cajas en UN objeto con sombreado plano. blocks es una lista de (centro, tamaño) o
    (centro, tamaño, rotación_z): centro y tamaño son (x, y, z) en metros, la rotación en radianes.
    Cada caja se termina en su propio bmesh y solo entonces se añade al objeto."""
    whole = bmesh.new()
    for center, size, *rot in blocks:
        bm = bmesh.new()
        bmesh.ops.create_cube(bm, size=1.0)
        bmesh.ops.scale(bm, vec=Vector(size), verts=bm.verts)
        if chamfer > 0:
            bmesh.ops.bevel(bm, geom=bm.edges[:], offset=min(chamfer, min(size) * 0.25), segments=1, affect='EDGES')
        bmesh.ops.transform(bm, matrix=Matrix.Translation(Vector(center)) @ Matrix.Rotation(rot[0] if rot else 0.0, 4, 'Z'), verts=bm.verts)
        piece = bpy.data.meshes.new("_piece")
        bm.to_mesh(piece)
        bm.free()
        whole.from_mesh(piece)                                   # añade la caja terminada a la malla del objeto
        bpy.data.meshes.remove(piece)
    mesh = bpy.data.meshes.new(name)
    whole.to_mesh(mesh)
    whole.free()
    for poly in mesh.polygons:
        poly.use_smooth = False
    obj = bpy.data.objects.get(name)
    if obj is None:
        obj = bpy.data.objects.new(name, mesh)
        col.objects.link(obj)
    else:
        obj.data = mesh
    obj.data.materials.append(mat)
    return obj

# Una hilada de piedras de muro, alternando dos tamaños, en un solo objeto.
col = bpy.data.collections["LP_Model"]
stone = bpy.data.materials["LP_Stone_Light"]
lp_blocks("Wall_Course_01", col, stone,
          [((x * 0.42 - 1.26, -1.0, 0.35), (0.40 if x % 2 else 0.36, 0.20, 0.30)) for x in range(7)])

Formas y cómo obtenerlas

QuieresConstrúyelo como
Paredes, vigas, tablones, escalonesCajas, escaladas; afina la parte superior o inferior para dar carácter
Bloques de piedra, almenas, adoquines, ladrilloslp_blocks (arriba): muchas cajas con chaflán en un objeto
Techo a dos aguasUn prisma (perfil triangular extruido), sobresaliendo de las paredes por todos lados
TejasFilas de losas delgadas en la pendiente del techo, cada fila superponiendo la de abajo, con pequeño tamaño e inclinación aleatorios
Chimenea, torre, pilarCaja cónica; losa de tapa ligeramente más ancha
ÁrbolTronco: cilindro cónico de 5-6 lados. Follaje: 2-3 conos apilados (pino) o 1-3 icósferas desplazadas (frondoso)
RocaIcósfera con 1 subdivisión, vértices movidos aleatoriamente, aplanada en Z, hundida en el suelo
Terreno, islaUna rejilla con pocos cortes, vértices elevados por ruido, luego sombreado plano; o una losa gruesa irregular para una base de diorama
AguaUn plano o losa plana, azul, ligeramente brillante (Roughness 0.2)
Hierba, arbustosConos pequeños o icósferas aplanadas en grupos
Cosas redondas (barril, rueda, pozo)Cilindros de 6-8 lados

Presupuestos

Recuentos aproximados de triángulos, para juzgar si algo está sobreconstruido:

ActivoTriángulos
Accesorio pequeño (roca, caja, arbusto)20-150
Árbol60-300
Casa o edificio500-3,000
Personaje300-1,500
Diorama completo3,000-15,000

Imprime el recuento cuando termines. Muy por encima del presupuesto generalmente significa demasiados segmentos o un modificador que subdivide.

Luz y presentación

El estilo depende de la luz: los facetados solo se leen cuando las caras vecinas obtienen diferente brillo.

  • Un sol en ángulo (aproximadamente 45° arriba, 30-45° al lado), intensidad 3-4, con sombras suaves; más un mundo de un color de cielo claro con intensidad 0.6-1.0 para que las sombras no sean negras. Sin configuración de estudio de tres puntos. No subas la luz para obtener un fondo blanco, y no tiñas el mundo para colorearlo: el propio material del fondo da el color.
  • Un sol ligeramente cálido contra un mundo ligeramente frío da el aspecto clásico.
  • Configura la transformación de vista a Standard para que los colores de la paleta se mantengan como se eligieron (la transformación por defecto los vuelve grises).
  • Cámara: vista de tres cuartos desde arriba (30-35° hacia abajo), lente larga (50-85 mm) u ortográfica para un diorama.
  • Un fondo sólido en un color de la paleta, o una losa de suelo que termine en un borde limpio. Un plano de fondo debe ser mucho más grande que el modelo (20 veces o más), o el mundo del mismo color: ningún borde u horizonte puede mostrarse en el encuadre.
  • EEVEE es suficiente y rápido. Las sombras suaves y la oclusión ambiental ayudan mucho.

Los materiales, el renderizado a archivo y la solución de problemas están en blender-materials-render.

Para un motor de juego

Los activos low-poly generalmente van a un motor. Mantén el sombreado plano al exportar (los facetados se almacenan como normales divididas, lo que aumenta el recuento de vértices pero no el de triángulos), fusiona las piezas de un activo en una sola malla con unos pocos espacios de material, y coloca el origen en el centro inferior. Sigue blender-game-export para el resto.

La comprobación final (siempre tu última llamada)

Las herramientas de renderizado escriben un archivo y te dan su ruta: nunca ves la imagen. Así que la última llamada execute_blender_code de la tarea es final_check, copiada tal cual, y lo que imprime va al informe tal cual. Hace un pequeño render desde la cámara de la escena y nombra lo que está mal: objetos sin material, geometría rota, un modelo fuera del encuadre, un render quemado u oscuro, y, con el nombre del archivo de referencia, las diferencias en encuadre, brillo, color y qué tan sólida es la silueta.

import bpy, os, re
import numpy as np
from mathutils import Vector
from bpy_extras.object_utils import world_to_camera_view

BACKDROP_WORDS = ("ground", "backdrop", "floor", "sky", "shadow")

def subject_stats(path, size=128):
    """Una imagen dividida entre fondo (los colores de sus cuatro esquinas) y sujeto (el resto):
    cuánto de la imagen ocupa el sujeto, su caja, su brillo, saturación y colores."""
    img = bpy.data.images.load(path, check_existing=False)
    w, h = img.size
    sw, sh = (size, max(8, round(size * h / w))) if w >= h else (max(8, round(size * w / h)), size)
    img.scale(sw, sh)
    px = np.empty(len(img.pixels), dtype=np.float32)
    img.pixels.foreach_get(px)
    bpy.data.images.remove(img)
    rgb = px.reshape(sh, sw, 4)[:, :, :3]                       # la fila 0 es la parte inferior de la imagen
    cy, cx = max(2, sh // 8), max(2, sw // 8)
    corners = np.concatenate([rgb[:cy, :cx].reshape(-1, 3), rgb[:cy, -cx:].reshape(-1, 3),
                              rgb[-cy:, :cx].reshape(-1, 3), rgb[-cy:, -cx:].reshape(-1, 3)])
    # Fondo = cercano a uno de los colores de las esquinas (un degradado o una sombra suave aún cuenta).
    q = np.unique(np.round(corners * 8).astype(int), axis=0)
    flat = rgb.reshape(-1, 3)
    dist = np.min(np.abs(flat[:, None, :] * 8 - q[None, :, :]).max(axis=2), axis=1)
    subject = (dist > 1.0).reshape(sh, sw)
    share = float(subject.mean())
    whole = flat @ np.array([0.2126, 0.7152, 0.0722], dtype=np.float32)
    out = {"size": (w, h), "image_brightness": round(float(whole.mean()), 3), "subject_pct": round(100 * share, 1)}
    if share < 0.005:
        return 

…

[truncado para la traducción]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Skills relacionados