Ejemplo n.º 1
0
def build_node_tree(world: bpy.types.World, frag: Shader):
    """Generates the shader code for the given world."""
    world_name = arm.utils.safestr(world.name)
    world.world_defs = ''
    rpdat = arm.utils.get_rp()
    wrd = bpy.data.worlds['Arm']

    if callback is not None:
        callback()

    # Traverse world node tree
    is_parsed = False
    if world.node_tree is not None:
        output_node = node_utils.get_node_by_type(world.node_tree,
                                                  'OUTPUT_WORLD')
        if output_node is not None:
            is_parsed = parse_world_output(world, output_node, frag)

    # No world nodes/no output node, use background color
    if not is_parsed:
        solid_mat = rpdat.arm_material_model == 'Solid'
        if rpdat.arm_irradiance and not solid_mat:
            world.world_defs += '_Irr'
        col = world.color
        world.arm_envtex_color = [col[0], col[1], col[2], 1.0]
        world.arm_envtex_strength = 1.0

    # Clear to color if no texture or sky is provided
    if '_EnvSky' not in world.world_defs and '_EnvTex' not in world.world_defs:
        if '_EnvImg' not in world.world_defs:
            world.world_defs += '_EnvCol'
            frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')

            # Irradiance json file name
            world.arm_envtex_name = world_name
            world.arm_envtex_irr_name = world_name
        write_probes.write_color_irradiance(world_name, world.arm_envtex_color)

    # film_transparent
    if bpy.context.scene is not None and hasattr(
            bpy.context.scene.render,
            'film_transparent') and bpy.context.scene.render.film_transparent:
        world.world_defs += '_EnvTransp'
        world.world_defs += '_EnvCol'
        frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')

    # Clouds enabled
    if rpdat.arm_clouds and world.arm_use_clouds:
        world.world_defs += '_EnvClouds'
        # Also set this flag globally so that the required textures are
        # included
        wrd.world_defs += '_EnvClouds'
        frag_write_clouds(world, frag)

    if '_EnvSky' in world.world_defs or '_EnvTex' in world.world_defs or '_EnvImg' in world.world_defs or '_EnvClouds' in world.world_defs:
        frag.add_uniform('float envmapStrength', link='_envmapStrength')

    frag_write_main(world, frag)
Ejemplo n.º 2
0
def build():
    """Builds world shaders for all exported worlds."""
    global shader_datas

    wrd = bpy.data.worlds['Arm']
    rpdat = arm.utils.get_rp()

    mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid'
    envpath = os.path.join(arm.utils.get_fp_build(), 'compiled', 'Assets',
                           'envmaps')

    wrd.world_defs = ''
    worlds = []
    shader_datas = []

    with write_probes.setup_envmap_render():

        for scene in bpy.data.scenes:
            world = scene.world

            # Only export worlds from enabled scenes and only once per world
            if scene.arm_export and world is not None and world not in worlds:
                worlds.append(world)

                world.arm_envtex_name = ''
                create_world_shaders(world)

                if rpdat.arm_irradiance:
                    # Plain background color
                    if '_EnvCol' in world.world_defs:
                        world_name = arm.utils.safestr(world.name)
                        # Irradiance json file name
                        world.arm_envtex_name = world_name
                        world.arm_envtex_irr_name = world_name
                        write_probes.write_color_irradiance(
                            world_name, world.arm_envtex_color)

                    # Render world to envmap for (ir)radiance, if no
                    # other probes are exported
                    elif world.arm_envtex_name == '':
                        image_file = write_probes.render_envmap(envpath, world)
                        image_filepath = os.path.join(envpath, image_file)

                        world.arm_envtex_name = image_file
                        world.arm_envtex_irr_name = os.path.basename(
                            image_filepath).rsplit('.', 1)[0]

                        write_radiance = rpdat.arm_radiance and not mobile_mat
                        mip_count = write_probes.write_probes(
                            image_filepath,
                            write_probes.ENVMAP_FORMAT == 'JPEG', False,
                            world.arm_envtex_num_mips, write_radiance)
                        world.arm_envtex_num_mips = mip_count

                        if write_radiance:
                            # Set world def, everything else is handled by write_probes()
                            wrd.world_defs += '_Rad'
Ejemplo n.º 3
0
def build_node_tree(world):
    wname = arm.utils.safestr(world.name)
    wrd = bpy.data.worlds['Arm']
    wrd.world_defs = ''
    rpdat = arm.utils.get_rp()
    
    if callback != None:
        callback()
    
    # 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)
            parsed = True
    if parsed == False:
        solid_mat = rpdat.arm_material_model == 'Solid'
        if rpdat.arm_irradiance and not solid_mat:
            wrd.world_defs += '_Irr'
        c = world.color
        world.arm_envtex_color = [c[0], c[1], c[2], 1.0]
        world.arm_envtex_strength = 1.0
    
    # 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 hasattr(bpy.context.scene.render, 'film_transparent') and bpy.context.scene.render.film_transparent:
        wrd.world_defs += '_EnvTransp'
        wrd.world_defs += '_EnvCol'

    # Clouds enabled
    if rpdat.arm_clouds:
        wrd.world_defs += '_EnvClouds'

    if '_EnvSky' in wrd.world_defs or '_EnvTex' in wrd.world_defs or '_EnvImg' in wrd.world_defs or '_EnvClouds' in wrd.world_defs:
        wrd.world_defs += '_EnvStr'
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
def build_node_tree(world: bpy.types.World, frag: Shader, vert: Shader,
                    con: ShaderContext):
    """Generates the shader code for the given world."""
    world_name = arm.utils.safestr(world.name)
    world.world_defs = ''
    rpdat = arm.utils.get_rp()
    wrd = bpy.data.worlds['Arm']

    if callback is not None:
        callback()

    # film_transparent, do not render
    if bpy.context.scene is not None and bpy.context.scene.render.film_transparent:
        world.world_defs += '_EnvCol'
        frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')
        frag.write('fragColor.rgb = backgroundCol;')
        return

    parser_state = ParserState(ParserContext.WORLD, world)
    parser_state.con = con
    parser_state.curshader = frag
    parser_state.frag = frag
    parser_state.vert = vert
    cycles.state = parser_state

    # Traverse world node tree
    is_parsed = False
    if world.node_tree is not None:
        output_node = node_utils.get_node_by_type(world.node_tree,
                                                  'OUTPUT_WORLD')
        if output_node is not None:
            is_parsed = parse_world_output(world, output_node, frag)

    # No world nodes/no output node, use background color
    if not is_parsed:
        solid_mat = rpdat.arm_material_model == 'Solid'
        if rpdat.arm_irradiance and not solid_mat:
            world.world_defs += '_Irr'
        col = world.color
        world.arm_envtex_color = [col[0], col[1], col[2], 1.0]
        world.arm_envtex_strength = 1.0

    # Irradiance/Radiance: clear to color if no texture or sky is provided
    if rpdat.arm_irradiance or rpdat.arm_irradiance:
        if '_EnvSky' not in world.world_defs and '_EnvTex' not in world.world_defs and '_EnvImg' not in world.world_defs:
            # Irradiance json file name
            world.arm_envtex_name = world_name
            world.arm_envtex_irr_name = world_name
            write_probes.write_color_irradiance(world_name,
                                                world.arm_envtex_color)

    # Clouds enabled
    if rpdat.arm_clouds and world.arm_use_clouds:
        world.world_defs += '_EnvClouds'
        # Also set this flag globally so that the required textures are
        # included
        wrd.world_defs += '_EnvClouds'
        frag_write_clouds(world, frag)

    if '_EnvSky' in world.world_defs or '_EnvTex' in world.world_defs or '_EnvImg' in world.world_defs or '_EnvClouds' in world.world_defs:
        frag.add_uniform('float envmapStrength', link='_envmapStrength')

    # Clear background color
    if '_EnvCol' in world.world_defs:
        frag.write('fragColor.rgb = backgroundCol;')

    elif '_EnvTex' in world.world_defs and '_EnvLDR' in world.world_defs:
        frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(2.2));')

    if '_EnvClouds' in world.world_defs:
        frag.write(
            'if (n.z > 0.0) fragColor.rgb = mix(fragColor.rgb, traceClouds(fragColor.rgb, n), clamp(n.z * 5.0, 0, 1));'
        )

    if '_EnvLDR' in world.world_defs:
        frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')

    # Mark as non-opaque
    frag.write('fragColor.a = 0.0;')

    # Hack to make procedural textures work
    frag_bpos = (
        frag.contains('bposition')
        and not frag.contains('vec3 bposition')) or vert.contains('bposition')
    if frag_bpos:
        frag.add_in('vec3 bposition')
        vert.add_out('vec3 bposition')
        # Use normals for now
        vert.write('bposition = nor;')

    frag_mpos = (
        frag.contains('mposition')
        and not frag.contains('vec3 mposition')) or vert.contains('mposition')
    if frag_mpos:
        frag.add_in('vec3 mposition')
        vert.add_out('vec3 mposition')
        # Use normals for now
        vert.write('mposition = nor;')

    if frag.contains('texCoord') and not frag.contains('vec2 texCoord'):
        frag.add_in('vec2 texCoord')
        vert.add_out('vec2 texCoord')
        # World has no UV map
        vert.write('texCoord = vec2(1.0, 1.0);')
Ejemplo n.º 7
0
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