Forum: Blender


Subject: Blender Python Shader (Cycles) Automation

RobynsVeil opened this issue on Oct 18, 2015 · 32 posts


RobynsVeil posted Fri, 23 October 2015 at 5:44 AM

Okay, a bit more done: this will now put the absolute simplest of shaders on all skin surfaces. I'll flesh out the shader a bit next, then add other surfaces thereafter.

# simpleSkinShader001.py
# 
# Copyright (c) 23-Oct-2015, Robyn Hahn. Heaps of borrowed code.
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****

bl_info = {
    "name": "Simple skin shader for Poser Figures",
    "author": "Robyn Hahn",
    "version": (0, 1, 2),
    "blender": (2, 76, 0),
    "location": "-= Not a Tool For Blender, Yet =-",
    "description": "Generates a simple Cycles shader for a Poser figure",
    "warning": "early development",
    "wiki_url": "http://0.0.0.1",
    "category": "Simple Material Script"}

import bpy
import os.path

# sets renderer to Cycles
if bpy.context.scene.render.engine == 'BLENDER_RENDER':
    bpy.context.scene.render.engine = 'CYCLES'


# make sure your figure is selected and nothing else
bpy.ops.object.select_all(action='DESELECT')
selObj = bpy.data.objects['Katie-reposed']
selObj.select = True


# function generates node set (shader)
def buildShader(cImgClr, cImgBmp=None):
    selMats = selObj.active_material
    
    selMats.use_nodes = True
    treeNodes = selMats.node_tree
    nodeLinks = treeNodes.links
    
    # clears existing nodes, if any
    for n in treeNodes.nodes:
        treeNodes.nodes.remove(n)
        
    # create nodes: Texture Coordinate and Mapping
    shTcd = treeNodes.nodes.new('ShaderNodeTexCoord')
    shMap = treeNodes.nodes.new('ShaderNodeMapping')
    
    # create nodes: Image Texture
    sImgC = treeNodes.nodes.get('ShaderNodeTexImage')
    if sImgC is None:
        sImgC = treeNodes.nodes.new('ShaderNodeTexImage')    
    sImgC.image = cImgClr
    
    # create nodes: Diffuse
    shDif = treeNodes.nodes.get('ShaderNodeBsdfDiffuse')
    if shDif is None:
        shDif = treeNodes.nodes.new('ShaderNodeBsdfDiffuse')
    
    # create nodes: Glossy and Mix
    shGls = treeNodes.nodes.new('ShaderNodeBsdfGlossy')
    shMix = treeNodes.nodes.new('ShaderNodeMixShader')
    
    # create node: Material Output (sort-of like PoserSurface)
    shOut = treeNodes.nodes.get('ShaderNodeOutputMaterial')
    if shOut is None:
        shOut = treeNodes.nodes.new('ShaderNodeOutputMaterial')

    # Set node locations, roughly
    shTcd.location = -850, 300
    shMap.location = -600, 300
    sImgC.location = -200, 300
    shDif.location = 0, 400
    shGls.location = 0, 200
    shMix.location = 200, 300
    shOut.location = 400, 300

    # Link nodes
    nodeLinks.new(shTcd.outputs[2], shMap.inputs[0])
    nodeLinks.new(shMap.outputs[0], sImgC.inputs[0])
    nodeLinks.new(sImgC.outputs[0], shDif.inputs[0])
    nodeLinks.new(shDif.outputs[0], shMix.inputs[1])
    nodeLinks.new(shGls.outputs[0], shMix.inputs[2])
    nodeLinks.new(shMix.outputs[0], shOut.inputs[0])
    return selMats

bpy.context.object.active_material_index = 0

"""So far, this will set the skin shader for any limbs materials"""
for i in range(27):
    bPasteTex = False 
    selObj.active_material_index = i
    path = '/home/robyn/Documents/Blender/Projects/AllTextures/AllSkin/textures/'
    matName = selObj.active_material.name
    matType = matName[0:1]
    if matType == '3':
        imgFile = 'Syri_Limbs.jpg'
        bPasteTex = True
    if matType == '2':
        imgFile = 'Syri_Torso.jpg'
        bPasteTex = True
    if matType == '1':
        imgFile = 'Syri_Face.jpg'
        bPasteTex = True
    fullImg = path + imgFile
    img = bpy.data.images.load(filepath = fullImg)

    if bPasteTex:
        newMat = buildShader(img)

Again, you want to change the path, and the names of the files to reflect those that you have.

Off to play with making fun shaders! 😉

Monterey/Mint21.x/Win10 - Blender3.x - PP11.3(cm) - Musescore3.6.2

Wir sind gewohnt, daß die Menschen verhöhnen was sie nicht verstehen
[it is clear that humans have contempt for that which they do not understand] 

Metaphor of Chooks