armory/blender/arm/material/make_shader.py

120 lines
4.2 KiB
Python
Raw Normal View History

2017-03-14 20:43:54 +01:00
import os
import bpy
2017-03-15 12:30:14 +01:00
import arm.utils
import arm.assets as assets
import arm.material.mat_utils as mat_utils
import arm.material.mat_state as mat_state
from arm.material.shader_data import ShaderData
import arm.material.cycles as cycles
import arm.material.make_mesh as make_mesh
2017-03-28 14:30:51 +02:00
import arm.material.make_rect as make_rect
2017-03-15 12:30:14 +01:00
import arm.material.make_shadowmap as make_shadowmap
import arm.material.make_transluc as make_transluc
import arm.material.make_overlay as make_overlay
import arm.material.make_depth as make_depth
import arm.material.make_decal as make_decal
import arm.material.make_voxel as make_voxel
2017-05-20 19:07:15 +02:00
import arm.material.make_voxelbounce as make_voxelbounce
2017-03-14 20:43:54 +01:00
rpass_hook = None
def build(material, mat_users, mat_armusers, rid):
mat_state.mat_users = mat_users
mat_state.mat_armusers = mat_armusers
mat_state.material = material
mat_state.nodes = material.node_tree.nodes
mat_state.data = ShaderData(material)
mat_state.output_node = cycles.node_by_type(mat_state.nodes, 'OUTPUT_MATERIAL')
if mat_state.output_node == None:
2017-04-21 11:10:49 +02:00
# Place empty material output to keep compiler happy..
mat_state.output_node = mat_state.nodes.new('ShaderNodeOutputMaterial')
2017-03-14 20:43:54 +01:00
wrd = bpy.data.worlds['Arm']
rpasses = mat_utils.get_rpasses(material)
2017-05-13 17:17:43 +02:00
matname = arm.utils.safesrc(material.name)
2017-05-23 01:03:44 +02:00
rel_path = arm.utils.build_dir() + '/compiled/ShaderRaws/' + matname
2017-03-15 12:30:14 +01:00
full_path = arm.utils.get_fp() + '/' + rel_path
2017-03-14 20:43:54 +01:00
if not os.path.exists(full_path):
os.makedirs(full_path)
2017-05-25 16:48:41 +02:00
global_elems = []
2017-03-14 20:43:54 +01:00
if mat_users != None:
for bo in mat_users[material]:
# GPU Skinning
2017-04-04 23:11:31 +02:00
if arm.utils.export_bone_data(bo):
2017-05-25 16:48:41 +02:00
global_elems.append({'name': 'bone', 'size': 4})
global_elems.append({'name': 'weight', 'size': 4})
2017-03-14 20:43:54 +01:00
# Instancing
2017-08-19 12:10:06 +02:00
if bo.arm_instanced or len(bo.particle_systems) > 0:
2017-05-25 16:48:41 +02:00
global_elems.append({'name': 'off', 'size': 3})
mat_state.data.global_elems = global_elems
2017-03-14 20:43:54 +01:00
2017-03-21 03:06:38 +01:00
bind_constants = dict()
2017-03-14 20:43:54 +01:00
bind_textures = dict()
for rp in rpasses:
car = []
2017-03-21 03:06:38 +01:00
bind_constants[rp] = car
mat_state.bind_constants = car
2017-03-14 20:43:54 +01:00
tar = []
bind_textures[rp] = tar
mat_state.bind_textures = tar
if rp == 'mesh':
2017-04-22 15:08:44 +02:00
con = make_mesh.make(rp, rid)
2017-03-14 20:43:54 +01:00
2017-03-28 14:30:51 +02:00
elif rp == 'rect':
con = make_rect.make(rp)
2017-03-14 20:43:54 +01:00
elif rp == 'shadowmap':
con = make_shadowmap.make(rp, rpasses)
elif rp == 'translucent':
con = make_transluc.make(rp)
elif rp == 'overlay':
con = make_overlay.make(rp)
elif rp == 'decal':
con = make_decal.make(rp)
elif rp == 'depth':
con = make_depth.make(rp)
elif rp == 'voxel':
con = make_voxel.make(rp)
2017-05-20 19:07:15 +02:00
elif rp == 'voxelbounce':
con = make_voxelbounce.make(rp)
2017-03-14 20:43:54 +01:00
elif rpass_hook != None:
con = rpass_hook(rp)
2017-05-25 16:48:41 +02:00
2017-03-14 20:43:54 +01:00
write_shaders(rel_path, con, rp)
2017-03-15 12:30:14 +01:00
arm.utils.write_arm(full_path + '/' + matname + '_data.arm', mat_state.data.get())
2017-03-14 20:43:54 +01:00
shader_data_name = matname + '_data'
2017-05-23 01:03:44 +02:00
shader_data_path = arm.utils.build_dir() + '/compiled/ShaderRaws/' + matname + '/' + shader_data_name + '.arm'
2017-03-14 20:43:54 +01:00
assets.add_shader_data(shader_data_path)
2017-03-21 03:06:38 +01:00
return rpasses, mat_state.data, shader_data_name, bind_constants, bind_textures
2017-03-14 20:43:54 +01:00
def write_shaders(rel_path, con, rpass):
keep_cache = mat_state.material.is_cached
write_shader(rel_path, con.vert, 'vert', rpass, keep_cache)
write_shader(rel_path, con.frag, 'frag', rpass, keep_cache)
write_shader(rel_path, con.geom, 'geom', rpass, keep_cache)
write_shader(rel_path, con.tesc, 'tesc', rpass, keep_cache)
write_shader(rel_path, con.tese, 'tese', rpass, keep_cache)
def write_shader(rel_path, shader, ext, rpass, keep_cache=True):
if shader == None:
return
2017-05-13 17:17:43 +02:00
shader_rel_path = rel_path + '/' + arm.utils.safesrc(mat_state.material.name) + '_' + rpass + '.' + ext + '.glsl'
2017-03-15 12:30:14 +01:00
shader_path = arm.utils.get_fp() + '/' + shader_rel_path
2017-03-14 20:43:54 +01:00
assets.add_shader(shader_rel_path)
if not os.path.isfile(shader_path) or not keep_cache:
with open(shader_path, 'w') as f:
f.write(shader.get())