likes
comments
collection
share

灰常简单的blender脚本开发!!!

作者站长头像
站长
· 阅读数 12

人生苦短,搞下python。

前因

坐标前端3D网页,因为建模师曾经抱怨贴图太多需要手动一个个将图像纹理与原理化BSDF节点连接,建模师在网上找过一个插件,插件的算法是根据图片的名称去匹配相应名称的网格材质,但是之前的脚本是按照图片后缀序号排序的,所以网格也按照名称+序号排序刚好可以匹配好,我觉得不是太好,就改成了遍历匹配名称,优化了建模师对图片和网格排序费心费力的操作。大学本科(非科班)学过python语法,后续感觉python做什么东西都需要调库,找库又很麻烦,作为一个新手太不友好就放弃了。但python确实是一门优秀的编程语言。

为什么开发blender脚本

由于3D模型的格式太过丰富FBX obj glb等等,因为是做网页就选择了glb格式,blender完美的支持大部分格式模型的导入导出,因此作为工作中的一个模型转换工具被我经常使用,blender中的模型效果也基本与网页中的效果相同。 为了解决流程中的自动化问题,脚本只是过渡形态,后续会继续学习一下blender插件开发,将脚本与图形UI结合起来做到彻底的封装。

技术基础

BPY 一分钟入门

.py文件引入  import bpy;
bpy.context  与交互有关的对象都从这个里面去寻找,如选中某个Mesh
bpy.data     当前blender场景的所有属性
bpy.ops      对blender场景的操作,如脚本控制选中所有的mesh: bpy.ops.object.select_by_type(type="MESH");

3分钟实战(一):

为烘焙作准备工作的脚本:做过blender烘焙的小伙伴都知道,需要给每个材质都准备一个空的图像纹理,然后选中所有的网格

import bpy;
imageSize = 1024;
#生成新的图像纹理节点;  
def is_node_exit(nodes,str):
    for node in nodes:
        if(node.name ==str):
            return True;
        else:
            return False
for mesh in bpy.data.meshes:
    for mat in mesh.materials:
        is_exit = is_node_exit(mat.node_tree.nodes,mat.name+"_lightmap");
        if(is_exit):
            continue;
        else:
            imageNode = mat.node_tree.nodes.new(type="ShaderNodeTexImage");
            imageNode.image = bpy.data.images.new(mat.name+"_lightmap",width=imageSize,height=imageSize);
bpy.ops.object.select_by_type(type="MESH");

点击运行脚本就可以啦!这里可能会有一些问题,要点击到blender的场景,再点击运行脚本,渲染的按钮才会亮。

3分钟实战(二):

将渲染好的贴图自动链接到原理化bsdf节点上: 默认当前材质的节点只有一个原理化BSDF和一张刚刚渲染好的图像纹理。

import bpy;
def find_node_by_type(nodes,str):
    for node in nodes:
        if(node.type ==str):
            return node;
def find_texnode_by_name(nodes,str):
    for node in nodes:
        if(node.type =='TEX_IMAGE'):
            if(node.image.name ==str):
                return node;

for mesh in bpy.data.meshes:
    for mat in mesh.materials:
#        imageNode = mat.node_tree.nodes.new(type="ShaderNodeTexImage");
#        imageNode.image = bpy.data.images.new(mat.name+"_lightmap",width=imageSize,height=imageSize);
        nodeTex = find_texnode_by_name(mat.node_tree.nodes,mat.name+"_lightmap");
        nodeBSDF = find_node_by_type(mat.node_tree.nodes,"BSDF_PRINCIPLED");
#        for node in mat.node_tree.nodes:
#            if(node.type =="TexImage"):
#                nodeTex.append(node);
#                
#            if(node.type == "BSDF_PRINCIPLED"):
#                nodeBSDF.append(node);
#                
    mat.node_tree.links.new(nodeTex.outputs[0],nodeBSDF.inputs[0]);

相信经常使用blender的朋友已经可以看出来了,两次实战其实是我们建模的烘焙流程,这里我将烘焙好的贴图作为了模型的表面色贴图,因为原理化BSDF不支持lightMap通道,不想这样做的小伙伴可以将贴图暂时链接到自发光贴图上导出,导入自己的变成框架后,将自发光通道上面的贴图重新赋予到lightMap通道上面,并将自发光通道清除一下。 本次只是一次小试牛刀,其实里面还有很多优化空间,距离实际使用还差那么亿点点。不过也可以极大的优化建模师的繁琐操作。这次先介绍的这里,下次见。