2017-05-25 16:48:41 +02:00
|
|
|
import bpy
|
2017-03-15 12:30:14 +01:00
|
|
|
import arm.material.cycles as cycles
|
|
|
|
import arm.material.mat_state as mat_state
|
|
|
|
import arm.material.mat_utils as mat_utils
|
|
|
|
import arm.material.make_skin as make_skin
|
|
|
|
import arm.material.make_tess as make_tess
|
2017-09-27 00:04:47 +02:00
|
|
|
import arm.material.make_particle as make_particle
|
2017-03-23 12:01:25 +01:00
|
|
|
import arm.material.make_mesh as make_mesh
|
2017-04-19 11:48:30 +02:00
|
|
|
import arm.utils
|
2016-12-19 01:25:22 +01:00
|
|
|
|
2016-12-20 00:39:18 +01:00
|
|
|
def make(context_id, rpasses):
|
2017-05-25 16:48:41 +02:00
|
|
|
|
2017-08-21 12:17:55 +02:00
|
|
|
is_disp = mat_utils.disp_linked(mat_state.output_node) and mat_state.material.arm_tess_shadows
|
2017-05-25 16:48:41 +02:00
|
|
|
|
|
|
|
vs = [{'name': 'pos', 'size': 3}]
|
|
|
|
if is_disp:
|
|
|
|
vs.append({'name': 'nor', 'size': 3})
|
|
|
|
|
|
|
|
con_shadowmap = mat_state.data.add_context({ 'name': context_id, 'vertex_structure': vs, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False })
|
2016-12-19 01:25:22 +01:00
|
|
|
|
|
|
|
vert = con_shadowmap.make_vert()
|
|
|
|
frag = con_shadowmap.make_frag()
|
|
|
|
geom = None
|
|
|
|
tesc = None
|
|
|
|
tese = None
|
|
|
|
|
2017-04-26 14:21:22 +02:00
|
|
|
gapi = arm.utils.get_gapi()
|
|
|
|
if gapi == 'direct3d9':
|
2017-04-19 11:48:30 +02:00
|
|
|
frag.add_out('vec4 fragColor') # Definition requred for d3d9 - pixel shader must minimally write all four components of COLOR0
|
2017-03-23 12:01:25 +01:00
|
|
|
vert.write_main_header('vec4 spos = vec4(pos, 1.0);')
|
2016-12-19 01:25:22 +01:00
|
|
|
|
2017-08-21 12:17:55 +02:00
|
|
|
parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard
|
2016-12-20 00:39:18 +01:00
|
|
|
if parse_opacity:
|
2017-03-11 01:50:47 +01:00
|
|
|
frag.write('vec3 n;') # Discard at compile time
|
|
|
|
frag.write('float dotNV;')
|
2016-12-20 00:39:18 +01:00
|
|
|
frag.write('float opacity;')
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('bone'):
|
2016-12-19 01:25:22 +01:00
|
|
|
make_skin.skin_pos(vert)
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('off'):
|
2017-01-14 17:37:18 +01:00
|
|
|
vert.write('spos.xyz += off;')
|
|
|
|
|
2017-09-27 00:04:47 +02:00
|
|
|
wrd = bpy.data.worlds['Arm']
|
|
|
|
if wrd.arm_gpu_particles and mat_state.material.arm_particle:
|
|
|
|
make_particle.write(vert)
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if is_disp:
|
2016-12-19 01:25:22 +01:00
|
|
|
tesc = con_shadowmap.make_tesc()
|
|
|
|
tese = con_shadowmap.make_tese()
|
|
|
|
tesc.ins = vert.outs
|
|
|
|
tese.ins = tesc.outs
|
|
|
|
frag.ins = tese.outs
|
|
|
|
|
|
|
|
vert.add_out('vec3 wposition')
|
|
|
|
vert.add_out('vec3 wnormal')
|
|
|
|
vert.add_uniform('mat4 W', '_worldMatrix')
|
2017-03-11 01:50:47 +01:00
|
|
|
vert.add_uniform('mat3 N', '_normalMatrix')
|
|
|
|
vert.write('wnormal = normalize(N * nor);')
|
2016-12-19 01:25:22 +01:00
|
|
|
vert.write('wposition = vec4(W * spos).xyz;')
|
|
|
|
|
2017-08-23 22:53:39 +02:00
|
|
|
make_tess.tesc_levels(tesc, mat_state.material.arm_tess_shadows_inner, mat_state.material.arm_tess_shadows_outer)
|
2016-12-20 00:39:18 +01:00
|
|
|
make_tess.interpolate(tese, 'wposition', 3)
|
|
|
|
make_tess.interpolate(tese, 'wnormal', 3, normalize=True)
|
2016-12-19 01:25:22 +01:00
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
cycles.parse(mat_state.nodes, con_shadowmap, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity)
|
2016-12-19 01:25:22 +01:00
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('tex'):
|
2016-12-19 01:25:22 +01:00
|
|
|
vert.add_out('vec2 texCoord')
|
|
|
|
vert.write('texCoord = tex;')
|
|
|
|
tese.write_pre = True
|
2016-12-20 00:39:18 +01:00
|
|
|
make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord'))
|
2016-12-19 01:25:22 +01:00
|
|
|
tese.write_pre = False
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('tex1'):
|
2016-12-19 01:25:22 +01:00
|
|
|
vert.add_out('vec2 texCoord1')
|
|
|
|
vert.write('texCoord1 = tex1;')
|
|
|
|
tese.write_pre = True
|
2016-12-20 00:39:18 +01:00
|
|
|
make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1'))
|
2016-12-19 01:25:22 +01:00
|
|
|
tese.write_pre = False
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('col'):
|
2016-12-19 01:25:22 +01:00
|
|
|
vert.add_out('vec3 vcolor')
|
|
|
|
vert.write('vcolor = col;')
|
|
|
|
tese.write_pre = True
|
2017-01-14 12:44:43 +01:00
|
|
|
make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor'))
|
2016-12-19 01:25:22 +01:00
|
|
|
tese.write_pre = False
|
|
|
|
|
|
|
|
tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix')
|
|
|
|
tese.write('wposition += wnormal * disp * 0.2;')
|
|
|
|
tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
|
|
|
|
# No displacement
|
|
|
|
else:
|
|
|
|
frag.ins = vert.outs
|
2017-09-21 23:47:49 +02:00
|
|
|
billboard = mat_state.material.arm_billboard
|
|
|
|
if billboard == 'spherical':
|
|
|
|
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrixSphere')
|
|
|
|
elif billboard == 'cylindrical':
|
|
|
|
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrixCylinder')
|
|
|
|
else: # none
|
|
|
|
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
|
2016-12-19 01:25:22 +01:00
|
|
|
vert.write('gl_Position = LWVP * spos;')
|
2016-12-20 00:39:18 +01:00
|
|
|
|
|
|
|
if parse_opacity:
|
2017-05-25 16:48:41 +02:00
|
|
|
cycles.parse(mat_state.nodes, con_shadowmap, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=True)
|
2016-12-20 00:39:18 +01:00
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('tex'):
|
2016-12-20 00:39:18 +01:00
|
|
|
vert.add_out('vec2 texCoord')
|
2017-09-22 13:18:01 +02:00
|
|
|
if mat_state.material.arm_tilesheet_mat:
|
|
|
|
vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
|
|
|
|
vert.write('texCoord = tex + tilesheetOffset;')
|
|
|
|
else:
|
|
|
|
vert.write('texCoord = tex;')
|
2016-12-20 00:39:18 +01:00
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('tex1'):
|
2016-12-20 00:39:18 +01:00
|
|
|
vert.add_out('vec2 texCoord1')
|
|
|
|
vert.write('texCoord1 = tex1;')
|
|
|
|
|
2017-05-25 16:48:41 +02:00
|
|
|
if con_shadowmap.is_elem('col'):
|
2016-12-20 00:39:18 +01:00
|
|
|
vert.add_out('vec3 vcolor')
|
|
|
|
vert.write('vcolor = col;')
|
2016-12-19 01:25:22 +01:00
|
|
|
|
2017-07-05 23:26:13 +02:00
|
|
|
# TODO: interleaved buffer has to match vertex structure of mesh context
|
|
|
|
if not bpy.data.worlds['Arm'].arm_deinterleaved_buffers:
|
|
|
|
con_shadowmap.add_elem('nor', 3)
|
2017-07-08 12:26:03 +02:00
|
|
|
if mat_state.material.export_uvs:
|
|
|
|
con_shadowmap.add_elem('tex', 2)
|
2017-07-05 23:26:13 +02:00
|
|
|
|
2017-05-26 00:22:00 +02:00
|
|
|
# TODO: pass vbuf with proper struct
|
2017-06-22 12:25:42 +02:00
|
|
|
if gapi.startswith('direct3d') and bpy.data.worlds['Arm'].arm_deinterleaved_buffers == False:
|
2017-05-26 00:22:00 +02:00
|
|
|
vert.write('vec3 t1 = nor; // TODO: Temp for d3d')
|
|
|
|
if con_shadowmap.is_elem('tex'):
|
|
|
|
vert.write('vec2 t2 = tex; // TODO: Temp for d3d')
|
|
|
|
|
2016-12-20 00:39:18 +01:00
|
|
|
if parse_opacity:
|
2017-08-21 12:17:55 +02:00
|
|
|
opac = mat_state.material.arm_discard_opacity_shadows
|
2017-07-08 15:12:37 +02:00
|
|
|
frag.write('if (opacity < {0}) discard;'.format(opac))
|
2016-12-20 00:39:18 +01:00
|
|
|
|
2017-03-11 01:50:47 +01:00
|
|
|
# frag.write('fragColor = vec4(0.0);')
|
2016-12-19 01:25:22 +01:00
|
|
|
|
2017-03-23 12:01:25 +01:00
|
|
|
make_mesh.make_finalize(con_shadowmap)
|
|
|
|
|
2016-12-19 01:25:22 +01:00
|
|
|
return con_shadowmap
|