Pipeline: generate material from baked bpr textures
This commit is contained in:
parent
a1a961e7a7
commit
6538f70d54
2 changed files with 122 additions and 0 deletions
120
cg/blender/texturing/shading.py
Normal file
120
cg/blender/texturing/shading.py
Normal file
|
@ -0,0 +1,120 @@
|
|||
# coding: utf-8
|
||||
# Copyright (C) 2023 Ilia Kurochkin <brothermechanic@gmail.com>
|
||||
#
|
||||
# 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 3 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.
|
||||
'''
|
||||
DESCRIPTION.
|
||||
Set up materials.
|
||||
'''
|
||||
__version__ = '0.1'
|
||||
|
||||
import logging
|
||||
import os
|
||||
import bpy
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
def assign_pbr_material(obj_names, textures_path):
|
||||
''' Assign material with PBR textures pack. '''
|
||||
|
||||
textures = sorted(os.listdir(textures_path))
|
||||
|
||||
for obj_name in obj_names:
|
||||
|
||||
part_name = obj_name.rpartition('_')[0]
|
||||
|
||||
obj = bpy.data.objects[obj_name]
|
||||
if len(obj.material_slots) > 0:
|
||||
# should be only one material so clear all exist slots
|
||||
obj.data.materials.clear()
|
||||
|
||||
if part_name in bpy.data.materials:
|
||||
# if material is already in scene
|
||||
obj.data.materials.append(bpy.data.materials[part_name])
|
||||
continue
|
||||
|
||||
# create Principled BSDF based material
|
||||
bmat = bpy.data.materials.new(name=part_name)
|
||||
bmat.use_nodes = True
|
||||
principled_node = bmat.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
for texture in textures:
|
||||
print(1, 'texture', texture)
|
||||
if not texture.startswith('T_' + part_name):
|
||||
continue
|
||||
print(2, 'texture', texture)
|
||||
if '_ao.' in texture:
|
||||
image_obj = bpy.data.images.load(os.path.join(textures_path, texture))
|
||||
image_obj.colorspace_settings.name = 'Linear'
|
||||
texture_ao = bmat.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
texture_ao.location = -1000, 500
|
||||
texture_ao.image = bpy.data.images[image_obj.name]
|
||||
|
||||
mix_node = bmat.node_tree.nodes.new(type="ShaderNodeMix")
|
||||
mix_node.location = -500, 500
|
||||
#mix_node.data_type = 'RGBA'
|
||||
mix_node.blend_type = 'MULTIPLY'
|
||||
mix_node.inputs['Factor'].default_value = 0.5
|
||||
|
||||
bmat.node_tree.links.new(texture_ao.outputs['Color'], mix_node.inputs['B'])
|
||||
bmat.node_tree.links.new(mix_node.outputs[0], principled_node.inputs['Base Color'])
|
||||
|
||||
|
||||
if '_d.' in texture:
|
||||
image_obj = bpy.data.images.load(os.path.join(textures_path, texture))
|
||||
image_obj.colorspace_settings.name = 'sRGB'
|
||||
texture_d = bmat.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
texture_d.location = -1000, 0
|
||||
texture_d.image = bpy.data.images[image_obj.name]
|
||||
|
||||
if texture_ao:
|
||||
bmat.node_tree.links.new(texture_d.outputs['Color'], mix_node.inputs['A'])
|
||||
else:
|
||||
bmat.node_tree.links.new(texture_d.outputs['Color'], principled_node.inputs['Base Color'])
|
||||
|
||||
if '_m.' in texture:
|
||||
image_obj = bpy.data.images.load(os.path.join(textures_path, texture))
|
||||
image_obj.colorspace_settings.name = 'Linear'
|
||||
texture_m = bmat.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
texture_m.location = -1000, -500
|
||||
texture_m.image = bpy.data.images[image_obj.name]
|
||||
|
||||
bmat.node_tree.links.new(texture_m.outputs['Color'], principled_node.inputs['Metallic'])
|
||||
|
||||
if '_r.' in texture:
|
||||
image_obj = bpy.data.images.load(os.path.join(textures_path, texture))
|
||||
image_obj.colorspace_settings.name = 'Linear'
|
||||
texture_r = bmat.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
texture_r.location = -1000, -1000
|
||||
texture_r.image = bpy.data.images[image_obj.name]
|
||||
|
||||
bmat.node_tree.links.new(texture_r.outputs['Color'], principled_node.inputs['Roughness'])
|
||||
|
||||
if '_n.' in texture:
|
||||
image_obj = bpy.data.images.load(os.path.join(textures_path, texture))
|
||||
image_obj.colorspace_settings.name = 'Non-Color'
|
||||
texture_n = bmat.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
texture_n.location = -1000, -1500
|
||||
texture_n.image = bpy.data.images[image_obj.name]
|
||||
|
||||
normal_node = bmat.node_tree.nodes.new(type="ShaderNodeNormalMap")
|
||||
normal_node.location = -500, -1500
|
||||
|
||||
bmat.node_tree.links.new(texture_n.outputs['Color'], normal_node.inputs['Color'])
|
||||
bmat.node_tree.links.new(normal_node.outputs['Normal'], principled_node.inputs['Normal'])
|
||||
|
||||
|
||||
obj.data.materials.append(bmat)
|
||||
|
||||
logger.info('Shading of %s objects is finished!', len(obj_names))
|
||||
return True
|
|
@ -24,6 +24,7 @@ from blender.processing.lowpoly_setup import parts_to_shells
|
|||
from blender.processing.uv_setup import uv_unwrap
|
||||
from blender.texturing.bake_submitter import bw_submit
|
||||
from blender.texturing.composing import compose_baked_textures
|
||||
from blender.texturing.shading import assign_pbr_material
|
||||
from blender.export.dae import export_dae
|
||||
from blender.export.stl import export_stl
|
||||
import bpy
|
||||
|
@ -132,6 +133,7 @@ def cg_pipeline(**kwargs):
|
|||
bpy.ops.wm.open_mainfile(filepath=blend_path)
|
||||
textures_path = bw_submit(lowpoly_obj_names)
|
||||
compose_baked_textures(textures_path)
|
||||
assign_pbr_material(lowpoly_obj_names, textures_path)
|
||||
|
||||
# export object meshes and urdf
|
||||
to_urdf = collections.defaultdict(list)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue