mcpField
B
blender-uv-texturing

blender-uv-texturing

github.com/roble3创意与媒体1281.2k 次安装2 周前更新
代码仓库

关于 blender-uv-texturing

用于将图像纹理和图集贴合到 3D 模型的 Blender 技能,涵盖 UV 映射、材质设置、烘焙与验证,适用于模板驱动的资产。

主要功能

  1. 01视图投射 UV 映射
  2. 02按部件映射图集
  3. 03PBR 纹理与色彩空间设置
  4. 04Alpha 贴花配置
  5. 05烘焙目标设置
  6. 06UV 与导出验证

适用场景

  1. 01将图集贴合到模型的不同部件
  2. 02设置粗糙度、法线或光照贴图
  3. 03配置不带黑色底板的 Alpha 贴花
  4. 04导出 GLB 前检查 UV 覆盖

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/roble3/cc-blender-skill --skill blender-uv-texturing

安装后在 Claude Code 中输入/blender-uv-texturing确认已加载。

附带文件evals/evals.jsonreferences/overview.md

详细介绍

Blender UV 贴图

这项技能填补了“分配材质”与“提供的贴图包确实适配模型”之间的空白。对于由模板/图集驱动的资产,这是必需步骤。

决策树

What does the texture represent?
├── Whole object from front/reference → Project-from-View style UVs from the validation camera
├── Atlas with separate parts         → crop/map each part to its own UV island/rectangle
├── Repeating material                → generated/object coords or tiled UVs
├── Face/expression decal             → alpha material plane or projected UV island; no black background
├── Roughness/bump/normal map         → Non-Color data, correct node type
└── Lightmap                          → separate UV/lightmap channel or optional multiply helper; not emission

不可妥协的规则

  1. 图像贴图需要材质节点设置才能渲染/导出;仅在视口中显示 UV 并不足够。
  2. Basecolor/albedo = sRGB。Roughness、metallic、bump、normal、AO/lightmap = Non-Color。
  3. 图集贴图必须按区域映射。切勿将整张图集应用到每个网格部件。
  4. Alpha 贴花必须使用连接了 Alpha 的材质设置(BLEND、Alpha Hashed 或 Alpha Clip),并使用带键控透明度/正确设置的 PNG。不要留下黑色平面。
  5. 对于 GLB,尽可能使用导出器可识别的节点:带有 Image Texture 输入的 Principled BSDF、UV、法线、切线。
  6. 在最终调整材质之前,使用检查纹理或叠加渲染进行验证。

配方

根据世界 X/Z 边界创建正面投影 UV
import bpy

def assign_front_projected_uv(obj_name, uv_name='UV_front_projected'):
    obj = bpy.data.objects[obj_name]
    mesh = obj.data
    uv = mesh.uv_layers.get(uv_name) or mesh.uv_layers.new(name=uv_name)
    mesh.uv_layers.active = uv
    xs = [v.co.x for v in mesh.vertices]
    zs = [v.co.z for v in mesh.vertices]
    minx, maxx = min(xs), max(xs)
    minz, maxz = min(zs), max(zs)
    dx = max(maxx - minx, 1e-8)
    dz = max(maxz - minz, 1e-8)
    for poly in mesh.polygons:
        for li in poly.loop_indices:
            co = mesh.vertices[mesh.loops[li].vertex_index].co
            uv.data[li].uv = ((co.x - minx) / dx, (co.z - minz) / dz)
    mesh.update()
将网格映射到图集中的矩形区域

图集矩形为归一化 UV 坐标中的 [u0, v0, u1, v1]。在创建局部 0–1 UV 后使用此方法。

def remap_uv_rect(obj_name, rect, uv_name=None):
    obj = bpy.data.objects[obj_name]
    layer = obj.data.uv_layers.get(uv_name) if uv_name else obj.data.uv_layers.active
    u0, v0, u1, v1 = rect
    for item in layer.data:
        u, v = item.uv
        item.uv = (u0 + u * (u1-u0), v0 + v * (v1-v0))
    obj.data.update()
使用正确色彩空间的图像贴图材质
import bpy

def image(path, colorspace):
    img = bpy.data.images.load(path, check_existing=True)
    img.colorspace_settings.name = colorspace
    return img

def make_pbr_texture_material(name, basecolor, roughness=None, normal_or_bump=None, alpha=False):
    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    nt = mat.node_tree
    bsdf = nt.nodes.get('Principled BSDF')
    tex = nt.nodes.new('ShaderNodeTexImage')
    tex.image = image(basecolor, 'sRGB')
    nt.links.new(tex.outputs['Color'], bsdf.inputs['Base Color'])
    if alpha and 'Alpha' in bsdf.inputs:
        nt.links.new(tex.outputs['Alpha'], bsdf.inputs['Alpha'])
        mat.blend_method = 'BLEND'
    if roughness:
        r = nt.nodes.new('ShaderNodeTexImage')
        r.image = image(roughness, 'Non-Color')
        nt.links.new(r.outputs['Color'], bsdf.inputs['Roughness'])
    if normal_or_bump:
        btex = nt.nodes.new('ShaderNodeTexImage')
        btex.image = image(normal_or_bump, 'Non-Color')
        bump = nt.nodes.new('ShaderNodeBump')
        bump.inputs['Strength'].default_value = 0.02
        nt.links.new(btex.outputs['Color'], bump.inputs['Height'])
        nt.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])
    return mat
烘焙目标设置

Blender 烘焙需要 UV 映射,并且需要一个活动的 Image Texture 节点或颜色属性作为烘焙目标。使用 Cycles 进行烘焙。

import bpy

obj = bpy.data.objects['GEO-target']
bpy.context.scene.render.engine = 'CYCLES'
img = bpy.data.images.new('BAKE_target', 2048, 2048, alpha=True)
mat = obj.data.materials[0]
mat.use_nodes = True
node = mat.node_tree.nodes.new('ShaderNodeTexImage')
node.image = img
mat.node_tree.nodes.active = node
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
bpy.ops.object.bake(type='DIFFUSE', pass_filter={'COLOR'}, margin=16)
img.filepath_raw = '/tmp/bake_target.png'
img.file_format = 'PNG'
img.save()

封闭/挤出表面覆盖检查

对于封闭或挤出的资产,不要止步于正面投影。使用 closed-surface-uv-coverage 分别验证正面、背面和侧壁的材质/UV/生成式覆盖。背面/侧面的曲线叠加只是点缀,不能代替纹理填充。

验证清单

  • UV 图层存在且处于活动状态。
  • 检查纹理在朝向正面的部件上没有明显拉伸。
  • 图集矩形按部件划分,而不是到处使用整张图集。
  • Roughness/bump/normal/lightmap 的色彩空间为 Non-Color。
  • Alpha 材质已设置混合模式,且没有黑色底板。
  • 基础 GLB 嵌入/导出预期图像,并排除参考平面。
  • 正面叠加渲染确认纹理与源模板对齐。

摘要来源

  • Blender 手册:渲染纹理输出的 UV/图像贴图工作流需要材质节点。
  • Blender 手册:Image Texture 节点的 Vector 未连接时,会使用活动 UV 映射。
  • Blender 手册:Cycles 烘焙需要 UV 映射,以及活动的 Image Texture/Color Attribute 目标。
  • Blender 手册:glTF 导出器支持网格、UV、纹理和材质,主要基于 Principled BSDF。
  • Khronos glTF PBR:基础色、金属度/粗糙度、法线及相关贴图是实时传输的核心概念。

评论

支持 Markdown