Decals pass

This commit is contained in:
Lubos Lenco 2017-05-24 11:04:15 +02:00
parent 52efec23da
commit cfa18ecc00
10 changed files with 97 additions and 30 deletions

View file

@ -32,12 +32,13 @@ NodeTypeMesh = 2
NodeTypeLamp = 3
NodeTypeCamera = 4
NodeTypeSpeaker = 5
NodeTypeDecal = 6
AnimationTypeSampled = 0
AnimationTypeLinear = 1
AnimationTypeBezier = 2
ExportEpsilon = 1.0e-6
structIdentifier = ["object", "bone_object", "mesh_object", "lamp_object", "camera_object", "speaker_object"]
structIdentifier = ["object", "bone_object", "mesh_object", "lamp_object", "camera_object", "speaker_object", "decal_object"]
subtranslationName = ["xloc", "yloc", "zloc"]
subrotationName = ["xrot", "yrot", "zrot"]
@ -1295,6 +1296,8 @@ class ArmoryExporter:
o['material_refs'].append(bobject.override_material_name)
else: # Export assigned material
self.export_material_ref(bobject, bobject.material_slots[i].material, i, o)
if bobject.material_slots[i].material.decal:
o['type'] = 'decal_object'
# No material, mimic cycles and assign default
if len(o['material_refs']) == 0:
self.use_default_material(bobject, o)
@ -2417,7 +2420,6 @@ class ArmoryExporter:
self.defaultSkinMaterialObjects = []
self.materialToArmObjectDict = dict()
self.objectToArmObjectDict = dict()
self.uvprojectUsersArray = [] # For processing decals
self.active_layers = []
for i in range(0, len(self.scene.layers)):
if self.scene.layers[i] == True:
@ -2524,8 +2526,6 @@ class ArmoryExporter:
if not self.camera_spawned:
log.warn('No camera found in active scene layers')
self.postprocess()
if self.restoreFrame:
self.scene.frame_set(originalFrame, originalSubframe)
@ -2671,24 +2671,9 @@ class ArmoryExporter:
wrd.generate_ocean = True
# Take position and bounds
wrd.generate_ocean_level = bobject.location.z
elif m.type == 'UV_PROJECT' and m.show_render:
self.uvprojectUsersArray.append(bobject)
return export_object
def postprocess(self):
# Check uv project users
for bobject in self.uvprojectUsersArray:
for m in bobject.modifiers:
if m.type == 'UV_PROJECT':
# Mark all projectors as decals
for pnode in m.projectors:
o = self.objectToArmObjectDict[bobject]
po = self.objectToArmObjectDict[pnode.object]
po['type'] = 'decal_object'
po['material_refs'] = [o['material_refs'][0] + '_decal'] # Will fetch a proper context used in render path
break
def post_export_object(self, bobject, o, type):
# Animation setup
if arm.utils.is_bone_animation_enabled(bobject) or arm.utils.is_object_animation_enabled(bobject):

View file

@ -139,8 +139,8 @@ def make_deferred(cam):
if cam.rp_volumetriclight:
links.new(nodes['Deferred Light'].outputs[0], nodes['Volumetric Light'].inputs[0])
# if not cam.rp_decals:
# relink('Set Target.005', 'SSAO')
if not cam.rp_decals:
relink('Set Target Decal', 'SSAO')
if not cam.rp_ssao:
relink('SSAO', 'Deferred Indirect')

View file

@ -17,6 +17,8 @@
import arm.material.cycles_functions as c_functions
import arm.material.cycles_state as c_state
basecol_texname = ''
def parse(nodes, vert, frag, geom, tesc, tese, parse_surface=True, parse_opacity=True, parse_displacement=True, basecol_only=False):
output_node = node_by_type(nodes, 'OUTPUT_MATERIAL')
if output_node != None:
@ -37,6 +39,7 @@ def parse_output(node, _vert, _frag, _geom, _tesc, _tese, _parse_surface, _parse
global parsing_basecol
global parse_teximage_vector
global basecol_only
global basecol_texname
vert = _vert
frag = _frag
geom = _geom
@ -47,6 +50,7 @@ def parse_output(node, _vert, _frag, _geom, _tesc, _tese, _parse_surface, _parse
parsing_basecol = False
parse_teximage_vector = True
basecol_only = _basecol_only
basecol_texname = ''
# Surface
if parse_surface or parse_opacity:
@ -679,6 +683,8 @@ def store_var_name(node):
def texture_store(node, tex, tex_name, to_linear=False):
global parse_teximage_vector
global parsing_basecol
global basecol_texname
c_state.mat_bind_texture(tex)
c_state.mat_add_elem('tex', 2)
curshader.add_uniform('sampler2D {0}'.format(tex_name))
@ -693,6 +699,8 @@ def texture_store(node, tex, tex_name, to_linear=False):
curshader.write('vec4 {0} = texture({1}, {2}.xy);'.format(tex_store, tex_name, uv_name))
if to_linear:
curshader.write('{0}.rgb = pow({0}.rgb, vec3(2.2));'.format(tex_store))
if parsing_basecol:
basecol_texname = tex_store
return tex_store
def parse_vector(node, socket):
@ -848,7 +856,7 @@ def parse_normal_map_color_input(inp, str_inp=None):
frag.write_pre = True
parse_teximage_vector = False # Force texCoord for normal map image vector
defplus = c_state.get_rp_renderer() == 'Deferred Plus'
if not c_state.get_arm_export_tangents() or defplus: # Compute TBN matrix
if not c_state.get_arm_export_tangents() or defplus or c_state.mat_get_material().decal: # Compute TBN matrix
frag.write('vec3 texn = ({0}) * 2.0 - 1.0;'.format(parse_vector_input(inp)))
frag.add_include('../../Shaders/std/normals.glsl')
if defplus:

View file

@ -1,5 +1,70 @@
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
import arm.utils
def make(context_id):
pass
# con_decal = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise' })
# return con_transluc
con_decal = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise',
'blend_source': 'source_alpha',
'blend_destination': 'inverse_source_alpha',
'blend_operation': 'add',
'color_write_alpha': False
})
vert = con_decal.make_vert()
frag = con_decal.make_frag()
geom = None
tesc = None
tese = None
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
vert.add_uniform('mat3 N', '_normalMatrix')
vert.add_out('vec4 wvpposition')
vert.add_out('vec3 wnormal')
vert.write('wnormal = N * vec3(0.0, 0.0, 1.0);')
vert.write('wvpposition = WVP * vec4(pos, 1.0);')
vert.write('gl_Position = wvpposition;')
frag.add_include('../../Shaders/compiled.glsl')
frag.add_include('../../Shaders/std/gbuffer.glsl')
frag.ins = vert.outs
frag.add_uniform('sampler2D gbufferD')
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
frag.add_uniform('mat4 invW', '_inverseWorldMatrix')
frag.add_uniform('vec3 eye', '_cameraPosition')
frag.add_out('vec4[2] fragColor')
frag.write_main_header(' vec3 n = normalize(wnormal);')
frag.write_main_header(' vec2 screenPosition = wvpposition.xy / wvpposition.w;')
frag.write_main_header(' vec2 depthCoord = screenPosition * 0.5 + 0.5;')
frag.write_main_header(' float depth = texture(gbufferD, depthCoord).r * 2.0 - 1.0;')
frag.write_main_header(' vec3 wpos = getPos2(invVP, depth, depthCoord);')
frag.write_main_header(' vec4 mpos = invW * vec4(wpos, 1.0);')
frag.write_main_header(' if (abs(mpos.x) > 1.0) discard;')
frag.write_main_header(' if (abs(mpos.y) > 1.0) discard;')
frag.write_main_header(' if (abs(mpos.z) > 1.0) discard;')
frag.write_main_header(' vec3 vVec = normalize(eye - wpos);')
frag.write_main_header(' vec2 texCoord = mpos.xy * 0.5 + 0.5;')
frag.write('vec3 basecol;')
frag.write('float roughness;')
frag.write('float metallic;')
frag.write('float occlusion;')
cycles.parse(mat_state.nodes, vert, frag, geom, tesc, tese, parse_opacity=False)
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);')
if cycles.basecol_texname == '':
frag.write('const float alpha = 1.0;')
else:
frag.write('const float alpha = {0}.a;'.format(cycles.basecol_texname))
frag.write('fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), alpha);')
frag.write('fragColor[1] = vec4(basecol.rgb, alpha);')
return con_decal

View file

@ -25,10 +25,9 @@ def get_rpasses(material):
# if material.depthpass:
# ar.append('depth')
# if material.decal:
# ar.append('decal')
if material.overlay:
if material.decal:
ar.append('decal')
elif material.overlay:
ar.append('overlay')
elif is_transluc(material):
ar.append('translucent')

View file

@ -510,7 +510,8 @@ def init_properties():
bpy.types.Material.export_tangents = bpy.props.BoolProperty(name="Export Tangents", default=False)
bpy.types.Material.vertex_structure = bpy.props.StringProperty(name="Vertex Structure", default='')
bpy.types.Material.skip_context = bpy.props.StringProperty(name="Skip Context", default='')
bpy.types.Material.overlay = bpy.props.BoolProperty(name="X-Ray", default=False)
bpy.types.Material.overlay = bpy.props.BoolProperty(name="Overlay", default=False)
bpy.types.Material.decal = bpy.props.BoolProperty(name="Decal", default=False)
bpy.types.Material.override_cull = bpy.props.BoolProperty(name="Override Cull-Mode", default=False)
bpy.types.Material.override_cull_mode = EnumProperty(
items = [('none', 'None', 'None'),

View file

@ -26,6 +26,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Off'
cam.rp_overlays_state = 'Off'
cam.rp_decals_state = 'Off'
cam.rp_sss_state = 'Off'
cam.rp_hdr = False
cam.rp_worldnodes = False
cam.rp_clearbackground = True
@ -49,6 +50,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Off'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
@ -71,6 +73,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Off'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
@ -93,6 +96,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Off'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
@ -115,6 +119,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Off'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
@ -142,6 +147,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Off'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
@ -165,6 +171,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Off'
cam.rp_overlays_state = 'Off'
cam.rp_decals_state = 'Off'
cam.rp_sss_state = 'Off'
cam.rp_hdr = False
cam.rp_worldnodes = False
cam.rp_clearbackground = True
@ -188,6 +195,7 @@ def set_preset(self, context, preset):
cam.rp_translucency_state = 'Off'
cam.rp_overlays_state = 'Off'
cam.rp_decals_state = 'Off'
cam.rp_sss_state = 'Off'
cam.rp_hdr = False
cam.rp_worldnodes = False
cam.rp_clearbackground = True

View file

@ -290,6 +290,7 @@ class MaterialPropsPanel(bpy.types.Panel):
layout.prop(bpy.data.worlds['Arm'], 'arm_material_advanced')
if bpy.data.worlds['Arm'].arm_material_advanced:
layout.prop(mat, 'overlay')
layout.prop(mat, 'decal')
layout.prop(mat, 'override_cull')
if mat.override_cull:
layout.prop(mat, 'override_cull_mode')

Binary file not shown.

Binary file not shown.