def parse_sky_hosekwilkie(node: bpy.types.ShaderNodeTexSky, state: ParserState) -> vec3str: world = state.world curshader = state.curshader # Match to cycles world.arm_envtex_strength *= 0.1 assets.add_khafile_def('arm_hosek') curshader.add_uniform('vec3 A', link="_hosekA") curshader.add_uniform('vec3 B', link="_hosekB") curshader.add_uniform('vec3 C', link="_hosekC") curshader.add_uniform('vec3 D', link="_hosekD") curshader.add_uniform('vec3 E', link="_hosekE") curshader.add_uniform('vec3 F', link="_hosekF") curshader.add_uniform('vec3 G', link="_hosekG") curshader.add_uniform('vec3 H', link="_hosekH") curshader.add_uniform('vec3 I', link="_hosekI") curshader.add_uniform('vec3 Z', link="_hosekZ") curshader.add_uniform('vec3 hosekSunDirection', link="_hosekSunDirection") curshader.add_function("""vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) { \tvec3 chi = (1 + cos_gamma * cos_gamma) / pow(1 + H * H - 2 * cos_gamma * H, vec3(1.5)); \treturn (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta)); }""") world.arm_envtex_sun_direction = [node.sun_direction[0], node.sun_direction[1], node.sun_direction[2]] world.arm_envtex_turbidity = node.turbidity world.arm_envtex_ground_albedo = node.ground_albedo wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' if not state.radiance_written: # Irradiance json file name wname = arm.utils.safestr(world.name) world.arm_envtex_irr_name = wname write_probes.write_sky_irradiance(wname) # Radiance if rpdat.arm_radiance and rpdat.arm_irradiance and not mobile_mat: wrd.world_defs += '_Rad' hosek_path = 'armory/Assets/hosek/' sdk_path = arm.utils.get_sdk_path() # Use fake maps for now assets.add(sdk_path + '/' + hosek_path + 'hosek_radiance.hdr') for i in range(0, 8): assets.add(sdk_path + '/' + hosek_path + 'hosek_radiance_' + str(i) + '.hdr') world.arm_envtex_name = 'hosek' world.arm_envtex_num_mips = 8 state.radiance_written = True curshader.write('float cos_theta = clamp(pos.z, 0.0, 1.0);') curshader.write('float cos_gamma = dot(pos, hosekSunDirection);') curshader.write('float gamma_val = acos(cos_gamma);') return 'Z * hosekWilkie(cos_theta, gamma_val, cos_gamma) * envmapStrength;'
def make_rpath(): assets_path = arm.utils.get_sdk_path() + 'armory/Assets/' wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() if rpdat.rp_hdr: assets.add_khafile_def('rp_hdr') else: wrd.world_defs += '_LDR' if rpdat.rp_shadows: wrd.world_defs += '_ShadowMap' assets.add_khafile_def('rp_shadowmap') assets.add_khafile_def('rp_shadowmap_cascade={0}'.format(rpdat.rp_shadowmap_cascade)) assets.add_khafile_def('rp_shadowmap_cube={0}'.format(rpdat.rp_shadowmap_cube)) assets.add_khafile_def('rp_background={0}'.format(rpdat.rp_background)) if rpdat.rp_background == 'World': assets.add_shader_pass('world_pass') if '_EnvClouds' in wrd.world_defs: assets.add(assets_path + 'noise256.png') assets.add_embedded_data('noise256.png') if rpdat.rp_render_to_texture: assets.add_khafile_def('rp_render_to_texture') if rpdat.rp_compositornodes: assets.add_khafile_def('rp_compositornodes') compo_depth = False if rpdat.arm_tonemap != 'Off': wrd.compo_defs = '_CTone' + rpdat.arm_tonemap if rpdat.rp_antialiasing == 'FXAA': wrd.compo_defs += '_CFXAA' if rpdat.arm_letterbox: wrd.compo_defs += '_CLetterbox' if rpdat.arm_grain: wrd.compo_defs += '_CGrain' if bpy.data.scenes[0].cycles.film_exposure != 1.0: wrd.compo_defs += '_CExposure' if rpdat.arm_fog: wrd.compo_defs += '_CFog' compo_depth = True if len(bpy.data.cameras) > 0 and bpy.data.cameras[0].dof_distance > 0.0: wrd.compo_defs += '_CDOF' compo_depth = True if compo_depth: wrd.compo_defs += '_CDepth' assets.add_khafile_def('rp_compositordepth') if rpdat.arm_lens_texture != '': wrd.compo_defs += '_CLensTex' assets.add_embedded_data('lenstexture.jpg') if rpdat.arm_fisheye: wrd.compo_defs += '_CFishEye' if rpdat.arm_vignette: wrd.compo_defs += '_CVignette' if rpdat.arm_lensflare: wrd.compo_defs += '_CGlare' if rpdat.arm_lut_texture != '': wrd.compo_defs += '_CLUT' assets.add_embedded_data('luttexture.jpg') if '_CDOF' in wrd.compo_defs or '_CFXAA' in wrd.compo_defs or '_CSharpen' in wrd.compo_defs: wrd.compo_defs += '_CTexStep' if '_CDOF' in wrd.compo_defs or '_CFog' in wrd.compo_defs or '_CGlare' in wrd.compo_defs: wrd.compo_defs += '_CCameraProj' assets.add_shader_pass('compositor_pass') else: assets.add_shader_pass('copy_pass') assets.add_khafile_def('rp_antialiasing={0}'.format(rpdat.rp_antialiasing)) if rpdat.rp_antialiasing == 'SMAA' or rpdat.rp_antialiasing == 'TAA': assets.add_shader_pass('smaa_edge_detect') assets.add_shader_pass('smaa_blend_weight') assets.add_shader_pass('smaa_neighborhood_blend') assets.add(assets_path + 'smaa_area.png') assets.add(assets_path + 'smaa_search.png') assets.add_embedded_data('smaa_area.png') assets.add_embedded_data('smaa_search.png') wrd.world_defs += '_SMAA' if rpdat.rp_antialiasing == 'TAA': assets.add_shader_pass('taa_pass') assets.add_shader_pass('copy_pass') if rpdat.rp_antialiasing == 'TAA' or rpdat.rp_motionblur == 'Object': assets.add_khafile_def('arm_veloc') wrd.world_defs += '_Veloc' if rpdat.rp_antialiasing == 'TAA': assets.add_khafile_def('arm_taa') assets.add_khafile_def('rp_supersampling={0}'.format(rpdat.rp_supersampling)) if rpdat.rp_supersampling == '4': assets.add_shader_pass('supersample_resolve') if rpdat.rp_volumetriclight: wrd.world_defs += '_Sun' assets.add_khafile_def('rp_volumetriclight') assets.add_shader_pass('volumetric_light') assets.add_shader_pass('blur_bilat_pass') assets.add_shader_pass('blur_bilat_blend_pass') assets.add(assets_path + 'blue_noise64.png') assets.add_embedded_data('blue_noise64.png') if rpdat.rp_bloom: assets.add_khafile_def('rp_bloom') assets.add_shader_pass('bloom_pass') assets.add_shader_pass('blur_gaus_pass') if rpdat.arm_rp_resolution == 'Custom': assets.add_khafile_def('rp_resolution_filter={0}'.format(rpdat.arm_rp_resolution_filter))
def write_khafilejs(is_play, export_physics: bool, export_navigation: bool, export_ui: bool, is_publish: bool, import_traits: List[str]) -> None: wrd = bpy.data.worlds['Arm'] sdk_path = arm.utils.get_sdk_path() rel_path = arm.utils.get_relative_paths() # Convert absolute paths to relative project_path = arm.utils.get_fp() build_dir = arm.utils.build_dir() # Whether to use relative paths for paths inside the SDK do_relpath_sdk = rel_path and on_same_drive(sdk_path, project_path) with open('khafile.js', 'w', encoding="utf-8") as khafile: khafile.write( """// Auto-generated let project = new Project('""" + arm.utils.safesrc(wrd.arm_project_name + '-' + wrd.arm_project_version) + """'); project.addSources('Sources'); """) # Auto-add assets located in Bundled directory if os.path.exists('Bundled'): for file in glob.glob("Bundled/**", recursive=True): if os.path.isfile(file): assets.add(file) # Auto-add shape key textures if exists if os.path.exists('MorphTargets'): for file in glob.glob("MorphTargets/**", recursive=True): if os.path.isfile(file): assets.add(file) # Add project shaders if os.path.exists('Shaders'): # Copy to enable includes shader_path = os.path.join(build_dir, 'compiled', 'Shaders', 'Project') if os.path.exists(shader_path): shutil.rmtree(shader_path, onerror=remove_readonly) shutil.copytree('Shaders', shader_path) khafile.write("project.addShaders('" + build_dir + "/compiled/Shaders/Project/**');\n") # for file in glob.glob("Shaders/**", recursive=True): # if os.path.isfile(file): # assets.add_shader(file) # Add engine sources if the project does not use its own armory/iron versions if not os.path.exists(os.path.join('Libraries', 'armory')): khafile.write(add_armory_library(sdk_path, 'armory', rel_path=do_relpath_sdk)) if not os.path.exists(os.path.join('Libraries', 'iron')): khafile.write(add_armory_library(sdk_path, 'iron', rel_path=do_relpath_sdk)) # Project libraries if os.path.exists('Libraries'): libs = os.listdir('Libraries') for lib in libs: if os.path.isdir('Libraries/' + lib): khafile.write('project.addLibrary("{0}");\n'.format(lib.replace('//', '/'))) # Subprojects, merge this with libraries if os.path.exists('Subprojects'): libs = os.listdir('Subprojects') for lib in libs: if os.path.isdir('Subprojects/' + lib): khafile.write('await project.addProject("Subprojects/{0}");\n'.format(lib)) if state.target.startswith('krom'): assets.add_khafile_def('js-es=6') if export_physics: assets.add_khafile_def('arm_physics') if wrd.arm_physics_engine == 'Bullet': assets.add_khafile_def('arm_bullet') if not os.path.exists('Libraries/haxebullet'): khafile.write(add_armory_library(sdk_path + '/lib/', 'haxebullet', rel_path=do_relpath_sdk)) if state.target.startswith('krom'): ammojs_path = sdk_path + '/lib/haxebullet/ammo/ammo.wasm.js' ammojs_path = ammojs_path.replace('\\', '/').replace('//', '/') khafile.write(add_assets(ammojs_path, rel_path=do_relpath_sdk)) ammojs_wasm_path = sdk_path + '/lib/haxebullet/ammo/ammo.wasm.wasm' ammojs_wasm_path = ammojs_wasm_path.replace('\\', '/').replace('//', '/') khafile.write(add_assets(ammojs_wasm_path, rel_path=do_relpath_sdk)) elif state.target == 'html5' or state.target == 'node': ammojs_path = sdk_path + '/lib/haxebullet/ammo/ammo.js' ammojs_path = ammojs_path.replace('\\', '/').replace('//', '/') khafile.write(add_assets(ammojs_path, rel_path=do_relpath_sdk)) elif wrd.arm_physics_engine == 'Oimo': assets.add_khafile_def('arm_oimo') if not os.path.exists('Libraries/oimo'): khafile.write(add_armory_library(sdk_path + '/lib/', 'oimo', rel_path=do_relpath_sdk)) if export_navigation: assets.add_khafile_def('arm_navigation') if not os.path.exists('Libraries/haxerecast'): khafile.write(add_armory_library(sdk_path + '/lib/', 'haxerecast', rel_path=do_relpath_sdk)) if state.target.startswith('krom') or state.target == 'html5': recastjs_path = sdk_path + '/lib/haxerecast/js/recast/recast.js' recastjs_path = recastjs_path.replace('\\', '/').replace('//', '/') khafile.write(add_assets(recastjs_path, rel_path=do_relpath_sdk)) if is_publish: assets.add_khafile_def('arm_published') if wrd.arm_dce: khafile.write("project.addParameter('-dce full');\n") if wrd.arm_no_traces: khafile.write("project.addParameter('--no-traces');\n") if wrd.arm_asset_compression: assets.add_khafile_def('arm_compress') else: assets.add_khafile_def(f'arm_assert_level={wrd.arm_assert_level}') if wrd.arm_assert_quit: assets.add_khafile_def('arm_assert_quit') # khafile.write("""project.addParameter("--macro include('armory.trait')");\n""") # khafile.write("""project.addParameter("--macro include('armory.trait.internal')");\n""") # if export_physics: # khafile.write("""project.addParameter("--macro include('armory.trait.physics')");\n""") # if wrd.arm_physics_engine == 'Bullet': # khafile.write("""project.addParameter("--macro include('armory.trait.physics.bullet')");\n""") # else: # khafile.write("""project.addParameter("--macro include('armory.trait.physics.oimo')");\n""") # if export_navigation: # khafile.write("""project.addParameter("--macro include('armory.trait.navigation')");\n""") if not wrd.arm_compiler_inline: khafile.write("project.addParameter('--no-inline');\n") use_live_patch = arm.utils.is_livepatch_enabled() if wrd.arm_debug_console or use_live_patch: import_traits.append('armory.trait.internal.Bridge') if use_live_patch: assets.add_khafile_def('arm_patch') # Include all logic node classes so that they can later # get instantiated khafile.write("""project.addParameter("--macro include('armory.logicnode')");\n""") import_traits = list(set(import_traits)) for i in range(0, len(import_traits)): khafile.write("project.addParameter('" + import_traits[i] + "');\n") khafile.write("""project.addParameter("--macro keep('""" + import_traits[i] + """')");\n""") noembed = wrd.arm_cache_build and not is_publish and state.target == 'krom' if noembed: # Load shaders manually assets.add_khafile_def('arm_noembed') noembed = False # TODO: always embed shaders for now, check compatibility with haxe compile server shaders_path = build_dir + '/compiled/Shaders/*.glsl' if rel_path: shaders_path = os.path.relpath(shaders_path, project_path).replace('\\', '/') khafile.write('project.addShaders("' + shaders_path + '", { noembed: ' + str(noembed).lower() + '});\n') if arm.utils.get_gapi() == 'direct3d11': # noprocessing flag - gets renamed to .d3d11 shaders_path = build_dir + '/compiled/Hlsl/*.glsl' if rel_path: shaders_path = os.path.relpath(shaders_path, project_path).replace('\\', '/') khafile.write('project.addShaders("' + shaders_path + '", { noprocessing: true, noembed: ' + str(noembed).lower() + ' });\n') # Move assets for published game to /data folder use_data_dir = is_publish and (state.target == 'krom-windows' or state.target == 'krom-linux' or state.target == 'windows-hl' or state.target == 'linux-hl') if use_data_dir: assets.add_khafile_def('arm_data_dir') ext = 'arm' if wrd.arm_minimize else 'json' assets_path = build_dir + '/compiled/Assets/**' assets_path_sh = build_dir + '/compiled/Shaders/*.' + ext if rel_path: assets_path = os.path.relpath(assets_path, project_path).replace('\\', '/') assets_path_sh = os.path.relpath(assets_path_sh, project_path).replace('\\', '/') dest = '' if use_data_dir: dest += ', destination: "data/{name}"' khafile.write('project.addAssets("' + assets_path + '", { notinlist: true ' + dest + '});\n') khafile.write('project.addAssets("' + assets_path_sh + '", { notinlist: true ' + dest + '});\n') shader_data_references = sorted(list(set(assets.shader_datas))) for ref in shader_data_references: ref = ref.replace('\\', '/').replace('//', '/') if '/compiled/' in ref: # Asset already included continue do_relpath_shaders = rel_path and on_same_drive(ref, project_path) khafile.write(add_assets(ref, use_data_dir=use_data_dir, rel_path=do_relpath_shaders)) asset_references = sorted(list(set(assets.assets))) for ref in asset_references: ref = ref.replace('\\', '/').replace('//', '/') if '/compiled/' in ref: # Asset already included continue quality = 1.0 s = ref.lower() if s.endswith('.wav'): quality = wrd.arm_sound_quality elif s.endswith('.png') or s.endswith('.jpg'): quality = wrd.arm_texture_quality do_relpath_assets = rel_path and on_same_drive(ref, project_path) khafile.write(add_assets(ref, quality=quality, use_data_dir=use_data_dir, rel_path=do_relpath_assets)) if wrd.arm_sound_quality < 1.0 or state.target == 'html5': assets.add_khafile_def('arm_soundcompress') if wrd.arm_audio == 'Disabled': assets.add_khafile_def('kha_no_ogg') else: assets.add_khafile_def('arm_audio') if wrd.arm_texture_quality < 1.0: assets.add_khafile_def('arm_texcompress') if wrd.arm_debug_console: assets.add_khafile_def('arm_debug') khafile.write(add_shaders(sdk_path + "/armory/Shaders/debug_draw/**", rel_path=do_relpath_sdk)) if not is_publish and state.target == 'html5': khafile.write("project.addParameter('--debug');\n") if arm.utils.get_pref_or_default('haxe_times', False): khafile.write("project.addParameter('--times');\n") if export_ui: if not os.path.exists('Libraries/zui'): khafile.write(add_armory_library(sdk_path, 'lib/zui', rel_path=do_relpath_sdk)) p = sdk_path + '/armory/Assets/font_default.ttf' p = p.replace('//', '/') khafile.write(add_assets(p.replace('\\', '/'), use_data_dir=use_data_dir, rel_path=do_relpath_sdk)) assets.add_khafile_def('arm_ui') if not wrd.arm_minimize: assets.add_khafile_def('arm_json') if wrd.arm_deinterleaved_buffers: assets.add_khafile_def('arm_deinterleaved') if wrd.arm_batch_meshes: assets.add_khafile_def('arm_batch') if wrd.arm_stream_scene: assets.add_khafile_def('arm_stream') rpdat = arm.utils.get_rp() if rpdat.arm_skin != 'Off': assets.add_khafile_def('arm_skin') if rpdat.arm_morph_target != 'Off': assets.add_khafile_def('arm_morph_target') if rpdat.arm_particles != 'Off': assets.add_khafile_def('arm_particles') if rpdat.rp_draw_order == 'Shader': assets.add_khafile_def('arm_draworder_shader') if arm.utils.get_viewport_controls() == 'azerty': assets.add_khafile_def('arm_azerty') if os.path.exists(project_path + '/Bundled/config.arm'): assets.add_khafile_def('arm_config') if is_publish and wrd.arm_loadscreen: assets.add_khafile_def('arm_loadscreen') if wrd.arm_winresize or state.target == 'html5': assets.add_khafile_def('arm_resizable') # if bpy.data.scenes[0].unit_settings.system_rotation == 'DEGREES': # assets.add_khafile_def('arm_degrees') # Allow libraries to recognize Armory assets.add_khafile_def('armory') for d in assets.khafile_defs: khafile.write("project.addDefine('" + d + "');\n") for p in assets.khafile_params: khafile.write("project.addParameter('" + p + "');\n") if state.target.startswith('android'): bundle = 'org.armory3d.' + wrd.arm_project_package if wrd.arm_project_bundle == '' else wrd.arm_project_bundle khafile.write("project.targetOptions.android_native.package = '{0}';\n".format(arm.utils.safestr(bundle))) if wrd.arm_winorient != 'Multi': khafile.write("project.targetOptions.android_native.screenOrientation = '{0}';\n".format(wrd.arm_winorient.lower())) # Android SDK Versions khafile.write("project.targetOptions.android_native.compileSdkVersion = '{0}';\n".format(wrd.arm_project_android_sdk_compile)) khafile.write("project.targetOptions.android_native.minSdkVersion = '{0}';\n".format(wrd.arm_project_android_sdk_min)) khafile.write("project.targetOptions.android_native.targetSdkVersion = '{0}';\n".format(wrd.arm_project_android_sdk_target)) # Permissions if len(wrd.arm_exporter_android_permission_list) > 0: perms = '' for item in wrd.arm_exporter_android_permission_list: perm = "'android.permission."+ item.arm_android_permissions + "'" # Checking In if perms.find(perm) == -1: if len(perms) > 0: perms = perms + ', ' + perm else: perms = perm if len(perms) > 0: khafile.write("project.targetOptions.android_native.permissions = [{0}];\n".format(perms)) # Android ABI Filters if len(wrd.arm_exporter_android_abi_list) > 0: abis = '' for item in wrd.arm_exporter_android_abi_list: abi = "'"+ item.arm_android_abi + "'" # Checking In if abis.find(abi) == -1: if len(abis) > 0: abis = abis + ', ' + abi else: abis = abi if len(abis) > 0: khafile.write("project.targetOptions.android_native.abiFilters = [{0}];\n".format(abis)) elif state.target.startswith('ios'): bundle = 'org.armory3d.' + wrd.arm_project_package if wrd.arm_project_bundle == '' else wrd.arm_project_bundle khafile.write("project.targetOptions.ios.bundle = '{0}';\n".format(arm.utils.safestr(bundle))) if wrd.arm_project_icon != '': shutil.copy(bpy.path.abspath(wrd.arm_project_icon), project_path + '/icon.png') if wrd.arm_khafile is not None: khafile.write(wrd.arm_khafile.as_string()) khafile.write("\n\nresolve(project);\n")
def build_node_tree(world): output = {} dat = {} output['material_datas'] = [dat] wname = arm.utils.safestr(world.name) dat['name'] = wname + '_material' context = {} dat['contexts'] = [context] context['name'] = 'world' context['bind_constants'] = [] context['bind_textures'] = [] bpy.data.worlds['Arm'].world_defs = '' # Traverse world node tree output_node = nodes.get_node_by_type(world.node_tree, 'OUTPUT_WORLD') if output_node != None: parse_world_output(world, output_node, context) # Clear to color if no texture or sky is provided wrd = bpy.data.worlds['Arm'] if '_EnvSky' not in wrd.world_defs and '_EnvTex' not in wrd.world_defs: if '_EnvImg' not in wrd.world_defs: wrd.world_defs += '_EnvCol' # Irradiance json file name world.world_envtex_name = wname world.world_envtex_irr_name = wname write_probes.write_color_irradiance(wname, world.world_envtex_color) # Clouds enabled if wrd.generate_clouds: wrd.world_defs += '_EnvClouds' # Percentage closer soft shadows if wrd.generate_pcss_state == 'On': wrd.world_defs += '_PCSS' sdk_path = arm.utils.get_sdk_path() assets.add(sdk_path + 'armory/Assets/noise64.png') assets.add_embedded_data('noise64.png') # Screen-space ray-traced shadows if wrd.generate_ssrs: wrd.world_defs += '_SSRS' if wrd.generate_two_sided_area_lamp: wrd.world_defs += '_TwoSidedAreaLamp' # Alternative models if wrd.lighting_model == 'Cycles': wrd.world_defs += '_Cycles' # TODO: Lamp texture test.. if wrd.generate_lamp_texture != '': bpy.data.worlds['Arm'].world_defs += '_LampColTex' if not wrd.generate_lamp_falloff: bpy.data.worlds['Arm'].world_defs += '_NoLampFalloff' voxelgi = False for cam in bpy.data.cameras: if cam.is_probe: wrd.world_defs += '_Probes' 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 voxelgi: assets.add_khafile_def('arm_voxelgi') if wrd.voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if wrd.voxelgi_multibounce: wrd.world_defs += '_VoxelGIMulti' wrd.world_defs += '_VoxelGI' wrd.world_defs += '_Rad' # Always do radiance for voxels wrd.world_defs += '_Irr' if arm.utils.get_gapi().startswith( 'direct3d'): # Flip Y axis in drawQuad command wrd.world_defs += '_InvY' # Area lamps for lamp in bpy.data.lamps: if lamp.type == 'AREA': wrd.world_defs += '_PolyLight' break # Data will be written after render path has been processed to gather all defines return output
def build(): rpdat = arm.utils.get_rp() if rpdat.rp_driver != 'Armory' and arm.api.drivers[ rpdat.rp_driver]['make_rpath'] != None: arm.api.drivers[rpdat.rp_driver]['make_rpath']() return assets_path = arm.utils.get_sdk_path() + '/armory/Assets/' wrd = bpy.data.worlds['Arm'] add_world_defs() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' if not mobile_mat: # Always include assets.add(assets_path + 'brdf.png') assets.add_embedded_data('brdf.png') if rpdat.rp_hdr: assets.add_khafile_def('rp_hdr') assets.add_khafile_def('rp_renderer={0}'.format(rpdat.rp_renderer)) if rpdat.rp_depthprepass: assets.add_khafile_def('rp_depthprepass') if rpdat.rp_shadows: assets.add_khafile_def('rp_shadowmap') assets.add_khafile_def('rp_shadowmap_cascade={0}'.format( arm.utils.get_cascade_size(rpdat))) assets.add_khafile_def('rp_shadowmap_cube={0}'.format( rpdat.rp_shadowmap_cube)) assets.add_khafile_def('rp_background={0}'.format(rpdat.rp_background)) if rpdat.rp_background == 'World': assets.add_shader_pass('world_pass') if '_EnvClouds' in wrd.world_defs: assets.add(assets_path + 'clouds_base.raw') assets.add_embedded_data('clouds_base.raw') assets.add(assets_path + 'clouds_detail.raw') assets.add_embedded_data('clouds_detail.raw') assets.add(assets_path + 'clouds_map.png') assets.add_embedded_data('clouds_map.png') if rpdat.rp_renderer == 'Deferred' and not rpdat.rp_compositornodes: assets.add_shader_pass('copy_pass') if rpdat.rp_render_to_texture: assets.add_khafile_def('rp_render_to_texture') if rpdat.rp_renderer == 'Forward' and not rpdat.rp_compositornodes: assets.add_shader_pass('copy_pass') if rpdat.rp_compositornodes: assets.add_khafile_def('rp_compositornodes') compo_depth = False if rpdat.arm_tonemap != 'Off': wrd.compo_defs = '_CTone' + rpdat.arm_tonemap if rpdat.rp_antialiasing == 'FXAA': wrd.compo_defs += '_CFXAA' if rpdat.arm_letterbox: wrd.compo_defs += '_CLetterbox' if rpdat.arm_grain: wrd.compo_defs += '_CGrain' if rpdat.arm_sharpen: wrd.compo_defs += '_CSharpen' if bpy.data.scenes[0].view_settings.exposure != 0.0: wrd.compo_defs += '_CExposure' if rpdat.arm_fog: wrd.compo_defs += '_CFog' compo_depth = True focus_distance = 0.0 if len(bpy.data.cameras) > 0 and bpy.data.cameras[0].dof.use_dof: focus_distance = bpy.data.cameras[0].dof.focus_distance if focus_distance > 0.0: wrd.compo_defs += '_CDOF' compo_depth = True if rpdat.arm_lens_texture != '': wrd.compo_defs += '_CLensTex' assets.add_embedded_data('lenstexture.jpg') if rpdat.arm_lens_texture_masking: wrd.compo_defs += '_CLensTexMasking' if rpdat.arm_fisheye: wrd.compo_defs += '_CFishEye' if rpdat.arm_vignette: wrd.compo_defs += '_CVignette' if rpdat.arm_lensflare: wrd.compo_defs += '_CGlare' compo_depth = True if rpdat.arm_lut_texture != '': wrd.compo_defs += '_CLUT' assets.add_embedded_data('luttexture.jpg') if '_CDOF' in wrd.compo_defs or '_CFXAA' in wrd.compo_defs or '_CSharpen' in wrd.compo_defs: wrd.compo_defs += '_CTexStep' if '_CDOF' in wrd.compo_defs or '_CFog' in wrd.compo_defs or '_CGlare' in wrd.compo_defs: wrd.compo_defs += '_CCameraProj' if compo_depth: wrd.compo_defs += '_CDepth' assets.add_khafile_def('rp_compositordepth') if rpdat.rp_pp: wrd.compo_defs += '_CPostprocess' assets.add_shader_pass('compositor_pass') assets.add_khafile_def('rp_antialiasing={0}'.format( rpdat.rp_antialiasing)) if rpdat.rp_antialiasing == 'SMAA' or rpdat.rp_antialiasing == 'TAA': assets.add_shader_pass('smaa_edge_detect') assets.add_shader_pass('smaa_blend_weight') assets.add_shader_pass('smaa_neighborhood_blend') assets.add(assets_path + 'smaa_area.png') assets.add(assets_path + 'smaa_search.png') assets.add_embedded_data('smaa_area.png') assets.add_embedded_data('smaa_search.png') wrd.world_defs += '_SMAA' if rpdat.rp_antialiasing == 'TAA': assets.add_shader_pass('taa_pass') assets.add_shader_pass('copy_pass') if rpdat.rp_antialiasing == 'TAA' or rpdat.rp_motionblur == 'Object': assets.add_khafile_def('arm_veloc') wrd.world_defs += '_Veloc' if rpdat.rp_antialiasing == 'TAA': assets.add_khafile_def('arm_taa') assets.add_khafile_def('rp_supersampling={0}'.format( rpdat.rp_supersampling)) if rpdat.rp_supersampling == '4': assets.add_shader_pass('supersample_resolve') assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi)) if rpdat.rp_ssgi != 'Off': wrd.world_defs += '_SSAO' if rpdat.rp_ssgi == 'SSAO': assets.add_shader_pass('ssao_pass') assets.add_shader_pass('blur_edge_pass') else: assets.add_shader_pass('ssgi_pass') assets.add_shader_pass('blur_edge_pass') if rpdat.arm_ssgi_half_res: assets.add_khafile_def('rp_ssgi_half') if rpdat.rp_bloom: assets.add_khafile_def('rp_bloom') assets.add_shader_pass('bloom_pass') assets.add_shader_pass('blur_gaus_pass') if rpdat.rp_ssr: assets.add_khafile_def('rp_ssr') assets.add_shader_pass('ssr_pass') assets.add_shader_pass('blur_adaptive_pass') if rpdat.arm_ssr_half_res: assets.add_khafile_def('rp_ssr_half') if rpdat.rp_overlays: assets.add_khafile_def('rp_overlays') if rpdat.rp_translucency: assets.add_khafile_def('rp_translucency') assets.add_shader_pass('translucent_resolve') if rpdat.rp_stereo: assets.add_khafile_def('rp_stereo') assets.add_khafile_def('arm_vr') wrd.world_defs += '_VR' has_voxels = arm.utils.voxel_support() if rpdat.rp_voxelao and has_voxels and rpdat.arm_material_model == 'Full': assets.add_khafile_def('rp_voxelao') assets.add_khafile_def('rp_voxelgi_resolution={0}'.format( rpdat.rp_voxelgi_resolution)) assets.add_khafile_def('rp_voxelgi_resolution_z={0}'.format( rpdat.rp_voxelgi_resolution_z)) if rpdat.arm_rp_resolution == 'Custom': assets.add_khafile_def('rp_resolution_filter={0}'.format( rpdat.arm_rp_resolution_filter)) if rpdat.rp_renderer == 'Deferred': if rpdat.arm_material_model == 'Full': assets.add_shader_pass('deferred_light') else: # mobile, solid assets.add_shader_pass('deferred_light_' + rpdat.arm_material_model.lower()) assets.add_khafile_def('rp_material_' + rpdat.arm_material_model.lower()) if len(bpy.data.lightprobes) > 0: wrd.world_defs += '_Probes' assets.add_khafile_def('rp_probes') assets.add_shader_pass('probe_planar') assets.add_shader_pass('probe_cubemap') assets.add_shader_pass('copy_pass') if rpdat.rp_volumetriclight: assets.add_khafile_def('rp_volumetriclight') assets.add_shader_pass('volumetric_light') assets.add_shader_pass('blur_bilat_pass') assets.add_shader_pass('blur_bilat_blend_pass') assets.add(assets_path + 'blue_noise64.png') assets.add_embedded_data('blue_noise64.png') if rpdat.rp_decals: assets.add_khafile_def('rp_decals') if rpdat.rp_water: assets.add_khafile_def('rp_water') assets.add_shader_pass('water_pass') assets.add_shader_pass('copy_pass') assets.add(assets_path + 'water_base.png') assets.add_embedded_data('water_base.png') assets.add(assets_path + 'water_detail.png') assets.add_embedded_data('water_detail.png') assets.add(assets_path + 'water_foam.png') assets.add_embedded_data('water_foam.png') if rpdat.rp_blending: assets.add_khafile_def('rp_blending') if rpdat.rp_sss: assets.add_khafile_def('rp_sss') wrd.world_defs += '_SSS' assets.add_shader_pass('sss_pass') if (rpdat.rp_ssr and rpdat.arm_ssr_half_res) or (rpdat.rp_ssgi != 'Off' and rpdat.arm_ssgi_half_res): assets.add_shader_pass('downsample_depth') if rpdat.rp_motionblur != 'Off': assets.add_khafile_def('rp_motionblur={0}'.format(rpdat.rp_motionblur)) assets.add_shader_pass('copy_pass') if rpdat.rp_motionblur == 'Camera': assets.add_shader_pass('motion_blur_pass') else: assets.add_shader_pass('motion_blur_veloc_pass') if rpdat.rp_compositornodes and rpdat.rp_autoexposure: assets.add_khafile_def('rp_autoexposure') assets.add_shader_pass('histogram_pass') if rpdat.rp_dynres: assets.add_khafile_def('rp_dynres') if rpdat.rp_pp: assets.add_khafile_def('rp_pp') if rpdat.rp_chromatic_aberration: assets.add_shader_pass('copy_pass') assets.add_khafile_def('rp_chromatic_aberration') assets.add_shader_pass('chromatic_aberration_pass') gbuffer2 = '_Veloc' in wrd.world_defs if gbuffer2: assets.add_khafile_def('rp_gbuffer2') wrd.world_defs += '_gbuffer2' if callback != None: callback()
def add_world_defs(): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() # Screen-space ray-traced shadows if rpdat.arm_ssrs: wrd.world_defs += '_SSRS' if rpdat.arm_micro_shadowing: wrd.world_defs += '_MicroShadowing' if rpdat.arm_two_sided_area_light: wrd.world_defs += '_TwoSidedAreaLight' # Store contexts if rpdat.rp_hdr == False: wrd.world_defs += '_LDR' if wrd.arm_light_ies_texture != '': wrd.world_defs += '_LightIES' assets.add_embedded_data('iestexture.png') if wrd.arm_light_clouds_texture != '': wrd.world_defs += '_LightClouds' assets.add_embedded_data('cloudstexture.png') if rpdat.rp_renderer == 'Deferred': assets.add_khafile_def('arm_deferred') wrd.world_defs += '_Deferred' # Shadows if rpdat.rp_shadows: wrd.world_defs += '_ShadowMap' if rpdat.rp_shadowmap_cascades != '1': wrd.world_defs += '_CSM' assets.add_khafile_def('arm_csm') # SS if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO': if rpdat.rp_ssgi == 'RTGI': wrd.world_defs += '_RTGI' if rpdat.arm_ssgi_rays == '9': wrd.world_defs += '_SSGICone9' if rpdat.rp_autoexposure: wrd.world_defs += '_AutoExposure' has_voxels = arm.utils.voxel_support() if rpdat.rp_voxelao and has_voxels and rpdat.arm_material_model == 'Full': wrd.world_defs += '_VoxelCones' + rpdat.arm_voxelgi_cones if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' if rpdat.arm_voxelgi_temporal: assets.add_khafile_def('arm_voxelgi_temporal') wrd.world_defs += '_VoxelGITemporal' wrd.world_defs += '_VoxelAOvar' # Write a shader variant if rpdat.arm_voxelgi_shadows: wrd.world_defs += '_VoxelShadow' if rpdat.arm_voxelgi_occ == 0.0: wrd.world_defs += '_VoxelAONoTrace' if arm.utils.get_legacy_shaders() or 'ios' in state.target: wrd.world_defs += '_Legacy' assets.add_khafile_def('arm_legacy') # Light defines point_lights = 0 for bo in bpy.data.objects: # TODO: temp if bo.type == 'LIGHT': light = bo.data if light.type == 'AREA' and '_LTC' not in wrd.world_defs: point_lights += 1 wrd.world_defs += '_LTC' assets.add_khafile_def('arm_ltc') if light.type == 'SUN' and '_Sun' not in wrd.world_defs: wrd.world_defs += '_Sun' if light.type == 'POINT' or light.type == 'SPOT': point_lights += 1 if light.type == 'SPOT' and '_Spot' not in wrd.world_defs: wrd.world_defs += '_Spot' assets.add_khafile_def('arm_spot') if point_lights == 1: wrd.world_defs += '_SinglePoint' elif point_lights > 1: wrd.world_defs += '_Clusters' assets.add_khafile_def('arm_clusters') if '_Rad' in wrd.world_defs and '_Brdf' not in wrd.world_defs: wrd.world_defs += '_Brdf'
def add_world_defs(): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() # Screen-space ray-traced shadows if rpdat.arm_ssrs: wrd.world_defs += '_SSRS' if wrd.arm_two_sided_area_lamp: wrd.world_defs += '_TwoSidedAreaLamp' # Store contexts if rpdat.rp_hdr == False: wrd.world_defs += '_LDR' # Alternative models if rpdat.arm_diffuse_model == 'OrenNayar': wrd.world_defs += '_OrenNayar' # TODO: Lamp texture test.. if wrd.arm_lamp_texture != '': wrd.world_defs += '_LampColTex' if wrd.arm_lamp_ies_texture != '': wrd.world_defs += '_LampIES' assets.add_embedded_data('iestexture.png') if wrd.arm_lamp_clouds_texture != '': wrd.world_defs += '_LampClouds' assets.add_embedded_data('cloudstexture.png') if rpdat.rp_renderer == 'Deferred': assets.add_khafile_def('arm_deferred') # GI voxelgi = False voxelao = False has_voxels = arm.utils.voxel_support() if has_voxels: if rpdat.rp_gi == 'Voxel GI': voxelgi = True elif rpdat.rp_gi == 'Voxel AO': voxelao = True # Shadows if rpdat.rp_shadowmap_cascades != '1': if voxelgi: log.warn( 'Disabling shadow cascades - Voxel GI does not support cascades yet' ) else: wrd.world_defs += '_CSM' assets.add_khafile_def('arm_csm') if rpdat.rp_shadowmap == 'Off': wrd.world_defs += '_NoShadows' assets.add_khafile_def('arm_no_shadows') # SS # if rpdat.rp_dfrs: # wrd.world_defs += '_DFRS' # assets.add_khafile_def('arm_sdf') # if rpdat.rp_dfao: # wrd.world_defs += '_DFAO' # assets.add_khafile_def('arm_sdf') # if rpdat.rp_dfgi: # wrd.world_defs += '_DFGI' # assets.add_khafile_def('arm_sdf') if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO': if rpdat.rp_ssgi == 'RTGI': wrd.world_defs += '_RTGI' if wrd.arm_ssgi_rays == '9': wrd.world_defs += '_SSGICone9' if rpdat.rp_autoexposure: wrd.world_defs += '_AutoExposure' if voxelgi or voxelao: assets.add_khafile_def('arm_voxelgi') wrd.world_defs += '_VoxelCones' + wrd.arm_voxelgi_cones if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' if rpdat.arm_voxelgi_temporal: assets.add_khafile_def('arm_voxelgi_temporal') wrd.world_defs += '_VoxelGITemporal' if voxelgi: wrd.world_defs += '_VoxelGI' if rpdat.arm_voxelgi_shadows: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIShadow' if rpdat.arm_voxelgi_refraction: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIRefract' if rpdat.arm_voxelgi_emission: wrd.world_defs += '_VoxelGIEmission' elif voxelao: wrd.world_defs += '_VoxelAO' if arm.utils.get_gapi().startswith( 'direct3d'): # Flip Y axis in drawQuad command wrd.world_defs += '_InvY' # Area lamps for lamp in bpy.data.lamps: if lamp.type == 'AREA': wrd.world_defs += '_LTC' assets.add_khafile_def('arm_ltc') break if '_Rad' in wrd.world_defs or '_VoxelGI' in wrd.world_defs: wrd.world_defs += '_Brdf' if '_Brdf' in wrd.world_defs or '_VoxelAO' in wrd.world_defs: wrd.world_defs += '_IndPos'
def add_world_defs(): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() # Screen-space ray-traced shadows if rpdat.arm_ssrs: wrd.world_defs += '_SSRS' if rpdat.arm_two_sided_area_light: wrd.world_defs += '_TwoSidedAreaLight' # Store contexts if rpdat.rp_hdr == False: wrd.world_defs += '_LDR' # Alternative models if rpdat.arm_diffuse_model == 'OrenNayar': wrd.world_defs += '_OrenNayar' # TODO: Light texture test.. if wrd.arm_light_texture != '': wrd.world_defs += '_LightColTex' if wrd.arm_light_ies_texture != '': wrd.world_defs += '_LightIES' assets.add_embedded_data('iestexture.png') if wrd.arm_light_clouds_texture != '': wrd.world_defs += '_LightClouds' assets.add_embedded_data('cloudstexture.png') if rpdat.rp_renderer == 'Deferred': assets.add_khafile_def('arm_deferred') wrd.world_defs += '_Deferred' # GI voxelgi = False voxelao = False has_voxels = arm.utils.voxel_support() if has_voxels: if rpdat.rp_gi == 'Voxel GI': voxelgi = True elif rpdat.rp_gi == 'Voxel AO': voxelao = True # Shadows if rpdat.rp_shadowmap == 'Off': wrd.world_defs += '_NoShadows' assets.add_khafile_def('arm_no_shadows') else: if rpdat.rp_shadowmap_cascades != '1': if voxelgi: log.warn( 'Disabling shadow cascades - Voxel GI does not support cascades yet' ) else: wrd.world_defs += '_CSM' assets.add_khafile_def('arm_csm') # SS # if rpdat.rp_dfrs: # wrd.world_defs += '_DFRS' # assets.add_khafile_def('arm_sdf') # if rpdat.rp_dfao: # wrd.world_defs += '_DFAO' # assets.add_khafile_def('arm_sdf') # if rpdat.rp_dfgi: # wrd.world_defs += '_DFGI' # assets.add_khafile_def('arm_sdf') if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO': if rpdat.rp_ssgi == 'RTGI': wrd.world_defs += '_RTGI' if rpdat.arm_ssgi_rays == '9': wrd.world_defs += '_SSGICone9' if rpdat.rp_autoexposure: wrd.world_defs += '_AutoExposure' if voxelgi or voxelao: assets.add_khafile_def('arm_voxelgi') wrd.world_defs += '_VoxelCones' + rpdat.arm_voxelgi_cones if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' if rpdat.arm_voxelgi_temporal: assets.add_khafile_def('arm_voxelgi_temporal') wrd.world_defs += '_VoxelGITemporal' if voxelgi: wrd.world_defs += '_VoxelGI' assets.add_shader_external( arm.utils.get_sdk_path() + '/armory/Shaders/voxel_light/voxel_light.comp.glsl') if rpdat.arm_voxelgi_bounces != "1": assets.add_khafile_def('rp_gi_bounces={0}'.format( rpdat.arm_voxelgi_bounces)) assets.add_shader_external( arm.utils.get_sdk_path() + '/armory/Shaders/voxel_bounce/voxel_bounce.comp.glsl') if rpdat.arm_voxelgi_shadows: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIShadow' if rpdat.arm_voxelgi_refraction: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIRefract' if rpdat.rp_voxelgi_relight: assets.add_khafile_def('rp_voxelgi_relight') elif voxelao: wrd.world_defs += '_VoxelAO' if arm.utils.get_gapi().startswith( 'direct3d'): # Flip Y axis in drawQuad command wrd.world_defs += '_InvY' if arm.utils.get_legacy_shaders() and not state.is_viewport: wrd.world_defs += '_Legacy' # Area lights lights = bpy.data.lights if bpy.app.version >= (2, 80, 1) else bpy.data.lamps for light in lights: if light.type == 'AREA': wrd.world_defs += '_LTC' assets.add_khafile_def('arm_ltc') break if '_Rad' in wrd.world_defs or '_VoxelGI' in wrd.world_defs: wrd.world_defs += '_Brdf' if '_Brdf' in wrd.world_defs or '_VoxelAO' in wrd.world_defs: wrd.world_defs += '_IndPos'
def add_world_defs(): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() # Screen-space ray-traced shadows if rpdat.arm_ssrs: wrd.world_defs += '_SSRS' if rpdat.arm_two_sided_area_light: wrd.world_defs += '_TwoSidedAreaLight' # Store contexts if rpdat.rp_hdr == False: wrd.world_defs += '_LDR' if wrd.arm_light_ies_texture != '': wrd.world_defs += '_LightIES' assets.add_embedded_data('iestexture.png') if wrd.arm_light_clouds_texture != '': wrd.world_defs += '_LightClouds' assets.add_embedded_data('cloudstexture.png') if rpdat.rp_renderer == 'Deferred': assets.add_khafile_def('arm_deferred') wrd.world_defs += '_Deferred' # GI voxelgi = False voxelao = False has_voxels = arm.utils.voxel_support() if has_voxels and rpdat.arm_material_model == 'Full': if rpdat.rp_gi == 'Voxel GI': voxelgi = True elif rpdat.rp_gi == 'Voxel AO': voxelao = True # Shadows if rpdat.rp_shadows: wrd.world_defs += '_ShadowMap' if rpdat.rp_shadowmap_cascades != '1': if voxelgi: log.warn('Disabling shadow cascades - Voxel GI does not support cascades yet') else: wrd.world_defs += '_CSM' assets.add_khafile_def('arm_csm') # SS if rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO': if rpdat.rp_ssgi == 'RTGI': wrd.world_defs += '_RTGI' if rpdat.arm_ssgi_rays == '9': wrd.world_defs += '_SSGICone9' if rpdat.rp_autoexposure: wrd.world_defs += '_AutoExposure' if voxelgi or voxelao: assets.add_khafile_def('arm_voxelgi') wrd.world_defs += '_VoxelCones' + rpdat.arm_voxelgi_cones if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' if rpdat.arm_voxelgi_temporal: assets.add_khafile_def('arm_voxelgi_temporal') wrd.world_defs += '_VoxelGITemporal' if voxelgi: wrd.world_defs += '_VoxelGI' # assets.add_shader_external(arm.utils.get_sdk_path() + '/armory/Shaders/voxel_light/voxel_light.comp.glsl') # if rpdat.arm_voxelgi_bounces != "1": # assets.add_khafile_def('rp_gi_bounces={0}'.format(rpdat.arm_voxelgi_bounces)) # assets.add_shader_external(arm.utils.get_sdk_path() + '/armory/Shaders/voxel_bounce/voxel_bounce.comp.glsl') # if rpdat.arm_voxelgi_shadows: # wrd.world_defs += '_VoxelGIShadow' if rpdat.rp_voxelgi_relight: assets.add_khafile_def('rp_voxelgi_relight') elif voxelao: wrd.world_defs += '_VoxelAOvar' # Write a shader variant if arm.utils.get_legacy_shaders() and not state.is_viewport: wrd.world_defs += '_Legacy' # Light defines point_lights = 0 for bo in bpy.data.objects: # TODO: temp if bo.type == 'LIGHT': light = bo.data if light.type == 'AREA' and '_LTC' not in wrd.world_defs: wrd.world_defs += '_LTC' assets.add_khafile_def('arm_ltc') if light.type == 'SUN' and '_Sun' not in wrd.world_defs: wrd.world_defs += '_Sun' if light.type == 'POINT' or light.type == 'SPOT': point_lights += 1 if light.type == 'SPOT' and '_Spot' not in wrd.world_defs: wrd.world_defs += '_Spot' assets.add_khafile_def('arm_spot') if point_lights == 1: wrd.world_defs += '_SinglePoint' elif point_lights > 1: wrd.world_defs += '_Clusters' assets.add_khafile_def('arm_clusters') if '_Rad' in wrd.world_defs or '_VoxelGI' in wrd.world_defs: wrd.world_defs += '_Brdf'
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 # Gather defs from linked nodes if node.bl_idname == 'TAAPassNodeType' or node.bl_idname == 'MotionBlurVelocityPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType': if preprocess_renderpath.velocity_def_added == False: assets.add_khafile_def('arm_veloc') bpy.data.worlds['Arm'].rp_defs += '_Veloc' preprocess_renderpath.velocity_def_added = True if node.bl_idname == 'TAAPassNodeType': assets.add_khafile_def('arm_taa') # bpy.data.worlds['Arm'].rp_defs += '_TAA' elif node.bl_idname == 'SMAAPassNodeType': bpy.data.worlds['Arm'].rp_defs += '_SMAA' elif node.bl_idname == 'SSAOPassNodeType' or node.bl_idname == 'ApplySSAOPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType': if bpy.data.worlds['Arm'].generate_ssao: # SSAO enabled bpy.data.worlds['Arm'].rp_defs += '_SSAO' elif node.bl_idname == 'DrawStereoNodeType': assets.add_khafile_def('arm_vr') bpy.data.worlds['Arm'].rp_defs += '_VR' elif node.bl_idname == 'CallFunctionNodeType': global dynRes_added fstr = node.inputs[1].default_value if not dynRes_added and fstr.startswith( 'armory.renderpath.DynamicResolutionScale'): bpy.data.worlds['Arm'].rp_defs += '_DynRes' dynRes_added = True # Collect render targets if node.bl_idname == 'SetTargetNodeType' or node.bl_idname == 'BindTargetNodeType' or node.bl_idname == 'QuadPassNodeType' or node.bl_idname == 'DrawCompositorNodeType' or node.bl_idname == 'DrawCompositorWithFXAANodeType': if node.inputs[1].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[1]) parse_render_target(tnode, node_group, render_targets, depth_buffers) # Traverse loops elif node.bl_idname == 'LoopStagesNodeType' or node.bl_idname == 'LoopLampsNodeType' or node.bl_idname == 'DrawStereoNodeType': if node.outputs[1].is_linked: loop_node = nodes.find_node_by_link_from(node_group, node, node.outputs[1]) traverse_renderpath(loop_node, node_group, render_targets, depth_buffers) # Prebuilt elif node.bl_idname == 'MotionBlurPassNodeType' or node.bl_idname == 'MotionBlurVelocityPassNodeType' or node.bl_idname == 'CopyPassNodeType' or node.bl_idname == 'BlendPassNodeType' or node.bl_idname == 'CombinePassNodeType' or node.bl_idname == 'DebugNormalsPassNodeType' or node.bl_idname == 'FXAAPassNodeType' or node.bl_idname == 'TAAPassNodeType' or node.bl_idname == 'WaterPassNodeType' or node.bl_idname == 'DeferredLightPassNodeType' or node.bl_idname == 'DeferredIndirectPassNodeType' or node.bl_idname == 'VolumetricLightPassNodeType' or node.bl_idname == 'TranslucentResolvePassNodeType': if node.inputs[1].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[1]) parse_render_target(tnode, node_group, render_targets, depth_buffers) elif node.bl_idname == 'SSRPassNodeType' or node.bl_idname == 'ApplySSAOPassNodeType' or node.bl_idname == 'BloomPassNodeType' or node.bl_idname == 'SMAAPassNodeType': for i in range(1, 4): if node.inputs[i].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[i]) parse_render_target(tnode, node_group, render_targets, depth_buffers) elif node.bl_idname == 'SSAOPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType' or node.bl_idname == 'SSSPassNodeType' or node.bl_idname == 'BlurBasicPassNodeType': for i in range(1, 3): if node.inputs[i].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[i]) parse_render_target(tnode, node_group, render_targets, depth_buffers) # Next stage if node.outputs[0].is_linked: stagenode = nodes.find_node_by_link_from(node_group, node, node.outputs[0]) traverse_renderpath(stagenode, node_group, render_targets, depth_buffers)
def parse_color(world, node): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' # Env map included if node.type == 'TEX_ENVIRONMENT' and node.image != None: image = node.image filepath = image.filepath if image.packed_file == None and not os.path.isfile( arm.utils.asset_path(filepath)): log.warn(world.name + ' - unable to open ' + image.filepath) return # Reference image name tex_file = arm.utils.extract_filename(image.filepath) base = tex_file.rsplit('.', 1) ext = base[1].lower() if ext == 'hdr': target_format = 'HDR' else: target_format = 'JPEG' do_convert = ext != 'hdr' and ext != 'jpg' if do_convert: if ext == 'exr': tex_file = base[0] + '.hdr' target_format = 'HDR' else: tex_file = base[0] + '.jpg' target_format = 'JPEG' if image.packed_file != None: # Extract packed data unpack_path = arm.utils.get_fp_build( ) + '/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + tex_file filepath = unpack_filepath if do_convert: if not os.path.isfile(unpack_filepath): arm.utils.unpack_image(image, unpack_filepath, file_format=target_format) elif os.path.isfile(unpack_filepath) == False or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: if do_convert: unpack_path = arm.utils.get_fp_build( ) + '/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) converted_path = unpack_path + '/' + tex_file filepath = converted_path # TODO: delete cache when file changes if not os.path.isfile(converted_path): arm.utils.convert_image(image, converted_path, file_format=target_format) assets.add(converted_path) else: # Link image path to assets assets.add(arm.utils.asset_path(image.filepath)) # Generate prefiltered envmaps world.arm_envtex_name = tex_file world.arm_envtex_irr_name = tex_file.rsplit('.', 1)[0] disable_hdr = target_format == 'JPEG' mip_count = world.arm_envtex_num_mips mip_count = write_probes.write_probes(filepath, disable_hdr, mip_count, arm_radiance=rpdat.arm_radiance) world.arm_envtex_num_mips = mip_count # Append envtex define wrd.world_defs += '_EnvTex' # Append LDR define if disable_hdr: wrd.world_defs += '_EnvLDR' # Append radiance define if rpdat.arm_irradiance and rpdat.arm_radiance and not mobile_mat: wrd.world_defs += '_Rad' # Static image background elif node.type == 'TEX_IMAGE': image = node.image filepath = image.filepath if image.packed_file != None: # Extract packed data filepath = arm.utils.build_dir() + '/compiled/Assets/unpacked' unpack_path = arm.utils.get_fp() + filepath if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + image.name if os.path.isfile(unpack_filepath) == False or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: # Link image path to assets assets.add(arm.utils.asset_path(image.filepath)) # Reference image name tex_file = arm.utils.extract_filename(image.filepath) world.arm_envtex_name = tex_file # Append sky define elif node.type == 'TEX_SKY': # Match to cycles world.arm_envtex_strength *= 0.1 wrd.world_defs += '_EnvSky' assets.add_khafile_def('arm_hosek') world.arm_envtex_sun_direction = [ node.sun_direction[0], node.sun_direction[1], node.sun_direction[2] ] world.arm_envtex_turbidity = node.turbidity world.arm_envtex_ground_albedo = node.ground_albedo # Irradiance json file name wname = arm.utils.safestr(world.name) world.arm_envtex_irr_name = wname write_probes.write_sky_irradiance(wname) # Radiance if rpdat.arm_radiance_sky and rpdat.arm_radiance and rpdat.arm_irradiance and not mobile_mat: wrd.world_defs += '_Rad' hosek_path = 'armory/Assets/hosek/' sdk_path = arm.utils.get_sdk_path() # Use fake maps for now assets.add(sdk_path + hosek_path + 'hosek_radiance.hdr') for i in range(0, 8): assets.add(sdk_path + hosek_path + 'hosek_radiance_' + str(i) + '.hdr') world.arm_envtex_name = 'hosek' world.arm_envtex_num_mips = 8
def build(): assets_path = arm.utils.get_sdk_path() + 'armory/Assets/' wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' if not mobile_mat: # Always include assets.add(assets_path + 'brdf.png') assets.add_embedded_data('brdf.png') if rpdat.rp_hdr: assets.add_khafile_def('rp_hdr') assets.add_khafile_def('rp_renderer={0}'.format(rpdat.rp_renderer)) if rpdat.rp_depthprepass: assets.add_khafile_def('rp_depthprepass') if rpdat.rp_shadowmap != 'Off': assets.add_khafile_def('rp_shadowmap') assets.add_khafile_def('rp_shadowmap_size={0}'.format( rpdat.rp_shadowmap)) assets.add_khafile_def('rp_background={0}'.format(rpdat.rp_background)) if rpdat.rp_background == 'World': if '_EnvClouds' in wrd.world_defs: assets.add(assets_path + 'noise256.png') assets.add_embedded_data('noise256.png') if rpdat.rp_render_to_texture: assets.add_khafile_def('rp_render_to_texture') if rpdat.rp_compositornodes: assets.add_khafile_def('rp_compositornodes') compo_depth = False if wrd.arm_tonemap != 'Off': wrd.compo_defs = '_CTone' + wrd.arm_tonemap if rpdat.rp_antialiasing != 'Off': wrd.compo_defs += '_CFXAA' if wrd.arm_letterbox: wrd.compo_defs += '_CLetterbox' if wrd.arm_grain: wrd.compo_defs += '_CGrain' if bpy.data.scenes[0].cycles.film_exposure != 1.0: wrd.compo_defs += '_CExposure' if wrd.arm_fog: wrd.compo_defs += '_CFog' compo_depth = True if len(bpy.data.cameras ) > 0 and bpy.data.cameras[0].dof_distance > 0.0: wrd.compo_defs += '_CDOF' compo_depth = True if compo_depth: wrd.compo_defs += '_CDepth' if wrd.arm_lens_texture != '': wrd.compo_defs += '_CLensTex' assets.add_embedded_data('lenstexture.jpg') if wrd.arm_fisheye: wrd.compo_defs += '_CFishEye' if wrd.arm_vignette: wrd.compo_defs += '_CVignette' if wrd.arm_lensflare: wrd.compo_defs += '_CGlare' assets.add_shader2('compositor_pass', 'compositor_pass') else: assets.add_shader2('copy_pass', 'copy_pass') assets.add_khafile_def('rp_antialiasing={0}'.format( rpdat.rp_antialiasing)) if rpdat.rp_antialiasing == 'SMAA' or rpdat.rp_antialiasing == 'TAA': assets.add_shader2('smaa_edge_detect', 'smaa_edge_detect') assets.add_shader2('smaa_blend_weight', 'smaa_blend_weight') assets.add_shader2('smaa_neighborhood_blend', 'smaa_neighborhood_blend') assets.add(assets_path + 'smaa_area.png') assets.add(assets_path + 'smaa_search.png') assets.add_embedded_data('smaa_area.png') assets.add_embedded_data('smaa_search.png') wrd.world_defs += '_SMAA' if rpdat.rp_antialiasing == 'TAA': assets.add_shader2('taa_pass', 'taa_pass') assets.add_shader2('copy_pass', 'copy_pass') if rpdat.rp_antialiasing == 'TAA' or rpdat.rp_motionblur == 'Object': assets.add_khafile_def('arm_veloc') wrd.world_defs += '_Veloc' if rpdat.rp_antialiasing == 'TAA': assets.add_khafile_def('arm_taa') assets.add_khafile_def('rp_supersampling={0}'.format( rpdat.rp_supersampling)) if rpdat.rp_supersampling == '4': assets.add_shader2('supersample_resolve', 'supersample_resolve') if rpdat.rp_overlays: assets.add_khafile_def('rp_overlays') if rpdat.rp_translucency: assets.add_khafile_def('rp_translucency') assets.add_shader2('translucent_resolve', 'translucent_resolve') if rpdat.rp_stereo: assets.add_khafile_def('rp_stereo') assets.add_khafile_def('arm_vr') wrd.world_defs += '_VR' assets.add(assets_path + 'vr.png') assets.add_embedded_data('vr.png') assets.add_khafile_def('rp_gi={0}'.format(rpdat.rp_gi)) if rpdat.rp_gi != 'Off': assets.add_khafile_def('rp_gi={0}'.format(rpdat.rp_gi)) assets.add_khafile_def('rp_voxelgi_resolution={0}'.format( rpdat.rp_voxelgi_resolution)) assets.add_khafile_def('rp_voxelgi_resolution_z={0}'.format( rpdat.rp_voxelgi_resolution_z)) if rpdat.rp_voxelgi_hdr: assets.add_khafile_def('rp_voxelgi_hdr') if rpdat.arm_voxelgi_shadows: assets.add_khafile_def('rp_voxelgi_shadows') if rpdat.arm_voxelgi_refraction: assets.add_khafile_def('rp_voxelgi_refraction') if rpdat.arm_rp_resolution != 'Display': assets.add_khafile_def('rp_resolution={0}'.format( rpdat.arm_rp_resolution)) assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi)) if rpdat.rp_ssgi != 'Off': wrd.world_defs += '_SSAO' if rpdat.rp_ssgi == 'SSAO': assets.add_shader2('ssao_pass', 'ssao_pass') assets.add_shader2('blur_edge_pass', 'blur_edge_pass') assets.add(assets_path + 'noise8.png') assets.add_embedded_data('noise8.png') else: assets.add_shader2('ssgi_pass', 'ssgi_pass') assets.add_shader2('ssgi_blur_pass', 'ssgi_blur_pass') if rpdat.rp_renderer == 'Deferred': assets.add_shader2('deferred_indirect', 'deferred_indirect') assets.add_shader2('deferred_light', 'deferred_light') assets.add_shader2('deferred_light_quad', 'deferred_light_quad') if rpdat.rp_rendercapture: assets.add_khafile_def('rp_rendercapture') assets.add_khafile_def('rp_rendercapture_format={0}'.format( wrd.rp_rendercapture_format)) assets.add_shader2('copy_pass', 'copy_pass') if rpdat.rp_volumetriclight: assets.add_khafile_def('rp_volumetriclight') assets.add_shader2('volumetric_light_quad', 'volumetric_light_quad') assets.add_shader2('volumetric_light', 'volumetric_light') assets.add_shader2('blur_edge_pass', 'blur_edge_pass') if rpdat.rp_decals: assets.add_khafile_def('rp_decals') if rpdat.rp_ocean: assets.add_khafile_def('rp_ocean') assets.add_shader2('water_pass', 'water_pass') if rpdat.rp_blending_state != 'Off': assets.add_khafile_def('rp_blending') if rpdat.rp_bloom: assets.add_khafile_def('rp_bloom') assets.add_shader2('bloom_pass', 'bloom_pass') assets.add_shader2('blur_gaus_pass', 'blur_gaus_pass') if rpdat.rp_sss: assets.add_khafile_def('rp_sss') wrd.world_defs += '_SSS' assets.add_shader2('sss_pass', 'sss_pass') if rpdat.rp_ssr: assets.add_khafile_def('rp_ssr') assets.add_shader2('ssr_pass', 'ssr_pass') assets.add_shader2('blur_adaptive_pass', 'blur_adaptive_pass') if rpdat.arm_ssr_half_res: assets.add_khafile_def('rp_ssr_half') if rpdat.rp_motionblur != 'Off': assets.add_khafile_def('rp_motionblur={0}'.format(rpdat.rp_motionblur)) assets.add_shader2('copy_pass', 'copy_pass') if rpdat.rp_motionblur == 'Camera': assets.add_shader2('motion_blur_pass', 'motion_blur_pass') else: assets.add_shader2('motion_blur_veloc_pass', 'motion_blur_veloc_pass') if rpdat.rp_compositornodes and rpdat.rp_autoexposure: assets.add_khafile_def('rp_autoexposure') if rpdat.rp_dynres: assets.add_khafile_def('rp_dynres')
def write_khafilejs(is_play, export_physics, export_navigation, export_ui, is_publish, enable_dce, in_viewport, import_traits, import_logicnodes): sdk_path = arm.utils.get_sdk_path() wrd = bpy.data.worlds['Arm'] with open('khafile.js', 'w') as f: f.write( """// Auto-generated let project = new Project('""" + arm.utils.safestr(wrd.arm_project_name) + """'); project.addSources('Sources'); """) # Auto-add assets located in Bundled directory if os.path.exists('Bundled'): for file in glob.glob("Bundled/**", recursive=True): if os.path.isfile(file): assets.add(file) if os.path.exists('Shaders'): # Copy to enable includes if os.path.exists(arm.utils.build_dir() + '/compiled/Shaders/Project'): shutil.rmtree(arm.utils.build_dir() + '/compiled/Shaders/Project', onerror=remove_readonly) shutil.copytree('Shaders', arm.utils.build_dir() + '/compiled/Shaders/Project') f.write("project.addShaders('" + arm.utils.build_dir() + "/compiled/Shaders/Project/**');\n") # for file in glob.glob("Shaders/**", recursive=True): # if os.path.isfile(file): # assets.add_shader(file) if not os.path.exists('Libraries/armory'): f.write(add_armory_library(sdk_path, 'armory')) if not os.path.exists('Libraries/iron'): f.write(add_armory_library(sdk_path, 'iron')) # Project libraries if os.path.exists('Libraries'): libs = os.listdir('Libraries') for lib in libs: if os.path.isdir('Libraries/' + lib): f.write('project.addLibrary("{0}");\n'.format(lib)) # Subprojects, merge this with libraries if os.path.exists('Subprojects'): libs = os.listdir('Subprojects') for lib in libs: if os.path.isdir('Subprojects/' + lib): f.write('await project.addProject("Subprojects/{0}");\n'.format(lib)) if wrd.arm_audio == 'Disabled': assets.add_khafile_def('arm_no_audio') if export_physics: assets.add_khafile_def('arm_physics') if wrd.arm_physics == 'Bullet': assets.add_khafile_def('arm_bullet') if not os.path.exists('Libraries/haxebullet'): f.write(add_armory_library(sdk_path + '/lib/', 'haxebullet')) if state.target.startswith('krom') or state.target == 'html5' or state.target == 'node': ammojs_path = sdk_path + '/lib/haxebullet/js/ammo/ammo.js' ammojs_path = ammojs_path.replace('\\', '/') f.write(add_assets(ammojs_path)) # haxe.macro.Compiler.includeFile(ammojs_path) elif wrd.arm_physics == 'Oimo': assets.add_khafile_def('arm_oimo') if not os.path.exists('Libraries/oimo'): f.write(add_armory_library(sdk_path + '/lib/', 'oimo')) if export_navigation: assets.add_khafile_def('arm_navigation') if not os.path.exists('Libraries/haxerecast'): f.write(add_armory_library(sdk_path + '/lib/', 'haxerecast')) if state.target.startswith('krom') or state.target == 'html5': recastjs_path = sdk_path + '/lib/haxerecast/js/recast/recast.js' recastjs_path = recastjs_path.replace('\\', '/') f.write(add_assets(recastjs_path)) if not is_publish: f.write("""project.addParameter("--macro include('armory.trait')");\n""") f.write("""project.addParameter("--macro include('armory.trait.internal')");\n""") if export_physics: f.write("""project.addParameter("--macro include('armory.trait.physics')");\n""") if wrd.arm_physics == 'Bullet': f.write("""project.addParameter("--macro include('armory.trait.physics.bullet')");\n""") else: f.write("""project.addParameter("--macro include('armory.trait.physics.oimo')");\n""") if export_navigation: f.write("""project.addParameter("--macro include('armory.trait.navigation')");\n""") if import_logicnodes: # Live patching for logic nodes f.write("""project.addParameter("--macro include('armory.logicnode')");\n""") if enable_dce: f.write("project.addParameter('-dce full');\n") if in_viewport: import_traits.append('armory.trait.internal.Bridge') import_traits = list(set(import_traits)) for i in range(0, len(import_traits)): f.write("project.addParameter('" + import_traits[i] + "');\n") f.write("""project.addParameter("--macro keep('""" + import_traits[i] + """')");\n""") shaderload = state.target == 'krom' or state.target == 'html5' if arm.utils.get_player_gapi() != 'opengl': # TODO: shader from source for d3d11 shaderload = False if wrd.arm_cache_compiler and shaderload and not is_publish: # Load shaders manually assets.add_khafile_def('arm_shaderload') shader_references = sorted(list(set(assets.shaders))) for ref in shader_references: ref = ref.replace('\\', '/') f.write("project.addShaders('" + ref + "');\n") shader_data_references = sorted(list(set(assets.shader_datas))) for ref in shader_data_references: ref = ref.replace('\\', '/') f.write(add_assets(ref)) asset_references = sorted(list(set(assets.assets))) for ref in asset_references: ref = ref.replace('\\', '/') quality = 1.0 s = ref.lower() if s.endswith('.wav'): quality = wrd.arm_sound_quality elif s.endswith('.png') or s.endswith('.jpg'): quality = wrd.arm_texture_quality f.write(add_assets(ref, quality=quality)) if wrd.arm_sound_quality < 1.0 or state.target == 'html5': assets.add_khafile_def('arm_soundcompress') if wrd.arm_texture_quality < 1.0: assets.add_khafile_def('arm_texcompress') if wrd.arm_play_console: assets.add_khafile_def('arm_debug') f.write("project.addShaders('" + sdk_path + "/armory/Shaders/debug_draw/**');\n") if export_ui: if not os.path.exists('Libraries/zui'): f.write(add_armory_library(sdk_path, 'lib/zui')) p = sdk_path + '/armory/Assets/droid_sans.ttf' f.write(add_assets(p.replace('\\', '/'))) assets.add_khafile_def('arm_ui') if wrd.arm_hscript == 'Enabled': if not os.path.exists('Libraries/hscript'): f.write(add_armory_library(sdk_path, 'lib/hscript')) assets.add_khafile_def('arm_hscript') if wrd.arm_formatlib == 'Enabled': if not os.path.exists('Libraries/iron_format'): f.write(add_armory_library(sdk_path, 'lib/iron_format')) if wrd.arm_minimize == False: assets.add_khafile_def('arm_json') if wrd.arm_deinterleaved_buffers == True: assets.add_khafile_def('arm_deinterleaved') if wrd.arm_batch_meshes == True: assets.add_khafile_def('arm_batch') if wrd.arm_stream_scene: assets.add_khafile_def('arm_stream') rpdat = arm.utils.get_rp() if rpdat.arm_skin == 'CPU': assets.add_khafile_def('arm_skin_cpu') elif rpdat.arm_skin == 'GPU (Matrix)': assets.add_khafile_def('arm_skin_mat') elif rpdat.arm_skin == 'GPU Off': assets.add_khafile_def('arm_skin_off') if arm.utils.get_viewport_controls() == 'azerty': assets.add_khafile_def('arm_azerty') assets.add_khafile_def('arm_fast') # assets.add_khafile_def('arm_kha_' + arm.utils.get_kha_version()) for d in assets.khafile_defs: f.write("project.addDefine('" + d + "');\n") khafile_text = wrd.arm_khafile if khafile_text != '': f.write(bpy.data.texts[khafile_text].as_string()) if state.target == 'android-native': f.write("project.targetOptions.android_native.package = 'org.armory3d.{0}';\n".format(arm.utils.safestr(wrd.arm_project_package))) if wrd.arm_winorient != 'Multi': f.write("project.targetOptions.android_native.screenOrientation = '{0}';\n".format(wrd.arm_winorient.lower())) # if state.target == 'ios': # f.write("project.targetOptions.ios.bundle = 'org.armory3d.{0}';\n".format(arm.utils.safestr(wrd.arm_project_package))) f.write("\n\nresolve(project);\n")
def build_node_tree(world): output = {} dat = {} output['material_datas'] = [dat] wname = arm.utils.safestr(world.name) dat['name'] = wname + '_material' context = {} dat['contexts'] = [context] context['name'] = 'world' context['bind_constants'] = [] context['bind_textures'] = [] wrd = bpy.data.worlds['Arm'] wrd.world_defs = '' rpdat = arm.utils.get_rp() # Traverse world node tree parsed = False if world.node_tree != None: output_node = node_utils.get_node_by_type(world.node_tree, 'OUTPUT_WORLD') if output_node != None: parse_world_output(world, output_node, context) parsed = True if parsed == False: solid_mat = rpdat.arm_material_model == 'Solid' if wrd.arm_irradiance and not solid_mat: wrd.world_defs += '_Irr' envmap_strength_const = {} envmap_strength_const['name'] = 'envmapStrength' envmap_strength_const['float'] = 1.0 context['bind_constants'].append(envmap_strength_const) c = world.horizon_color world.arm_envtex_color = [c[0], c[1], c[2], 1.0] world.arm_envtex_strength = envmap_strength_const['float'] # Clear to color if no texture or sky is provided if '_EnvSky' not in wrd.world_defs and '_EnvTex' not in wrd.world_defs: if '_EnvImg' not in wrd.world_defs: wrd.world_defs += '_EnvCol' # Irradiance json file name world.arm_envtex_name = wname world.arm_envtex_irr_name = wname write_probes.write_color_irradiance(wname, world.arm_envtex_color) # film_transparent if bpy.context.scene != None and bpy.context.scene.cycles != None and bpy.context.scene.cycles.film_transparent: wrd.world_defs += '_EnvTransp' wrd.world_defs += '_EnvCol' # Clouds enabled if rpdat.arm_clouds: wrd.world_defs += '_EnvClouds' # Screen-space ray-traced shadows if rpdat.arm_ssrs: wrd.world_defs += '_SSRS' if wrd.arm_two_sided_area_lamp: wrd.world_defs += '_TwoSidedAreaLamp' # Store contexts if rpdat.rp_hdr == False: wrd.world_defs += '_LDR' # Alternative models if rpdat.arm_diffuse_model == 'OrenNayar': wrd.world_defs += '_OrenNayar' # TODO: Lamp texture test.. if wrd.arm_lamp_texture != '': wrd.world_defs += '_LampColTex' if wrd.arm_lamp_ies_texture != '': wrd.world_defs += '_LampIES' assets.add_embedded_data('iestexture.png') if wrd.arm_lamp_clouds_texture != '': wrd.world_defs += '_LampClouds' assets.add_embedded_data('cloudstexture.png') voxelgi = False voxelao = False if rpdat.rp_renderer == 'Deferred': assets.add_khafile_def('arm_deferred') # Shadows if rpdat.rp_shadowmap_cascades != '1' and rpdat.rp_gi == 'Off': wrd.world_defs += '_CSM' assets.add_khafile_def('arm_csm') if rpdat.rp_shadowmap == 'Off': wrd.world_defs += '_NoShadows' assets.add_khafile_def('arm_no_shadows') # GI if rpdat.rp_gi == 'Voxel GI': voxelgi = True elif rpdat.rp_gi == 'Voxel AO': voxelao = True # SS # if rpdat.rp_dfrs: # wrd.world_defs += '_DFRS' # assets.add_khafile_def('arm_sdf') # if rpdat.rp_dfao: # wrd.world_defs += '_DFAO' # assets.add_khafile_def('arm_sdf') # if rpdat.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 rpdat.rp_ssgi == 'RTGI' or rpdat.rp_ssgi == 'RTAO': if rpdat.rp_ssgi == 'RTGI': wrd.world_defs += '_RTGI' if wrd.arm_ssgi_rays == '9': wrd.world_defs += '_SSGICone9' if rpdat.rp_autoexposure: wrd.world_defs += '_AutoExposure' if voxelgi or voxelao: assets.add_khafile_def('arm_voxelgi') if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' if voxelgi and wrd.arm_voxelgi_diff_cones == '5': wrd.world_defs += '_VoxelGICone5' if voxelao and wrd.arm_voxelgi_ao_cones == '9': wrd.world_defs += '_VoxelAOCone9' wrd.world_defs += '_Rad' # Always do radiance for voxels wrd.world_defs += '_Irr' if voxelgi: assets.add_khafile_def('arm_voxelgi') if rpdat.arm_voxelgi_shadows: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIShadow' if rpdat.arm_voxelgi_refraction: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIRefract' if rpdat.arm_voxelgi_emission: wrd.world_defs += '_VoxelGIEmission' wrd.world_defs += '_VoxelGI' elif voxelao: wrd.world_defs += '_VoxelAO' if arm.utils.get_gapi().startswith( 'direct3d'): # Flip Y axis in drawQuad command wrd.world_defs += '_InvY' # Area lamps for lamp in bpy.data.lamps: if lamp.type == 'AREA': wrd.world_defs += '_LTC' assets.add_khafile_def('arm_ltc') break # Data will be written after render path has been processed to gather all defines return output
def write_khafilejs(is_play, export_physics, export_navigation, is_publish): global check_dot_path sdk_path = arm.utils.get_sdk_path() # Merge duplicates and sort shader_references = sorted(list(set(assets.shaders))) shader_data_references = sorted(list(set(assets.shader_datas))) asset_references = sorted(list(set(assets.assets))) wrd = bpy.data.worlds['Arm'] with open('khafile.js', 'w') as f: f.write( """// Auto-generated let project = new Project('""" + arm.utils.safestr(wrd.arm_project_name) + """'); project.addSources('Sources'); """) # TODO: Khamake bug workaround - assets & shaders located in folder starting with '.' get discarded - copy them to project check_dot_path = False if '/.' in sdk_path: check_dot_path = True if not os.path.exists(arm.utils.build_dir() + '/compiled/KhaShaders'): kha_shaders_path = arm.utils.get_kha_path() + '/Sources/Shaders' shutil.copytree(kha_shaders_path, arm.utils.build_dir() + '/compiled/KhaShaders') f.write("project.addShaders('" + arm.utils.build_dir() + "/compiled/KhaShaders/**');\n") # Auto-add assets located in Bundled directory if os.path.exists('Bundled'): f.write(add_assets("Bundled/**")) if os.path.exists('Libraries/armory'): f.write('project.addLibrary("armory")') else: f.write(add_armory_library(sdk_path, 'armory')) if os.path.exists('Libraries/iron'): f.write('project.addLibrary("iron")') else: f.write(add_armory_library(sdk_path, 'iron')) # Project libraries for lib in wrd.my_librarytraitlist: if lib.enabled_prop: f.write('project.addLibrary("{0}");\n'.format(lib.name)) if export_physics: assets.add_khafile_def('arm_physics') f.write(add_armory_library(sdk_path + '/lib/', 'haxebullet')) if state.target == 'krom' or state.target == 'html5': ammojs_path = sdk_path + '/lib/haxebullet/js/ammo/ammo.js' ammojs_path = ammojs_path.replace('\\', '/') f.write(add_assets(ammojs_path)) if export_navigation: assets.add_khafile_def('arm_navigation') f.write(add_armory_library(sdk_path + '/lib/', 'haxerecast')) if state.target == 'krom' or state.target == 'html5': recastjs_path = sdk_path + '/lib/haxerecast/js/recast/recast.js' recastjs_path = recastjs_path.replace('\\', '/') f.write(add_assets(recastjs_path)) if is_publish: f.write("project.addParameter('-dce full');") shaderload = state.target == 'krom' or state.target == 'html5' if wrd.arm_cache_compiler and shaderload and not is_publish: # Load shaders manually assets.add_khafile_def('arm_shaderload') for ref in shader_references: f.write("project.addShaders('" + ref + "');\n") for ref in shader_data_references: ref = ref.replace('\\', '/') f.write(add_assets(ref)) for ref in asset_references: ref = ref.replace('\\', '/') f.write(add_assets(ref)) if wrd.arm_play_console: assets.add_khafile_def('arm_profile') if wrd.arm_play_console or wrd.arm_ui: f.write(add_armory_library(sdk_path, 'lib/zui')) p = sdk_path + '/armory/Assets/droid_sans.ttf' f.write(add_assets(p.replace('\\', '/'))) assets.add_khafile_def('arm_ui') if wrd.arm_hscript: f.write(add_armory_library(sdk_path, 'lib/hscript')) if wrd.arm_minimize == False: assets.add_khafile_def('arm_json') if wrd.arm_deinterleaved_buffers == True: assets.add_khafile_def('arm_deinterleaved') if wrd.arm_batch_meshes == True: assets.add_khafile_def('arm_batch') if wrd.arm_stream_scene: assets.add_khafile_def('arm_stream') if wrd.generate_gpu_skin == False: assets.add_khafile_def('arm_cpu_skin') for d in assets.khafile_defs: f.write("project.addDefine('" + d + "');\n") config_text = wrd.arm_khafile if config_text != '': f.write(bpy.data.texts[config_text].as_string()) f.write("\n\nresolve(project);\n")
def write_khafilejs(is_play, export_physics, export_navigation, export_ui, is_publish, enable_dce, is_viewport, import_traits, import_logicnodes): sdk_path = arm.utils.get_sdk_path() rel_path = arm.utils.get_relative_paths() # Convert absolute paths to relative wrd = bpy.data.worlds['Arm'] with open('khafile.js', 'w') as f: f.write( """// Auto-generated let project = new Project('""" + arm.utils.safestr(wrd.arm_project_name) + """'); project.addSources('Sources'); """) # Auto-add assets located in Bundled directory if os.path.exists('Bundled'): for file in glob.glob("Bundled/**", recursive=True): if os.path.isfile(file): assets.add(file) if os.path.exists('Shaders'): # Copy to enable includes if os.path.exists(arm.utils.build_dir() + '/compiled/Shaders/Project'): shutil.rmtree(arm.utils.build_dir() + '/compiled/Shaders/Project', onerror=remove_readonly) shutil.copytree('Shaders', arm.utils.build_dir() + '/compiled/Shaders/Project') f.write("project.addShaders('" + arm.utils.build_dir() + "/compiled/Shaders/Project/**');\n") # for file in glob.glob("Shaders/**", recursive=True): # if os.path.isfile(file): # assets.add_shader(file) if not os.path.exists('Libraries/armory'): f.write(add_armory_library(sdk_path, 'armory', rel_path=rel_path)) if not os.path.exists('Libraries/iron'): f.write(add_armory_library(sdk_path, 'iron', rel_path=rel_path)) # Project libraries if os.path.exists('Libraries'): libs = os.listdir('Libraries') for lib in libs: if os.path.isdir('Libraries/' + lib): f.write('project.addLibrary("{0}");\n'.format(lib.replace('//', '/'))) # Subprojects, merge this with libraries if os.path.exists('Subprojects'): libs = os.listdir('Subprojects') for lib in libs: if os.path.isdir('Subprojects/' + lib): f.write('await project.addProject("Subprojects/{0}");\n'.format(lib)) if wrd.arm_audio == 'Disabled': assets.add_khafile_def('arm_no_audio') assets.add_khafile_def('kha_no_ogg') if export_physics: assets.add_khafile_def('arm_physics') if wrd.arm_physics_engine == 'Bullet': assets.add_khafile_def('arm_bullet') if not os.path.exists('Libraries/haxebullet'): f.write(add_armory_library(sdk_path + '/lib/', 'haxebullet', rel_path=rel_path)) if state.target.startswith('krom') or state.target == 'html5' or state.target == 'node': ammojs_path = sdk_path + '/lib/haxebullet/js/ammo/ammo.js' ammojs_path = ammojs_path.replace('\\', '/').replace('//', '/') f.write(add_assets(ammojs_path, rel_path=rel_path)) # haxe.macro.Compiler.includeFile(ammojs_path) elif wrd.arm_physics_engine == 'Oimo': assets.add_khafile_def('arm_oimo') if not os.path.exists('Libraries/oimo'): f.write(add_armory_library(sdk_path + '/lib/', 'oimo', rel_path=rel_path)) if export_navigation: assets.add_khafile_def('arm_navigation') if not os.path.exists('Libraries/haxerecast'): f.write(add_armory_library(sdk_path + '/lib/', 'haxerecast', rel_path=rel_path)) if state.target.startswith('krom') or state.target == 'html5': recastjs_path = sdk_path + '/lib/haxerecast/js/recast/recast.js' recastjs_path = recastjs_path.replace('\\', '/').replace('//', '/') f.write(add_assets(recastjs_path, rel_path=rel_path)) if is_publish: assets.add_khafile_def('arm_published') if wrd.arm_asset_compression: assets.add_khafile_def('arm_compress') else: pass # f.write("""project.addParameter("--macro include('armory.trait')");\n""") # f.write("""project.addParameter("--macro include('armory.trait.internal')");\n""") # if export_physics: # f.write("""project.addParameter("--macro include('armory.trait.physics')");\n""") # if wrd.arm_physics_engine == 'Bullet': # f.write("""project.addParameter("--macro include('armory.trait.physics.bullet')");\n""") # else: # f.write("""project.addParameter("--macro include('armory.trait.physics.oimo')");\n""") # if export_navigation: # f.write("""project.addParameter("--macro include('armory.trait.navigation')");\n""") # if import_logicnodes: # Live patching for logic nodes # f.write("""project.addParameter("--macro include('armory.logicnode')");\n""") if not wrd.arm_compiler_inline: f.write("project.addParameter('--no-inline');\n") if enable_dce: f.write("project.addParameter('-dce full');\n") if is_viewport or wrd.arm_debug_console: import_traits.append('armory.trait.internal.Bridge') import_traits = list(set(import_traits)) for i in range(0, len(import_traits)): f.write("project.addParameter('" + import_traits[i] + "');\n") f.write("""project.addParameter("--macro keep('""" + import_traits[i] + """')");\n""") shaderload = state.target == 'krom' or state.target == 'html5' if wrd.arm_cache_build and shaderload and not is_publish: # Load shaders manually assets.add_khafile_def('arm_shaderload') shaders_path = arm.utils.build_dir() + '/compiled/Shaders/*.glsl' if rel_path: shaders_path = os.path.relpath(shaders_path, arm.utils.get_fp()).replace('\\', '/') f.write('project.addShaders("' + shaders_path + '");\n') if arm.utils.get_gapi() == 'direct3d11': # noprocessing flag - gets renamed to .d3d11 shaders_path = arm.utils.build_dir() + '/compiled/Hlsl/*.glsl' if rel_path: shaders_path = os.path.relpath(shaders_path, arm.utils.get_fp()).replace('\\', '/') f.write('project.addShaders("' + shaders_path + '", { noprocessing: true });\n') # Move assets for published game to /data folder use_data_dir = is_publish and (state.target == 'krom-windows' or state.target == 'krom-linux' or state.target == 'windows' or state.target == 'linux') if use_data_dir: assets.add_khafile_def('arm_data_dir') ext = 'arm' if wrd.arm_minimize else 'json' assets_path = arm.utils.build_dir() + '/compiled/Assets/**' assets_path_sh = arm.utils.build_dir() + '/compiled/Shaders/*.' + ext if rel_path: assets_path = os.path.relpath(assets_path, arm.utils.get_fp()).replace('\\', '/') assets_path_sh = os.path.relpath(assets_path_sh, arm.utils.get_fp()).replace('\\', '/') dest = '' if use_data_dir: dest += ', destination: "data/{name}"' f.write('project.addAssets("' + assets_path + '", { notinlist: true ' + dest + '});\n') f.write('project.addAssets("' + assets_path_sh + '", { notinlist: true ' + dest + '});\n') shader_data_references = sorted(list(set(assets.shader_datas))) for ref in shader_data_references: ref = ref.replace('\\', '/').replace('//', '/') if '/compiled/' in ref: # Asset already included continue f.write(add_assets(ref, use_data_dir=use_data_dir, rel_path=rel_path)) asset_references = sorted(list(set(assets.assets))) for ref in asset_references: ref = ref.replace('\\', '/').replace('//', '/') if '/compiled/' in ref: # Asset already included continue quality = 1.0 s = ref.lower() if s.endswith('.wav'): quality = wrd.arm_sound_quality elif s.endswith('.png') or s.endswith('.jpg'): quality = wrd.arm_texture_quality f.write(add_assets(ref, quality=quality, use_data_dir=use_data_dir, rel_path=rel_path)) if wrd.arm_sound_quality < 1.0 or state.target == 'html5': assets.add_khafile_def('arm_soundcompress') if wrd.arm_texture_quality < 1.0: assets.add_khafile_def('arm_texcompress') if wrd.arm_debug_console: assets.add_khafile_def('arm_debug') f.write(add_shaders(sdk_path + "/armory/Shaders/debug_draw/**", rel_path=rel_path)) if export_ui: if not os.path.exists('Libraries/zui'): f.write(add_armory_library(sdk_path, 'lib/zui', rel_path=rel_path)) p = sdk_path + '/armory/Assets/font_default.ttf' p = p.replace('//', '/') f.write(add_assets(p.replace('\\', '/'), use_data_dir=use_data_dir, rel_path=rel_path)) assets.add_khafile_def('arm_ui') if wrd.arm_hscript == 'Enabled': if not os.path.exists('Libraries/hscript'): f.write(add_armory_library(sdk_path, 'lib/hscript', rel_path=rel_path)) assets.add_khafile_def('arm_hscript') if wrd.arm_formatlib == 'Enabled': if not os.path.exists('Libraries/iron_format'): f.write(add_armory_library(sdk_path, 'lib/iron_format', rel_path=rel_path)) if wrd.arm_minimize == False: assets.add_khafile_def('arm_json') if wrd.arm_deinterleaved_buffers == True: assets.add_khafile_def('arm_deinterleaved') if wrd.arm_batch_meshes == True: assets.add_khafile_def('arm_batch') if wrd.arm_stream_scene: assets.add_khafile_def('arm_stream') rpdat = arm.utils.get_rp() if rpdat.arm_skin == 'CPU': assets.add_khafile_def('arm_skin_cpu') elif rpdat.arm_skin == 'GPU (Matrix)': assets.add_khafile_def('arm_skin_mat') if rpdat.arm_skin != 'Off': assets.add_khafile_def('arm_skin') if rpdat.arm_particles == 'GPU': assets.add_khafile_def('arm_particles_gpu') if rpdat.arm_particles != 'Off': assets.add_khafile_def('arm_particles') if rpdat.rp_draw_order == 'Distance': assets.add_khafile_def('arm_draworder_dist') if arm.utils.get_viewport_controls() == 'azerty': assets.add_khafile_def('arm_azerty') if os.path.exists(arm.utils.get_fp() + '/Bundled/config.arm'): assets.add_khafile_def('arm_config') if is_publish and wrd.arm_loadscreen: assets.add_khafile_def('arm_loadscreen') # if bpy.data.scenes[0].unit_settings.system_rotation == 'DEGREES': # assets.add_khafile_def('arm_degrees') assets.add_khafile_def('arm_fast') for d in assets.khafile_defs: f.write("project.addDefine('" + d + "');\n") khafile_text = wrd.arm_khafile if khafile_text != '': f.write(bpy.data.texts[khafile_text].as_string()) if state.target.startswith('android-native'): bundle = 'org.armory3d.' + wrd.arm_project_package if wrd.arm_project_bundle == '' else wrd.arm_project_bundle f.write("project.targetOptions.android_native.package = '{0}';\n".format(arm.utils.safestr(bundle))) if wrd.arm_winorient != 'Multi': f.write("project.targetOptions.android_native.screenOrientation = '{0}';\n".format(wrd.arm_winorient.lower())) elif state.target.startswith('ios'): bundle = 'org.armory3d.' + wrd.arm_project_package if wrd.arm_project_bundle == '' else wrd.arm_project_bundle f.write("project.targetOptions.ios.bundle = '{0}';\n".format(arm.utils.safestr(bundle))) if wrd.arm_project_icon != '': shutil.copy(bpy.path.abspath(wrd.arm_project_icon), arm.utils.get_fp() + '/icon.png') f.write("\n\nresolve(project);\n")
def write_khafilejs(is_play, export_physics, export_navigation, export_ui, is_publish, enable_dce, in_viewport, import_traits, import_logicnodes): global check_dot_path sdk_path = arm.utils.get_sdk_path() wrd = bpy.data.worlds['Arm'] with open('khafile.js', 'w') as f: f.write("""// Auto-generated let project = new Project('""" + arm.utils.safestr(wrd.arm_project_name) + """'); project.addSources('Sources'); """) # TODO: Khamake bug workaround - assets & shaders located in folder starting with '.' get discarded - copy them to project check_dot_path = False if '/.' in sdk_path: check_dot_path = True if not os.path.exists(arm.utils.build_dir() + '/compiled/KhaShaders'): kha_shaders_path = arm.utils.get_kha_path( ) + '/Sources/Shaders' shutil.copytree(kha_shaders_path, arm.utils.build_dir() + '/compiled/KhaShaders') f.write("project.addShaders('" + arm.utils.build_dir() + "/compiled/KhaShaders/**');\n") # Auto-add assets located in Bundled directory if os.path.exists('Bundled'): for file in glob.glob("Bundled/**", recursive=True): if os.path.isfile(file): assets.add(file) if os.path.exists('Shaders'): for file in glob.glob("Shaders/**", recursive=True): if os.path.isfile(file): assets.add_shader(file) if not os.path.exists('Libraries/armory'): f.write(add_armory_library(sdk_path, 'armory')) if not os.path.exists('Libraries/iron'): f.write(add_armory_library(sdk_path, 'iron')) # Project libraries if os.path.exists('Libraries'): libs = os.listdir('Libraries') for lib in libs: if os.path.isdir('Libraries/' + lib): f.write('project.addLibrary("{0}");\n'.format(lib)) if export_physics: assets.add_khafile_def('arm_physics') if wrd.arm_physics == 'Bullet': assets.add_khafile_def('arm_bullet') if not os.path.exists('Libraries/haxebullet'): f.write( add_armory_library(sdk_path + '/lib/', 'haxebullet')) if state.target == 'krom' or state.target == 'html5' or state.target == 'node': ammojs_path = sdk_path + '/lib/haxebullet/js/ammo/ammo.js' ammojs_path = ammojs_path.replace('\\', '/') f.write(add_assets(ammojs_path)) elif wrd.arm_physics == 'Oimo': assets.add_khafile_def('arm_oimo') if not os.path.exists('Libraries/oimo'): f.write(add_armory_library(sdk_path + '/lib/', 'oimo')) if export_navigation: assets.add_khafile_def('arm_navigation') if not os.path.exists('Libraries/haxerecast'): f.write(add_armory_library(sdk_path + '/lib/', 'haxerecast')) if state.target == 'krom' or state.target == 'html5': recastjs_path = sdk_path + '/lib/haxerecast/js/recast/recast.js' recastjs_path = recastjs_path.replace('\\', '/') f.write(add_assets(recastjs_path)) if not is_publish: f.write( """project.addParameter("--macro include('armory.trait')");\n""" ) f.write( """project.addParameter("--macro include('armory.trait.internal')");\n""" ) if export_physics: f.write( """project.addParameter("--macro include('armory.trait.physics')");\n""" ) if wrd.arm_physics == 'Bullet': f.write( """project.addParameter("--macro include('armory.trait.physics.bullet')");\n""" ) else: f.write( """project.addParameter("--macro include('armory.trait.physics.oimo')");\n""" ) if export_navigation: f.write( """project.addParameter("--macro include('armory.trait.navigation')");\n""" ) if import_logicnodes: # Live patching for logic nodes f.write( """project.addParameter("--macro include('armory.logicnode')");\n""" ) if enable_dce: f.write("project.addParameter('-dce full');\n") if in_viewport: assets.add_khafile_def('arm_viewport') import_traits.append('armory.trait.internal.Bridge') import_traits = list(set(import_traits)) for i in range(0, len(import_traits)): f.write("project.addParameter('" + import_traits[i] + "');\n") f.write("""project.addParameter("--macro keep('""" + import_traits[i] + """')");\n""") if state.is_render: assets.add_khafile_def('arm_render') if state.is_render_anim: assets.add_khafile_def('arm_render_anim') if not os.path.exists('Libraries/iron_format'): f.write( add_armory_library(sdk_path + '/lib/', 'iron_format')) shaderload = state.target == 'krom' or state.target == 'html5' if wrd.arm_cache_compiler and shaderload and not is_publish: # Load shaders manually assets.add_khafile_def('arm_shaderload') sceneload = state.target == 'krom' if wrd.arm_play_live_patch and is_play and in_viewport and sceneload: # Scene patch assets.add_khafile_def('arm_sceneload') shader_references = sorted(list(set(assets.shaders))) for ref in shader_references: ref = ref.replace('\\', '/') f.write("project.addShaders('" + ref + "');\n") shader_data_references = sorted(list(set(assets.shader_datas))) for ref in shader_data_references: ref = ref.replace('\\', '/') f.write(add_assets(ref)) asset_references = sorted(list(set(assets.assets))) for ref in asset_references: ref = ref.replace('\\', '/') quality = 1.0 s = ref.lower() if s.endswith('.wav'): quality = wrd.arm_sound_quality elif s.endswith('.png') or s.endswith('.jpg'): quality = wrd.arm_texture_quality f.write(add_assets(ref, quality=quality)) if wrd.arm_sound_quality < 1.0 or state.target == 'html5': assets.add_khafile_def('arm_soundcompress') if wrd.arm_texture_quality < 1.0: assets.add_khafile_def('arm_texcompress') if wrd.arm_play_console: assets.add_khafile_def('arm_debug') f.write("project.addShaders('" + sdk_path + "/armory/Shaders/debug_draw/**');\n") if export_ui: if not os.path.exists('Libraries/zui'): f.write(add_armory_library(sdk_path, 'lib/zui')) p = sdk_path + '/armory/Assets/droid_sans.ttf' f.write(add_assets(p.replace('\\', '/'))) assets.add_khafile_def('arm_ui') if wrd.arm_hscript == 'Enabled': if not os.path.exists('Libraries/hscript'): f.write(add_armory_library(sdk_path, 'lib/hscript')) assets.add_khafile_def('arm_hscript') if wrd.arm_minimize == False: assets.add_khafile_def('arm_json') if wrd.arm_deinterleaved_buffers == True: assets.add_khafile_def('arm_deinterleaved') if wrd.arm_batch_meshes == True: assets.add_khafile_def('arm_batch') if wrd.arm_stream_scene: assets.add_khafile_def('arm_stream') if wrd.arm_skin == 'CPU': assets.add_khafile_def('arm_skin_cpu') elif wrd.arm_skin == 'GPU (Matrix)': assets.add_khafile_def('arm_skin_mat') if arm.utils.get_viewport_controls() == 'azerty': assets.add_khafile_def('arm_azerty') for d in assets.khafile_defs: f.write("project.addDefine('" + d + "');\n") config_text = wrd.arm_khafile if config_text != '': f.write(bpy.data.texts[config_text].as_string()) if wrd.arm_winorient != 'Multi': if state.target == 'android-native': f.write( "project.targetOptions.android_native.screenOrientation = '{0}';\n" .format(wrd.arm_winorient.lower())) f.write("\n\nresolve(project);\n")
def build_node_tree(world): output = {} dat = {} output['material_datas'] = [dat] wname = arm.utils.safestr(world.name) dat['name'] = wname + '_material' context = {} dat['contexts'] = [context] context['name'] = 'world' context['bind_constants'] = [] context['bind_textures'] = [] wrd = bpy.data.worlds['Arm'] wrd.world_defs = '' rpdat = arm.utils.get_rp() # Traverse world node tree parsed = False if world.node_tree != None: output_node = nodes.get_node_by_type(world.node_tree, 'OUTPUT_WORLD') if output_node != None: parse_world_output(world, output_node, context) parsed = True if parsed == False: if wrd.arm_irradiance and rpdat.arm_material_model != 'Restricted': wrd.world_defs += '_Irr' envmap_strength_const = {} envmap_strength_const['name'] = 'envmapStrength' envmap_strength_const['float'] = 1.0 context['bind_constants'].append(envmap_strength_const) world.arm_envtex_color = [0.051, 0.051, 0.051, 1.0] world.arm_envtex_strength = envmap_strength_const['float'] # Clear to color if no texture or sky is provided if '_EnvSky' not in wrd.world_defs and '_EnvTex' not in wrd.world_defs: if '_EnvImg' not in wrd.world_defs: wrd.world_defs += '_EnvCol' # Irradiance json file name world.arm_envtex_name = wname world.arm_envtex_irr_name = wname write_probes.write_color_irradiance(wname, world.arm_envtex_color) # Clouds enabled if rpdat.arm_clouds: wrd.world_defs += '_EnvClouds' # Percentage closer soft shadows if rpdat.arm_pcss_state == 'On': wrd.world_defs += '_PCSS' sdk_path = arm.utils.get_sdk_path() assets.add(sdk_path + 'armory/Assets/noise64.png') assets.add_embedded_data('noise64.png') # Screen-space ray-traced shadows if rpdat.arm_ssrs: wrd.world_defs += '_SSRS' if wrd.arm_two_sided_area_lamp: wrd.world_defs += '_TwoSidedAreaLamp' # Store contexts if rpdat.rp_hdr == False: wrd.world_defs += '_LDR' # Alternative models if rpdat.arm_material_model == 'Cycles': wrd.world_defs += '_Cycles' # TODO: Lamp texture test.. if wrd.arm_lamp_texture != '': wrd.world_defs += '_LampColTex' if wrd.arm_lamp_ies_texture != '': wrd.world_defs += '_LampIES' assets.add_embedded_data('iestexture.png') voxelgi = False voxelao = False if rpdat.rp_shadowmap == 'None': wrd.world_defs += '_NoShadows' assets.add_khafile_def('arm_no_shadows') if rpdat.rp_voxelgi: voxelgi = True elif rpdat.rp_voxelao: voxelao = True if rpdat.rp_dfrs: wrd.world_defs += '_DFRS' assets.add_khafile_def('arm_sdf') if rpdat.rp_dfao: wrd.world_defs += '_DFAO' assets.add_khafile_def('arm_sdf') if rpdat.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') if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' if rpdat.arm_voxelgi_shadows: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIShadow' if rpdat.arm_voxelgi_refraction: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIRefract' wrd.world_defs += '_VoxelGI' wrd.world_defs += '_Rad' # Always do radiance for voxels wrd.world_defs += '_Irr' elif voxelao: assets.add_khafile_def('arm_voxelgi') if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') wrd.world_defs += '_VoxelAO' wrd.world_defs += '_Rad' wrd.world_defs += '_Irr' if arm.utils.get_gapi().startswith( 'direct3d'): # Flip Y axis in drawQuad command wrd.world_defs += '_InvY' # Area lamps for lamp in bpy.data.lamps: if lamp.type == 'AREA': wrd.world_defs += '_PolyLight' break # Data will be written after render path has been processed to gather all defines return output
def build(): rpdat = arm.utils.get_rp() if rpdat.rp_driver != 'Armory' and arm.api.drivers[ rpdat.rp_driver]['make_rpath'] != None: arm.api.drivers[rpdat.rp_driver]['make_rpath']() return assets_path = arm.utils.get_sdk_path() + '/armory/Assets/' wrd = bpy.data.worlds['Arm'] add_world_defs() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' if not mobile_mat: # Always include assets.add(assets_path + 'brdf.png') assets.add_embedded_data('brdf.png') if rpdat.rp_hdr: assets.add_khafile_def('rp_hdr') assets.add_khafile_def('rp_renderer={0}'.format(rpdat.rp_renderer)) if rpdat.rp_depthprepass: assets.add_khafile_def('rp_depthprepass') if rpdat.rp_shadowmap != 'Off': assets.add_khafile_def('rp_shadowmap') assets.add_khafile_def('rp_shadowmap_size={0}'.format( rpdat.rp_shadowmap)) assets.add_khafile_def('rp_background={0}'.format(rpdat.rp_background)) if rpdat.rp_background == 'World': assets.add_shader_pass('world_pass') if '_EnvClouds' in wrd.world_defs: assets.add(assets_path + 'noise256.png') assets.add_embedded_data('noise256.png') if rpdat.rp_renderer == 'Deferred' and not rpdat.rp_compositornodes: assets.add_shader_pass('copy_pass') if rpdat.rp_renderer == 'Forward' and not rpdat.rp_compositornodes and rpdat.rp_render_to_texture: assets.add_shader_pass('copy_pass') if rpdat.rp_render_to_texture: assets.add_khafile_def('rp_render_to_texture') if rpdat.rp_compositornodes: assets.add_khafile_def('rp_compositornodes') compo_depth = False if rpdat.arm_tonemap != 'Off': wrd.compo_defs = '_CTone' + rpdat.arm_tonemap if rpdat.rp_antialiasing == 'FXAA': wrd.compo_defs += '_CFXAA' if rpdat.arm_letterbox: wrd.compo_defs += '_CLetterbox' if rpdat.arm_grain: wrd.compo_defs += '_CGrain' if rpdat.arm_sharpen: wrd.compo_defs += '_CSharpen' if bpy.data.scenes[0].cycles.film_exposure != 1.0: wrd.compo_defs += '_CExposure' if rpdat.arm_fog: wrd.compo_defs += '_CFog' compo_depth = True if len(bpy.data.cameras ) > 0 and bpy.data.cameras[0].dof_distance > 0.0: wrd.compo_defs += '_CDOF' compo_depth = True if compo_depth: wrd.compo_defs += '_CDepth' assets.add_khafile_def('rp_compositordepth') if rpdat.arm_lens_texture != '': wrd.compo_defs += '_CLensTex' assets.add_embedded_data('lenstexture.jpg') if rpdat.arm_fisheye: wrd.compo_defs += '_CFishEye' if rpdat.arm_vignette: wrd.compo_defs += '_CVignette' if rpdat.arm_lensflare: wrd.compo_defs += '_CGlare' if rpdat.arm_lut_texture != '': wrd.compo_defs += '_CLUT' assets.add_embedded_data('luttexture.jpg') if '_CDOF' in wrd.compo_defs or '_CFXAA' in wrd.compo_defs or '_CSharpen' in wrd.compo_defs: wrd.compo_defs += '_CTexStep' if '_CDOF' in wrd.compo_defs or '_CFog' in wrd.compo_defs or '_CGlare' in wrd.compo_defs: wrd.compo_defs += '_CCameraProj' assets.add_shader_pass('compositor_pass') assets.add_khafile_def('rp_antialiasing={0}'.format( rpdat.rp_antialiasing)) if rpdat.rp_antialiasing == 'SMAA' or rpdat.rp_antialiasing == 'TAA': assets.add_shader_pass('smaa_edge_detect') assets.add_shader_pass('smaa_blend_weight') assets.add_shader_pass('smaa_neighborhood_blend') assets.add(assets_path + 'smaa_area.png') assets.add(assets_path + 'smaa_search.png') assets.add_embedded_data('smaa_area.png') assets.add_embedded_data('smaa_search.png') wrd.world_defs += '_SMAA' if rpdat.rp_antialiasing == 'TAA': assets.add_shader_pass('taa_pass') assets.add_shader_pass('copy_pass') if rpdat.rp_antialiasing == 'TAA' or rpdat.rp_motionblur == 'Object': assets.add_khafile_def('arm_veloc') wrd.world_defs += '_Veloc' if rpdat.rp_antialiasing == 'TAA': assets.add_khafile_def('arm_taa') assets.add_khafile_def('rp_supersampling={0}'.format( rpdat.rp_supersampling)) if rpdat.rp_supersampling == '4': assets.add_shader_pass('supersample_resolve') if rpdat.rp_overlays: assets.add_khafile_def('rp_overlays') if rpdat.rp_translucency: assets.add_khafile_def('rp_translucency') assets.add_shader_pass('translucent_resolve') if rpdat.rp_stereo: assets.add_khafile_def('rp_stereo') assets.add_khafile_def('arm_vr') wrd.world_defs += '_VR' assets.add(assets_path + 'vr.png') assets.add_embedded_data('vr.png') rp_gi = rpdat.rp_gi has_voxels = arm.utils.voxel_support() if not has_voxels: rp_gi = 'Off' assets.add_khafile_def('rp_gi={0}'.format(rp_gi)) if rpdat.rp_gi != 'Off': if has_voxels: assets.add_khafile_def('rp_gi={0}'.format(rpdat.rp_gi)) assets.add_khafile_def('rp_voxelgi_resolution={0}'.format( rpdat.rp_voxelgi_resolution)) assets.add_khafile_def('rp_voxelgi_resolution_z={0}'.format( rpdat.rp_voxelgi_resolution_z)) if rpdat.rp_voxelgi_hdr: assets.add_khafile_def('rp_voxelgi_hdr') if rpdat.arm_voxelgi_shadows: assets.add_khafile_def('rp_voxelgi_shadows') if rpdat.arm_voxelgi_refraction: assets.add_khafile_def('rp_voxelgi_refraction') else: log.warn( 'Disabling Voxel GI - unsupported target - use Krom instead') if rpdat.arm_rp_resolution == 'Custom': assets.add_khafile_def('rp_resolution_filter={0}'.format( rpdat.arm_rp_resolution_filter)) assets.add_khafile_def('rp_ssgi={0}'.format(rpdat.rp_ssgi)) if rpdat.rp_ssgi != 'Off': wrd.world_defs += '_SSAO' if rpdat.rp_ssgi == 'SSAO': assets.add_shader_pass('ssao_pass') assets.add_shader_pass('blur_edge_pass') assets.add(assets_path + 'noise8.png') assets.add_embedded_data('noise8.png') else: assets.add_shader_pass('ssgi_pass') assets.add_shader_pass('ssgi_blur_pass') if rpdat.rp_renderer == 'Deferred': assets.add_shader_pass('deferred_indirect') assets.add_shader_pass('deferred_light') assets.add_shader_pass('deferred_light_quad') if rpdat.rp_volumetriclight: assets.add_khafile_def('rp_volumetriclight') assets.add_shader_pass('volumetric_light_quad') assets.add_shader_pass('volumetric_light') assets.add_shader_pass('blur_bilat_pass') assets.add_shader_pass('blur_bilat_blend_pass') assets.add(assets_path + 'blue_noise64.png') assets.add_embedded_data('blue_noise64.png') if rpdat.rp_decals: assets.add_khafile_def('rp_decals') if rpdat.rp_ocean: assets.add_khafile_def('rp_ocean') assets.add_shader_pass('water_pass') if rpdat.rp_blending: assets.add_khafile_def('rp_blending') if rpdat.rp_bloom: assets.add_khafile_def('rp_bloom') assets.add_shader_pass('bloom_pass') assets.add_shader_pass('blur_gaus_pass') if rpdat.rp_sss: assets.add_khafile_def('rp_sss') wrd.world_defs += '_SSS' assets.add_shader_pass('sss_pass') if rpdat.rp_ssr: assets.add_khafile_def('rp_ssr') assets.add_shader_pass('ssr_pass') assets.add_shader_pass('blur_adaptive_pass') if rpdat.arm_ssr_half_res: assets.add_khafile_def('rp_ssr_half') if rpdat.rp_ssr_z_only: wrd.world_defs += '_SSRZOnly' if rpdat.rp_motionblur != 'Off': assets.add_khafile_def('rp_motionblur={0}'.format(rpdat.rp_motionblur)) assets.add_shader_pass('copy_pass') if rpdat.rp_motionblur == 'Camera': assets.add_shader_pass('motion_blur_pass') else: assets.add_shader_pass('motion_blur_veloc_pass') if rpdat.rp_compositornodes and rpdat.rp_autoexposure: assets.add_khafile_def('rp_autoexposure') if rpdat.rp_dynres: assets.add_khafile_def('rp_dynres') if rpdat.arm_soft_shadows == 'On': if rpdat.rp_shadowmap_cascades == '1': assets.add_shader_pass('dilate_pass') assets.add_shader_pass('visibility_pass') assets.add_shader_pass('blur_shadow_pass') assets.add_khafile_def('rp_soft_shadows') wrd.world_defs += '_SoftShadows' if rpdat.arm_soft_shadows_penumbra != 1: wrd.world_defs += '_PenumbraScale' else: log.warn( 'Disabling soft shadows - "Armory Render Path - Cascades" requires to be set to 1 for now' ) gbuffer2_direct = '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs or rpdat.arm_voxelgi_refraction gbuffer2 = '_Veloc' in wrd.world_defs or gbuffer2_direct if gbuffer2: assets.add_khafile_def('rp_gbuffer2') wrd.world_defs += '_gbuffer2' if gbuffer2_direct: assets.add_khafile_def('rp_gbuffer2_direct') wrd.world_defs += '_gbuffer2direct' if callback != None: callback()
def parse_color(world: bpy.types.World, node: bpy.types.Node, frag: Shader): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' # Env map included if node.type == 'TEX_ENVIRONMENT' and node.image is not None: world.world_defs += '_EnvTex' frag.add_include('std/math.glsl') frag.add_uniform('sampler2D envmap', link='_envmap') image = node.image filepath = image.filepath if image.packed_file is None and not os.path.isfile( arm.utils.asset_path(filepath)): log.warn(world.name + ' - unable to open ' + image.filepath) return # Reference image name tex_file = arm.utils.extract_filename(image.filepath) base = tex_file.rsplit('.', 1) ext = base[1].lower() if ext == 'hdr': target_format = 'HDR' else: target_format = 'JPEG' do_convert = ext != 'hdr' and ext != 'jpg' if do_convert: if ext == 'exr': tex_file = base[0] + '.hdr' target_format = 'HDR' else: tex_file = base[0] + '.jpg' target_format = 'JPEG' if image.packed_file is not None: # Extract packed data unpack_path = arm.utils.get_fp_build( ) + '/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + tex_file filepath = unpack_filepath if do_convert: if not os.path.isfile(unpack_filepath): arm.utils.unpack_image(image, unpack_filepath, file_format=target_format) elif not os.path.isfile(unpack_filepath) or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: if do_convert: unpack_path = arm.utils.get_fp_build( ) + '/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) converted_path = unpack_path + '/' + tex_file filepath = converted_path # TODO: delete cache when file changes if not os.path.isfile(converted_path): arm.utils.convert_image(image, converted_path, file_format=target_format) assets.add(converted_path) else: # Link image path to assets assets.add(arm.utils.asset_path(image.filepath)) # Generate prefiltered envmaps world.arm_envtex_name = tex_file world.arm_envtex_irr_name = tex_file.rsplit('.', 1)[0] disable_hdr = target_format == 'JPEG' mip_count = world.arm_envtex_num_mips mip_count = write_probes.write_probes(filepath, disable_hdr, mip_count, arm_radiance=rpdat.arm_radiance) world.arm_envtex_num_mips = mip_count # Append LDR define if disable_hdr: world.world_defs += '_EnvLDR' # Append radiance define if rpdat.arm_irradiance and rpdat.arm_radiance and not mobile_mat: wrd.world_defs += '_Rad' # Static image background elif node.type == 'TEX_IMAGE': world.world_defs += '_EnvImg' # Background texture frag.add_uniform('sampler2D envmap', link='_envmap') frag.add_uniform('vec2 screenSize', link='_screenSize') image = node.image filepath = image.filepath if image.packed_file is not None: # Extract packed data filepath = arm.utils.build_dir() + '/compiled/Assets/unpacked' unpack_path = arm.utils.get_fp() + filepath if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + image.name if os.path.isfile(unpack_filepath) == False or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: # Link image path to assets assets.add(arm.utils.asset_path(image.filepath)) # Reference image name tex_file = arm.utils.extract_filename(image.filepath) base = tex_file.rsplit('.', 1) ext = base[1].lower() if ext == 'hdr': target_format = 'HDR' else: target_format = 'JPEG' # Generate prefiltered envmaps world.arm_envtex_name = tex_file world.arm_envtex_irr_name = tex_file.rsplit('.', 1)[0] disable_hdr = target_format == 'JPEG' mip_count = world.arm_envtex_num_mips mip_count = write_probes.write_probes(filepath, disable_hdr, mip_count, arm_radiance=rpdat.arm_radiance) world.arm_envtex_num_mips = mip_count # Append sky define elif node.type == 'TEX_SKY': # Match to cycles world.arm_envtex_strength *= 0.1 world.world_defs += '_EnvSky' assets.add_khafile_def('arm_hosek') frag.add_uniform('vec3 A', link="_hosekA") frag.add_uniform('vec3 B', link="_hosekB") frag.add_uniform('vec3 C', link="_hosekC") frag.add_uniform('vec3 D', link="_hosekD") frag.add_uniform('vec3 E', link="_hosekE") frag.add_uniform('vec3 F', link="_hosekF") frag.add_uniform('vec3 G', link="_hosekG") frag.add_uniform('vec3 H', link="_hosekH") frag.add_uniform('vec3 I', link="_hosekI") frag.add_uniform('vec3 Z', link="_hosekZ") frag.add_uniform('vec3 hosekSunDirection', link="_hosekSunDirection") frag.add_function( '''vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) { \tvec3 chi = (1 + cos_gamma * cos_gamma) / pow(1 + H * H - 2 * cos_gamma * H, vec3(1.5)); \treturn (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta)); }''') world.arm_envtex_sun_direction = [ node.sun_direction[0], node.sun_direction[1], node.sun_direction[2] ] world.arm_envtex_turbidity = node.turbidity world.arm_envtex_ground_albedo = node.ground_albedo # Irradiance json file name wname = arm.utils.safestr(world.name) world.arm_envtex_irr_name = wname write_probes.write_sky_irradiance(wname) # Radiance if rpdat.arm_radiance and rpdat.arm_irradiance and not mobile_mat: wrd.world_defs += '_Rad' hosek_path = 'armory/Assets/hosek/' sdk_path = arm.utils.get_sdk_path() # Use fake maps for now assets.add(sdk_path + '/' + hosek_path + 'hosek_radiance.hdr') for i in range(0, 8): assets.add(sdk_path + '/' + hosek_path + 'hosek_radiance_' + str(i) + '.hdr') world.arm_envtex_name = 'hosek' world.arm_envtex_num_mips = 8