Emission fixes

This commit is contained in:
luboslenco 2019-01-23 18:09:53 +01:00
parent 00602d721d
commit 89cad4e25e
5 changed files with 76 additions and 13 deletions

View file

@ -166,7 +166,7 @@ in vec3 viewRay;
out vec4 fragColor;
void main() {
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, metallic/roughness, depth
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, metallic/roughness, matid
vec3 n;
n.z = 1.0 - abs(g0.x) - abs(g0.y);
@ -278,6 +278,13 @@ void main() {
// #endif
#endif
#ifdef _Emission
if (g0.a == 1.0) {
fragColor.rgb += g1.rgb; // materialid
albedo = vec3(0.0);
}
#endif
// Show voxels
// vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99);
// vec3 direction = vec3(0.0, 0.0, -1.0);

View file

@ -71,6 +71,7 @@ def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface,
particle_info['angular_velocity'] = False
sample_bump = False
sample_bump_res = ''
wrd = bpy.data.worlds['Arm']
# Surface
if parse_surface or parse_opacity:
@ -79,13 +80,15 @@ def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface,
normal_parsed = False
curshader = frag
out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity = parse_shader_input(node.inputs[0])
out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity, out_emission = parse_shader_input(node.inputs[0])
if parse_surface:
frag.write('basecol = {0};'.format(out_basecol))
frag.write('roughness = {0};'.format(out_roughness))
frag.write('metallic = {0};'.format(out_metallic))
frag.write('occlusion = {0};'.format(out_occlusion))
frag.write('specular = {0};'.format(out_specular))
if '_Emission' in wrd.world_defs:
frag.write('emission = {0};'.format(out_emission))
if parse_opacity:
frag.write('opacity = {0};'.format(out_opacity))
@ -149,7 +152,8 @@ def parse_shader_input(inp):
out_occlusion = '1.0'
out_specular = '1.0'
out_opacity = '1.0'
return out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity
out_emission = '0.0'
return out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity, out_emission
def parse_shader(node, socket):
global emission_found
@ -159,6 +163,7 @@ def parse_shader(node, socket):
out_occlusion = '1.0'
out_specular = '1.0'
out_opacity = '1.0'
out_emission = '0.0'
if node.type == 'GROUP':
if node.node_tree.name.startswith('Armory PBR'):
@ -177,9 +182,10 @@ def parse_shader(node, socket):
parse_normal_map_color_input(node.inputs[5])
# Emission
if node.inputs[6].is_linked or node.inputs[6].default_value != 0.0:
out_emission = parse_value_input(node.inputs[6])
out_emission = '1.0'
emission_strength = parse_value_input(node.inputs[6])
emission_found = True
out_basecol = '({0} + vec3({1} * 100.0))'.format(out_basecol, out_emission)
out_basecol = '({0} * {1})'.format(out_basecol, emission_strength)
if parse_opacity:
out_opacity = parse_value_input(node.inputs[1])
else:
@ -195,26 +201,28 @@ def parse_shader(node, socket):
fac_inv_var = node_name(node.name) + '_fac_inv'
curshader.write('{0}float {1} = {2};'.format(prefix, fac_var, fac))
curshader.write('{0}float {1} = 1.0 - {2};'.format(prefix, fac_inv_var, fac_var))
bc1, rough1, met1, occ1, spec1, opac1 = parse_shader_input(node.inputs[1])
bc2, rough2, met2, occ2, spec2, opac2 = parse_shader_input(node.inputs[2])
bc1, rough1, met1, occ1, spec1, opac1, emi1 = parse_shader_input(node.inputs[1])
bc2, rough2, met2, occ2, spec2, opac2, emi2 = parse_shader_input(node.inputs[2])
if parse_surface:
out_basecol = '({0} * {3} + {1} * {2})'.format(bc1, bc2, fac_var, fac_inv_var)
out_roughness = '({0} * {3} + {1} * {2})'.format(rough1, rough2, fac_var, fac_inv_var)
out_metallic = '({0} * {3} + {1} * {2})'.format(met1, met2, fac_var, fac_inv_var)
out_occlusion = '({0} * {3} + {1} * {2})'.format(occ1, occ2, fac_var, fac_inv_var)
out_specular = '({0} * {3} + {1} * {2})'.format(spec1, spec2, fac_var, fac_inv_var)
out_emission = '({0} * {3} + {1} * {2})'.format(emi1, emi2, fac_var, fac_inv_var)
if parse_opacity:
out_opacity = '({0} * {3} + {1} * {2})'.format(opac1, opac2, fac_var, fac_inv_var)
elif node.type == 'ADD_SHADER':
bc1, rough1, met1, occ1, spec1, opac1 = parse_shader_input(node.inputs[0])
bc2, rough2, met2, occ2, spec2, opac2 = parse_shader_input(node.inputs[1])
bc1, rough1, met1, occ1, spec1, opac1, emi1 = parse_shader_input(node.inputs[0])
bc2, rough2, met2, occ2, spec2, opac2, emi2 = parse_shader_input(node.inputs[1])
if parse_surface:
out_basecol = '({0} + {1})'.format(bc1, bc2)
out_roughness = '({0} * 0.5 + {1} * 0.5)'.format(rough1, rough2)
out_metallic = '({0} * 0.5 + {1} * 0.5)'.format(met1, met2)
out_occlusion = '({0} * 0.5 + {1} * 0.5)'.format(occ1, occ2)
out_specular = '({0} * 0.5 + {1} * 0.5)'.format(spec1, spec2)
out_emission = '({0} * 0.5 + {1} * 0.5)'.format(emi1, emi2)
if parse_opacity:
out_opacity = '({0} * 0.5 + {1} * 0.5)'.format(opac1, opac2)
@ -270,9 +278,10 @@ def parse_shader(node, socket):
if parse_surface:
# Multiply basecol
out_basecol = parse_vector_input(node.inputs[0])
out_emission = '1.0'
emission_found = True
strength = parse_value_input(node.inputs[1])
out_basecol = '({0} * ({1} * 100.0))'.format(out_basecol, strength)
emission_strength = parse_value_input(node.inputs[1])
out_basecol = '({0} * {1})'.format(out_basecol, emission_strength)
elif node.type == 'BSDF_GLASS':
if parse_surface:
@ -325,7 +334,7 @@ def parse_shader(node, socket):
elif node.type == 'VOLUME_SCATTER':
pass
return out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity
return out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity, out_emission
def parse_displacement_input(inp):
if inp.is_linked:

View file

@ -68,6 +68,7 @@ def make_base(con_mesh, parse_opacity):
global write_material_attribs
global write_material_attribs_post
global write_vertex_attribs
wrd = bpy.data.worlds['Arm']
vert = con_mesh.make_vert()
frag = con_mesh.make_frag()
@ -110,6 +111,8 @@ def make_base(con_mesh, parse_opacity):
frag.write('float metallic;')
frag.write('float occlusion;')
frag.write('float specular;')
if '_Emission' in wrd.world_defs:
frag.write('float emission;')
if parse_opacity:
frag.write('float opacity;')
cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity)
@ -242,7 +245,12 @@ def make_deferred(con_mesh):
frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));')
frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);')
frag.write('fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0);')
if '_Emission' in wrd.world_defs:
frag.write('float matid = 0.0;')
frag.write('if (emission > 0) matid = 1.0;')
else:
frag.write('const float matid = 0.0;')
frag.write('fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), matid);')
frag.write('fragColor[1] = vec4(basecol.rgb, packFloat2(occlusion, specular));')
if '_gbuffer2' in wrd.world_defs:
@ -284,6 +292,8 @@ def make_forward_mobile(con_mesh):
frag.write('float metallic;')
frag.write('float occlusion;')
frag.write('float specular;')
if '_Emission' in wrd.world_defs:
frag.write('float emission;')
arm_discard = mat_state.material.arm_discard
blend = mat_state.material.arm_blending
@ -434,6 +444,8 @@ def make_forward_solid(con_mesh):
frag.write('float metallic;')
frag.write('float occlusion;')
frag.write('float specular;')
if '_Emission' in wrd.world_defs:
frag.write('float emission;')
arm_discard = mat_state.material.arm_discard
blend = mat_state.material.arm_blending
@ -661,3 +673,9 @@ def make_forward_base(con_mesh, parse_opacity=False):
frag.write('indirectSpecular *= f0 * envBRDF.x + envBRDF.y;')
frag.write('indirect += indirectSpecular * voxelgiSpec * specular;')
frag.write('}')
if '_Emission' in wrd.world_defs:
frag.write('if (emission > 0.0) {')
frag.write(' direct = vec3(0.0);')
frag.write(' indirect += basecol;')
frag.write('}')

View file

@ -31,6 +31,9 @@ def build(material, mat_users, mat_armusers):
wrd = bpy.data.worlds['Arm']
rpdat = arm.utils.get_rp()
rpasses = mat_utils.get_rpasses(material)
is_emissive = mat_utils.is_emmisive(material)
if is_emissive and '_Emission' not in wrd.world_defs:
wrd.world_defs += '_Emission'
matname = arm.utils.safesrc(arm.utils.asset_name(material))
rel_path = arm.utils.build_dir() + '/compiled/Shaders/'
full_path = arm.utils.get_fp() + '/' + rel_path

View file

@ -75,3 +75,29 @@ def is_transluc_type(node):
(node.type == 'GROUP' and node.node_tree.name.startswith('Armory PBR') and (node.inputs[1].is_linked or node.inputs[1].default_value != 1.0)):
return True
return False
def is_emmisive(material):
nodes = material.node_tree.nodes
output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')
if output_node == None or output_node.inputs[0].is_linked == False:
return False
surface_node = output_node.inputs[0].links[0].from_node
return is_emmisive_traverse(surface_node)
def is_emmisive_traverse(node):
# TODO: traverse groups
if is_emmisive_type(node):
return True
for inp in node.inputs:
if inp.is_linked:
res = is_emmisive_traverse(inp.links[0].from_node)
if res:
return True
return False
def is_emmisive_type(node):
if node.type == 'EMISSION' or \
(node.type == 'GROUP' and node.node_tree.name.startswith('Armory PBR') and (node.inputs[6].is_linked or node.inputs[6].default_value != 0.0)):
return True
return False