2016-12-17 15:34:43 +01:00
|
|
|
import bpy
|
2017-03-15 12:30:14 +01:00
|
|
|
import arm.utils
|
2017-11-20 14:32:36 +01:00
|
|
|
import arm.node_utils
|
2017-03-15 12:30:14 +01:00
|
|
|
import arm.material.make_shader as make_shader
|
|
|
|
import arm.material.mat_batch as mat_batch
|
|
|
|
import arm.material.mat_state as mat_state
|
2018-10-26 19:45:07 +02:00
|
|
|
import arm.material.cycles as cycles
|
2017-03-14 20:43:54 +01:00
|
|
|
|
2017-11-20 14:32:36 +01:00
|
|
|
def glsl_type(t): # Merge with cycles
|
2017-03-14 20:43:54 +01:00
|
|
|
if t == 'RGB' or t == 'RGBA' or t == 'VECTOR':
|
|
|
|
return 'vec3'
|
|
|
|
else:
|
|
|
|
return 'float'
|
|
|
|
|
2017-11-20 14:32:36 +01:00
|
|
|
def glsl_value(val):
|
2017-03-14 20:43:54 +01:00
|
|
|
if str(type(val)) == "<class 'bpy_prop_array'>":
|
|
|
|
res = []
|
|
|
|
for v in val:
|
|
|
|
res.append(v)
|
|
|
|
return res
|
|
|
|
else:
|
|
|
|
return val
|
2017-02-09 22:52:47 +01:00
|
|
|
|
2017-08-21 15:36:21 +02:00
|
|
|
def parse(material, mat_data, mat_users, mat_armusers):
|
2016-12-19 01:25:22 +01:00
|
|
|
wrd = bpy.data.worlds['Arm']
|
2017-08-21 20:16:06 +02:00
|
|
|
rpdat = arm.utils.get_rp()
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2017-03-14 20:43:54 +01:00
|
|
|
# No batch - shader data per material
|
2017-09-17 16:59:00 +02:00
|
|
|
if material.arm_custom_material != '':
|
|
|
|
rpasses = ['mesh']
|
|
|
|
sd = {}
|
|
|
|
sd['contexts'] = []
|
|
|
|
con = {}
|
2018-12-14 15:27:43 +01:00
|
|
|
con['vertex_elements'] = []
|
2017-09-17 16:59:00 +02:00
|
|
|
elem = {}
|
|
|
|
elem['name'] = 'pos'
|
2018-12-14 15:27:43 +01:00
|
|
|
elem['data'] = 'short4norm'
|
|
|
|
con['vertex_elements'].append(elem)
|
2017-09-17 16:59:00 +02:00
|
|
|
elem = {}
|
|
|
|
elem['name'] = 'nor'
|
2018-12-14 15:27:43 +01:00
|
|
|
elem['data'] = 'short2norm'
|
|
|
|
con['vertex_elements'].append(elem)
|
2017-09-17 16:59:00 +02:00
|
|
|
sd['contexts'].append(con)
|
|
|
|
shader_data_name = material.arm_custom_material
|
|
|
|
bind_constants = {}
|
|
|
|
bind_constants['mesh'] = []
|
|
|
|
bind_textures = {}
|
|
|
|
bind_textures['mesh'] = []
|
|
|
|
elif not wrd.arm_batch_materials or material.name.startswith('armdefault'):
|
2017-08-21 15:36:21 +02:00
|
|
|
rpasses, shader_data, shader_data_name, bind_constants, bind_textures = make_shader.build(material, mat_users, mat_armusers)
|
2017-09-17 16:59:00 +02:00
|
|
|
sd = shader_data.sd
|
2017-03-14 20:43:54 +01:00
|
|
|
else:
|
|
|
|
rpasses, shader_data, shader_data_name, bind_constants, bind_textures = mat_batch.get(material)
|
2017-09-17 16:59:00 +02:00
|
|
|
sd = shader_data.sd
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2017-03-14 20:43:54 +01:00
|
|
|
# Material
|
2016-12-19 01:25:22 +01:00
|
|
|
for rp in rpasses:
|
2017-03-14 20:43:54 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
c = {}
|
|
|
|
c['name'] = rp
|
2017-03-14 20:43:54 +01:00
|
|
|
c['bind_constants'] = [] + bind_constants[rp]
|
|
|
|
c['bind_textures'] = [] + bind_textures[rp]
|
|
|
|
mat_data['contexts'].append(c)
|
2016-12-17 15:34:43 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
if rp == 'mesh':
|
|
|
|
const = {}
|
|
|
|
const['name'] = 'receiveShadow'
|
2017-08-21 12:17:55 +02:00
|
|
|
const['bool'] = material.arm_receive_shadow
|
2016-12-19 01:25:22 +01:00
|
|
|
c['bind_constants'].append(const)
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2017-11-25 20:09:55 +01:00
|
|
|
if material.arm_material_id != 0:
|
|
|
|
const = {}
|
|
|
|
const['name'] = 'materialID'
|
|
|
|
const['int'] = material.arm_material_id
|
|
|
|
c['bind_constants'].append(const)
|
|
|
|
if material.arm_material_id == 2:
|
|
|
|
wrd.world_defs += '_Hair'
|
|
|
|
elif rpdat.rp_sss_state == 'On':
|
2017-06-27 10:55:46 +02:00
|
|
|
sss = False
|
2017-11-20 14:32:36 +01:00
|
|
|
sss_node = arm.node_utils.get_node_by_type(material.node_tree, 'SUBSURFACE_SCATTERING')
|
2017-05-23 15:01:56 +02:00
|
|
|
if sss_node != None and sss_node.outputs[0].is_linked: # Check linked node
|
2017-06-27 10:55:46 +02:00
|
|
|
sss = True
|
2017-11-20 14:32:36 +01:00
|
|
|
sss_node = arm.node_utils.get_node_by_type(material.node_tree, 'BSDF_PRINCIPLED')
|
2017-06-27 10:55:46 +02:00
|
|
|
if sss_node != None and sss_node.outputs[0].is_linked and (sss_node.inputs[1].is_linked or sss_node.inputs[1].default_value != 0.0):
|
|
|
|
sss = True
|
2017-11-20 14:32:36 +01:00
|
|
|
sss_node = arm.node_utils.get_node_armorypbr(material.node_tree)
|
2017-07-09 19:44:19 +02:00
|
|
|
if sss_node != None and sss_node.outputs[0].is_linked and (sss_node.inputs[8].is_linked or sss_node.inputs[8].default_value != 0.0):
|
2017-07-07 18:21:44 +02:00
|
|
|
sss = True
|
2019-01-24 12:47:51 +01:00
|
|
|
const = {}
|
|
|
|
const['name'] = 'materialID'
|
2017-06-27 10:55:46 +02:00
|
|
|
if sss:
|
2017-05-23 15:01:56 +02:00
|
|
|
const['int'] = 2
|
2019-01-24 12:47:51 +01:00
|
|
|
else:
|
|
|
|
const['int'] = 0
|
|
|
|
c['bind_constants'].append(const)
|
2017-05-23 15:01:56 +02:00
|
|
|
|
2017-03-14 20:43:54 +01:00
|
|
|
# TODO: Mesh only material batching
|
|
|
|
if wrd.arm_batch_materials:
|
|
|
|
# Set textures uniforms
|
|
|
|
if len(c['bind_textures']) > 0:
|
|
|
|
c['bind_textures'] = []
|
|
|
|
for node in material.node_tree.nodes:
|
|
|
|
if node.type == 'TEX_IMAGE':
|
2017-05-13 17:17:43 +02:00
|
|
|
tex_name = arm.utils.safesrc(node.name)
|
2018-10-26 19:45:07 +02:00
|
|
|
tex = cycles.make_texture(node, tex_name)
|
2017-03-14 20:43:54 +01:00
|
|
|
if tex == None: # Empty texture
|
|
|
|
tex = {}
|
|
|
|
tex['name'] = tex_name
|
|
|
|
tex['file'] = ''
|
|
|
|
c['bind_textures'].append(tex)
|
|
|
|
|
|
|
|
# Set marked inputs as uniforms
|
|
|
|
for node in material.node_tree.nodes:
|
|
|
|
for inp in node.inputs:
|
|
|
|
if inp.is_uniform:
|
2017-05-13 17:17:43 +02:00
|
|
|
uname = arm.utils.safesrc(inp.node.name) + arm.utils.safesrc(inp.name) # Merge with cycles
|
2017-03-14 20:43:54 +01:00
|
|
|
const = {}
|
|
|
|
const['name'] = uname
|
2017-11-20 14:32:36 +01:00
|
|
|
const[glsl_type(inp.type)] = glsl_value(inp.default_value)
|
2017-03-14 20:43:54 +01:00
|
|
|
c['bind_constants'].append(const)
|
2016-12-15 00:18:59 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
elif rp == 'translucent':
|
2016-12-17 15:34:43 +01:00
|
|
|
const = {}
|
|
|
|
const['name'] = 'receiveShadow'
|
2017-08-21 12:17:55 +02:00
|
|
|
const['bool'] = material.arm_receive_shadow
|
2016-12-17 15:34:43 +01:00
|
|
|
c['bind_constants'].append(const)
|
2018-01-23 15:41:09 +01:00
|
|
|
|
2018-04-14 15:07:05 +02:00
|
|
|
ext = '' if wrd.arm_minimize else '.json'
|
2018-11-22 17:13:21 +01:00
|
|
|
mat_data['shader'] = shader_data_name + ext + '/' + shader_data_name
|
2016-12-17 15:34:43 +01:00
|
|
|
|
2017-09-17 16:59:00 +02:00
|
|
|
return sd, rpasses
|