armory/blender/arm/material/make_depth.py

172 lines
7.3 KiB
Python
Raw Normal View History

2017-02-07 11:50:21 +01:00
import bpy
2017-10-24 13:13:26 +02:00
import arm.material.cycles as cycles
2017-03-15 12:30:14 +01:00
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
2017-10-24 13:13:26 +02:00
import arm.material.make_skin as make_skin
2018-08-29 09:35:48 +02:00
import arm.material.make_inst as make_inst
2017-10-24 13:13:26 +02:00
import arm.material.make_tess as make_tess
import arm.material.make_particle as make_particle
2018-12-14 15:27:43 +01:00
import arm.material.make_finalize as make_finalize
2017-12-20 15:37:58 +01:00
import arm.assets as assets
2017-03-15 12:30:14 +01:00
import arm.utils
2016-12-19 01:25:22 +01:00
2017-10-24 13:13:26 +02:00
def make(context_id, rpasses, shadowmap=False):
2017-02-07 11:50:21 +01:00
2018-05-07 23:09:38 +02:00
is_disp = mat_utils.disp_linked(mat_state.output_node)
2017-10-24 13:13:26 +02:00
2018-12-14 15:27:43 +01:00
vs = [{'name': 'pos', 'data': 'short4norm'}]
2017-10-24 13:13:26 +02:00
if is_disp:
2018-12-14 15:27:43 +01:00
vs.append({'name': 'nor', 'data': 'short2norm'})
2017-10-24 13:13:26 +02:00
2018-12-15 13:33:59 +01:00
con_depth = mat_state.data.add_context({ 'name': context_id, 'vertex_elements': 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 })
2017-02-07 11:50:21 +01:00
vert = con_depth.make_vert()
frag = con_depth.make_frag()
2017-10-24 13:13:26 +02:00
geom = None
tesc = None
tese = None
2018-12-14 15:27:43 +01:00
vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);')
2017-10-24 13:13:26 +02:00
parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard
if parse_opacity:
frag.write('vec3 n;') # Discard at compile time
frag.write('float dotNV;')
frag.write('float opacity;')
if con_depth.is_elem('bone'):
make_skin.skin_pos(vert)
2018-08-29 09:35:48 +02:00
if con_depth.is_elem('ipos'):
make_inst.inst_pos(con_depth, vert)
2017-10-24 13:13:26 +02:00
rpdat = arm.utils.get_rp()
if mat_state.material.arm_particle_flag and rpdat.arm_particles == 'GPU':
2018-08-03 08:56:26 +02:00
make_particle.write(vert, shadowmap=shadowmap)
2017-10-24 13:13:26 +02:00
if is_disp:
2018-05-07 23:09:38 +02:00
if rpdat.arm_rp_displacement == 'Vertex':
vert.add_uniform('mat3 N', '_normalMatrix')
2018-12-30 00:01:34 +01:00
vert.write('vec3 wnormal = normalize(N * vec3(nor.xy, pos.w));')
2018-05-07 23:09:38 +02:00
cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity)
if con_depth.is_elem('tex'):
vert.add_out('vec2 texCoord') ## vs only, remove out
2018-12-14 15:27:43 +01:00
vert.add_uniform('float texUnpack', link='_texUnpack')
vert.write_attrib('texCoord = tex * texUnpack;')
2018-06-13 14:14:09 +02:00
if con_depth.is_elem('tex1'):
vert.add_out('vec2 texCoord1') ## vs only, remove out
2018-12-14 15:27:43 +01:00
vert.add_uniform('float texUnpack', link='_texUnpack')
vert.write_attrib('texCoord1 = tex1 * texUnpack;')
if con_depth.is_elem('col'):
vert.add_out('vec3 vcolor')
2019-01-07 10:42:45 +01:00
vert.write_attrib('vcolor = col.rgb;')
2018-05-10 13:52:07 +02:00
vert.write('wposition += wnormal * disp * 0.1;')
2018-05-07 23:09:38 +02:00
if shadowmap:
vert.add_uniform('mat4 LVP', '_lightViewProjectionMatrix')
2018-05-07 23:09:38 +02:00
vert.write('gl_Position = LVP * vec4(wposition, 1.0);')
else:
vert.add_uniform('mat4 VP', '_viewProjectionMatrix')
vert.write('gl_Position = VP * vec4(wposition, 1.0);')
else: # Tessellation
tesc = con_depth.make_tesc()
tese = con_depth.make_tese()
tesc.ins = vert.outs
tese.ins = tesc.outs
frag.ins = tese.outs
vert.add_out('vec3 wnormal')
vert.add_uniform('mat3 N', '_normalMatrix')
2018-12-14 15:27:43 +01:00
vert.write('wnormal = normalize(N * vec3(nor.xy, pos.w));')
2018-05-07 23:09:38 +02:00
make_tess.tesc_levels(tesc, rpdat.arm_tess_shadows_inner, rpdat.arm_tess_shadows_outer)
make_tess.interpolate(tese, 'wposition', 3)
make_tess.interpolate(tese, 'wnormal', 3, normalize=True)
cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity)
if con_depth.is_elem('tex'):
vert.add_out('vec2 texCoord')
2018-12-14 15:27:43 +01:00
vert.add_uniform('float texUnpack', link='_texUnpack')
vert.write('texCoord = tex * texUnpack;')
2018-05-07 23:09:38 +02:00
tese.write_pre = True
make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord'))
tese.write_pre = False
if con_depth.is_elem('tex1'):
vert.add_out('vec2 texCoord1')
vert.write('texCoord1 = tex1;')
tese.write_pre = True
make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1'))
tese.write_pre = False
if con_depth.is_elem('col'):
vert.add_out('vec3 vcolor')
2019-01-07 10:42:45 +01:00
vert.write('vcolor = col.rgb;')
2018-05-07 23:09:38 +02:00
tese.write_pre = True
make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor'))
tese.write_pre = False
if shadowmap:
tese.add_uniform('mat4 LVP', '_lightViewProjectionMatrix')
2018-05-10 13:52:07 +02:00
tese.write('wposition += wnormal * disp * 0.1;')
2018-05-07 23:09:38 +02:00
tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
else:
tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
2018-05-10 13:52:07 +02:00
tese.write('wposition += wnormal * disp * 0.1;')
2018-05-07 23:09:38 +02:00
tese.write('gl_Position = VP * vec4(wposition, 1.0);')
2017-10-24 13:13:26 +02:00
# No displacement
else:
frag.ins = vert.outs
billboard = mat_state.material.arm_billboard
if shadowmap:
if billboard == 'spherical':
vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrixSphere')
2017-10-24 13:13:26 +02:00
elif billboard == 'cylindrical':
vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrixCylinder')
2017-10-24 13:13:26 +02:00
else: # off
vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrix')
2017-10-24 13:13:26 +02:00
vert.write('gl_Position = LWVP * spos;')
else:
if billboard == 'spherical':
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixSphere')
elif billboard == 'cylindrical':
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixCylinder')
else: # off
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
vert.write('gl_Position = WVP * spos;')
if parse_opacity:
cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=True)
if con_depth.is_elem('tex'):
vert.add_out('vec2 texCoord')
2018-12-14 15:27:43 +01:00
vert.add_uniform('float texUnpack', link='_texUnpack')
2019-01-22 12:38:47 +01:00
if mat_state.material.arm_tilesheet_flag:
2017-10-24 13:13:26 +02:00
vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
2018-12-14 15:27:43 +01:00
vert.write('texCoord = tex * texUnpack + tilesheetOffset;')
2017-10-24 13:13:26 +02:00
else:
2018-12-14 15:27:43 +01:00
vert.write('texCoord = tex * texUnpack;')
2017-10-24 13:13:26 +02:00
if con_depth.is_elem('tex1'):
vert.add_out('vec2 texCoord1')
vert.write('texCoord1 = tex1;')
if con_depth.is_elem('col'):
vert.add_out('vec3 vcolor')
2019-01-07 10:42:45 +01:00
vert.write('vcolor = col.rgb;')
2017-10-24 13:13:26 +02:00
if parse_opacity:
2019-01-24 12:47:51 +01:00
if mat_state.material.arm_discard:
opac = mat_state.material.arm_discard_opacity_shadows
else:
opac = '1.0'
2017-10-24 13:13:26 +02:00
frag.write('if (opacity < {0}) discard;'.format(opac))
2017-02-07 11:50:21 +01:00
2018-12-14 15:27:43 +01:00
make_finalize.make(con_depth)
2018-01-04 11:37:27 +01:00
2017-12-20 15:37:58 +01:00
assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])
assets.fs_equal(con_depth, assets.shader_cons['depth_frag'])
2017-02-07 11:50:21 +01:00
return con_depth