Reorg + use generation operator when initially creating Blender materials + make all texture fields in SWBF materials properties paths
This commit is contained in:
parent
8974131550
commit
9bd8479e31
|
@ -63,8 +63,8 @@ from .msh_material_properties import *
|
||||||
from .msh_skeleton_properties import *
|
from .msh_skeleton_properties import *
|
||||||
from .msh_collision_prim_properties import *
|
from .msh_collision_prim_properties import *
|
||||||
from .msh_to_blend import *
|
from .msh_to_blend import *
|
||||||
|
from .msh_material_operators import *
|
||||||
from .zaa_to_blend import *
|
from .zaa_to_blend import *
|
||||||
from .material_props_to_nodes_op import GenerateMaterialFromSWBFProperties
|
|
||||||
|
|
||||||
|
|
||||||
class ExportMSH(Operator, ExportHelper):
|
class ExportMSH(Operator, ExportHelper):
|
||||||
|
@ -203,63 +203,6 @@ def menu_func_import(self, context):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FillSWBFMaterialProperties(bpy.types.Operator):
|
|
||||||
bl_idname = "swbf_msh.fill_mat_props"
|
|
||||||
bl_label = "Fill SWBF Material Properties"
|
|
||||||
bl_description = ("Fill in SWBF properties of all materials used by selected objects.\n"
|
|
||||||
"Only considers materials that use nodes.\n"
|
|
||||||
"Please see 'Materials > Materials Operators' in the docs for more details.")
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
|
|
||||||
slots = sum([list(ob.material_slots) for ob in bpy.context.selected_objects if ob.type == 'MESH'],[])
|
|
||||||
mats = [slot.material for slot in slots if (slot.material and slot.material.node_tree)]
|
|
||||||
|
|
||||||
for mat in mats:
|
|
||||||
try:
|
|
||||||
for BSDF_node in [n for n in mat.node_tree.nodes if n.type == 'BSDF_PRINCIPLED']:
|
|
||||||
base_col = BSDF_node.inputs['Base Color']
|
|
||||||
|
|
||||||
for link in base_col.links :
|
|
||||||
link_node = link.from_node
|
|
||||||
|
|
||||||
if link_node.type != 'TEX_IMAGE':
|
|
||||||
continue
|
|
||||||
|
|
||||||
tex_name = link_node.image.name
|
|
||||||
|
|
||||||
i = tex_name.find(".tga")
|
|
||||||
|
|
||||||
# Get rid of trailing number in case one is present
|
|
||||||
if i > 0:
|
|
||||||
tex_name = tex_name[0:i+4]
|
|
||||||
|
|
||||||
mat.swbf_msh_mat.rendertype = 'NORMAL_BF2'
|
|
||||||
mat.swbf_msh_mat.diffuse_map = tex_name
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
# Many chances for null ref exceptions. None if user reads doc section...
|
|
||||||
pass
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_SWBF(bpy.types.Menu):
|
|
||||||
bl_label = "SWBF"
|
|
||||||
|
|
||||||
def draw(self, _context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.operator("swbf_msh.fill_mat_props", text="Fill SWBF Material Properties")
|
|
||||||
|
|
||||||
|
|
||||||
def draw_matfill_menu(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.separator()
|
|
||||||
layout.menu("VIEW3D_MT_SWBF")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(CollisionPrimitiveProperties)
|
bpy.utils.register_class(CollisionPrimitiveProperties)
|
||||||
|
|
||||||
|
@ -283,7 +226,7 @@ def register():
|
||||||
bpy.utils.register_class(VIEW3D_MT_SWBF)
|
bpy.utils.register_class(VIEW3D_MT_SWBF)
|
||||||
bpy.types.VIEW3D_MT_object_context_menu.append(draw_matfill_menu)
|
bpy.types.VIEW3D_MT_object_context_menu.append(draw_matfill_menu)
|
||||||
|
|
||||||
bpy.utils.register_class(GenerateMaterialFromSWBFProperties)
|
bpy.utils.register_class(GenerateMaterialNodesFromSWBFProperties)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,7 +250,7 @@ def unregister():
|
||||||
bpy.utils.unregister_class(VIEW3D_MT_SWBF)
|
bpy.utils.unregister_class(VIEW3D_MT_SWBF)
|
||||||
bpy.types.VIEW3D_MT_object_context_menu.remove(draw_matfill_menu)
|
bpy.types.VIEW3D_MT_object_context_menu.remove(draw_matfill_menu)
|
||||||
|
|
||||||
bpy.utils.unregister_class(GenerateMaterialFromSWBFProperties)
|
bpy.utils.unregister_class(GenerateMaterialNodesFromSWBFProperties)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
""" Operator for creating/modifying nodes to approximate appearance of SWBF material.
|
|
||||||
Only relevant if the builtin Eevee renderer is being used. """
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
from typing import Dict
|
|
||||||
from .msh_material import *
|
|
||||||
from .msh_material_gather import *
|
|
||||||
from .msh_material_properties import *
|
|
||||||
|
|
||||||
from .msh_material_utilities import _REVERSE_RENDERTYPES_MAPPING
|
|
||||||
|
|
||||||
from math import sqrt
|
|
||||||
|
|
||||||
|
|
||||||
from bpy.props import BoolProperty, EnumProperty, StringProperty
|
|
||||||
from bpy.types import Operator, Menu
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateMaterialFromSWBFProperties(bpy.types.Operator):
|
|
||||||
|
|
||||||
bl_idname = "swbf_msh.generate_material"
|
|
||||||
bl_label = "Generate Nodes"
|
|
||||||
bl_description= """Generate Cycles shader nodes from SWBF material properties.
|
|
||||||
|
|
||||||
The nodes generated are meant to give one a general idea
|
|
||||||
of how the material would look ingame. They cannot
|
|
||||||
to provide an exact emulation"""
|
|
||||||
|
|
||||||
|
|
||||||
material_name: StringProperty(
|
|
||||||
name = "Material Name",
|
|
||||||
description = "Name of material whose SWBF properties the generated nodes will emulate."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
|
|
||||||
material = bpy.data.materials[self.material_name]
|
|
||||||
|
|
||||||
|
|
||||||
if material and material.swbf_msh_mat:
|
|
||||||
|
|
||||||
mat_props = material.swbf_msh_mat
|
|
||||||
|
|
||||||
material.node_tree.nodes.clear()
|
|
||||||
|
|
||||||
bsdf = material.node_tree.nodes.new("ShaderNodeBsdfPrincipled")
|
|
||||||
|
|
||||||
diffuse_texture_path = mat_props.diffuse_map
|
|
||||||
if diffuse_texture_path:
|
|
||||||
texImage = material.node_tree.nodes.new('ShaderNodeTexImage')
|
|
||||||
texImage.image = bpy.data.images.load(diffuse_texture_path)
|
|
||||||
texImage.image.alpha_mode = 'CHANNEL_PACKED'
|
|
||||||
material.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
|
|
||||||
|
|
||||||
bsdf.inputs["Roughness"].default_value = 1.0
|
|
||||||
bsdf.inputs["Specular"].default_value = 0.0
|
|
||||||
|
|
||||||
if mat_props.hardedged_transparency:
|
|
||||||
material.blend_method = "CLIP"
|
|
||||||
material.node_tree.links.new(bsdf.inputs['Alpha'], texImage.outputs['Alpha'])
|
|
||||||
|
|
||||||
material.use_backface_culling = not bool(mat_props.doublesided)
|
|
||||||
|
|
||||||
|
|
||||||
output = material.node_tree.nodes.new("ShaderNodeOutputMaterial")
|
|
||||||
material.node_tree.links.new(output.inputs['Surface'], bsdf.outputs['BSDF'])
|
|
||||||
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
""" Operators for basic emulation and mapping of SWBF material system in Blender.
|
||||||
|
Only relevant if the builtin Eevee renderer is being used! """
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
from .msh_material_properties import *
|
||||||
|
|
||||||
|
from math import sqrt
|
||||||
|
|
||||||
|
from bpy.props import BoolProperty, EnumProperty, StringProperty
|
||||||
|
from bpy.types import Operator, Menu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FillSWBFMaterialProperties
|
||||||
|
|
||||||
|
# Iterates through all material slots of all selected
|
||||||
|
# objects and fills basic SWBF material properties
|
||||||
|
# from any Principled BSDF nodes it finds.
|
||||||
|
|
||||||
|
|
||||||
|
class FillSWBFMaterialProperties(bpy.types.Operator):
|
||||||
|
bl_idname = "swbf_msh.fill_mat_props"
|
||||||
|
bl_label = "Fill SWBF Material Properties"
|
||||||
|
bl_description = ("Fill in SWBF properties of all materials used by selected objects.\n"
|
||||||
|
"Only considers materials that use nodes.\n"
|
||||||
|
"Please see 'Materials > Materials Operators' in the docs for more details.")
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
slots = sum([list(ob.material_slots) for ob in bpy.context.selected_objects if ob.type == 'MESH'],[])
|
||||||
|
mats = [slot.material for slot in slots if (slot.material and slot.material.node_tree)]
|
||||||
|
|
||||||
|
for mat in mats:
|
||||||
|
try:
|
||||||
|
for BSDF_node in [n for n in mat.node_tree.nodes if n.type == 'BSDF_PRINCIPLED']:
|
||||||
|
base_col = BSDF_node.inputs['Base Color']
|
||||||
|
|
||||||
|
for link in base_col.links :
|
||||||
|
link_node = link.from_node
|
||||||
|
|
||||||
|
if link_node.type != 'TEX_IMAGE':
|
||||||
|
continue
|
||||||
|
|
||||||
|
tex_name = link_node.image.name
|
||||||
|
|
||||||
|
i = tex_name.find(".tga")
|
||||||
|
|
||||||
|
# Get rid of trailing number in case one is present
|
||||||
|
if i > 0:
|
||||||
|
tex_name = tex_name[0:i+4]
|
||||||
|
|
||||||
|
mat.swbf_msh_mat.rendertype = 'NORMAL_BF2'
|
||||||
|
mat.swbf_msh_mat.diffuse_map = tex_name
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
# Many chances for null ref exceptions. None if user reads doc section...
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class VIEW3D_MT_SWBF(bpy.types.Menu):
|
||||||
|
bl_label = "SWBF"
|
||||||
|
|
||||||
|
def draw(self, _context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.operator("swbf_msh.fill_mat_props", text="Fill SWBF Material Properties")
|
||||||
|
|
||||||
|
|
||||||
|
def draw_matfill_menu(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.separator()
|
||||||
|
layout.menu("VIEW3D_MT_SWBF")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# GenerateMaterialNodesFromSWBFProperties
|
||||||
|
|
||||||
|
# Creates shader nodes to emulate SWBF material properties.
|
||||||
|
# Will probably only support for a narrow subset of properties...
|
||||||
|
|
||||||
|
class GenerateMaterialNodesFromSWBFProperties(bpy.types.Operator):
|
||||||
|
|
||||||
|
bl_idname = "swbf_msh.generate_material_nodes"
|
||||||
|
bl_label = "Generate Nodes"
|
||||||
|
bl_description= """Generate Cycles shader nodes from SWBF material properties.
|
||||||
|
|
||||||
|
The nodes generated are meant to give one a general idea
|
||||||
|
of how the material would look ingame. They cannot
|
||||||
|
to provide an exact emulation"""
|
||||||
|
|
||||||
|
|
||||||
|
material_name: StringProperty(
|
||||||
|
name = "Material Name",
|
||||||
|
description = "Name of material whose SWBF properties the generated nodes will emulate."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
material = bpy.data.materials[self.material_name]
|
||||||
|
|
||||||
|
|
||||||
|
if material and material.swbf_msh_mat:
|
||||||
|
|
||||||
|
material.use_nodes = True
|
||||||
|
mat_props = material.swbf_msh_mat
|
||||||
|
|
||||||
|
material.node_tree.nodes.clear()
|
||||||
|
|
||||||
|
bsdf = material.node_tree.nodes.new("ShaderNodeBsdfPrincipled")
|
||||||
|
|
||||||
|
diffuse_texture_path = mat_props.diffuse_map
|
||||||
|
if diffuse_texture_path:
|
||||||
|
texImage = material.node_tree.nodes.new('ShaderNodeTexImage')
|
||||||
|
texImage.image = bpy.data.images.load(diffuse_texture_path)
|
||||||
|
texImage.image.alpha_mode = 'CHANNEL_PACKED'
|
||||||
|
material.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
|
||||||
|
|
||||||
|
bsdf.inputs["Roughness"].default_value = 1.0
|
||||||
|
bsdf.inputs["Specular"].default_value = 0.0
|
||||||
|
|
||||||
|
if mat_props.hardedged_transparency:
|
||||||
|
material.blend_method = "CLIP"
|
||||||
|
material.node_tree.links.new(bsdf.inputs['Alpha'], texImage.outputs['Alpha'])
|
||||||
|
|
||||||
|
material.use_backface_culling = not bool(mat_props.doublesided)
|
||||||
|
|
||||||
|
|
||||||
|
output = material.node_tree.nodes.new("ShaderNodeOutputMaterial")
|
||||||
|
material.node_tree.links.new(output.inputs['Surface'], bsdf.outputs['BSDF'])
|
||||||
|
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
|
@ -9,7 +9,7 @@ from .msh_material_ui_strings import *
|
||||||
from .msh_material_utilities import _REVERSE_RENDERTYPES_MAPPING
|
from .msh_material_utilities import _REVERSE_RENDERTYPES_MAPPING
|
||||||
|
|
||||||
|
|
||||||
from .material_props_to_nodes_op import GenerateMaterialFromSWBFProperties
|
from .msh_material_operators import GenerateMaterialNodesFromSWBFProperties
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,21 +177,25 @@ class MaterialProperties(PropertyGroup):
|
||||||
detail_map: StringProperty(name="Detail Map",
|
detail_map: StringProperty(name="Detail Map",
|
||||||
description="Detail maps allow you to add in 'detail' to the diffuse "
|
description="Detail maps allow you to add in 'detail' to the diffuse "
|
||||||
"map at runtime. Or they can be used as fake ambient occlusion "
|
"map at runtime. Or they can be used as fake ambient occlusion "
|
||||||
"maps or even wacky emissive maps. See docs for more details.")
|
"maps or even wacky emissive maps. See docs for more details.",
|
||||||
|
subtype='FILE_PATH')
|
||||||
|
|
||||||
normal_map: StringProperty(name="Normal Map",
|
normal_map: StringProperty(name="Normal Map",
|
||||||
description="Normal maps can provide added detail from lighting. "
|
description="Normal maps can provide added detail from lighting. "
|
||||||
"If Specular is enabled the alpha channel will be "
|
"If Specular is enabled the alpha channel will be "
|
||||||
"the Gloss Map.")
|
"the Gloss Map.",
|
||||||
|
subtype='FILE_PATH')
|
||||||
|
|
||||||
environment_map: StringProperty(name="Environment Map",
|
environment_map: StringProperty(name="Environment Map",
|
||||||
description="Environment map for the material. Provides static "
|
description="Environment map for the material. Provides static "
|
||||||
"reflections around the surface. Must be a cubemap.")
|
"reflections around the surface. Must be a cubemap.",
|
||||||
|
subtype='FILE_PATH')
|
||||||
|
|
||||||
distortion_map: StringProperty(name="Distortion Map",
|
distortion_map: StringProperty(name="Distortion Map",
|
||||||
description="Distortion maps control how Refractive materials "
|
description="Distortion maps control how Refractive materials "
|
||||||
"distort the scene behind them. Should be a normal map "
|
"distort the scene behind them. Should be a normal map "
|
||||||
"with '-forceformat v8u8' in it's '.tga.option' file.")
|
"with '-forceformat v8u8' in it's '.tga.option' file.",
|
||||||
|
subtype='FILE_PATH')
|
||||||
|
|
||||||
# Below props are for yet unsupported render types
|
# Below props are for yet unsupported render types
|
||||||
data_value_0: IntProperty(name="", description="First data value")
|
data_value_0: IntProperty(name="", description="First data value")
|
||||||
|
@ -199,10 +203,10 @@ class MaterialProperties(PropertyGroup):
|
||||||
|
|
||||||
rendertype_value: IntProperty(name="Rendertype Value", description="Raw number value of rendertype.", min=0, max=31)
|
rendertype_value: IntProperty(name="Rendertype Value", description="Raw number value of rendertype.", min=0, max=31)
|
||||||
|
|
||||||
texture_0: StringProperty(name="1", description="First texture slot")
|
texture_0: StringProperty(name="1", description="First texture slot", subtype='FILE_PATH', default="white.tga")
|
||||||
texture_1: StringProperty(name="2", description="Second texture slot")
|
texture_1: StringProperty(name="2", description="Second texture slot", subtype='FILE_PATH')
|
||||||
texture_2: StringProperty(name="3", description="Third texture slot")
|
texture_2: StringProperty(name="3", description="Third texture slot", subtype='FILE_PATH')
|
||||||
texture_3: StringProperty(name="4", description="Fourth texture slot")
|
texture_3: StringProperty(name="4", description="Fourth texture slot", subtype='FILE_PATH')
|
||||||
|
|
||||||
|
|
||||||
class MaterialPropertiesPanel(bpy.types.Panel):
|
class MaterialPropertiesPanel(bpy.types.Panel):
|
||||||
|
@ -291,6 +295,6 @@ class MaterialPropertiesPanel(bpy.types.Panel):
|
||||||
layout.prop(material_props, "texture_3")
|
layout.prop(material_props, "texture_3")
|
||||||
|
|
||||||
|
|
||||||
op_props = layout.operator("swbf_msh.generate_material", text="Generate Nodes")
|
op_props = layout.operator("swbf_msh.generate_material_nodes", text="Generate Nodes")
|
||||||
op_props.material_name = context.material.name
|
op_props.material_name = context.material.name
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from typing import Dict
|
||||||
from .msh_material import *
|
from .msh_material import *
|
||||||
from .msh_material_gather import *
|
from .msh_material_gather import *
|
||||||
from .msh_material_properties import *
|
from .msh_material_properties import *
|
||||||
|
from .msh_material_operators import *
|
||||||
|
|
||||||
from .msh_material_utilities import _REVERSE_RENDERTYPES_MAPPING
|
from .msh_material_utilities import _REVERSE_RENDERTYPES_MAPPING
|
||||||
|
|
||||||
|
@ -33,38 +34,20 @@ def find_texture_path(folder_path : str, name : str) -> str:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def swbf_material_to_blend(material_name : str, material : Material, folder_path : str) -> bpy.types.Material:
|
def swbf_material_to_blend(material_name : str, material : Material, folder_path : str) -> bpy.types.Material:
|
||||||
|
|
||||||
new_mat = bpy.data.materials.new(name=material_name)
|
new_mat = bpy.data.materials.new(name=material_name)
|
||||||
new_mat.use_nodes = True
|
|
||||||
bsdf = new_mat.node_tree.nodes["Principled BSDF"]
|
|
||||||
|
|
||||||
diffuse_texture_path = find_texture_path(folder_path, material.texture0)
|
|
||||||
|
|
||||||
if diffuse_texture_path:
|
|
||||||
texImage = new_mat.node_tree.nodes.new('ShaderNodeTexImage')
|
|
||||||
texImage.image = bpy.data.images.load(diffuse_texture_path)
|
|
||||||
texImage.image.alpha_mode = 'CHANNEL_PACKED'
|
|
||||||
new_mat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
|
|
||||||
|
|
||||||
bsdf.inputs["Roughness"].default_value = 1.0
|
|
||||||
bsdf.inputs["Specular"].default_value = 0.0
|
|
||||||
|
|
||||||
if material.flags & MaterialFlags.HARDEDGED_TRANSPARENCY:
|
|
||||||
new_mat.blend_method = "CLIP"
|
|
||||||
new_mat.node_tree.links.new(bsdf.inputs['Alpha'], texImage.outputs['Alpha'])
|
|
||||||
|
|
||||||
|
|
||||||
new_mat.use_backface_culling = not bool(material.flags & MaterialFlags.DOUBLESIDED)
|
|
||||||
|
|
||||||
|
|
||||||
fill_material_props(material, new_mat.swbf_msh_mat, folder_path)
|
fill_material_props(material, new_mat.swbf_msh_mat, folder_path)
|
||||||
|
|
||||||
|
bpy.ops.swbf_msh.generate_material_nodes('EXEC_DEFAULT', material_name=new_mat.name)
|
||||||
|
|
||||||
return new_mat
|
return new_mat
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def fill_material_props(material : Material, material_properties, folder_path):
|
def fill_material_props(material, material_properties, folder_path):
|
||||||
""" Fills MaterialProperties from Material instance """
|
""" Fills MaterialProperties from Material instance """
|
||||||
|
|
||||||
if material_properties is None or material is None:
|
if material_properties is None or material is None:
|
||||||
|
@ -135,14 +118,19 @@ def _fill_material_props_data(material, material_properties):
|
||||||
def _fill_material_props_texture_maps(material, material_properties, folder_path):
|
def _fill_material_props_texture_maps(material, material_properties, folder_path):
|
||||||
|
|
||||||
t0path = find_texture_path(folder_path, material.texture0)
|
t0path = find_texture_path(folder_path, material.texture0)
|
||||||
|
t1path = find_texture_path(folder_path, material.texture1)
|
||||||
|
t2path = find_texture_path(folder_path, material.texture2)
|
||||||
|
t3path = find_texture_path(folder_path, material.texture3)
|
||||||
|
|
||||||
material_properties.texture_0 = t0path if t0path else material.texture0
|
material_properties.texture_0 = t0path if t0path else material.texture0
|
||||||
material_properties.texture_1 = material.texture1
|
material_properties.texture_1 = t1path if t1path else material.texture1
|
||||||
material_properties.texture_2 = material.texture2
|
material_properties.texture_2 = t2path if t2path else material.texture2
|
||||||
material_properties.texture_3 = material.texture3
|
material_properties.texture_3 = t3path if t3path else material.texture3
|
||||||
|
|
||||||
material_properties.diffuse_map = t0path
|
material_properties.diffuse_map = t0path
|
||||||
material_properties.distortion_map = material.texture1
|
material_properties.distortion_map = t1path
|
||||||
material_properties.normal_map = material.texture1
|
material_properties.normal_map = t1path
|
||||||
material_properties.detail_map = material.texture2
|
material_properties.detail_map = t2path
|
||||||
material_properties.environment_map = material.texture3
|
material_properties.environment_map = t3path
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue