def parse_sky_hosekwilkie(node: bpy.types.ShaderNodeTexSky, state: ParserState) -> vec3str: world = state.world curshader = state.curshader # Match to cycles world.arm_envtex_strength *= 0.1 assets.add_khafile_def('arm_hosek') curshader.add_uniform('vec3 A', link="_hosekA") curshader.add_uniform('vec3 B', link="_hosekB") curshader.add_uniform('vec3 C', link="_hosekC") curshader.add_uniform('vec3 D', link="_hosekD") curshader.add_uniform('vec3 E', link="_hosekE") curshader.add_uniform('vec3 F', link="_hosekF") curshader.add_uniform('vec3 G', link="_hosekG") curshader.add_uniform('vec3 H', link="_hosekH") curshader.add_uniform('vec3 I', link="_hosekI") curshader.add_uniform('vec3 Z', link="_hosekZ") curshader.add_uniform('vec3 hosekSunDirection', link="_hosekSunDirection") curshader.add_function("""vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) { \tvec3 chi = (1 + cos_gamma * cos_gamma) / pow(1 + H * H - 2 * cos_gamma * H, vec3(1.5)); \treturn (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta)); }""") world.arm_envtex_sun_direction = [node.sun_direction[0], node.sun_direction[1], node.sun_direction[2]] world.arm_envtex_turbidity = node.turbidity world.arm_envtex_ground_albedo = node.ground_albedo wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' if not state.radiance_written: # Irradiance json file name wname = arm.utils.safestr(world.name) world.arm_envtex_irr_name = wname write_probes.write_sky_irradiance(wname) # Radiance if rpdat.arm_radiance and rpdat.arm_irradiance and not mobile_mat: wrd.world_defs += '_Rad' hosek_path = 'armory/Assets/hosek/' sdk_path = arm.utils.get_sdk_path() # Use fake maps for now assets.add(sdk_path + '/' + hosek_path + 'hosek_radiance.hdr') for i in range(0, 8): assets.add(sdk_path + '/' + hosek_path + 'hosek_radiance_' + str(i) + '.hdr') world.arm_envtex_name = 'hosek' world.arm_envtex_num_mips = 8 state.radiance_written = True curshader.write('float cos_theta = clamp(pos.z, 0.0, 1.0);') curshader.write('float cos_gamma = dot(pos, hosekSunDirection);') curshader.write('float gamma_val = acos(cos_gamma);') return 'Z * hosekWilkie(cos_theta, gamma_val, cos_gamma) * envmapStrength;'
def parse_tex_environment(node: bpy.types.ShaderNodeTexEnvironment, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str: if state.context == ParserContext.OBJECT: log.warn('Environment Texture node is not supported for object node trees, using default value') return c.to_vec3([0.0, 0.0, 0.0]) if node.image is None: return c.to_vec3([1.0, 0.0, 1.0]) world = state.world world.world_defs += '_EnvTex' curshader = state.curshader curshader.add_include('std/math.glsl') curshader.add_uniform('sampler2D envmap', link='_envmap') image = node.image filepath = image.filepath if image.packed_file is None and not os.path.isfile(arm.utils.asset_path(filepath)): log.warn(world.name + ' - unable to open ' + image.filepath) return c.to_vec3([1.0, 0.0, 1.0]) # Reference image name tex_file = arm.utils.extract_filename(image.filepath) base = tex_file.rsplit('.', 1) ext = base[1].lower() if ext == 'hdr': target_format = 'HDR' else: target_format = 'JPEG' do_convert = ext != 'hdr' and ext != 'jpg' if do_convert: if ext == 'exr': tex_file = base[0] + '.hdr' target_format = 'HDR' else: tex_file = base[0] + '.jpg' target_format = 'JPEG' if image.packed_file is not None: # Extract packed data unpack_path = arm.utils.get_fp_build() + '/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + tex_file filepath = unpack_filepath if do_convert: if not os.path.isfile(unpack_filepath): arm.utils.unpack_image(image, unpack_filepath, file_format=target_format) elif not os.path.isfile(unpack_filepath) or os.path.getsize(unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: if do_convert: unpack_path = arm.utils.get_fp_build() + '/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) converted_path = unpack_path + '/' + tex_file filepath = converted_path # TODO: delete cache when file changes if not os.path.isfile(converted_path): arm.utils.convert_image(image, converted_path, file_format=target_format) assets.add(converted_path) else: # Link image path to assets assets.add(arm.utils.asset_path(image.filepath)) rpdat = arm.utils.get_rp() if not state.radiance_written: # Generate prefiltered envmaps world.arm_envtex_name = tex_file world.arm_envtex_irr_name = tex_file.rsplit('.', 1)[0] disable_hdr = target_format == 'JPEG' from_srgb = image.colorspace_settings.name == "sRGB" mip_count = world.arm_envtex_num_mips mip_count = write_probes.write_probes(filepath, disable_hdr, from_srgb, mip_count, arm_radiance=rpdat.arm_radiance) world.arm_envtex_num_mips = mip_count state.radiance_written = True # Append LDR define if disable_hdr: world.world_defs += '_EnvLDR' wrd = bpy.data.worlds['Arm'] mobile_mat = rpdat.arm_material_model == 'Mobile' or rpdat.arm_material_model == 'Solid' # Append radiance define if rpdat.arm_irradiance and rpdat.arm_radiance and not mobile_mat: wrd.world_defs += '_Rad' return 'texture(envmap, envMapEquirect(pos)).rgb * envmapStrength'