forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			259 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			259 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								import bpy
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles as cycles
							 | 
						||
| 
								 | 
							
								import lnx.material.mat_state as mat_state
							 | 
						||
| 
								 | 
							
								import lnx.material.mat_utils as mat_utils
							 | 
						||
| 
								 | 
							
								import lnx.material.make_skin as make_skin
							 | 
						||
| 
								 | 
							
								import lnx.material.make_inst as make_inst
							 | 
						||
| 
								 | 
							
								import lnx.material.make_tess as make_tess
							 | 
						||
| 
								 | 
							
								import lnx.material.make_mesh as make_mesh
							 | 
						||
| 
								 | 
							
								import lnx.material.make_attrib as make_attrib
							 | 
						||
| 
								 | 
							
								import lnx.material.make_particle as make_particle
							 | 
						||
| 
								 | 
							
								import lnx.material.make_finalize as make_finalize
							 | 
						||
| 
								 | 
							
								import lnx.material.make_morph_target as make_morph_target
							 | 
						||
| 
								 | 
							
								import lnx.assets as assets
							 | 
						||
| 
								 | 
							
								import lnx.utils
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if lnx.is_reload(__name__):
							 | 
						||
| 
								 | 
							
								    cycles = lnx.reload_module(cycles)
							 | 
						||
| 
								 | 
							
								    mat_state = lnx.reload_module(mat_state)
							 | 
						||
| 
								 | 
							
								    mat_utils = lnx.reload_module(mat_utils)
							 | 
						||
| 
								 | 
							
								    make_skin = lnx.reload_module(make_skin)
							 | 
						||
| 
								 | 
							
								    make_inst = lnx.reload_module(make_inst)
							 | 
						||
| 
								 | 
							
								    make_tess = lnx.reload_module(make_tess)
							 | 
						||
| 
								 | 
							
								    make_particle = lnx.reload_module(make_particle)
							 | 
						||
| 
								 | 
							
								    make_finalize = lnx.reload_module(make_finalize)
							 | 
						||
| 
								 | 
							
								    assets = lnx.reload_module(assets)
							 | 
						||
| 
								 | 
							
								    lnx.utils = lnx.reload_module(lnx.utils)
							 | 
						||
| 
								 | 
							
								else:
							 | 
						||
| 
								 | 
							
								    lnx.enable_reload(__name__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    is_disp = mat_utils.disp_linked(mat_state.output_node)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    vs = [{'name': 'pos', 'data': 'short4norm'}]
							 | 
						||
| 
								 | 
							
								    if is_disp or shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								        vs.append({'name': 'nor', 'data': 'short2norm'})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								        con_depth = mat_state.data.add_context({
							 | 
						||
| 
								 | 
							
								            'name': context_id,
							 | 
						||
| 
								 | 
							
								            'vertex_elements': vs,
							 | 
						||
| 
								 | 
							
								            'depth_write': False,
							 | 
						||
| 
								 | 
							
								            'depth_read': True,
							 | 
						||
| 
								 | 
							
								            'compare_mode': 'less',
							 | 
						||
| 
								 | 
							
								            'cull_mode': 'clockwise',
							 | 
						||
| 
								 | 
							
								            'blend_source': 'blend_zero',
							 | 
						||
| 
								 | 
							
								            'blend_destination': 'source_color',
							 | 
						||
| 
								 | 
							
								            'blend_operation': 'add',
							 | 
						||
| 
								 | 
							
								            'color_writes_red': [True],
							 | 
						||
| 
								 | 
							
								            'color_writes_green': [True],
							 | 
						||
| 
								 | 
							
								            'color_writes_blue': [True],
							 | 
						||
| 
								 | 
							
								            'color_writes_alpha': [True]
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								    else:
							 | 
						||
| 
								 | 
							
								        con_depth = mat_state.data.add_context({
							 | 
						||
| 
								 | 
							
								            'name': context_id,
							 | 
						||
| 
								 | 
							
								            'vertex_elements': vs,
							 | 
						||
| 
								 | 
							
								            'depth_write': True,
							 | 
						||
| 
								 | 
							
								            'depth_read': False,
							 | 
						||
| 
								 | 
							
								            'compare_mode': 'less',
							 | 
						||
| 
								 | 
							
								            'cull_mode': 'clockwise',
							 | 
						||
| 
								 | 
							
								            'color_writes_red': [False],
							 | 
						||
| 
								 | 
							
								            'color_writes_green': [False],
							 | 
						||
| 
								 | 
							
								            'color_writes_blue': [False],
							 | 
						||
| 
								 | 
							
								            'color_writes_alpha': [False]
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    vert = con_depth.make_vert()
							 | 
						||
| 
								 | 
							
								    frag = con_depth.make_frag()
							 | 
						||
| 
								 | 
							
								    geom = None
							 | 
						||
| 
								 | 
							
								    tesc = None
							 | 
						||
| 
								 | 
							
								    tese = None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);')
							 | 
						||
| 
								 | 
							
								    vert.add_include('compiled.inc')
							 | 
						||
| 
								 | 
							
								    frag.add_include('compiled.inc')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    parse_opacity = 'translucent' in rpasses or 'refraction' in rpasses or mat_state.material.lnx_discard
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    parse_custom_particle = (cycles.node_by_name(mat_state.nodes, 'LnxCustomParticleNode') is not None)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								        billboard = mat_state.material.lnx_billboard
							 | 
						||
| 
								 | 
							
								        if billboard == 'spherical':
							 | 
						||
| 
								 | 
							
								            vert.add_uniform('mat3 N', '_normalMatrixSphere')
							 | 
						||
| 
								 | 
							
								        elif billboard == 'cylindrical':
							 | 
						||
| 
								 | 
							
								            vert.add_uniform('mat3 N', '_normalMatrixCylinder')
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            vert.add_uniform('mat3 N', '_normalMatrix')
							 | 
						||
| 
								 | 
							
								        make_mesh._write_material_attribs_default(frag, parse_opacity) #TODO remove duplicate parsing
							 | 
						||
| 
								 | 
							
								        vert.add_out('vec3 wnormal')
							 | 
						||
| 
								 | 
							
								        make_attrib.write_norpos(con_depth, vert)
							 | 
						||
| 
								 | 
							
								        frag.write_attrib('vec3 n = normalize(wnormal);')
							 | 
						||
| 
								 | 
							
								        cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, basecol_only=True, parse_opacity=True)
							 | 
						||
| 
								 | 
							
								    elif parse_opacity:
							 | 
						||
| 
								 | 
							
								        frag.write('float opacity;')
							 | 
						||
| 
								 | 
							
								        frag.write('float ior;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(con_depth).is_elem('morph'):
							 | 
						||
| 
								 | 
							
								        make_morph_target.morph_pos(vert)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if con_depth.is_elem('bone'):
							 | 
						||
| 
								 | 
							
								        make_skin.skin_pos(vert)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (not is_disp and parse_custom_particle):
							 | 
						||
| 
								 | 
							
								        cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if con_depth.is_elem('ipos'):
							 | 
						||
| 
								 | 
							
								        make_inst.inst_pos(con_depth, vert)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rpdat = lnx.utils.get_rp()
							 | 
						||
| 
								 | 
							
								    if mat_state.material.lnx_particle_flag and rpdat.lnx_particles == 'On':
							 | 
						||
| 
								 | 
							
								        make_particle.write(vert, shadowmap=shadowmap)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if is_disp:
							 | 
						||
| 
								 | 
							
								        if rpdat.lnx_rp_displacement == 'Vertex':
							 | 
						||
| 
								 | 
							
								            frag.ins = vert.outs
							 | 
						||
| 
								 | 
							
								            vert.add_uniform('mat3 N', '_normalMatrix')
							 | 
						||
| 
								 | 
							
								            vert.write('vec3 wnormal = normalize(N * vec3(nor.xy, pos.w));')
							 | 
						||
| 
								 | 
							
								            if(con_depth.is_elem('ipos')):
							 | 
						||
| 
								 | 
							
								                vert.write('wposition = vec4(W * spos).xyz;')
							 | 
						||
| 
								 | 
							
								                if(con_depth.is_elem('irot')):
							 | 
						||
| 
								 | 
							
								                    vert.write('wnormal = normalize(N * mirot * vec3(nor.xy, pos.w));')
							 | 
						||
| 
								 | 
							
								            if not shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								                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
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('float texUnpack', link='_texUnpack')
							 | 
						||
| 
								 | 
							
								                vert.write_attrib('texCoord = tex * texUnpack;')
							 | 
						||
| 
								 | 
							
								            if con_depth.is_elem('tex1'):
							 | 
						||
| 
								 | 
							
								                vert.add_out('vec2 texCoord1') ## vs only, remove out
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('float texUnpack', link='_texUnpack')
							 | 
						||
| 
								 | 
							
								                vert.write_attrib('texCoord1 = tex1 * texUnpack;')
							 | 
						||
| 
								 | 
							
								            if con_depth.is_elem('col'):
							 | 
						||
| 
								 | 
							
								                vert.add_out('vec3 vcolor')
							 | 
						||
| 
								 | 
							
								                vert.write_attrib('vcolor = col.rgb;')
							 | 
						||
| 
								 | 
							
								            vert.write('wposition += wnormal * disp;')
							 | 
						||
| 
								 | 
							
								            if shadowmap:
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('mat4 LVP', '_lightViewProjectionMatrix')
							 | 
						||
| 
								 | 
							
								                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')
							 | 
						||
| 
								 | 
							
								            vert.write('wnormal = normalize(N * vec3(nor.xy, pos.w));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            make_tess.tesc_levels(tesc, rpdat.lnx_tess_shadows_inner, rpdat.lnx_tess_shadows_outer)
							 | 
						||
| 
								 | 
							
								            make_tess.interpolate(tese, 'wposition', 3)
							 | 
						||
| 
								 | 
							
								            make_tess.interpolate(tese, 'wnormal', 3, normalize=True)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if not shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								                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')
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('float texUnpack', link='_texUnpack')
							 | 
						||
| 
								 | 
							
								                vert.write('texCoord = tex * texUnpack;')
							 | 
						||
| 
								 | 
							
								                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')
							 | 
						||
| 
								 | 
							
								                vert.write('vcolor = col.rgb;')
							 | 
						||
| 
								 | 
							
								                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')
							 | 
						||
| 
								 | 
							
								                tese.write('wposition += wnormal * disp;')
							 | 
						||
| 
								 | 
							
								                tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
							 | 
						||
| 
								 | 
							
								                tese.write('wposition += wnormal * disp;')
							 | 
						||
| 
								 | 
							
								                tese.write('gl_Position = VP * vec4(wposition, 1.0);')
							 | 
						||
| 
								 | 
							
								    # No displacement
							 | 
						||
| 
								 | 
							
								    else:
							 | 
						||
| 
								 | 
							
								        frag.ins = vert.outs
							 | 
						||
| 
								 | 
							
								        billboard = mat_state.material.lnx_billboard
							 | 
						||
| 
								 | 
							
								        if shadowmap:
							 | 
						||
| 
								 | 
							
								            if billboard == 'spherical':
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrixSphere')
							 | 
						||
| 
								 | 
							
								            elif billboard == 'cylindrical':
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrixCylinder')
							 | 
						||
| 
								 | 
							
								            else: # off
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrix')
							 | 
						||
| 
								 | 
							
								            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:
							 | 
						||
| 
								 | 
							
								            if not parse_custom_particle and not shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								                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')
							 | 
						||
| 
								 | 
							
								                vert.add_uniform('float texUnpack', link='_texUnpack')
							 | 
						||
| 
								 | 
							
								                if mat_state.material.lnx_tilesheet_flag:
							 | 
						||
| 
								 | 
							
								                    vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
							 | 
						||
| 
								 | 
							
								                    vert.write('texCoord = tex * texUnpack + tilesheetOffset;')
							 | 
						||
| 
								 | 
							
								                else:
							 | 
						||
| 
								 | 
							
								                    vert.write('texCoord = tex * texUnpack;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            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')
							 | 
						||
| 
								 | 
							
								                vert.write('vcolor = col.rgb;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								        frag.add_out('vec4 fragColor')
							 | 
						||
| 
								 | 
							
								        vert.add_out('vec4 wvpposition')
							 | 
						||
| 
								 | 
							
								        vert.write('wvpposition = gl_Position;')
							 | 
						||
| 
								 | 
							
								        frag.write('float depth = (wvpposition.z / wvpposition.w) * 0.5 + 0.5;')
							 | 
						||
| 
								 | 
							
								        frag.write('vec3 color = basecol;')
							 | 
						||
| 
								 | 
							
								        frag.write('color *= 1.0 - opacity;')
							 | 
						||
| 
								 | 
							
								        frag.write('fragColor = vec4(color, depth);')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if parse_opacity and not shadowmap_transparent:
							 | 
						||
| 
								 | 
							
								        if mat_state.material.lnx_discard:
							 | 
						||
| 
								 | 
							
								            opac = mat_state.material.lnx_discard_opacity_shadows
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            opac = '1.0'
							 | 
						||
| 
								 | 
							
								        frag.write('if (opacity < {0}) discard;'.format(opac))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    make_finalize.make(con_depth)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])
							 | 
						||
| 
								 | 
							
								    assets.fs_equal(con_depth, assets.shader_cons['depth_frag'])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return con_depth
							 |