2016-12-17 15:34:43 +01:00
|
|
|
import bpy
|
2016-12-13 01:09:17 +01:00
|
|
|
import armutils
|
|
|
|
import os
|
2016-12-17 15:34:43 +01:00
|
|
|
import assets
|
2016-12-13 01:09:17 +01:00
|
|
|
from material.shader_data import ShaderData
|
2016-12-19 01:25:22 +01:00
|
|
|
import material.cycles as cycles
|
|
|
|
import material.mat_state as mat_state
|
|
|
|
import material.mat_utils as mat_utils
|
|
|
|
import material.make_mesh as make_mesh
|
2016-12-20 14:15:09 +01:00
|
|
|
import material.make_shadowmap as make_shadowmap
|
2016-12-19 01:25:22 +01:00
|
|
|
import material.make_transluc as make_transluc
|
2016-12-20 00:39:18 +01:00
|
|
|
import material.make_overlay as make_overlay
|
2017-02-07 11:50:21 +01:00
|
|
|
import material.make_depth as make_depth
|
|
|
|
import material.make_decal as make_decal
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2017-02-09 22:52:47 +01:00
|
|
|
rpass_hook = None
|
|
|
|
mesh_make = make_mesh.make
|
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
def parse(material, mat_data, mat_users, rid):
|
|
|
|
wrd = bpy.data.worlds['Arm']
|
|
|
|
mat_state.material = material
|
|
|
|
mat_state.nodes = material.node_tree.nodes
|
|
|
|
mat_state.mat_data = mat_data
|
|
|
|
mat_state.mat_users = mat_users
|
|
|
|
mat_state.output_node = cycles.node_by_type(mat_state.nodes, 'OUTPUT_MATERIAL')
|
|
|
|
if mat_state.output_node == None:
|
|
|
|
return None
|
2016-12-21 00:51:04 +01:00
|
|
|
matname = armutils.safe_source_name(material.name)
|
2016-12-23 13:33:59 +01:00
|
|
|
mat_state.rel_path = 'build/compiled/ShaderRaws/' + matname
|
|
|
|
mat_state.path = armutils.get_fp() + '/' + mat_state.rel_path
|
2016-12-19 01:25:22 +01:00
|
|
|
if not os.path.exists(mat_state.path):
|
|
|
|
os.makedirs(mat_state.path)
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
mat_state.data = ShaderData(material)
|
|
|
|
mat_state.data.add_elem('pos', 3)
|
|
|
|
mat_state.data.add_elem('nor', 3)
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-20 00:39:18 +01:00
|
|
|
if mat_users != None:
|
|
|
|
for bo in mat_users[material]:
|
|
|
|
# GPU Skinning
|
|
|
|
if bo.find_armature() and armutils.is_bone_animation_enabled(bo) and wrd.generate_gpu_skin == True:
|
|
|
|
mat_state.data.add_elem('bone', 4)
|
|
|
|
mat_state.data.add_elem('weight', 4)
|
|
|
|
|
|
|
|
# Instancing
|
|
|
|
if bo.instanced_children or len(bo.particle_systems) > 0:
|
|
|
|
mat_state.data.add_elem('off', 3)
|
2016-12-19 01:25:22 +01:00
|
|
|
|
|
|
|
rpasses = mat_utils.get_rpasses(material)
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
for rp in rpasses:
|
|
|
|
c = {}
|
|
|
|
c['name'] = rp
|
|
|
|
c['bind_constants'] = []
|
|
|
|
c['bind_textures'] = []
|
|
|
|
mat_state.mat_data['contexts'].append(c)
|
|
|
|
mat_state.mat_context = c
|
2016-12-17 15:34:43 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
if rp == 'mesh':
|
|
|
|
const = {}
|
|
|
|
const['name'] = 'receiveShadow'
|
|
|
|
const['bool'] = material.receive_shadow
|
|
|
|
c['bind_constants'].append(const)
|
2017-02-09 22:52:47 +01:00
|
|
|
con = mesh_make(rp, rid)
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-20 00:39:18 +01:00
|
|
|
elif rp == 'shadowmap':
|
2016-12-20 14:15:09 +01:00
|
|
|
con = make_shadowmap.make(rp, rpasses)
|
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'
|
|
|
|
const['bool'] = material.receive_shadow
|
|
|
|
c['bind_constants'].append(const)
|
2016-12-19 01:25:22 +01:00
|
|
|
con = make_transluc.make(rp)
|
2016-12-17 15:34:43 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
elif rp == 'overlay':
|
|
|
|
con = make_overlay.make(rp)
|
2016-12-17 15:34:43 +01:00
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
elif rp == 'decal':
|
|
|
|
con = make_decal.make(rp)
|
|
|
|
|
|
|
|
elif rp == 'depth':
|
|
|
|
con = make_depth.make(rp)
|
2017-02-09 22:52:47 +01:00
|
|
|
|
|
|
|
elif rpass_hook != None:
|
|
|
|
con = rpass_hook(rp)
|
2016-12-17 15:34:43 +01:00
|
|
|
|
2016-12-15 00:18:59 +01:00
|
|
|
write_shaders(con, rp)
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-21 00:51:04 +01:00
|
|
|
armutils.write_arm(mat_state.path + '/' + matname + '_data.arm', mat_state.data.get())
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-21 00:51:04 +01:00
|
|
|
shader_data_name = matname + '_data'
|
|
|
|
shader_data_path = 'build/compiled/ShaderRaws/' + matname + '/' + shader_data_name + '.arm'
|
2016-12-17 15:34:43 +01:00
|
|
|
assets.add_shader_data(shader_data_path)
|
|
|
|
mat_data['shader'] = shader_data_name + '/' + shader_data_name
|
|
|
|
|
2017-02-15 13:15:24 +01:00
|
|
|
return mat_state.data.sd, 'translucent' in rpasses, 'overlay' in rpasses, 'decal' in rpasses
|
2016-12-13 01:09:17 +01:00
|
|
|
|
2016-12-17 15:34:43 +01:00
|
|
|
def write_shaders(con, rpass):
|
2016-12-21 00:51:04 +01:00
|
|
|
keep_cache = mat_state.material.is_cached
|
|
|
|
write_shader(con.vert, 'vert', rpass, keep_cache)
|
|
|
|
write_shader(con.frag, 'frag', rpass, keep_cache)
|
|
|
|
write_shader(con.geom, 'geom', rpass, keep_cache)
|
|
|
|
write_shader(con.tesc, 'tesc', rpass, keep_cache)
|
|
|
|
write_shader(con.tese, 'tese', rpass, keep_cache)
|
|
|
|
|
|
|
|
def write_shader(shader, ext, rpass, keep_cache=True):
|
|
|
|
if shader == None:
|
|
|
|
return
|
2016-12-23 13:33:59 +01:00
|
|
|
shader_rel_path = mat_state.rel_path + '/' + armutils.safe_source_name(mat_state.material.name) + '_' + rpass + '.' + ext + '.glsl'
|
|
|
|
shader_path = armutils.get_fp() + '/' + shader_rel_path
|
|
|
|
assets.add_shader(shader_rel_path)
|
2016-12-21 19:15:51 +01:00
|
|
|
if not os.path.isfile(shader_path) or not keep_cache:
|
2016-12-17 15:34:43 +01:00
|
|
|
with open(shader_path, 'w') as f:
|
2016-12-21 00:51:04 +01:00
|
|
|
f.write(shader.get())
|