UI merging

This commit is contained in:
Lubos Lenco 2017-08-19 12:10:06 +02:00
parent b4325b2e27
commit 6984325499
18 changed files with 808 additions and 861 deletions

View file

@ -1103,7 +1103,7 @@ class ArmoryExporter:
if not bone.parent:
self.process_bone(bone)
if bobject.type != 'MESH' or bobject.instanced_children == False:
if bobject.type != 'MESH' or bobject.arm_instanced == False:
for subbobject in bobject.children:
self.process_bobject(subbobject)
@ -1296,12 +1296,9 @@ class ArmoryExporter:
o['material_refs'] = []
for i in range(len(bobject.material_slots)):
if bobject.override_material: # Overwrite material slot
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 != None and bobject.material_slots[i].material.decal:
o['type'] = 'decal_object'
self.export_material_ref(bobject, bobject.material_slots[i].material, i, o)
if bobject.material_slots[i].material != None and 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)
@ -1425,7 +1422,7 @@ class ArmoryExporter:
if not hasattr(o, 'children') and len(bobject.children) > 0:
o['children'] = []
if bobject.type != 'MESH' or bobject.instanced_children == False:
if bobject.type != 'MESH' or bobject.arm_instanced == False:
for subbobject in bobject.children:
if subbobject.parent_type != "BONE":
self.export_object(subbobject, scene, None, o)
@ -2097,10 +2094,11 @@ class ArmoryExporter:
o['far_plane'] = objref.lamp_clip_end
o['fov'] = objref.lamp_fov
o['shadows_bias'] = objref.lamp_shadows_bias
if bpy.data.cameras[0].rp_shadowmap == 'None':
wrd = bpy.data.worlds['Arm']
if wrd.rp_shadowmap == 'None':
o['shadowmap_size'] = 0
else:
o['shadowmap_size'] = int(bpy.data.cameras[0].rp_shadowmap)
o['shadowmap_size'] = int(wrd.rp_shadowmap)
if o['type'] == 'sun': # Scale bias for ortho light matrix
o['shadows_bias'] *= 10.0
if (objtype == 'POINT' or objtype == 'SPOT') and objref.shadow_soft_size > 0.1: # No sun for now
@ -2151,7 +2149,8 @@ class ArmoryExporter:
o['far_plane'] = objref.clip_end
o['fov'] = objref.angle
if bpy.data.worlds['Arm'].arm_play_camera != 'Scene' and ArmoryExporter.in_viewport:
wrd = bpy.data.worlds['Arm']
if wrd.arm_play_camera != 'Scene' and ArmoryExporter.in_viewport:
pw = self.get_viewport_panels_w()
# Tool shelf and properties hidden
proj, is_persp = self.get_viewport_projection_matrix()
@ -2172,7 +2171,7 @@ class ArmoryExporter:
o['mirror_resolution_y'] = int(objref.mirror_resolution_y)
o['frustum_culling'] = objref.frustum_culling
o['render_path'] = objref.renderpath_path + '/' + objref.renderpath_path # Same file name and id
o['render_path'] = wrd.renderpath_path + '/' + wrd.renderpath_path # Same file name and id
if self.scene.world != None and 'Background' in self.scene.world.node_tree.nodes: # TODO: parse node tree
background_node = self.scene.world.node_tree.nodes['Background']
@ -2322,27 +2321,26 @@ class ArmoryExporter:
self.make_default_mat('armdefaultskin', self.defaultSkinMaterialObjects)
# Auto-enable render-path featues
if len(bpy.data.cameras) > 0:
rebuild_rp = False
cam = bpy.data.cameras[0]
if cam.rp_translucency_state == 'Auto' and cam.rp_translucency != transluc_used:
cam.rp_translucency = transluc_used
rebuild_rp = True
if cam.rp_overlays_state == 'Auto' and cam.rp_overlays != overlays_used:
cam.rp_overlays = overlays_used
rebuild_rp = True
if cam.rp_decals_state == 'Auto' and cam.rp_decals != decals_used:
cam.rp_decals = decals_used
rebuild_rp = True
# if cam.rp_sss_state == 'Auto' and cam.rp_sss != sss_used:
# cam.rp_sss = sss_used
# rebuild_rp = True
if rebuild_rp:
self.rebuild_render_path(cam)
rebuild_rp = False
wrd = bpy.data.worlds['Arm']
if wrd.rp_translucency_state == 'Auto' and wrd.rp_translucency != transluc_used:
wrd.rp_translucency = transluc_used
rebuild_rp = True
if wrd.rp_overlays_state == 'Auto' and wrd.rp_overlays != overlays_used:
wrd.rp_overlays = overlays_used
rebuild_rp = True
if wrd.rp_decals_state == 'Auto' and wrd.rp_decals != decals_used:
wrd.rp_decals = decals_used
rebuild_rp = True
# if wrd.rp_sss_state == 'Auto' and wrd.rp_sss != sss_used:
# wrd.rp_sss = sss_used
# rebuild_rp = True
if rebuild_rp:
self.rebuild_render_path(wrd)
def rebuild_render_path(self, cam):
def rebuild_render_path(self, wrd):
# No shader invalidate required?
make_renderer.make_renderer(cam)
make_renderer.make_renderer(wrd)
# Rebuild modified path
assets_path = arm.utils.get_sdk_path() + 'armory/Assets/'
make_renderpath.build_node_trees(assets_path)
@ -2636,7 +2634,7 @@ class ArmoryExporter:
is_instanced = False
instance_offsets = None
for n in refs:
if n.instanced_children == True:
if n.arm_instanced == True:
is_instanced = True
# Save offset data
instance_offsets = [0.0, 0.0, 0.0] # Include parent
@ -2668,6 +2666,7 @@ class ArmoryExporter:
return is_instanced, instance_offsets
def preprocess(self):
wrd = bpy.data.worlds['Arm']
ArmoryExporter.export_all_flag = True
ArmoryExporter.export_physics = False # Indicates whether rigid body is exported
ArmoryExporter.export_navigation = False
@ -2679,21 +2678,19 @@ class ArmoryExporter:
ArmoryExporter.import_traits = [] # Referenced traits
ArmoryExporter.option_mesh_only = False
ArmoryExporter.option_mesh_per_file = True
ArmoryExporter.option_optimize_mesh = bpy.data.worlds['Arm'].arm_optimize_mesh
ArmoryExporter.option_minimize = bpy.data.worlds['Arm'].arm_minimize
ArmoryExporter.option_sample_animation = bpy.data.worlds['Arm'].arm_sampled_animation
ArmoryExporter.option_optimize_mesh = wrd.arm_optimize_mesh
ArmoryExporter.option_minimize = wrd.arm_minimize
ArmoryExporter.option_sample_animation = wrd.arm_sampled_animation
ArmoryExporter.sample_animation_flag = ArmoryExporter.option_sample_animation
# Only one render path for scene for now
# Used for material shader export and khafile
if len(bpy.data.cameras) > 0:
ArmoryExporter.renderpath_id = bpy.data.cameras[0].renderpath_id
ArmoryExporter.renderpath_passes = bpy.data.cameras[0].renderpath_passes.split('_')
ArmoryExporter.mesh_context = 'mesh'
ArmoryExporter.mesh_context_empty = ''
ArmoryExporter.shadows_context = 'shadowmap'
ArmoryExporter.translucent_context = 'translucent'
ArmoryExporter.overlay_context = 'overlay'
ArmoryExporter.renderpath_id = wrd.renderpath_id
ArmoryExporter.renderpath_passes = wrd.renderpath_passes.split('_')
ArmoryExporter.mesh_context = 'mesh'
ArmoryExporter.mesh_context_empty = ''
ArmoryExporter.shadows_context = 'shadowmap'
ArmoryExporter.translucent_context = 'translucent'
ArmoryExporter.overlay_context = 'overlay'
def preprocess_object(self, bobject): # Returns false if object should not be exported
export_object = True

View file

@ -68,7 +68,7 @@ def on_scene_update_post(context):
krom_location, krom_path = arm.utils.krom_paths()
fp = krom_location
resx, resy = arm.utils.get_render_resolution(arm.utils.get_active_scene())
cformat = bpy.data.cameras[0].rp_rendercapture_format
cformat = bpy.data.worlds['Arm'].rp_rendercapture_format
if cformat == '8bit':
cbits = 4
ctype = numpy.uint8
@ -227,7 +227,7 @@ def on_load_post(context):
wrd = bpy.data.worlds['Arm']
wrd.arm_recompile = True
for lib in wrd.my_librarytraitlist:
for lib in wrd.arm_librarylist:
if lib.enabled_prop:
fp = arm.utils.get_fp() + '/Libraries/' + lib.name
if fp not in appended_py_paths and os.path.exists(fp + '/blender.py'):

View file

@ -6,7 +6,292 @@ group = None
nodes = None
links = None
def make_renderer(cam):
updating_preset = False
def set_preset(self, context, preset):
global updating_preset
wrd = bpy.data.worlds['Arm']
updating_preset = True
if preset == 'Low':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'PBR'
wrd.rp_shadowmap = '1024'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_clearbackground = True
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = False
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'None'
wrd.rp_compositornodes = False
wrd.rp_volumetriclight = False
wrd.rp_ssao = False
wrd.rp_ssr = False
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'Forward':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'PBR'
wrd.rp_shadowmap = '2048'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = True
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'SMAA'
wrd.rp_compositornodes = True
wrd.rp_volumetriclight = False
wrd.rp_ssao = True
wrd.rp_ssr = True
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'Deferred':
wrd.rp_renderer = 'Deferred'
wrd.material_model = 'PBR'
wrd.rp_shadowmap = '2048'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = True
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'FXAA'
wrd.rp_compositornodes = True
wrd.rp_volumetriclight = False
wrd.rp_ssao = True
wrd.rp_ssr = False
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'Max':
wrd.rp_renderer = 'Deferred'
wrd.material_model = 'PBR'
wrd.rp_shadowmap = '4096'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = True
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'TAA'
wrd.rp_compositornodes = True
wrd.rp_volumetriclight = False
wrd.rp_ssao = True
wrd.rp_ssr = True
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'Render Capture':
wrd.rp_renderer = 'Deferred'
wrd.rp_shadowmap = '8192'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = True
wrd.rp_voxelgi_resolution = '256'
wrd.rp_render_to_texture = True
wrd.rp_supersampling = '2'
wrd.rp_antialiasing = 'TAA'
wrd.rp_compositornodes = True
wrd.rp_volumetriclight = False
wrd.rp_ssao = True
wrd.rp_ssr = True
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = True
wrd.rp_rendercapture_format = '8bit'
wrd.rp_motionblur = 'None'
wrd.material_model = 'Cycles'
wrd.generate_pcss_state = 'On'
elif preset == 'Deferred Plus':
wrd.rp_renderer = 'Deferred Plus'
wrd.material_model = 'PBR'
wrd.rp_shadowmap = '4096'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = True
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'TAA'
wrd.rp_compositornodes = True
wrd.rp_volumetriclight = False
wrd.rp_ssao = True
wrd.rp_ssr = True
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'VR Low':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
wrd.rp_shadowmap = '1024'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_clearbackground = True
wrd.rp_stereo = True
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = False
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'None'
wrd.rp_compositornodes = False
wrd.rp_volumetriclight = False
wrd.rp_ssao = False
wrd.rp_ssr = False
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'Mobile Low':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
wrd.rp_shadowmap = '1024'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_clearbackground = True
wrd.rp_stereo = False
wrd.rp_greasepencil = False
wrd.rp_voxelgi = False
wrd.rp_render_to_texture = False
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'None'
wrd.rp_compositornodes = False
wrd.rp_volumetriclight = False
wrd.rp_ssao = False
wrd.rp_ssr = False
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
elif preset == 'Grease Pencil':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
wrd.rp_shadowmap = 'None'
wrd.rp_meshes = False
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_clearbackground = True
wrd.rp_stereo = False
wrd.rp_greasepencil = True
wrd.rp_render_to_texture = False
wrd.rp_supersampling = '1'
wrd.rp_antialiasing = 'None'
wrd.rp_compositornodes = False
wrd.rp_volumetriclight = False
wrd.rp_ssao = False
wrd.rp_ssr = False
wrd.rp_dfrs = False
wrd.rp_dfao = False
wrd.rp_dfgi = False
wrd.rp_bloom = False
wrd.rp_eyeadapt = False
wrd.rp_rendercapture = False
wrd.rp_motionblur = 'None'
updating_preset = False
set_renderpath(self, context)
def set_renderpath(self, context):
global updating_preset
if updating_preset == True:
return
# assets.invalidate_compiled_data(self, context)
assets.invalidate_shader_cache(self, context)
make_renderer.make_renderer(bpy.data.worlds['Arm'])
bpy.data.worlds['Arm'].renderpath_path = 'armory_default'
def make_renderer(wrd):
global group
global nodes
global links
@ -14,24 +299,24 @@ def make_renderer(cam):
if bpy.data.filepath.endswith('arm_data.blend'): # Prevent load in library itself
return
if cam.rp_renderer == 'Forward':
if wrd.rp_renderer == 'Forward':
load_library('forward_path', 'armory_default')
group = bpy.data.node_groups['armory_default']
nodes = group.nodes
links = group.links
make_forward(cam)
elif cam.rp_renderer == 'Deferred':
make_forward(wrd)
elif wrd.rp_renderer == 'Deferred':
load_library('deferred_path', 'armory_default')
group = bpy.data.node_groups['armory_default']
nodes = group.nodes
links = group.links
make_deferred(cam)
elif cam.rp_renderer == 'Deferred Plus':
make_deferred(wrd)
elif wrd.rp_renderer == 'Deferred Plus':
load_library('deferred_plus_path', 'armory_default')
group = bpy.data.node_groups['armory_default']
nodes = group.nodes
links = group.links
make_deferred_plus(cam)
make_deferred_plus(wrd)
def relink(start_node, next_node):
if len(nodes[start_node].inputs[0].links) > 0:
@ -40,14 +325,14 @@ def relink(start_node, next_node):
links.remove(l)
links.new(n.outputs[0], nodes[next_node].inputs[0])
def make_forward(cam):
def make_forward(wrd):
nodes['Begin'].inputs[1].default_value = cam.rp_hdr
nodes['Screen'].inputs[0].default_value = int(cam.rp_supersampling)
nodes['Begin'].inputs[1].default_value = wrd.rp_hdr
nodes['Screen'].inputs[0].default_value = int(wrd.rp_supersampling)
if cam.rp_shadowmap != 'None':
if wrd.rp_shadowmap != 'None':
n = nodes['Shadow Map']
n.inputs[1].default_value = n.inputs[2].default_value = int(cam.rp_shadowmap)
n.inputs[1].default_value = n.inputs[2].default_value = int(wrd.rp_shadowmap)
else:
l = nodes['Begin'].outputs[0].links[0]
links.remove(l)
@ -55,67 +340,67 @@ def make_forward(cam):
relink('Bind Target Mesh SM', 'Draw Meshes Mesh') # No shadowmap bind
relink('Bind Target Transluc SM', 'Draw Meshes Transluc')
if cam.rp_stereo:
if cam.rp_shadowmap != 'None':
if wrd.rp_stereo:
if wrd.rp_shadowmap != 'None':
links.new(nodes['Bind Target Mesh SM'].outputs[0], nodes['Draw Stereo'].inputs[0])
else:
links.new(nodes['Clear Target Mesh'].outputs[0], nodes['Draw Stereo'].inputs[0])
links.new(nodes['Draw Stereo'].outputs[1], nodes['Draw Meshes Mesh'].inputs[0])
if cam.rp_greasepencil:
if cam.rp_shadowmap != 'None':
if wrd.rp_greasepencil:
if wrd.rp_shadowmap != 'None':
links.new(nodes['Bind Target Mesh SM'].outputs[0], nodes['Draw Grease Pencil'].inputs[0])
else:
links.new(nodes['Clear Target Mesh'].outputs[0], nodes['Draw Grease Pencil'].inputs[0])
links.new(nodes['Draw Grease Pencil'].outputs[0], nodes['Draw Meshes Mesh'].inputs[0])
if not cam.rp_meshes:
if not wrd.rp_meshes:
relink('Draw Meshes Mesh', 'Draw World')
if not cam.rp_worldnodes:
if not wrd.rp_worldnodes:
relink('Draw World', 'Set Target Accum')
if cam.rp_clearbackground:
if wrd.rp_clearbackground:
nodes['Clear Target Mesh'].inputs[1].default_value = True
if not cam.rp_render_to_texture:
if not wrd.rp_render_to_texture:
links.new(nodes['Framebuffer'].outputs[0], nodes['Set Target Mesh'].inputs[1])
if cam.rp_worldnodes:
if wrd.rp_worldnodes:
l = nodes['Draw World'].outputs[0].links[0]
elif cam.rp_greasepencil and not cam.rp_meshes:
elif wrd.rp_greasepencil and not wrd.rp_meshes:
l = nodes['Draw Grease Pencil'].outputs[0].links[0]
else:
l = nodes['Draw Meshes Mesh'].outputs[0].links[0]
links.remove(l)
if not cam.rp_translucency:
if not wrd.rp_translucency:
relink('Set Target Accum', 'Draw Compositor + FXAA')
last_node = 'Draw Compositor + FXAA'
if cam.rp_antialiasing == 'SMAA':
if wrd.rp_antialiasing == 'SMAA':
pass
elif cam.rp_antialiasing == 'TAA':
elif wrd.rp_antialiasing == 'TAA':
pass
elif cam.rp_antialiasing == 'FXAA':
elif wrd.rp_antialiasing == 'FXAA':
pass
elif cam.rp_antialiasing == 'None':
elif wrd.rp_antialiasing == 'None':
last_node = 'Draw Compositor'
relink('Draw Compositor + FXAA', 'Draw Compositor')
if cam.rp_overlays:
if wrd.rp_overlays:
links.new(last_node.outputs[0], nodes['Clear Target Overlay'].inputs[0])
def make_deferred(cam):
def make_deferred(wrd):
nodes['Begin'].inputs[1].default_value = cam.rp_hdr
nodes['Screen'].inputs[0].default_value = int(cam.rp_supersampling)
nodes['Begin'].inputs[1].default_value = wrd.rp_hdr
nodes['Screen'].inputs[0].default_value = int(wrd.rp_supersampling)
if cam.rp_voxelgi:
if wrd.rp_voxelgi:
n = nodes['Image 3D Voxels']
# if cam.rp_voxelgi_hdr:
# if wrd.rp_voxelgi_hdr:
# n.inputs[4].default_value = 'RGBA64'
links.new(nodes['Begin'].outputs[0], nodes['Branch Function Voxelize'].inputs[0])
links.new(nodes['Merge Stages Voxelize'].outputs[0], nodes['Set Target Mesh'].inputs[0])
res = int(cam.rp_voxelgi_resolution)
res = int(wrd.rp_voxelgi_resolution)
n.inputs[1].default_value = res
n.inputs[2].default_value = res
n.inputs[3].default_value = res
@ -128,9 +413,9 @@ def make_deferred(cam):
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light'].inputs[4])
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light.001'].inputs[4])
if cam.rp_shadowmap != 'None':
if wrd.rp_shadowmap != 'None':
n = nodes['Shadow Map']
n.inputs[1].default_value = n.inputs[2].default_value = int(cam.rp_shadowmap)
n.inputs[1].default_value = n.inputs[2].default_value = int(wrd.rp_shadowmap)
else:
l = nodes['Loop Lamps'].outputs[1].links[0]
links.remove(l)
@ -141,53 +426,53 @@ def make_deferred(cam):
links.remove(l)
relink('Bind Target Transluc SM', 'Draw Meshes Transluc')
if cam.rp_volumetriclight:
if wrd.rp_volumetriclight:
links.new(nodes['Deferred Light'].outputs[0], nodes['Volumetric Light'].inputs[0])
if not cam.rp_decals:
if not wrd.rp_decals:
relink('Set Target Decal', 'SSAO')
if not cam.rp_ssao:
if not wrd.rp_ssao:
relink('SSAO', 'Deferred Indirect')
l = nodes['Deferred Indirect'].inputs[3].links[0]
links.remove(l)
if not cam.rp_worldnodes:
if not wrd.rp_worldnodes:
relink('Draw World', 'Water')
if cam.rp_clearbackground:
if wrd.rp_clearbackground:
nodes['Clear Target Mesh'].inputs[1].default_value = True
if not cam.rp_ocean:
if not wrd.rp_ocean:
relink('Water', 'Set Target Accum')
if not cam.rp_translucency:
if not wrd.rp_translucency:
relink('Set Target Accum', 'Bloom')
if not cam.rp_bloom:
if not wrd.rp_bloom:
relink('Bloom', 'SSS')
if not cam.rp_sss:
if not wrd.rp_sss:
relink('SSS', 'SSR')
if not cam.rp_ssr:
if not wrd.rp_ssr:
relink('SSR', 'Draw Compositor')
if bpy.data.worlds['Arm'].generate_ssr_half_res: # TODO: Move to cam
if bpy.data.worlds['Arm'].generate_ssr_half_res:
links.new(nodes['ssra'].outputs[0], nodes['SSR'].inputs[2])
links.new(nodes['ssrb'].outputs[0], nodes['SSR'].inputs[3])
last_node = 'Draw Compositor'
if not cam.rp_compositornodes:
if not wrd.rp_compositornodes:
pass
if cam.rp_overlays:
if wrd.rp_overlays:
links.new(nodes[last_node].outputs[0], nodes['Clear Target Overlay'].inputs[0])
last_node = 'Draw Meshes Overlay'
links.new(nodes[last_node].outputs[0], nodes['SMAA'].inputs[0])
if cam.rp_antialiasing == 'SMAA':
if wrd.rp_antialiasing == 'SMAA':
last_node = 'SMAA'
elif cam.rp_antialiasing == 'TAA':
elif wrd.rp_antialiasing == 'TAA':
last_node = 'Copy'
links.new(nodes['SMAA'].outputs[0], nodes['TAA'].inputs[0])
links.new(nodes['Reroute.019'].outputs[0], nodes['SMAA'].inputs[5])
@ -196,37 +481,37 @@ def make_deferred(cam):
# Clear velocity
relink('Set Target Mesh', 'Set Target Veloc')
links.new(nodes['Clear Target Veloc'].outputs[0], nodes['Set Target Mesh'].inputs[0])
elif cam.rp_antialiasing == 'FXAA':
elif wrd.rp_antialiasing == 'FXAA':
last_node = 'FXAA'
relink('SMAA', 'FXAA')
elif cam.rp_antialiasing == 'None':
elif wrd.rp_antialiasing == 'None':
last_node = 'Draw Compositor'
l = nodes['Draw Compositor'].outputs[0].links[0]
links.remove(l)
links.new(nodes['Framebuffer'].outputs[0], nodes['Draw Compositor'].inputs[1])
if cam.rp_supersampling == '4':
if wrd.rp_supersampling == '4':
links.new(nodes[last_node].outputs[0], nodes['SS Resolve'].inputs[0])
last_node = 'SS Resolve'
if cam.rp_antialiasing == 'SMAA':
if wrd.rp_antialiasing == 'SMAA':
links.new(nodes['Reroute.014'].outputs[0], nodes['SMAA'].inputs[1])
links.new(nodes['Reroute.014'].outputs[0], nodes['SS Resolve'].inputs[2])
elif cam.rp_antialiasing == 'TAA':
elif wrd.rp_antialiasing == 'TAA':
links.new(nodes['Reroute.008'].outputs[0], nodes['TAA'].inputs[1])
links.new(nodes['Reroute.008'].outputs[0], nodes['SS Resolve'].inputs[2])
elif cam.rp_antialiasing == 'FXAA':
elif wrd.rp_antialiasing == 'FXAA':
links.new(nodes['Reroute.008'].outputs[0], nodes['FXAA'].inputs[1])
links.new(nodes['Reroute.008'].outputs[0], nodes['SS Resolve'].inputs[2])
elif cam.rp_antialiasing == 'None':
elif wrd.rp_antialiasing == 'None':
links.new(nodes['Reroute.008'].outputs[0], nodes['Draw Compositor'].inputs[1])
links.new(nodes['Reroute.008'].outputs[0], nodes['SS Resolve'].inputs[2])
if cam.rp_eyeadapt:
if wrd.rp_eyeadapt:
links.new(nodes[last_node].outputs[0], nodes['Histogram'].inputs[0])
links.new(nodes['histogram'].outputs[0], nodes['Draw Compositor'].inputs[5])
if cam.rp_rendercapture:
if wrd.rp_rendercapture:
# links.new(nodes[last_node].outputs[0], nodes['CopyCapture'].inputs[0])
fb = nodes['Framebuffer']
cc = nodes['CopyCapture']
@ -234,20 +519,20 @@ def make_deferred(cam):
for l in fb.outputs[0].links:
if l.to_node != cc:
links.new(cn.outputs[0], l.to_socket)
if cam.rp_rendercapture_format == '8bit':
if wrd.rp_rendercapture_format == '8bit':
cn.inputs[4].default_value = 'RGBA32'
elif cam.rp_rendercapture_format == '16bit':
elif wrd.rp_rendercapture_format == '16bit':
cn.inputs[4].default_value = 'RGBA64'
elif cam.rp_rendercapture_format == '32bit':
elif wrd.rp_rendercapture_format == '32bit':
cn.inputs[4].default_value = 'RGBA128'
def make_deferred_plus(cam):
def make_deferred_plus(wrd):
pass
# Handling node data
def check_default():
if (bpy.data.node_groups.get('armory_default') == None or bpy.data.filepath == '') and len(bpy.data.cameras) > 0: # Old RP nodes can be saved in startup file, reload those when fp is ''
make_renderer(bpy.data.cameras[0])
if (bpy.data.node_groups.get('armory_default') == None or bpy.data.filepath == ''): # Old RP nodes can be saved in startup file, reload those when fp is ''
make_renderer(bpy.data.worlds['Arm'])
def reload_blend_data():
armory_pbr = bpy.data.node_groups.get('Armory PBR')

View file

@ -17,29 +17,27 @@ def build_node_trees(assets_path):
fp = os.path.sep.join(s)
os.chdir(fp)
wrd = bpy.data.worlds['Arm']
# Make sure Assets dir exists
if not os.path.exists(arm.utils.build_dir() + '/compiled/Assets/renderpaths'):
os.makedirs(arm.utils.build_dir() + '/compiled/Assets/renderpaths')
build_node_trees.assets_path = assets_path
if bpy.data.worlds['Arm'].material_model != 'Restricted':
if wrd.material_model != 'Restricted':
# Always include
assets.add(assets_path + 'brdf.png')
assets.add_embedded_data('brdf.png')
bpy.data.worlds['Arm'].rp_defs = ''
# Export render path for each camera
wrd.rp_defs = ''
parsed_paths = []
for cam in bpy.data.cameras:
# if cam.game_export
if cam.renderpath_path not in parsed_paths:
node_group = bpy.data.node_groups[cam.renderpath_path]
build_node_tree(cam, node_group)
parsed_paths.append(cam.renderpath_path)
if wrd.renderpath_path not in parsed_paths:
node_group = bpy.data.node_groups[wrd.renderpath_path]
build_node_tree(wrd, node_group)
parsed_paths.append(wrd.renderpath_path)
def build_node_tree(cam, node_group):
build_node_tree.cam = cam
def build_node_tree(wrd, node_group):
build_node_tree.wrd = wrd
output = {}
dat = {}
output['renderpath_datas'] = [dat]
@ -253,7 +251,7 @@ def make_draw_compositor(stage, node_group, node, with_fxaa=False):
if wrd.generate_fog:
compositor_defs += '_CFog'
# compo_pos = True
if build_node_tree.cam.dof_distance > 0.0:
if bpy.data.cameras[0].dof_distance > 0.0:
compositor_defs += '_CDOF'
compo_depth = True
# if compo_pos:
@ -753,7 +751,7 @@ def get_root_node(node_group):
for n in node_group.nodes:
if n.bl_idname == 'BeginNodeType':
# Store contexts
build_node_tree.cam.renderpath_id = n.inputs[0].default_value
build_node_tree.wrd.renderpath_id = n.inputs[0].default_value
# TODO: deprecated
if len(n.inputs) > 5:
if n.inputs[5].default_value == False:
@ -774,16 +772,16 @@ def preprocess_renderpath(root_node, node_group):
render_targets3D = []
depth_buffers = []
preprocess_renderpath.velocity_def_added = False
build_node_tree.cam.renderpath_passes = ''
build_node_tree.wrd.renderpath_passes = ''
traverse_renderpath(root_node, node_group, render_targets, depth_buffers)
return render_targets, depth_buffers
def traverse_renderpath(node, node_group, render_targets, depth_buffers):
# Gather linked draw geometry contexts
if node.bl_idname == 'DrawMeshesNodeType':
if build_node_tree.cam.renderpath_passes != '':
build_node_tree.cam.renderpath_passes += '_' # Separator
build_node_tree.cam.renderpath_passes += node.inputs[1].default_value
if build_node_tree.wrd.renderpath_passes != '':
build_node_tree.wrd.renderpath_passes += '_' # Separator
build_node_tree.wrd.renderpath_passes += node.inputs[1].default_value
# Gather defs from linked nodes
if node.bl_idname == 'TAAPassNodeType' or node.bl_idname == 'MotionBlurVelocityPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType':

View file

@ -88,23 +88,24 @@ def build_node_tree(world):
assets.add_embedded_data('iestexture.png')
voxelgi = False
for cam in bpy.data.cameras:
if cam.rp_shadowmap == 'None':
wrd.world_defs += '_NoShadows'
assets.add_khafile_def('arm_no_shadows')
if cam.rp_voxelgi:
voxelgi = True
if cam.rp_dfrs:
wrd.world_defs += '_DFRS'
assets.add_khafile_def('arm_sdf')
if cam.rp_dfao:
wrd.world_defs += '_DFAO'
assets.add_khafile_def('arm_sdf')
if cam.rp_dfgi:
wrd.world_defs += '_DFGI'
assets.add_khafile_def('arm_sdf')
wrd.world_defs += '_Rad' # Always do radiance for gi
wrd.world_defs += '_Irr'
# for wrd in bpy.data.worlds:
wrd = bpy.data.worlds['Arm']
if wrd.rp_shadowmap == 'None':
wrd.world_defs += '_NoShadows'
assets.add_khafile_def('arm_no_shadows')
if wrd.rp_voxelgi:
voxelgi = True
if wrd.rp_dfrs:
wrd.world_defs += '_DFRS'
assets.add_khafile_def('arm_sdf')
if wrd.rp_dfao:
wrd.world_defs += '_DFAO'
assets.add_khafile_def('arm_sdf')
if wrd.rp_dfgi:
wrd.world_defs += '_DFGI'
assets.add_khafile_def('arm_sdf')
wrd.world_defs += '_Rad' # Always do radiance for gi
wrd.world_defs += '_Irr'
if voxelgi:
assets.add_khafile_def('arm_voxelgi')

View file

@ -7,7 +7,7 @@ import arm.material.make_texture
import arm.material.mat_state as mat_state
def get_rp_renderer():
return bpy.data.cameras[0].rp_renderer
return bpy.data.worlds['Arm'].rp_renderer
def get_arm_export_tangents():
return bpy.data.worlds['Arm'].arm_export_tangents

View file

@ -45,7 +45,7 @@ def parse(material, mat_data, mat_users, mat_armusers, rid):
const['bool'] = material.receive_shadow
c['bind_constants'].append(const)
if bpy.data.cameras[0].rp_sss_state == 'On':
if bpy.data.worlds['Arm'].rp_sss_state == 'On':
sss = False
sss_node = arm.nodes.get_node_by_type(material.node_tree, 'SUBSURFACE_SCATTERING')
if sss_node != None and sss_node.outputs[0].is_linked: # Check linked node

View file

@ -45,7 +45,7 @@ def build(material, mat_users, mat_armusers, rid):
global_elems.append({'name': 'bone', 'size': 4})
global_elems.append({'name': 'weight', 'size': 4})
# Instancing
if bo.instanced_children or len(bo.particle_systems) > 0:
if bo.arm_instanced or len(bo.particle_systems) > 0:
global_elems.append({'name': 'off', 'size': 3})
mat_state.data.global_elems = global_elems

View file

@ -45,7 +45,7 @@ def make(context_id):
frag.add_include('../../Shaders/std/imageatomic.glsl')
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')
# if bpy.data.cameras[0].rp_voxelgi_hdr:
# if bpy.data.worlds['Arm'].rp_voxelgi_hdr:
# frag.add_uniform('layout(RGBA16) image3D voxels')
# else:
# frag.add_uniform('layout(RGBA8) image3D voxels')
@ -142,7 +142,7 @@ def make(context_id):
if wrd.material_model == 'Cycles':
frag.write('color = min(color * 0.9, vec3(0.9)) + min(color / 200.0, 0.1);') # Higher range to allow emission
# if bpy.data.cameras[0].rp_voxelgi_hdr:
# if bpy.data.worlds['Arm'].rp_voxelgi_hdr:
# frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
# else:
frag.write('color = clamp(color, vec3(0.0), vec3(1.0));')

View file

@ -27,7 +27,7 @@ def get_rpasses(material):
# ar.append('depth')
wrd = bpy.data.worlds['Arm']
vgirefract = bpy.data.cameras[0].rp_voxelgi and wrd.voxelgi_refraction
vgirefract = wrd.rp_voxelgi and wrd.voxelgi_refraction
if material.decal:
ar.append('decal')
@ -39,18 +39,19 @@ def get_rpasses(material):
ar.append('mesh')
for con in add_mesh_contexts:
ar.append(con)
if bpy.data.cameras[0].rp_voxelgi:
if wrd.rp_voxelgi:
ar.append('voxel')
if wrd.voxelgi_multibounce:
ar.append('voxelbounce')
if bpy.data.cameras[0].rp_renderer == 'Deferred Plus':
if wrd.rp_renderer == 'Deferred Plus':
ar.append('rect')
shadows_enabled = False
for cam in bpy.data.cameras:
if cam.rp_shadowmap != 'None':
shadows_enabled = True
break
# for wrd in bpy.data.worlds:
wrd = bpy.data.worlds['Arm']
if wrd.rp_shadowmap != 'None':
shadows_enabled = True
# break
if material.cast_shadow and shadows_enabled and ('mesh' in ar or 'translucent' in ar):
ar.append('shadowmap')

View file

@ -4,7 +4,6 @@ import os
import shutil
from arm.props_traits_library import *
import arm.props_ui as props_ui
import arm.props_renderer as props_renderer
import arm.assets as assets
import arm.log as log
import arm.utils
@ -19,10 +18,10 @@ except ImportError:
arm_version = '17.08'
def update_preset(self, context):
props_renderer.set_preset(self, context, self.rp_preset)
make_renderer.set_preset(self, context, self.rp_preset)
def update_renderpath(self, context):
props_renderer.set_renderpath(self, context)
make_renderer.set_renderpath(self, context)
def update_material_model(self, context):
assets.invalidate_shader_cache(self, context)
@ -140,8 +139,8 @@ def init_properties():
name="Target", default='html5', description='Build paltform')
bpy.types.World.arm_project_name = StringProperty(name="Name", description="Exported project name", default="")
bpy.types.World.arm_project_package = StringProperty(name="Package", description="Package name for scripts", default="arm")
bpy.types.World.my_librarytraitlist = bpy.props.CollectionProperty(type=ListLibraryTraitItem)
bpy.types.World.librarytraitlist_index = bpy.props.IntProperty(name="Library index", default=0)
bpy.types.World.arm_librarylist = bpy.props.CollectionProperty(type=ListLibraryTraitItem)
bpy.types.World.arm_librarylist_index = bpy.props.IntProperty(name="Library index", default=0)
bpy.types.World.arm_play_active_scene = BoolProperty(name="Play Active Scene", description="Load currently edited scene when launching player", default=True)
bpy.types.World.arm_project_scene = StringProperty(name="Scene", description="Scene to load when launching player")
bpy.types.World.arm_samples_per_pixel = EnumProperty(
@ -246,18 +245,16 @@ def init_properties():
name="Graphics API", default='webgl', description='Based on currently selected target', update=update_gapi_html5)
# For object
bpy.types.Object.instanced_children = bpy.props.BoolProperty(name="Instanced Children", description="Use instaced rendering", default=False, update=invalidate_instance_cache)
bpy.types.Object.instanced_children_loc_x = bpy.props.BoolProperty(name="X", default=True)
bpy.types.Object.instanced_children_loc_y = bpy.props.BoolProperty(name="Y", default=True)
bpy.types.Object.instanced_children_loc_z = bpy.props.BoolProperty(name="Z", default=True)
bpy.types.Object.instanced_children_rot_x = bpy.props.BoolProperty(name="X", default=False)
bpy.types.Object.instanced_children_rot_y = bpy.props.BoolProperty(name="Y", default=False)
bpy.types.Object.instanced_children_rot_z = bpy.props.BoolProperty(name="Z", default=False)
bpy.types.Object.instanced_children_scale_x = bpy.props.BoolProperty(name="X", default=False)
bpy.types.Object.instanced_children_scale_y = bpy.props.BoolProperty(name="Y", default=False)
bpy.types.Object.instanced_children_scale_z = bpy.props.BoolProperty(name="Z", default=False)
bpy.types.Object.override_material = bpy.props.BoolProperty(name="Override Material", default=False)
bpy.types.Object.override_material_name = bpy.props.StringProperty(name="Name", default="")
bpy.types.Object.arm_instanced = bpy.props.BoolProperty(name="Instanced Children", description="Use instaced rendering", default=False, update=invalidate_instance_cache)
bpy.types.Object.arm_instanced_loc_x = bpy.props.BoolProperty(name="X", default=True)
bpy.types.Object.arm_instanced_loc_y = bpy.props.BoolProperty(name="Y", default=True)
bpy.types.Object.arm_instanced_loc_z = bpy.props.BoolProperty(name="Z", default=True)
# bpy.types.Object.arm_instanced_rot_x = bpy.props.BoolProperty(name="X", default=False)
# bpy.types.Object.arm_instanced_rot_y = bpy.props.BoolProperty(name="Y", default=False)
# bpy.types.Object.arm_instanced_rot_z = bpy.props.BoolProperty(name="Z", default=False)
# bpy.types.Object.arm_instanced_scale_x = bpy.props.BoolProperty(name="X", default=False)
# bpy.types.Object.arm_instanced_scale_y = bpy.props.BoolProperty(name="Y", default=False)
# bpy.types.Object.arm_instanced_scale_z = bpy.props.BoolProperty(name="Z", default=False)
bpy.types.Object.game_export = bpy.props.BoolProperty(name="Export", description="Export object data", default=True)
bpy.types.Object.spawn = bpy.props.BoolProperty(name="Spawn", description="Auto-add this object when creating scene", default=True)
bpy.types.Object.mobile = bpy.props.BoolProperty(name="Mobile", description="Object moves during gameplay", default=True)
@ -289,14 +286,16 @@ def init_properties():
bpy.types.Armature.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=False)
# For camera
bpy.types.Camera.frustum_culling = bpy.props.BoolProperty(name="Frustum Culling", description="Perform frustum culling for this camera", default=True)
bpy.types.Camera.renderpath_path = bpy.props.StringProperty(name="Render Path", description="Render path nodes used for this camera", default="armory_default", update=assets.invalidate_shader_cache)
bpy.types.Camera.renderpath_id = bpy.props.StringProperty(name="Render Path ID", description="Asset ID", default="deferred")
bpy.types.Camera.renderpath_passes = bpy.props.StringProperty(name="Render Path Passes", description="Referenced render passes", default="")
bpy.types.Camera.is_mirror = bpy.props.BoolProperty(name="Mirror", description="Render this camera into texture", default=False)
bpy.types.Camera.mirror_resolution_x = bpy.props.FloatProperty(name="X", default=512.0)
bpy.types.Camera.mirror_resolution_y = bpy.props.FloatProperty(name="Y", default=256.0)
bpy.types.World.renderpath_path = bpy.props.StringProperty(name="Render Path", description="Render path nodes", default="armory_default", update=assets.invalidate_shader_cache)
bpy.types.World.renderpath_id = bpy.props.StringProperty(name="Render Path ID", description="Asset ID", default="deferred")
bpy.types.World.renderpath_passes = bpy.props.StringProperty(name="Render Path Passes", description="Referenced render passes", default="")
# Render path generator
bpy.types.Camera.rp_preset = EnumProperty(
bpy.types.World.rp_preset = EnumProperty(
items=[('Low', 'Low', 'Low'),
('VR Low', 'VR Low', 'VR Low'),
('Mobile Low', 'Mobile Low', 'Mobile Low'),
@ -308,20 +307,20 @@ def init_properties():
('Grease Pencil', 'Grease Pencil', 'Grease Pencil'),
],
name="Preset", description="Render path preset", default='Deferred', update=update_preset)
bpy.types.Camera.rp_renderer = EnumProperty(
bpy.types.World.rp_renderer = EnumProperty(
items=[('Forward', 'Forward', 'Forward'),
('Deferred', 'Deferred', 'Deferred'),
('Deferred Plus', 'Deferred Plus', 'Deferred Plus'),
],
name="Renderer", description="Renderer type", default='Deferred', update=update_renderpath)
bpy.types.Camera.rp_depthprepass = bpy.props.BoolProperty(name="Depth Prepass", description="Depth Prepass for mesh context", default=False, update=update_renderpath)
bpy.types.Camera.rp_meshes = bpy.props.BoolProperty(name="Meshes", description="Render mesh objects", default=True, update=update_renderpath)
bpy.types.Camera.rp_hdr = bpy.props.BoolProperty(name="HDR", description="Render in HDR Space", default=True, update=update_renderpath)
bpy.types.Camera.rp_render_to_texture = bpy.props.BoolProperty(name="Post Process", description="Render scene to texture for further processing", default=True, update=update_renderpath)
bpy.types.Camera.rp_worldnodes = bpy.props.BoolProperty(name="World Nodes", description="Draw world nodes", default=True, update=update_renderpath)
bpy.types.Camera.rp_clearbackground = bpy.props.BoolProperty(name="Clear Background", description="Clear background with solid color", default=False, update=update_renderpath)
bpy.types.Camera.rp_compositornodes = bpy.props.BoolProperty(name="Compositor Nodes", description="Draw compositor nodes", default=True, update=update_renderpath)
bpy.types.Camera.rp_shadowmap = EnumProperty(
bpy.types.World.rp_depthprepass = bpy.props.BoolProperty(name="Depth Prepass", description="Depth Prepass for mesh context", default=False, update=update_renderpath)
bpy.types.World.rp_meshes = bpy.props.BoolProperty(name="Meshes", description="Render mesh objects", default=True, update=update_renderpath)
bpy.types.World.rp_hdr = bpy.props.BoolProperty(name="HDR", description="Render in HDR Space", default=True, update=update_renderpath)
bpy.types.World.rp_render_to_texture = bpy.props.BoolProperty(name="Post Process", description="Render scene to texture for further processing", default=True, update=update_renderpath)
bpy.types.World.rp_worldnodes = bpy.props.BoolProperty(name="World Nodes", description="Draw world nodes", default=True, update=update_renderpath)
bpy.types.World.rp_clearbackground = bpy.props.BoolProperty(name="Clear Background", description="Clear background with solid color", default=False, update=update_renderpath)
bpy.types.World.rp_compositornodes = bpy.props.BoolProperty(name="Compositor Nodes", description="Draw compositor nodes", default=True, update=update_renderpath)
bpy.types.World.rp_shadowmap = EnumProperty(
items=[('None', 'None', 'None'),
('512', '512', '512'),
('1024', '1024', '1024'),
@ -329,72 +328,72 @@ def init_properties():
('4096', '4096', '4096'),
('8192', '8192', '8192')],
name="Shadow Map", description="Shadow map resolution", default='2048', update=update_renderpath)
bpy.types.Camera.rp_supersampling = EnumProperty(
bpy.types.World.rp_supersampling = EnumProperty(
items=[('1', '1X', '1X'),
('2', '2X', '2X'),
('4', '4X', '4X')],
name="Super Sampling", description="Screen resolution multiplier", default='1', update=update_renderpath)
bpy.types.Camera.rp_antialiasing = EnumProperty(
bpy.types.World.rp_antialiasing = EnumProperty(
items=[('None', 'None', 'None'),
('FXAA', 'FXAA', 'FXAA'),
('SMAA', 'SMAA', 'SMAA'),
('TAA', 'TAA', 'TAA')],
name="Anti Aliasing", description="Post-process anti aliasing technique", default='SMAA', update=update_renderpath)
bpy.types.Camera.rp_volumetriclight = bpy.props.BoolProperty(name="Volumetric Light", description="Use volumetric lighting", default=False, update=update_renderpath)
bpy.types.Camera.rp_ssao = bpy.props.BoolProperty(name="SSAO", description="Screen space ambient occlusion", default=True, update=update_renderpath)
bpy.types.Camera.rp_ssr = bpy.props.BoolProperty(name="SSR", description="Screen space reflections", default=False, update=update_renderpath)
bpy.types.Camera.rp_dfao = bpy.props.BoolProperty(name="DFAO", description="Distance field ambient occlusion", default=False)
bpy.types.Camera.rp_dfrs = bpy.props.BoolProperty(name="DFRS", description="Distance field ray-traced shadows", default=False)
bpy.types.Camera.rp_dfgi = bpy.props.BoolProperty(name="DFGI", description="Distance field global illumination", default=False)
bpy.types.Camera.rp_bloom = bpy.props.BoolProperty(name="Bloom", description="Bloom processing", default=False, update=update_renderpath)
bpy.types.Camera.rp_eyeadapt = bpy.props.BoolProperty(name="Eye Adaptation", description="Auto-exposure based on histogram", default=False, update=update_renderpath)
bpy.types.Camera.rp_rendercapture = bpy.props.BoolProperty(name="Render Capture", description="Save output as render result", default=False, update=update_renderpath)
bpy.types.World.rp_volumetriclight = bpy.props.BoolProperty(name="Volumetric Light", description="Use volumetric lighting", default=False, update=update_renderpath)
bpy.types.World.rp_ssao = bpy.props.BoolProperty(name="SSAO", description="Screen space ambient occlusion", default=True, update=update_renderpath)
bpy.types.World.rp_ssr = bpy.props.BoolProperty(name="SSR", description="Screen space reflections", default=False, update=update_renderpath)
bpy.types.World.rp_dfao = bpy.props.BoolProperty(name="DFAO", description="Distance field ambient occlusion", default=False)
bpy.types.World.rp_dfrs = bpy.props.BoolProperty(name="DFRS", description="Distance field ray-traced shadows", default=False)
bpy.types.World.rp_dfgi = bpy.props.BoolProperty(name="DFGI", description="Distance field global illumination", default=False)
bpy.types.World.rp_bloom = bpy.props.BoolProperty(name="Bloom", description="Bloom processing", default=False, update=update_renderpath)
bpy.types.World.rp_eyeadapt = bpy.props.BoolProperty(name="Eye Adaptation", description="Auto-exposure based on histogram", default=False, update=update_renderpath)
bpy.types.World.rp_rendercapture = bpy.props.BoolProperty(name="Render Capture", description="Save output as render result", default=False, update=update_renderpath)
bpy.types.World.rp_rendercapture_format = EnumProperty(
items=[('8bit', '8bit', '8bit'),
('16bit', '16bit', '16bit'),
('32bit', '32bit', '32bit')],
name="Capture Format", description="Bits per color channel", default='8bit', update=update_renderpath)
bpy.types.Camera.rp_motionblur = EnumProperty(
bpy.types.World.rp_motionblur = EnumProperty(
items=[('None', 'None', 'None'),
('Camera', 'Camera', 'Camera'),
('Object', 'Object', 'Object')],
name="Motion Blur", description="Velocity buffer is used for object based motion blur", default='None', update=update_renderpath)
bpy.types.Camera.rp_translucency = bpy.props.BoolProperty(name="Translucency", description="Current render-path state", default=False)
bpy.types.Camera.rp_translucency_state = bpy.props.EnumProperty(
bpy.types.World.rp_translucency = bpy.props.BoolProperty(name="Translucency", description="Current render-path state", default=False)
bpy.types.World.rp_translucency_state = bpy.props.EnumProperty(
items=[('On', 'On', 'On'),
('Off', 'Off', 'Off'),
('Auto', 'Auto', 'Auto')],
name="Translucency", description="Order independent translucency", default='Auto', update=update_translucency_state)
bpy.types.Camera.rp_decals = bpy.props.BoolProperty(name="Decals", description="Current render-path state", default=False)
bpy.types.Camera.rp_decals_state = bpy.props.EnumProperty(
bpy.types.World.rp_decals = bpy.props.BoolProperty(name="Decals", description="Current render-path state", default=False)
bpy.types.World.rp_decals_state = bpy.props.EnumProperty(
items=[('On', 'On', 'On'),
('Off', 'Off', 'Off'),
('Auto', 'Auto', 'Auto')],
name="Decals", description="Decals pass", default='Auto', update=update_decals_state)
bpy.types.Camera.rp_overlays = bpy.props.BoolProperty(name="Overlays", description="Current render-path state", default=False)
bpy.types.Camera.rp_overlays_state = bpy.props.EnumProperty(
bpy.types.World.rp_overlays = bpy.props.BoolProperty(name="Overlays", description="Current render-path state", default=False)
bpy.types.World.rp_overlays_state = bpy.props.EnumProperty(
items=[('On', 'On', 'On'),
('Off', 'Off', 'Off'),
('Auto', 'Auto', 'Auto')],
name="Overlays", description="X-Ray pass", default='Auto', update=update_overlays_state)
bpy.types.Camera.rp_sss = bpy.props.BoolProperty(name="SSS", description="Current render-path state", default=False)
bpy.types.Camera.rp_sss_state = bpy.props.EnumProperty(
bpy.types.World.rp_sss = bpy.props.BoolProperty(name="SSS", description="Current render-path state", default=False)
bpy.types.World.rp_sss_state = bpy.props.EnumProperty(
items=[('On', 'On', 'On'),
('Off', 'Off', 'Off'),
('Auto', 'Auto', 'Auto')],
name="SSS", description="Sub-surface scattering pass", default='Auto', update=update_sss_state)
bpy.types.Camera.rp_stereo = bpy.props.BoolProperty(name="Stereo", description="Stereo rendering", default=False, update=update_renderpath)
bpy.types.Camera.rp_greasepencil = bpy.props.BoolProperty(name="Grease Pencil", description="Render Grease Pencil data", default=False, update=update_renderpath)
bpy.types.Camera.rp_ocean = bpy.props.BoolProperty(name="Ocean", description="Ocean pass", default=False, update=update_renderpath)
bpy.types.Camera.rp_voxelgi = bpy.props.BoolProperty(name="Voxel GI", description="Voxel-based Global Illumination", default=False, update=update_renderpath)
bpy.types.Camera.rp_voxelgi_resolution = bpy.props.EnumProperty(
bpy.types.World.rp_stereo = bpy.props.BoolProperty(name="Stereo", description="Stereo rendering", default=False, update=update_renderpath)
bpy.types.World.rp_greasepencil = bpy.props.BoolProperty(name="Grease Pencil", description="Render Grease Pencil data", default=False, update=update_renderpath)
bpy.types.World.rp_ocean = bpy.props.BoolProperty(name="Ocean", description="Ocean pass", default=False, update=update_renderpath)
bpy.types.World.rp_voxelgi = bpy.props.BoolProperty(name="Voxel GI", description="Voxel-based Global Illumination", default=False, update=update_renderpath)
bpy.types.World.rp_voxelgi_resolution = bpy.props.EnumProperty(
items=[('32', '32', '32'),
('64', '64', '64'),
('128', '128', '128'),
('256', '256', '256'),
('512', '512', '512')],
name="Resolution", description="3D texture resolution", default='128', update=update_renderpath)
bpy.types.Camera.rp_voxelgi_hdr = bpy.props.BoolProperty(name="HDR", description="Store voxels in RGBA64 instead of RGBA32", default=False, update=update_renderpath)
bpy.types.World.rp_voxelgi_hdr = bpy.props.BoolProperty(name="HDR", description="Store voxels in RGBA64 instead of RGBA32", default=False, update=update_renderpath)
bpy.types.World.generate_voxelgi_dimensions = bpy.props.FloatProperty(name="Dimensions", description="Voxelization bounds",default=16, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_revoxelize = bpy.props.BoolProperty(name="Revoxelize", description="Revoxelize scene each frame", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_multibounce = bpy.props.BoolProperty(name="Multi-bounce", description="Accumulate multiple light bounces", default=False, update=assets.invalidate_shader_cache)
@ -509,7 +508,6 @@ def init_properties():
# Skin
bpy.types.World.generate_gpu_skin = bpy.props.BoolProperty(name="GPU Skinning", description="Calculate skinning on GPU", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_gpu_skin_max_bones_auto = bpy.props.BoolProperty(name="Auto Bones", description="Calculate amount of maximum bones based on armatures", default=True, update=assets.invalidate_compiled_data)
# bpy.types.World.generate_gpu_skin_max_bones = bpy.props.IntProperty(name="Max Bones", default=50, min=1, max=84, update=assets.invalidate_shader_cache)
bpy.types.World.generate_gpu_skin_max_bones = bpy.props.IntProperty(name="Max Bones", default=50, min=1, max=3000, update=assets.invalidate_shader_cache)
# Material override flags
bpy.types.World.texture_filtering_state = EnumProperty(
@ -531,7 +529,6 @@ def init_properties():
# For material
bpy.types.NodeSocket.is_uniform = bpy.props.BoolProperty(name="Is Uniform", description="Mark node sockets to be processed as material uniforms", default=False)
bpy.types.NodeTree.is_cached = bpy.props.BoolProperty(name="Node Tree Cached", description="No need to reexport node tree", default=False)
# bpy.types.Node.is_uniform = bpy.props.BoolProperty(name="Is Uniform", description="Mark node values to be processed as material uniforms", default=False)
bpy.types.Material.signature = bpy.props.StringProperty(name="Signature", description="Unique string generated from material nodes", default="")
bpy.types.Material.is_cached = bpy.props.BoolProperty(name="Material Cached", description="No need to reexport material data", default=False, update=update_mat_cache)
bpy.types.Material.lock_cache = bpy.props.BoolProperty(name="Lock Material Cache", description="Prevent is_cached from updating", default=False)
@ -618,22 +615,16 @@ def init_properties_on_save():
def init_properties_on_load():
global arm_version
if not 'Arm' in bpy.data.worlds:
init_properties()
arm.utils.fetch_script_names()
wrd = bpy.data.worlds['Arm']
# Outdated project
if bpy.data.filepath != '' and wrd.arm_version != arm_version: # Call on project load only
print('Project updated to sdk v' + arm_version)
wrd.arm_version = arm_version
arm.make.clean_project()
if len(bpy.data.cameras) > 0:
make_renderer.make_renderer(bpy.data.cameras[0])
make_renderer.make_renderer(bpy.data.worlds['Arm'])
# Set url for embedded player
if arm.utils.with_krom():
barmory.set_files_location(arm.utils.get_fp_build() + '/krom')

View file

@ -52,12 +52,6 @@ class MY_UL_LodList(bpy.types.UIList):
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
def initObjectProperties():
# Mesh only for now
bpy.types.Mesh.my_lodlist = bpy.props.CollectionProperty(type=ListLodItem)
bpy.types.Mesh.lodlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
bpy.types.Mesh.lod_material = bpy.props.BoolProperty(name="Material Lod", description="Use materials of lod objects", default=False)
class LIST_OT_LodNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_lodlist.new_item"
@ -94,111 +88,14 @@ class LIST_OT_LodDeleteItem(bpy.types.Operator):
mdata.lodlist_index = index
return{'FINISHED'}
class ArmoryGenerateLodButton(bpy.types.Operator):
'''Automatically generate LoD levels'''
bl_idname = 'arm.generate_lod'
bl_label = 'Auto Generate'
def lod_name(self, name, level):
return name + '_LOD' + str(level + 1)
def execute(self, context):
obj = context.object
if obj == None:
return{'CANCELLED'}
# Clear
mdata = context.object.data
mdata.lodlist_index = 0
mdata.my_lodlist.clear()
# Lod levels
wrd = bpy.data.worlds['Arm']
ratio = wrd.arm_lod_gen_ratio
num_levels = wrd.arm_lod_gen_levels
for level in range(0, num_levels):
new_obj = obj.copy()
for i in range(0, 3):
new_obj.location[i] = 0
new_obj.rotation_euler[i] = 0
new_obj.scale[i] = 1
new_obj.data = obj.data.copy()
new_obj.name = self.lod_name(obj.name, level)
new_obj.parent = obj
new_obj.hide = True
new_obj.hide_render = True
mod = new_obj.modifiers.new('Decimate', 'DECIMATE')
mod.ratio = ratio
ratio *= wrd.arm_lod_gen_ratio
context.scene.objects.link(new_obj)
# Screen sizes
for level in range(0, num_levels):
mdata.my_lodlist.add()
mdata.my_lodlist[-1].name = self.lod_name(obj.name, level)
mdata.my_lodlist[-1].screen_size_prop = (1 - (1 / (num_levels + 1)) * level) - (1 / (num_levels + 1))
return{'FINISHED'}
class ToolsLodPanel(bpy.types.Panel):
bl_label = "Armory Lod"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
obj = bpy.context.object
# Mesh only for now
if obj.type != 'MESH':
return
mdata = obj.data
rows = 2
if len(mdata.my_lodlist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_LodList", "The_List", mdata, "my_lodlist", mdata, "lodlist_index", rows=rows)
col = row.column(align=True)
col.operator("my_lodlist.new_item", icon='ZOOMIN', text="")
col.operator("my_lodlist.delete_item", icon='ZOOMOUT', text="")
if mdata.lodlist_index >= 0 and len(mdata.my_lodlist) > 0:
item = mdata.my_lodlist[mdata.lodlist_index]
row = layout.row()
row.prop_search(item, "name", bpy.data, "objects", "Object")
row = layout.row()
row.prop(item, "screen_size_prop")
# Auto lod for meshes
if obj.type == 'MESH':
layout.separator()
layout.operator("arm.generate_lod")
wrd = bpy.data.worlds['Arm']
row = layout.row()
row.prop(wrd, 'arm_lod_gen_levels')
row.prop(wrd, 'arm_lod_gen_ratio')
layout.prop(mdata, "lod_material")
def register():
bpy.utils.register_class(ListLodItem)
bpy.utils.register_class(MY_UL_LodList)
bpy.utils.register_class(LIST_OT_LodNewItem)
bpy.utils.register_class(LIST_OT_LodDeleteItem)
bpy.utils.register_class(ArmoryGenerateLodButton)
bpy.utils.register_class(ToolsLodPanel)
initObjectProperties()
def unregister():
bpy.utils.unregister_class(ListLodItem)
bpy.utils.unregister_class(MY_UL_LodList)
bpy.utils.unregister_class(LIST_OT_LodNewItem)
bpy.utils.unregister_class(LIST_OT_LodDeleteItem)
bpy.utils.unregister_class(ArmoryGenerateLodButton)
bpy.utils.unregister_class(ToolsLodPanel)

View file

@ -1,481 +0,0 @@
import bpy
from bpy.types import Menu, Panel, UIList
from bpy.props import *
import arm.nodes_renderpath as nodes_renderpath
import arm.make_renderer as make_renderer
import arm.assets as assets
updating_preset = False
def set_preset(self, context, preset):
global updating_preset
cam = bpy.context.camera
if cam == None:
return
wrd = bpy.data.worlds['Arm']
updating_preset = True
if preset == 'Low':
cam.rp_renderer = 'Forward'
wrd.material_model = 'PBR'
cam.rp_shadowmap = '1024'
cam.rp_meshes = True
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
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = False
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'None'
cam.rp_compositornodes = False
cam.rp_volumetriclight = False
cam.rp_ssao = False
cam.rp_ssr = False
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'Forward':
cam.rp_renderer = 'Forward'
wrd.material_model = 'PBR'
cam.rp_shadowmap = '2048'
cam.rp_meshes = True
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Auto'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = True
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'SMAA'
cam.rp_compositornodes = True
cam.rp_volumetriclight = False
cam.rp_ssao = True
cam.rp_ssr = True
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'Deferred':
cam.rp_renderer = 'Deferred'
wrd.material_model = 'PBR'
cam.rp_shadowmap = '2048'
cam.rp_meshes = True
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Auto'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = True
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'FXAA'
cam.rp_compositornodes = True
cam.rp_volumetriclight = False
cam.rp_ssao = True
cam.rp_ssr = False
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'Max':
cam.rp_renderer = 'Deferred'
wrd.material_model = 'PBR'
cam.rp_shadowmap = '4096'
cam.rp_meshes = True
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Auto'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = True
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'TAA'
cam.rp_compositornodes = True
cam.rp_volumetriclight = False
cam.rp_ssao = True
cam.rp_ssr = True
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'Render Capture':
cam.rp_renderer = 'Deferred'
cam.rp_shadowmap = '8192'
cam.rp_meshes = True
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Auto'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = True
cam.rp_voxelgi_resolution = '256'
cam.rp_render_to_texture = True
cam.rp_supersampling = '2'
cam.rp_antialiasing = 'TAA'
cam.rp_compositornodes = True
cam.rp_volumetriclight = False
cam.rp_ssao = True
cam.rp_ssr = True
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = True
cam.rp_rendercapture_format = '8bit'
cam.rp_motionblur = 'None'
wrd.material_model = 'Cycles'
wrd.generate_pcss_state = 'On'
elif preset == 'Deferred Plus':
cam.rp_renderer = 'Deferred Plus'
wrd.material_model = 'PBR'
cam.rp_shadowmap = '4096'
cam.rp_meshes = True
cam.rp_translucency_state = 'Auto'
cam.rp_overlays_state = 'Auto'
cam.rp_decals_state = 'Auto'
cam.rp_sss_state = 'Auto'
cam.rp_hdr = True
cam.rp_worldnodes = True
cam.rp_clearbackground = False
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = True
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'TAA'
cam.rp_compositornodes = True
cam.rp_volumetriclight = False
cam.rp_ssao = True
cam.rp_ssr = True
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'VR Low':
cam.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
cam.rp_shadowmap = '1024'
cam.rp_meshes = True
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
cam.rp_stereo = True
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = False
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'None'
cam.rp_compositornodes = False
cam.rp_volumetriclight = False
cam.rp_ssao = False
cam.rp_ssr = False
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'Mobile Low':
cam.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
cam.rp_shadowmap = '1024'
cam.rp_meshes = True
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
cam.rp_stereo = False
cam.rp_greasepencil = False
cam.rp_voxelgi = False
cam.rp_render_to_texture = False
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'None'
cam.rp_compositornodes = False
cam.rp_volumetriclight = False
cam.rp_ssao = False
cam.rp_ssr = False
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
elif preset == 'Grease Pencil':
cam.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
cam.rp_shadowmap = 'None'
cam.rp_meshes = False
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
cam.rp_stereo = False
cam.rp_greasepencil = True
cam.rp_render_to_texture = False
cam.rp_supersampling = '1'
cam.rp_antialiasing = 'None'
cam.rp_compositornodes = False
cam.rp_volumetriclight = False
cam.rp_ssao = False
cam.rp_ssr = False
cam.rp_dfrs = False
cam.rp_dfao = False
cam.rp_dfgi = False
cam.rp_bloom = False
cam.rp_eyeadapt = False
cam.rp_rendercapture = False
cam.rp_motionblur = 'None'
updating_preset = False
set_renderpath(self, context)
def set_renderpath(self, context):
global updating_preset
if updating_preset == True:
return
if bpy.context.camera == None:
return
# assets.invalidate_compiled_data(self, context)
assets.invalidate_shader_cache(self, context)
make_renderer.make_renderer(bpy.context.camera)
bpy.context.camera.renderpath_path = 'armory_default'
# Menu in camera data region
class GenRPDataPropsPanel(bpy.types.Panel):
bl_label = "Armory Render Path"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "data"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
obj = bpy.context.object
if obj == None:
return
dat = obj.data
wrd = bpy.data.worlds['Arm']
if obj.type == 'CAMERA':
layout.prop(dat, "rp_preset")
layout.separator()
layout.prop(dat, "rp_renderer")
layout.prop(wrd, 'material_model')
layout.prop(dat, "rp_shadowmap")
layout.prop(dat, "rp_meshes")
layout.prop(dat, "rp_translucency_state")
layout.prop(dat, "rp_overlays_state")
layout.prop(dat, "rp_decals_state")
layout.prop(dat, "rp_sss_state")
if dat.rp_sss_state != 'Off':
layout.prop(wrd, 'sss_width')
layout.prop(dat, "rp_hdr")
layout.prop(dat, "rp_worldnodes")
if not dat.rp_worldnodes:
layout.prop(dat, "rp_clearbackground")
layout.prop(dat, "rp_stereo")
layout.prop(dat, "rp_greasepencil")
layout.prop(dat, 'rp_voxelgi')
if dat.rp_voxelgi:
layout.prop(dat, 'rp_voxelgi_resolution')
layout.prop(wrd, 'generate_voxelgi_dimensions')
row = layout.row()
row.prop(wrd, 'voxelgi_diff')
row.prop(wrd, 'voxelgi_spec')
row = layout.row()
row.prop(wrd, 'voxelgi_occ')
row.prop(wrd, 'voxelgi_env')
row = layout.row()
row.prop(wrd, 'voxelgi_step')
row.prop(wrd, 'voxelgi_range')
row = layout.row()
row.prop(wrd, 'voxelgi_revoxelize')
row.prop(wrd, 'voxelgi_multibounce')
row = layout.row()
row.prop(wrd, 'voxelgi_camera')
row.prop(wrd, 'voxelgi_anisotropic')
row = layout.row()
row.prop(wrd, 'voxelgi_shadows')
row.prop(wrd, 'voxelgi_refraction')
layout.prop(dat, 'rp_voxelgi_hdr')
layout.separator()
layout.prop(dat, "rp_render_to_texture")
if dat.rp_render_to_texture:
layout.prop(dat, "rp_supersampling")
layout.prop(dat, "rp_antialiasing")
layout.prop(dat, "rp_compositornodes")
layout.prop(dat, "rp_volumetriclight")
layout.prop(dat, "rp_ssao")
layout.prop(dat, "rp_ssr")
# layout.prop(dat, "rp_dfao")
# layout.prop(dat, "rp_dfrs")
# layout.prop(dat, "rp_dfgi")
layout.prop(dat, "rp_bloom")
layout.prop(dat, "rp_eyeadapt")
layout.prop(dat, "rp_motionblur")
layout.prop(dat, "rp_rendercapture")
layout.prop(dat, "rp_ocean")
class PropsRPDataPropsPanel(bpy.types.Panel):
bl_label = "Armory Render Props"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "data"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
obj = bpy.context.object
if obj == None:
return
wrd = bpy.data.worlds['Arm']
if obj.type == 'CAMERA':
layout.prop(wrd, 'generate_pcss_state')
if wrd.generate_pcss_state == 'On' or wrd.generate_pcss_state == 'Auto':
layout.prop(wrd, 'generate_pcss_rings')
layout.prop(wrd, 'generate_ssrs')
layout.prop(wrd, 'arm_samples_per_pixel')
row = layout.row()
row.prop(wrd, 'generate_gpu_skin')
if wrd.generate_gpu_skin:
row.prop(wrd, 'generate_gpu_skin_max_bones_auto')
if not wrd.generate_gpu_skin_max_bones_auto:
layout.prop(wrd, 'generate_gpu_skin_max_bones')
layout.prop(wrd, 'texture_filtering_state')
layout.prop(wrd, 'tessellation_enabled')
layout.prop(wrd, 'force_no_culling')
layout.prop(wrd, 'generate_two_sided_area_lamp')
layout.prop(wrd, 'generate_clouds')
if wrd.generate_clouds:
layout.prop(wrd, 'generate_clouds_density')
layout.prop(wrd, 'generate_clouds_size')
layout.prop(wrd, 'generate_clouds_lower')
layout.prop(wrd, 'generate_clouds_upper')
layout.prop(wrd, 'generate_clouds_wind')
layout.prop(wrd, 'generate_clouds_secondary')
layout.prop(wrd, 'generate_clouds_precipitation')
layout.prop(wrd, 'generate_clouds_eccentricity')
layout.label('SSAO')
# layout.prop(wrd, 'generate_ssao')
# if wrd.generate_ssao:
layout.prop(wrd, 'generate_ssao_size')
layout.prop(wrd, 'generate_ssao_strength')
layout.prop(wrd, 'generate_ssao_half_res')
layout.label('Bloom')
# layout.prop(wrd, 'generate_bloom')
# if wrd.generate_bloom:
layout.prop(wrd, 'generate_bloom_threshold')
layout.prop(wrd, 'generate_bloom_strength')
layout.prop(wrd, 'generate_bloom_radius')
layout.label('Motion Blur')
# layout.prop(wrd, 'generate_motion_blur')
# if wrd.generate_motion_blur:
layout.prop(wrd, 'generate_motion_blur_intensity')
layout.label('SSR')
# layout.prop(wrd, 'generate_ssr')
# if wrd.generate_ssr:
layout.prop(wrd, 'generate_ssr_ray_step')
layout.prop(wrd, 'generate_ssr_min_ray_step')
layout.prop(wrd, 'generate_ssr_search_dist')
layout.prop(wrd, 'generate_ssr_falloff_exp')
layout.prop(wrd, 'generate_ssr_jitter')
layout.prop(wrd, 'generate_ssr_half_res')
layout.label('SSRS')
layout.prop(wrd, 'generate_ssrs_ray_step')
layout.label('Volumetric Light')
# layout.prop(wrd, 'generate_volumetric_light')
# if wrd.generate_volumetric_light:
layout.prop(wrd, 'generate_volumetric_light_air_turbidity')
layout.prop(wrd, 'generate_volumetric_light_air_color')
layout.prop(wrd, 'generate_tonemap')
layout.prop(wrd, 'generate_letterbox')
if wrd.generate_letterbox:
layout.prop(wrd, 'generate_letterbox_size')
layout.prop(wrd, 'generate_grain')
if wrd.generate_grain:
layout.prop(wrd, 'generate_grain_strength')
layout.prop(wrd, 'generate_fog')
if wrd.generate_fog:
layout.prop(wrd, 'generate_fog_color')
layout.prop(wrd, 'generate_fog_amounta')
layout.prop(wrd, 'generate_fog_amountb')
layout.prop(wrd, 'generate_fisheye')
layout.prop(wrd, 'generate_vignette')
layout.prop(wrd, 'generate_lens_texture')
def register():
bpy.utils.register_class(GenRPDataPropsPanel)
bpy.utils.register_class(PropsRPDataPropsPanel)
def unregister():
bpy.utils.unregister_class(GenRPDataPropsPanel)
bpy.utils.unregister_class(PropsRPDataPropsPanel)

View file

@ -296,7 +296,7 @@ class ArmoryRefreshCanvasListButton(bpy.types.Operator):
return{'FINISHED'}
# Menu in tools region
class ToolsTraitsPanel(bpy.types.Panel):
class ArmTraitsPanel(bpy.types.Panel):
bl_label = "Armory Traits"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
@ -428,7 +428,7 @@ def register():
bpy.utils.register_class(ArmoryNewCanvasDialog)
bpy.utils.register_class(ArmoryRefreshScriptsButton)
bpy.utils.register_class(ArmoryRefreshCanvasListButton)
bpy.utils.register_class(ToolsTraitsPanel)
bpy.utils.register_class(ArmTraitsPanel)
initObjectProperties()
@ -445,4 +445,4 @@ def unregister():
bpy.utils.unregister_class(ArmoryNewCanvasDialog)
bpy.utils.unregister_class(ArmoryRefreshScriptsButton)
bpy.utils.unregister_class(ArmoryRefreshCanvasListButton)
bpy.utils.unregister_class(ToolsTraitsPanel)
bpy.utils.unregister_class(ArmTraitsPanel)

View file

@ -33,44 +33,44 @@ class MY_UL_LibraryTraitList(bpy.types.UIList):
class LIST_OT_LibraryTraitNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_librarytraitlist.new_item"
bl_idname = "arm_librarylist.new_item"
bl_label = "Add a new item"
def execute(self, context):
trait = bpy.data.worlds['Arm']
trait.my_librarytraitlist.add()
trait.librarytraitlist_index = len(trait.my_librarytraitlist) - 1
trait.arm_librarylist.add()
trait.arm_librarylist_index = len(trait.arm_librarylist) - 1
return{'FINISHED'}
class LIST_OT_LibraryTraitDeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_librarytraitlist.delete_item"
bl_idname = "arm_librarylist.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
trait = bpy.data.worlds['Arm']
return len(trait.my_librarytraitlist) > 0
return len(trait.arm_librarylist) > 0
def execute(self, context):
trait = bpy.data.worlds['Arm']
list = trait.my_librarytraitlist
index = trait.librarytraitlist_index
list = trait.arm_librarylist
index = trait.arm_librarylist_index
list.remove(index)
if index > 0:
index = index - 1
trait.librarytraitlist_index = index
trait.arm_librarylist_index = index
return{'FINISHED'}
class LIST_OT_LibraryTraitMoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "my_librarytraitlist.move_item"
bl_idname = "arm_librarylist.move_item"
bl_label = "Move an item in the list"
direction = bpy.props.EnumProperty(
items=(
@ -81,14 +81,14 @@ class LIST_OT_LibraryTraitMoveItem(bpy.types.Operator):
def poll(self, context):
""" Enable if there's something in the list. """
trait = bpy.data.worlds['Arm']
return len(trait.my_librarytraitlist) > 0
return len(trait.arm_librarylist) > 0
def move_index(self):
# Move index of an item render queue while clamping it
trait = bpy.data.worlds['Arm']
index = trait.librarytraitlist_index
list_length = len(trait.my_librarytraitlist) - 1
index = trait.arm_librarylist_index
list_length = len(trait.arm_librarylist) - 1
new_index = 0
if self.direction == 'UP':
@ -102,8 +102,8 @@ class LIST_OT_LibraryTraitMoveItem(bpy.types.Operator):
def execute(self, context):
trait = bpy.data.worlds['Arm']
list = trait.my_librarytraitlist
index = trait.librarytraitlist_index
list = trait.arm_librarylist
index = trait.arm_librarylist_index
if self.direction == 'DOWN':
neighbor = index + 1

View file

@ -8,7 +8,6 @@ import arm.make_renderer as make_renderer
import arm.make as make
import arm.make_utils as make_utils
import arm.make_state as state
import arm.props_renderer as props_renderer
import arm.assets as assets
import arm.log as log
@ -41,26 +40,23 @@ class ObjectPropsPanel(bpy.types.Panel):
row.prop(obj, 'object_animation_enabled')
if obj.type == 'MESH':
layout.prop(obj, 'instanced_children')
if obj.instanced_children:
layout.prop(obj, 'arm_instanced')
if obj.arm_instanced:
layout.label('Location')
column = layout.column()
column.prop(obj, 'instanced_children_loc_x')
column.prop(obj, 'instanced_children_loc_y')
column.prop(obj, 'instanced_children_loc_z')
column.prop(obj, 'arm_instanced_child')
column.prop(obj, 'arm_instanced_child')
column.prop(obj, 'arm_instanced_child')
# layout.label('Rotation')
# row = layout.row()
# row.prop(obj, 'instanced_children_rot_x')
# row.prop(obj, 'instanced_children_rot_y')
# row.prop(obj, 'instanced_children_rot_z')
# row.prop(obj, 'arm_instanced_child')
# row.prop(obj, 'arm_instanced_child')
# row.prop(obj, 'arm_instanced_child')
# layout.label('Scale')
# row = layout.row()
# row.prop(obj, 'instanced_children_scale_x')
# row.prop(obj, 'instanced_children_scale_y')
# row.prop(obj, 'instanced_children_scale_z')
# layout.prop(obj, 'override_material')
# if obj.override_material:
# layout.prop(obj, 'override_material_name')
# row.prop(obj, 'arm_instanced_childre')
# row.prop(obj, 'arm_instanced_childre')
# row.prop(obj, 'arm_instanced_childre')
class ModifiersPropsPanel(bpy.types.Panel):
bl_label = "Armory Props"
@ -431,23 +427,23 @@ class ArmoryProjectPanel(bpy.types.Panel):
layout.separator()
layout.label("Libraries:")
rows = 2
if len(wrd.my_librarytraitlist) > 1:
if len(wrd.arm_librarylist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_LibraryTraitList", "The_List", wrd, "my_librarytraitlist", wrd, "librarytraitlist_index", rows=rows)
row.template_list("MY_UL_LibraryTraitList", "The_List", wrd, "arm_librarylist", wrd, "arm_librarylist_index", rows=rows)
col = row.column(align=True)
col.operator("my_librarytraitlist.new_item", icon='ZOOMIN', text="")
col.operator("my_librarytraitlist.delete_item", icon='ZOOMOUT', text="")
col.operator("arm_librarylist.new_item", icon='ZOOMIN', text="")
col.operator("arm_librarylist.delete_item", icon='ZOOMOUT', text="")
if len(wrd.my_librarytraitlist) > 1:
if len(wrd.arm_librarylist) > 1:
col.separator()
col.operator("my_librarytraitlist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_librarytraitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
col.operator("arm_librarylist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("arm_librarylist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
# if wrd.librarytraitlist_index >= 0 and len(wrd.my_librarytraitlist) > 0:
# libitem = wrd.my_librarytraitlist[wrd.librarytraitlist_index]
# if wrd.arm_librarylist_index >= 0 and len(wrd.arm_librarylist) > 0:
# libitem = wrd.arm_librarylist[wrd.arm_librarylist_index]
layout.label('Armory v' + wrd.arm_version)
@ -533,7 +529,7 @@ class ArmoryPlayButton(bpy.types.Operator):
make_renderer.check_default()
if bpy.data.cameras[0].rp_rendercapture == True:
if bpy.data.worlds['Arm'].rp_rendercapture == True:
self.report({"ERROR"}, "Disable Camera - Armory Render Path - Render Capture first")
return {"CANCELLED"}
@ -568,7 +564,7 @@ class ArmoryPlayInViewportButton(bpy.types.Operator):
make_renderer.check_default()
if bpy.data.cameras[0].rp_rendercapture == True:
if bpy.data.worlds['Arm'].rp_rendercapture == True:
self.report({"ERROR"}, "Disable Camera - Armory Render Path - Render Capture first")
return {"CANCELLED"}
@ -757,7 +753,7 @@ class ArmoryRenderButton(bpy.types.Operator):
make.stop_project()
if bpy.data.worlds['Arm'].arm_play_runtime != 'Krom':
bpy.data.worlds['Arm'].arm_play_runtime = 'Krom'
if bpy.data.cameras[0].rp_rendercapture == False:
if bpy.data.worlds['Arm'].rp_rendercapture == False:
self.report({"ERROR"}, "Set Camera - Armory Render Path - Preset to Render Capture first")
return {"CANCELLED"}
assets.invalidate_enabled = False
@ -801,6 +797,263 @@ def draw_info_header(self, context):
if log.info_text != '':
layout.label(log.info_text)
class ArmRenderPathPanel(bpy.types.Panel):
bl_label = "Armory Render Path"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
dat = bpy.data.worlds['Arm']
wrd = bpy.data.worlds['Arm']
layout.prop(dat, "rp_preset")
layout.separator()
layout.prop(dat, "rp_renderer")
layout.prop(wrd, 'material_model')
layout.prop(dat, "rp_shadowmap")
layout.prop(dat, "rp_meshes")
layout.prop(dat, "rp_translucency_state")
layout.prop(dat, "rp_overlays_state")
layout.prop(dat, "rp_decals_state")
layout.prop(dat, "rp_sss_state")
if dat.rp_sss_state != 'Off':
layout.prop(wrd, 'sss_width')
layout.prop(dat, "rp_hdr")
layout.prop(dat, "rp_worldnodes")
if not dat.rp_worldnodes:
layout.prop(dat, "rp_clearbackground")
layout.prop(dat, "rp_stereo")
layout.prop(dat, "rp_greasepencil")
layout.prop(dat, 'rp_voxelgi')
if dat.rp_voxelgi:
layout.prop(dat, 'rp_voxelgi_resolution')
layout.prop(wrd, 'generate_voxelgi_dimensions')
row = layout.row()
row.prop(wrd, 'voxelgi_diff')
row.prop(wrd, 'voxelgi_spec')
row = layout.row()
row.prop(wrd, 'voxelgi_occ')
row.prop(wrd, 'voxelgi_env')
row = layout.row()
row.prop(wrd, 'voxelgi_step')
row.prop(wrd, 'voxelgi_range')
row = layout.row()
row.prop(wrd, 'voxelgi_revoxelize')
row.prop(wrd, 'voxelgi_multibounce')
row = layout.row()
row.prop(wrd, 'voxelgi_camera')
row.prop(wrd, 'voxelgi_anisotropic')
row = layout.row()
row.prop(wrd, 'voxelgi_shadows')
row.prop(wrd, 'voxelgi_refraction')
layout.prop(dat, 'rp_voxelgi_hdr')
layout.separator()
layout.prop(dat, "rp_render_to_texture")
if dat.rp_render_to_texture:
layout.prop(dat, "rp_supersampling")
layout.prop(dat, "rp_antialiasing")
layout.prop(dat, "rp_compositornodes")
layout.prop(dat, "rp_volumetriclight")
layout.prop(dat, "rp_ssao")
layout.prop(dat, "rp_ssr")
# layout.prop(dat, "rp_dfao")
# layout.prop(dat, "rp_dfrs")
# layout.prop(dat, "rp_dfgi")
layout.prop(dat, "rp_bloom")
layout.prop(dat, "rp_eyeadapt")
layout.prop(dat, "rp_motionblur")
layout.prop(dat, "rp_rendercapture")
layout.prop(dat, "rp_ocean")
class ArmRenderPropsPanel(bpy.types.Panel):
bl_label = "Armory Render Props"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
wrd = bpy.data.worlds['Arm']
layout.prop(wrd, 'generate_pcss_state')
if wrd.generate_pcss_state == 'On' or wrd.generate_pcss_state == 'Auto':
layout.prop(wrd, 'generate_pcss_rings')
layout.prop(wrd, 'generate_ssrs')
layout.prop(wrd, 'arm_samples_per_pixel')
row = layout.row()
row.prop(wrd, 'generate_gpu_skin')
if wrd.generate_gpu_skin:
row.prop(wrd, 'generate_gpu_skin_max_bones_auto')
if not wrd.generate_gpu_skin_max_bones_auto:
layout.prop(wrd, 'generate_gpu_skin_max_bones')
layout.prop(wrd, 'texture_filtering_state')
layout.prop(wrd, 'tessellation_enabled')
layout.prop(wrd, 'force_no_culling')
layout.prop(wrd, 'generate_two_sided_area_lamp')
layout.prop(wrd, 'generate_clouds')
if wrd.generate_clouds:
layout.prop(wrd, 'generate_clouds_density')
layout.prop(wrd, 'generate_clouds_size')
layout.prop(wrd, 'generate_clouds_lower')
layout.prop(wrd, 'generate_clouds_upper')
layout.prop(wrd, 'generate_clouds_wind')
layout.prop(wrd, 'generate_clouds_secondary')
layout.prop(wrd, 'generate_clouds_precipitation')
layout.prop(wrd, 'generate_clouds_eccentricity')
layout.label('SSAO')
# layout.prop(wrd, 'generate_ssao')
# if wrd.generate_ssao:
layout.prop(wrd, 'generate_ssao_size')
layout.prop(wrd, 'generate_ssao_strength')
layout.prop(wrd, 'generate_ssao_half_res')
layout.label('Bloom')
# layout.prop(wrd, 'generate_bloom')
# if wrd.generate_bloom:
layout.prop(wrd, 'generate_bloom_threshold')
layout.prop(wrd, 'generate_bloom_strength')
layout.prop(wrd, 'generate_bloom_radius')
layout.label('Motion Blur')
# layout.prop(wrd, 'generate_motion_blur')
# if wrd.generate_motion_blur:
layout.prop(wrd, 'generate_motion_blur_intensity')
layout.label('SSR')
# layout.prop(wrd, 'generate_ssr')
# if wrd.generate_ssr:
layout.prop(wrd, 'generate_ssr_ray_step')
layout.prop(wrd, 'generate_ssr_min_ray_step')
layout.prop(wrd, 'generate_ssr_search_dist')
layout.prop(wrd, 'generate_ssr_falloff_exp')
layout.prop(wrd, 'generate_ssr_jitter')
layout.prop(wrd, 'generate_ssr_half_res')
layout.label('SSRS')
layout.prop(wrd, 'generate_ssrs_ray_step')
layout.label('Volumetric Light')
# layout.prop(wrd, 'generate_volumetric_light')
# if wrd.generate_volumetric_light:
layout.prop(wrd, 'generate_volumetric_light_air_turbidity')
layout.prop(wrd, 'generate_volumetric_light_air_color')
layout.prop(wrd, 'generate_tonemap')
layout.prop(wrd, 'generate_letterbox')
if wrd.generate_letterbox:
layout.prop(wrd, 'generate_letterbox_size')
layout.prop(wrd, 'generate_grain')
if wrd.generate_grain:
layout.prop(wrd, 'generate_grain_strength')
layout.prop(wrd, 'generate_fog')
if wrd.generate_fog:
layout.prop(wrd, 'generate_fog_color')
layout.prop(wrd, 'generate_fog_amounta')
layout.prop(wrd, 'generate_fog_amountb')
layout.prop(wrd, 'generate_fisheye')
layout.prop(wrd, 'generate_vignette')
layout.prop(wrd, 'generate_lens_texture')
class ArmGenLodButton(bpy.types.Operator):
'''Automatically generate LoD levels'''
bl_idname = 'arm.generate_lod'
bl_label = 'Auto Generate'
def lod_name(self, name, level):
return name + '_LOD' + str(level + 1)
def execute(self, context):
obj = context.object
if obj == None:
return{'CANCELLED'}
# Clear
mdata = context.object.data
mdata.lodlist_index = 0
mdata.my_lodlist.clear()
# Lod levels
wrd = bpy.data.worlds['Arm']
ratio = wrd.arm_lod_gen_ratio
num_levels = wrd.arm_lod_gen_levels
for level in range(0, num_levels):
new_obj = obj.copy()
for i in range(0, 3):
new_obj.location[i] = 0
new_obj.rotation_euler[i] = 0
new_obj.scale[i] = 1
new_obj.data = obj.data.copy()
new_obj.name = self.lod_name(obj.name, level)
new_obj.parent = obj
new_obj.hide = True
new_obj.hide_render = True
mod = new_obj.modifiers.new('Decimate', 'DECIMATE')
mod.ratio = ratio
ratio *= wrd.arm_lod_gen_ratio
context.scene.objects.link(new_obj)
# Screen sizes
for level in range(0, num_levels):
mdata.my_lodlist.add()
mdata.my_lodlist[-1].name = self.lod_name(obj.name, level)
mdata.my_lodlist[-1].screen_size_prop = (1 - (1 / (num_levels + 1)) * level) - (1 / (num_levels + 1))
return{'FINISHED'}
class ArmLodPanel(bpy.types.Panel):
bl_label = "Armory Lod"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
obj = bpy.context.object
# Mesh only for now
if obj.type != 'MESH':
return
mdata = obj.data
rows = 2
if len(mdata.my_lodlist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_LodList", "The_List", mdata, "my_lodlist", mdata, "lodlist_index", rows=rows)
col = row.column(align=True)
col.operator("my_lodlist.new_item", icon='ZOOMIN', text="")
col.operator("my_lodlist.delete_item", icon='ZOOMOUT', text="")
if mdata.lodlist_index >= 0 and len(mdata.my_lodlist) > 0:
item = mdata.my_lodlist[mdata.lodlist_index]
row = layout.row()
row.prop_search(item, "name", bpy.data, "objects", "Object")
row = layout.row()
row.prop(item, "screen_size_prop")
# Auto lod for meshes
if obj.type == 'MESH':
layout.separator()
layout.operator("arm.generate_lod")
wrd = bpy.data.worlds['Arm']
row = layout.row()
row.prop(wrd, 'arm_lod_gen_levels')
row.prop(wrd, 'arm_lod_gen_ratio')
layout.prop(mdata, "lod_material")
def register():
bpy.utils.register_class(ObjectPropsPanel)
bpy.utils.register_class(ModifiersPropsPanel)
@ -816,6 +1069,8 @@ def register():
bpy.utils.register_class(ArmoryRenderPanel)
bpy.utils.register_class(ArmoryExporterPanel)
bpy.utils.register_class(ArmoryProjectPanel)
bpy.utils.register_class(ArmRenderPathPanel)
bpy.utils.register_class(ArmRenderPropsPanel)
# bpy.utils.register_class(ArmVirtualInputPanel)
# bpy.utils.register_class(ArmGlobalVarsPanel)
bpy.utils.register_class(ArmoryPlayButton)
@ -835,6 +1090,8 @@ def register():
bpy.utils.register_class(ArmoryRenderAnimButton)
bpy.utils.register_class(ArmoryGenerateNavmeshButton)
bpy.utils.register_class(ArmNavigationPanel)
bpy.utils.register_class(ArmGenLodButton)
bpy.utils.register_class(ArmLodPanel)
bpy.types.VIEW3D_HT_header.append(draw_view3d_header)
bpy.types.INFO_HT_header.prepend(draw_info_header)
@ -857,6 +1114,8 @@ def unregister():
bpy.utils.unregister_class(ArmoryRenderPanel)
bpy.utils.unregister_class(ArmoryExporterPanel)
bpy.utils.unregister_class(ArmoryProjectPanel)
bpy.utils.unregister_class(ArmRenderPathPanel)
bpy.utils.unregister_class(ArmRenderPropsPanel)
# bpy.utils.unregister_class(ArmVirtualInputPanel)
# bpy.utils.unregister_class(ArmGlobalVarsPanel)
bpy.utils.unregister_class(ArmoryPlayButton)
@ -876,3 +1135,5 @@ def unregister():
bpy.utils.unregister_class(ArmoryRenderAnimButton)
bpy.utils.unregister_class(ArmoryGenerateNavmeshButton)
bpy.utils.unregister_class(ArmNavigationPanel)
bpy.utils.unregister_class(ArmGenLodButton)
bpy.utils.unregister_class(ArmLodPanel)

View file

@ -66,7 +66,7 @@ project.addSources('Sources');
f.write(add_armory_library(sdk_path, 'iron'))
# Project libraries
for lib in wrd.my_librarytraitlist:
for lib in wrd.arm_librarylist:
if lib.enabled_prop:
f.write('project.addLibrary("{0}");\n'.format(lib.name))
@ -249,7 +249,7 @@ def write_indexhtml(w, h):
<html>
<head>
<meta charset="utf-8"/>""")
if bpy.data.cameras[0].rp_stereo:
if bpy.data.worlds['Arm'].rp_stereo:
f.write("""
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<style>
@ -263,7 +263,7 @@ def write_indexhtml(w, h):
</head>
<body style="margin: 0; padding: 0;">
""")
if bpy.data.cameras[0].rp_stereo:
if bpy.data.worlds['Arm'].rp_stereo:
f.write("""
<canvas style="width: 100vw; height: 100vh; display: block;" id='khanvas'></canvas>
""")
@ -387,9 +387,9 @@ const float compoDOFFstop = """ + str(round(bpy.data.cameras[0].gpu_dof.fstop *
const float compoDOFLength = 160.0;
""") # str(round(bpy.data.cameras[0].lens * 100) / 100)
if bpy.data.cameras[0].rp_voxelgi:
if bpy.data.worlds['Arm'].rp_voxelgi:
f.write(
"""const float voxelgiResolution = """ + str(bpy.data.cameras[0].rp_voxelgi_resolution) + """;
"""const float voxelgiResolution = """ + str(bpy.data.worlds['Arm'].rp_voxelgi_resolution) + """;
const float voxelgiDimensions = """ + str(round(wrd.generate_voxelgi_dimensions)) + """;
const float voxelgiDiff = """ + str(round(wrd.voxelgi_diff * 100) / 100) + """;
const float voxelgiSpec = """ + str(round(wrd.voxelgi_spec * 100) / 100) + """;
@ -399,7 +399,7 @@ const float voxelgiStep = """ + str(round(wrd.voxelgi_step * 100) / 100) + """;
const float voxelgiRange = """ + str(round(wrd.voxelgi_range * 100) / 100) + """;
""")
if bpy.data.cameras[0].rp_sss_state == 'On':
if bpy.data.worlds['Arm'].rp_sss_state == 'On':
f.write(
"""const float sssWidth = """ + str(wrd.sss_width / 10.0) + """;
""")

View file

@ -8,7 +8,6 @@ import arm.props_traits
import arm.props_lod
import arm.props
import arm.props_ui
import arm.props_renderer
import arm.handlers
import arm.space_armory
import arm.utils
@ -23,7 +22,6 @@ def register():
arm.props_traits_library.register()
arm.props.register()
arm.props_ui.register()
arm.props_renderer.register()
arm.nodes_logic.register()
arm.nodes_renderpath.register()
arm.make_renderer.register()
@ -48,7 +46,6 @@ def unregister():
arm.props_traits.unregister()
arm.props_lod.unregister()
arm.handlers.unregister()
arm.props_renderer.unregister()
arm.props_ui.unregister()
arm.props.unregister()
arm.props_traits_library.unregister()