Пример #1
0
def build_node_trees(assets_path):
    s = bpy.data.filepath.split(os.path.sep)
    s.pop()
    fp = os.path.sep.join(s)
    os.chdir(fp)

    # Make sure Assets dir exists
    if not os.path.exists('build/compiled/Assets/renderpaths'):
        os.makedirs('build/compiled/Assets/renderpaths')

    build_node_trees.assets_path = assets_path
    # Always include
    assets.add(assets_path + 'brdf.png')
    assets.add_embedded_data('brdf.png')

    bpy.data.worlds['Arm'].rp_defs = ''

    # Export render path for each camera
    parsed_paths = []
    for cam in bpy.data.cameras:
        # if cam.game_export
        if cam.renderpath_path not in parsed_paths:
            node_group = bpy.data.node_groups[cam.renderpath_path]
            build_node_tree(cam, node_group)
            parsed_paths.append(cam.renderpath_path)
Пример #2
0
def make_ssao_pass(stages, node_group, node):
    sc = 0.5 if bpy.data.worlds['Arm'].generate_ssao_half_res else 1.0
    make_quad_pass(stages,
                   node_group,
                   node,
                   target_index=1,
                   bind_target_indices=[3, 4],
                   bind_target_constants=['gbufferD', 'gbuffer0'],
                   shader_context='ssao_pass/ssao_pass/ssao_pass',
                   viewport_scale=sc)
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=2,
        bind_target_indices=[1, 4],
        bind_target_constants=['tex', 'gbuffer0'],
        shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_x',
        viewport_scale=sc)
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=1,
        bind_target_indices=[2, 4],
        bind_target_constants=['tex', 'gbuffer0'],
        shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_y')
    assets.add(build_node_trees.assets_path + 'noise8.png')
    assets.add_embedded_data('noise8.png')
Пример #3
0
def make_ssao_reproject_pass(stages, node_group, node):
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=1,
        bind_target_indices=[3, 4, 2, 5],
        bind_target_constants=['gbufferD', 'gbuffer0', 'slast', 'sveloc'],
        shader_context=
        'ssao_reproject_pass/ssao_reproject_pass/ssao_reproject_pass')
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=2,
        bind_target_indices=[1, 4],
        bind_target_constants=['tex', 'gbuffer0'],
        shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_x')
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=1,
        bind_target_indices=[2, 4],
        bind_target_constants=['tex', 'gbuffer0'],
        shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_y')
    assets.add(build_node_trees.assets_path + 'noise8.png')
    assets.add_embedded_data('noise8.png')
Пример #4
0
def make_apply_ssao_pass(stages, node_group, node):
    make_quad_pass(stages,
                   node_group,
                   node,
                   target_index=2,
                   bind_target_indices=[4, 5],
                   bind_target_constants=['gbufferD', 'gbuffer0'],
                   shader_context='ssao_pass/ssao_pass/ssao_pass')
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=3,
        bind_target_indices=[2, 5],
        bind_target_constants=['tex', 'gbuffer0'],
        shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_x')
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=1,
        bind_target_indices=[3, 5],
        bind_target_constants=['tex', 'gbuffer0'],
        shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_y_blend')
    assets.add(build_node_trees.assets_path + 'noise8.png')
    assets.add_embedded_data('noise8.png')
Пример #5
0
def make_draw_world(stage, node_group, node, dome=True):
    if dome:
        stage['command'] = 'draw_skydome'
    else:
        stage['command'] = 'draw_material_quad'
    # stage['params'].append(wname + '_material/' + wname + '_material/world')
    stage['params'].append('_worldMaterial')  # Link to active world
    # Link assets
    if '_EnvClouds' in bpy.data.worlds['Arm'].world_defs:
        assets.add(build_node_trees.assets_path + 'noise256.png')
        assets.add_embedded_data('noise256.png')
Пример #6
0
def make_smaa_pass(stages, node_group, node):
    stage = {}
    stage['params'] = []
    make_set_target(stage, node_group, node, target_index=2)
    stages.append(stage)

    stage = {}
    stage['params'] = []
    make_clear_target(stage, color_val=[0.0, 0.0, 0.0, 0.0])
    stages.append(stage)

    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=None,
        bind_target_indices=[4],
        bind_target_constants=['colorTex'],
        shader_context='smaa_edge_detect/smaa_edge_detect/smaa_edge_detect')

    stage = {}
    stage['params'] = []
    make_set_target(stage, node_group, node, target_index=3)
    stages.append(stage)

    stage = {}
    stage['params'] = []
    make_clear_target(stage, color_val=[0.0, 0.0, 0.0, 0.0])
    stages.append(stage)

    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=None,
        bind_target_indices=[2],
        bind_target_constants=['edgesTex'],
        shader_context='smaa_blend_weight/smaa_blend_weight/smaa_blend_weight')
    make_quad_pass(
        stages,
        node_group,
        node,
        target_index=1,
        bind_target_indices=[4, 3, 5],
        bind_target_constants=['colorTex', 'blendTex', 'sveloc'],
        shader_context=
        'smaa_neighborhood_blend/smaa_neighborhood_blend/smaa_neighborhood_blend'
    )
    assets.add(build_node_trees.assets_path + 'smaa_area.png')
    assets.add(build_node_trees.assets_path + 'smaa_search.png')
    assets.add_embedded_data('smaa_area.png')
    assets.add_embedded_data('smaa_search.png')
Пример #7
0
def make_draw_compositor(stage, node_group, node, with_fxaa=False):
    scon = 'compositor_pass'
    wrd = bpy.data.worlds['Arm']
    world_defs = wrd.world_defs + wrd.rp_defs
    compositor_defs = make_compositor.parse_defs(
        bpy.data.scenes[0].node_tree)  # Thrown in scene 0 for now
    compositor_defs += '_CTone' + wrd.generate_tonemap
    # Additional compositor flags
    compo_depth = False  # Read depth
    # compo_pos = False # Construct position from depth
    if with_fxaa:  # FXAA directly in compositor, useful for forward path
        compositor_defs += '_CFXAA'
    if wrd.generate_letterbox:
        compositor_defs += '_CLetterbox'
    if wrd.generate_grain:
        compositor_defs += '_CGrain'
    if bpy.data.scenes[0].cycles.film_exposure != 1.0:
        compositor_defs += '_CExposure'
    if wrd.generate_fog:
        compositor_defs += '_CFog'
        # compo_pos = True
    if build_node_tree.cam.dof_distance > 0.0:
        compositor_defs += '_CDOF'
        compo_depth = True
    # if compo_pos:
    # compositor_defs += '_CPos'
    # compo_depth = True
    if compo_depth:
        compositor_defs += '_CDepth'

    if wrd.generate_lens_texture != '':
        compositor_defs += '_CLensTex'
        assets.add_embedded_data('lenstexture.jpg')

    if wrd.generate_fisheye:
        compositor_defs += '_CFishEye'

    if wrd.generate_vignette:
        compositor_defs += '_CVignette'

    wrd.compo_defs = compositor_defs

    defs = world_defs + compositor_defs
    data_name = scon + defs

    stage['command'] = 'draw_shader_quad'
    stage['params'].append(data_name + '/' + data_name + '/' + scon)
    # Include data and shaders
    assets.add_shader2(scon, data_name)
Пример #8
0
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))
Пример #9
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
Пример #10
0
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()
Пример #11
0
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'
Пример #12
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
Пример #13
0
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'
Пример #14
0
def parse_value(node, socket):

    if node.type == 'GROUP':
        if node.node_tree.name.startswith('Armory PBR'):
            # Displacement
            if socket == node.outputs[1]:
                res = parse_value_input(node.inputs[10])
                if node.inputs[
                        11].is_linked or node.inputs[11].default_value != 1.0:
                    res = "({0} * {1})".format(
                        res, parse_value_input(node.inputs[11]))
                return res
            else:
                return None
        else:
            return parse_group(node, socket)

    elif node.type == 'GROUP_INPUT':
        return parse_group_input(node, socket)

    elif node.type == 'ATTRIBUTE':
        # Pass time till drivers are implemented
        if node.attribute_name == 'time':
            curshader.add_uniform('float time', link='_time')
            return 'time'
        else:
            return '0.0'

    elif node.type == 'CAMERA':
        # View Z Depth
        if socket == node.outputs[1]:
            return 'gl_FragCoord.z'
        # View Distance
        else:
            return 'length(eyeDir)'

    elif node.type == 'FRESNEL':
        ior = parse_value_input(node.inputs[0])
        #nor = parse_vectorZ_input(node.inputs[1])
        return 'pow(1.0 - dotNV, 7.25 / {0})'.format(ior)  # max(dotNV, 0.0)

    elif node.type == 'NEW_GEOMETRY':
        if socket == node.outputs[6]:  # Backfacing
            return '0.0'
        elif socket == node.outputs[7]:  # Pointiness
            return '0.0'

    elif node.type == 'HAIR_INFO':
        # Is Strand
        # Intercept
        # Thickness
        return '0.5'

    elif node.type == 'LAYER_WEIGHT':
        blend = parse_value_input(node.inputs[0])
        # nor = parse_vector_input(node.inputs[1])
        if socket == node.outputs[0]:  # Fresnel
            return 'clamp(pow(1.0 - dotNV, (1.0 - {0}) * 10.0), 0.0, 1.0)'.format(
                blend)
        elif socket == node.outputs[1]:  # Facing
            return '((1.0 - dotNV) * {0})'.format(blend)

    elif node.type == 'LIGHT_PATH':
        if socket == node.outputs[0]:  # Is Camera Ray
            return '1.0'
        elif socket == node.outputs[1]:  # Is Shadow Ray
            return '0.0'
        elif socket == node.outputs[2]:  # Is Diffuse Ray
            return '1.0'
        elif socket == node.outputs[3]:  # Is Glossy Ray
            return '1.0'
        elif socket == node.outputs[4]:  # Is Singular Ray
            return '0.0'
        elif socket == node.outputs[5]:  # Is Reflection Ray
            return '0.0'
        elif socket == node.outputs[6]:  # Is Transmission Ray
            return '0.0'
        elif socket == node.outputs[7]:  # Ray Length
            return '0.0'
        elif socket == node.outputs[8]:  # Ray Depth
            return '0.0'
        elif socket == node.outputs[9]:  # Transparent Depth
            return '0.0'
        elif socket == node.outputs[10]:  # Transmission Depth
            return '0.0'

    elif node.type == 'OBJECT_INFO':
        if socket == node.outputs[1]:  # Object Index
            curshader.add_uniform('float objectInfoIndex',
                                  link='_objectInfoIndex')
            return 'objectInfoIndex'
        elif socket == node.outputs[2]:  # Material Index
            curshader.add_uniform('float objectInfoMaterialIndex',
                                  link='_objectInfoMaterialIndex')
            return 'objectInfoMaterialIndex'
        elif socket == node.outputs[3]:  # Random
            curshader.add_uniform('float objectInfoRandom',
                                  link='_objectInfoRandom')
            return 'objectInfoRandom'

    elif node.type == 'PARTICLE_INFO':
        if socket == node.outputs[0]:  # Index
            return '0.0'
        elif socket == node.outputs[1]:  # Age
            return '0.0'
        elif socket == node.outputs[2]:  # Lifetime
            return '0.0'
        elif socket == node.outputs[4]:  # Size
            return '0.0'

    elif node.type == 'VALUE':
        return tovec1(node.outputs[0].default_value)

    elif node.type == 'WIREFRAME':
        #node.use_pixel_size
        # size = parse_value_input(node.inputs[0])
        return '0.0'

    elif node.type == 'TEX_BRICK':
        return '0.0'

    elif node.type == 'TEX_CHECKER':
        # TODO: do not recompute when color socket is also connected
        curshader.add_function(functions.str_tex_checker)
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        col1 = parse_vector_input(node.inputs[1])
        col2 = parse_vector_input(node.inputs[2])
        scale = parse_value_input(node.inputs[3])
        return 'tex_checker({0}, {1}, {2}, {3}).r'.format(
            co, col1, col2, scale)

    elif node.type == 'TEX_GRADIENT':
        return '0.0'

    elif node.type == 'TEX_IMAGE':
        # Already fetched
        if res_var_name(node, node.outputs[0]) in parsed:
            return '{0}.a'.format(store_var_name(node))
        tex_name = arm.utils.safe_source_name(node.name)
        tex = texture.make_texture(node, tex_name)
        if tex != None:
            return '{0}.a'.format(texture_store(node, tex, tex_name))
        else:
            tex_store = store_var_name(node)  # Pink color for missing texture
            curshader.write(
                'vec4 {0} = vec4(1.0, 0.0, 1.0, 1.0);'.format(tex_store))
            return '{0}.a'.format(tex_store)

    elif node.type == 'TEX_MAGIC':
        return '0.0'

    elif node.type == 'TEX_MUSGRAVE':
        # Fall back to noise
        curshader.add_function(functions.str_tex_noise)
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        scale = parse_value_input(node.inputs[1])
        # detail = parse_value_input(node.inputs[2])
        # distortion = parse_value_input(node.inputs[3])
        return 'tex_noise_f({0} * {1})'.format(co, scale)

    elif node.type == 'TEX_NOISE':
        curshader.add_function(functions.str_tex_noise)
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        scale = parse_value_input(node.inputs[1])
        # detail = parse_value_input(node.inputs[2])
        # distortion = parse_value_input(node.inputs[3])
        return 'tex_noise({0} * {1})'.format(co, scale)

    elif node.type == 'TEX_POINTDENSITY':
        return '0.0'

    elif node.type == 'TEX_VORONOI':
        curshader.add_function(functions.str_tex_voronoi)
        assets.add(arm.utils.get_sdk_path() + '/armory/Assets/' +
                   'noise64.png')
        assets.add_embedded_data('noise64.png')
        curshader.add_uniform('sampler2D snoise', link='_noise64')
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        scale = parse_value_input(node.inputs[1])
        if node.coloring == 'INTENSITY':
            return 'tex_voronoi({0} * {1}).a'.format(co, scale)
        else:  # CELLS
            return 'tex_voronoi({0} * {1}).r'.format(co, scale)

    elif node.type == 'TEX_WAVE':
        return '0.0'

    elif node.type == 'LIGHT_FALLOFF':
        # Constant, linear, quadratic
        # Shaders default to quadratic for now
        return '1.0'

    elif node.type == 'NORMAL':
        nor = parse_vector_input(node.inputs[0])
        return 'dot({0}, {1})'.format(tovec3(node.outputs[0].default_value),
                                      nor)

    elif node.type == 'VALTORGB':  # ColorRamp
        return '1.0'

    elif node.type == 'MATH':
        val1 = parse_value_input(node.inputs[0])
        val2 = parse_value_input(node.inputs[1])
        op = node.operation
        if op == 'ADD':
            out_val = '({0} + {1})'.format(val1, val2)
        elif op == 'SUBTRACT':
            out_val = '({0} - {1})'.format(val1, val2)
        elif op == 'MULTIPLY':
            out_val = '({0} * {1})'.format(val1, val2)
        elif op == 'DIVIDE':
            out_val = '({0} / {1})'.format(val1, val2)
        elif op == 'SINE':
            out_val = 'sin({0})'.format(val1)
        elif op == 'COSINE':
            out_val = 'cos({0})'.format(val1)
        elif op == 'TANGENT':
            out_val = 'tan({0})'.format(val1)
        elif op == 'ARCSINE':
            out_val = 'asin({0})'.format(val1)
        elif op == 'ARCCOSINE':
            out_val = 'acos({0})'.format(val1)
        elif op == 'ARCTANGENT':
            out_val = 'atan({0})'.format(val1)
        elif op == 'POWER':
            out_val = 'pow({0}, {1})'.format(val1, val2)
        elif op == 'LOGARITHM':
            out_val = 'log({0})'.format(val1)
        elif op == 'MINIMUM':
            out_val = 'min({0}, {1})'.format(val1, val2)
        elif op == 'MAXIMUM':
            out_val = 'max({0}, {1})'.format(val1, val2)
        elif op == 'ROUND':
            # out_val = 'round({0})'.format(val1)
            out_val = 'floor({0} + 0.5)'.format(val1)
        elif op == 'LESS_THAN':
            out_val = 'float({0} < {1})'.format(val1, val2)
        elif op == 'GREATER_THAN':
            out_val = 'float({0} > {1})'.format(val1, val2)
        elif op == 'MODULO':
            # out_val = 'float({0} % {1})'.format(val1, val2)
            out_val = 'mod({0}, {1})'.format(val1, val2)
        elif op == 'ABSOLUTE':
            out_val = 'abs({0})'.format(val1)
        if node.use_clamp:
            return 'clamp({0}, 0.0, 1.0)'.format(out_val)
        else:
            return out_val

    elif node.type == 'RGBTOBW':
        col = parse_vector_input(node.inputs[0])
        return '((({0}.r * 0.3 + {0}.g * 0.59 + {0}.b * 0.11) / 3.0) * 2.5)'.format(
            col)

    elif node.type == 'SEPHSV':
        return '0.0'

    elif node.type == 'SEPRGB':
        col = parse_vector_input(node.inputs[0])
        if socket == node.outputs[0]:
            return '{0}.r'.format(col)
        elif socket == node.outputs[1]:
            return '{0}.g'.format(col)
        elif socket == node.outputs[2]:
            return '{0}.b'.format(col)

    elif node.type == 'SEPXYZ':
        vec = parse_vector_input(node.inputs[0])
        if socket == node.outputs[0]:
            return '{0}.x'.format(vec)
        elif socket == node.outputs[1]:
            return '{0}.y'.format(vec)
        elif socket == node.outputs[2]:
            return '{0}.z'.format(vec)

    elif node.type == 'VECT_MATH':
        vec1 = parse_vector_input(node.inputs[0])
        vec2 = parse_vector_input(node.inputs[1])
        op = node.operation
        if op == 'DOT_PRODUCT':
            return 'dot({0}, {1})'.format(vec1, vec2)
        else:
            return '0.0'
Пример #15
0
def parse_rgb(node, socket):

    if node.type == 'GROUP':
        return parse_group(node, socket)

    elif node.type == 'GROUP_INPUT':
        return parse_group_input(node, socket)

    elif node.type == 'ATTRIBUTE':
        # Vcols only for now
        # node.attribute_name
        mat_state.data.add_elem('col', 3)
        return 'vcolor'

    elif node.type == 'RGB':
        return tovec3(socket.default_value)

    elif node.type == 'TEX_BRICK':
        # Pass through
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'TEX_CHECKER':
        curshader.add_function(functions.str_tex_checker)
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        col1 = parse_vector_input(node.inputs[1])
        col2 = parse_vector_input(node.inputs[2])
        scale = parse_value_input(node.inputs[3])
        return 'tex_checker({0}, {1}, {2}, {3})'.format(co, col1, col2, scale)

    elif node.type == 'TEX_ENVIRONMENT':
        # Pass through
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'TEX_GRADIENT':
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        grad = node.gradient_type
        if grad == 'LINEAR':
            f = '{0}.x'.format(co)
        elif grad == 'QUADRATIC':
            f = '0.0'
        elif grad == 'EASING':
            f = '0.0'
        elif grad == 'DIAGONAL':
            f = '({0}.x + {0}.y) * 0.5'.format(co)
        elif grad == 'RADIAL':
            f = 'atan({0}.y, {0}.x) / PI2 + 0.5'.format(co)
        elif grad == 'QUADRATIC_SPHERE':
            f = '0.0'
        elif grad == 'SPHERICAL':
            f = 'max(1.0 - sqrt({0}.x * {0}.x + {0}.y * {0}.y + {0}.z * {0}.z), 0.0)'.format(
                co)
        return 'vec3(clamp({0}, 0.0, 1.0))'.format(f)

    elif node.type == 'TEX_IMAGE':
        # Already fetched
        if res_var_name(node, node.outputs[1]) in parsed:
            return '{0}.rgb'.format(store_var_name(node))
        tex_name = arm.utils.safe_source_name(node.name)
        tex = texture.make_texture(node, tex_name)
        if tex != None:
            to_linear = parsing_basecol and not tex['file'].endswith('.hdr')
            return '{0}.rgb'.format(
                texture_store(node, tex, tex_name, to_linear))
        elif node.image == None:  # Empty texture
            tex = {}
            tex['name'] = tex_name
            tex['file'] = ''
            return '{0}.rgb'.format(texture_store(node, tex, tex_name, True))
        else:
            tex_store = store_var_name(node)  # Pink color for missing texture
            curshader.write(
                'vec4 {0} = vec4(1.0, 0.0, 1.0, 1.0);'.format(tex_store))
            return '{0}.rgb'.format(tex_store)

    elif node.type == 'TEX_MAGIC':
        # Pass through
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'TEX_MUSGRAVE':
        # Fall back to noise
        curshader.add_function(functions.str_tex_noise)
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        scale = parse_value_input(node.inputs[1])
        # detail = parse_value_input(node.inputs[2])
        # distortion = parse_value_input(node.inputs[3])
        return 'vec3(tex_noise_f({0} * {1}))'.format(co, scale)

    elif node.type == 'TEX_NOISE':
        curshader.add_function(functions.str_tex_noise)
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        scale = parse_value_input(node.inputs[1])
        # detail = parse_value_input(node.inputs[2])
        # distortion = parse_value_input(node.inputs[3])
        # Slow..
        return 'vec3(tex_noise({0} * {1}), tex_noise({0} * {1} + 0.33), tex_noise({0} * {1} + 0.66))'.format(
            co, scale)

    elif node.type == 'TEX_POINTDENSITY':
        # Pass through
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'TEX_SKY':
        # Pass through
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'TEX_VORONOI':
        curshader.add_function(functions.str_tex_voronoi)
        assets.add(arm.utils.get_sdk_path() + '/armory/Assets/' +
                   'noise64.png')
        assets.add_embedded_data('noise64.png')
        curshader.add_uniform('sampler2D snoise', link='_noise64')
        if node.inputs[0].is_linked:
            co = parse_vector_input(node.inputs[0])
        else:
            co = 'wposition'
        scale = parse_value_input(node.inputs[1])
        if node.coloring == 'INTENSITY':
            return 'vec3(tex_voronoi({0} / {1}).a)'.format(co, scale)
        else:  # CELLS
            return 'tex_voronoi({0} / {1}).rgb'.format(co, scale)

    elif node.type == 'TEX_WAVE':
        # Pass through
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'BRIGHTCONTRAST':
        out_col = parse_vector_input(node.inputs[0])
        bright = parse_value_input(node.inputs[1])
        contr = parse_value_input(node.inputs[2])
        curshader.add_function(\
"""vec3 brightcontrast(const vec3 col, const float bright, const float contr) {
    float a = 1.0 + contr;
    float b = bright - contr * 0.5;
    return max(a * col + b, 0.0);
}
""")
        return 'brightcontrast({0}, {1}, {2})'.format(out_col, bright, contr)

    elif node.type == 'GAMMA':
        out_col = parse_vector_input(node.inputs[0])
        gamma = parse_value_input(node.inputs[1])
        return 'pow({0}, vec3({1}))'.format(out_col, gamma)

    elif node.type == 'HUE_SAT':
        curshader.add_function(functions.str_hsv_to_rgb)
        hue = parse_value_input(node.inputs[0])
        sat = parse_value_input(node.inputs[1])
        val = parse_value_input(node.inputs[2])
        # fac = parse_value_input(node.inputs[3])
        # col = parse_vector_input(node.inputs[4])
        return 'hsv_to_rgb(vec3({0}, {1}, {2}))'.format(hue, sat, val)

    elif node.type == 'INVERT':
        fac = parse_value_input(node.inputs[0])
        out_col = parse_vector_input(node.inputs[1])
        return 'mix({0}, vec3(1.0) - ({0}), {1})'.format(out_col, fac)

    elif node.type == 'MIX_RGB':
        fac = parse_value_input(node.inputs[0])
        fac_var = node_name(node.name) + '_fac'
        curshader.write('float {0} = {1};'.format(fac_var, fac))
        col1 = parse_vector_input(node.inputs[1])
        col2 = parse_vector_input(node.inputs[2])
        blend = node.blend_type
        if blend == 'MIX':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var)
        elif blend == 'ADD':
            out_col = 'mix({0}, {0} + {1}, {2})'.format(col1, col2, fac_var)
        elif blend == 'MULTIPLY':
            out_col = 'mix({0}, {0} * {1}, {2})'.format(col1, col2, fac_var)
        elif blend == 'SUBTRACT':
            out_col = 'mix({0}, {0} - {1}, {2})'.format(col1, col2, fac_var)
        elif blend == 'SCREEN':
            out_col = '(vec3(1.0) - (vec3(1.0 - {2}) + {2} * (vec3(1.0) - {1})) * (vec3(1.0) - {0}))'.format(
                col1, col2, fac_var)
        elif blend == 'DIVIDE':
            out_col = '(vec3((1.0 - {2}) * {0} + {2} * {0} / {1}))'.format(
                col1, col2, fac_var)
        elif blend == 'DIFFERENCE':
            out_col = 'mix({0}, abs({0} - {1}), {2})'.format(
                col1, col2, fac_var)
        elif blend == 'DARKEN':
            out_col = 'min({0}, {1} * {2})'.format(col1, col2, fac_var)
        elif blend == 'LIGHTEN':
            out_col = 'max({0}, {1} * {2})'.format(col1, col2, fac_var)
        elif blend == 'OVERLAY':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'DODGE':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'BURN':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'HUE':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'SATURATION':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'VALUE':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'COLOR':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
        elif blend == 'SOFT_LIGHT':
            out_col = '((1.0 - {2}) * {0} + {2} * ((vec3(1.0) - {0}) * {1} * {0} + {0} * (vec3(1.0) - (vec3(1.0) - {1}) * (vec3(1.0) - {0}))));'.format(
                col1, col2, fac)
        elif blend == 'LINEAR_LIGHT':
            out_col = 'mix({0}, {1}, {2})'.format(col1, col2,
                                                  fac_var)  # Revert to mix
            # out_col = '({0} + {2} * (2.0 * ({1} - vec3(0.5))))'.format(col1, col2, fac_var)
        if node.use_clamp:
            return 'clamp({0}, vec3(0.0), vec3(1.0))'.format(out_col)
        else:
            return out_col

    elif node.type == 'CURVE_RGB':
        # Pass throuh
        return parse_vector_input(node.inputs[1])

    elif node.type == 'BLACKBODY':
        # Pass constant
        return tovec3([0.84, 0.38, 0.0])

    elif node.type == 'VALTORGB':  # ColorRamp
        fac = parse_value_input(node.inputs[0])
        interp = node.color_ramp.interpolation
        elems = node.color_ramp.elements
        if len(elems) == 1:
            return tovec3(elems[0].color)
        if interp == 'CONSTANT':
            fac_var = node_name(node.name) + '_fac'
            curshader.write('float {0} = {1};'.format(fac_var, fac))
            # Get index
            out_i = '0'
            for i in range(1, len(elems)):
                out_i += ' + ({0} > {1} ? 1 : 0)'.format(
                    fac_var, elems[i].position)
            # Write cols array
            cols_var = node_name(node.name) + '_cols'
            curshader.write('vec3 {0}[{1}];'.format(cols_var, len(elems)))
            for i in range(0, len(elems)):
                curshader.write('{0}[{1}] = vec3({2}, {3}, {4});'.format(
                    cols_var, i, elems[i].color[0], elems[i].color[1],
                    elems[i].color[2]))
            return '{0}[{1}]'.format(cols_var, out_i)
        else:  # Linear, .. - 2 elems only, end pos assumed to be 1
            # float f = clamp((pos - start) * (1.0 / (1.0 - start)), 0.0, 1.0);
            return 'mix({0}, {1}, clamp(({2} - {3}) * (1.0 / (1.0 - {3})), 0.0, 1.0))'.format(
                tovec3(elems[0].color), tovec3(elems[1].color), fac,
                elems[0].position)

    elif node.type == 'COMBHSV':
        # vec3 hsv2rgb(vec3 c) {
        #     vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
        #     vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
        #     return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
        # }
        # vec3 rgb2hsv(vec3 c) {
        #     vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
        #     vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
        #     vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

        #     float d = q.x - min(q.w, q.y);
        #     float e = 1.0e-10;
        #     return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
        # }
        # Pass constant
        return tovec3([0.0, 0.0, 0.0])

    elif node.type == 'COMBRGB':
        r = parse_value_input(node.inputs[0])
        g = parse_value_input(node.inputs[1])
        b = parse_value_input(node.inputs[2])
        return 'vec3({0}, {1}, {2})'.format(r, g, b)

    elif node.type == 'WAVELENGTH':
        # Pass constant
        return tovec3([0.0, 0.27, 0.19])
Пример #16
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
Пример #17
0
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'
Пример #18
0
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')
Пример #19
0
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 == 'SSSPassNodeType':
        bpy.data.worlds['Arm'].rp_defs += '_SSS'

    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'
        assets.add(build_node_trees.assets_path + 'vr.png')
        assets.add_embedded_data('vr.png')

    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 == 'MatIDToDepthNodeType' or node.bl_idname == 'BlendPassNodeType' or node.bl_idname == 'CombinePassNodeType' or node.bl_idname == 'DebugNormalsPassNodeType' or node.bl_idname == 'FXAAPassNodeType' or node.bl_idname == 'SSResolveNodeType' 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)
Пример #20
0
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()
Пример #21
0
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'