mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-12 23:05:55 +00:00
188 lines
6.3 KiB
GDScript
188 lines
6.3 KiB
GDScript
class_name FuncGodotTextureLoader
|
|
|
|
enum PBRSuffix {
|
|
ALBEDO,
|
|
NORMAL,
|
|
METALLIC,
|
|
ROUGHNESS,
|
|
EMISSION,
|
|
AO,
|
|
HEIGHT,
|
|
ORM
|
|
}
|
|
|
|
# Suffix string / Godot enum / StandardMaterial3D property
|
|
const PBR_SUFFIX_NAMES: Dictionary = {
|
|
PBRSuffix.ALBEDO: 'albedo',
|
|
PBRSuffix.NORMAL: 'normal',
|
|
PBRSuffix.METALLIC: 'metallic',
|
|
PBRSuffix.ROUGHNESS: 'roughness',
|
|
PBRSuffix.EMISSION: 'emission',
|
|
PBRSuffix.AO: 'ao',
|
|
PBRSuffix.HEIGHT: 'height',
|
|
PBRSuffix.ORM: 'orm'
|
|
}
|
|
|
|
const PBR_SUFFIX_PATTERNS: Dictionary = {
|
|
PBRSuffix.ALBEDO: '%s_albedo.%s',
|
|
PBRSuffix.NORMAL: '%s_normal.%s',
|
|
PBRSuffix.METALLIC: '%s_metallic.%s',
|
|
PBRSuffix.ROUGHNESS: '%s_roughness.%s',
|
|
PBRSuffix.EMISSION: '%s_emission.%s',
|
|
PBRSuffix.AO: '%s_ao.%s',
|
|
PBRSuffix.HEIGHT: '%s_height.%s',
|
|
PBRSuffix.ORM: '%s_orm.%s'
|
|
}
|
|
|
|
var PBR_SUFFIX_TEXTURES: Dictionary = {
|
|
PBRSuffix.ALBEDO: StandardMaterial3D.TEXTURE_ALBEDO,
|
|
PBRSuffix.NORMAL: StandardMaterial3D.TEXTURE_NORMAL,
|
|
PBRSuffix.METALLIC: StandardMaterial3D.TEXTURE_METALLIC,
|
|
PBRSuffix.ROUGHNESS: StandardMaterial3D.TEXTURE_ROUGHNESS,
|
|
PBRSuffix.EMISSION: StandardMaterial3D.TEXTURE_EMISSION,
|
|
PBRSuffix.AO: StandardMaterial3D.TEXTURE_AMBIENT_OCCLUSION,
|
|
PBRSuffix.HEIGHT: StandardMaterial3D.TEXTURE_HEIGHTMAP,
|
|
PBRSuffix.ORM: ORMMaterial3D.TEXTURE_ORM
|
|
}
|
|
|
|
const PBR_SUFFIX_PROPERTIES: Dictionary = {
|
|
PBRSuffix.NORMAL: 'normal_enabled',
|
|
PBRSuffix.EMISSION: 'emission_enabled',
|
|
PBRSuffix.AO: 'ao_enabled',
|
|
PBRSuffix.HEIGHT: 'heightmap_enabled',
|
|
}
|
|
|
|
var map_settings: FuncGodotMapSettings = FuncGodotMapSettings.new()
|
|
var texture_wad_resources: Array = []
|
|
|
|
# Overrides
|
|
func _init(new_map_settings: FuncGodotMapSettings) -> void:
|
|
map_settings = new_map_settings
|
|
load_texture_wad_resources()
|
|
|
|
# Business Logic
|
|
func load_texture_wad_resources() -> void:
|
|
texture_wad_resources.clear()
|
|
for texture_wad in map_settings.texture_wads:
|
|
if texture_wad and not texture_wad in texture_wad_resources:
|
|
texture_wad_resources.append(texture_wad)
|
|
|
|
func load_textures(texture_list: Array) -> Dictionary:
|
|
var texture_dict: Dictionary = {}
|
|
for texture_name in texture_list:
|
|
texture_dict[texture_name] = load_texture(texture_name)
|
|
return texture_dict
|
|
|
|
func load_texture(texture_name: String) -> Texture2D:
|
|
# Load albedo texture if it exists
|
|
for texture_extension in map_settings.texture_file_extensions:
|
|
var texture_path: String = "%s/%s.%s" % [map_settings.base_texture_dir, texture_name, texture_extension]
|
|
if ResourceLoader.exists(texture_path, "Texture2D") or ResourceLoader.exists(texture_path + ".import", "Texture2D"):
|
|
return load(texture_path) as Texture2D
|
|
|
|
var texture_name_lower: String = texture_name.to_lower()
|
|
for texture_wad in texture_wad_resources:
|
|
if texture_name_lower in texture_wad.textures:
|
|
return texture_wad.textures[texture_name_lower]
|
|
|
|
return load("res://addons/func_godot/textures/default_texture.png") as Texture2D
|
|
|
|
func create_materials(texture_list: Array) -> Dictionary:
|
|
var texture_materials: Dictionary = {}
|
|
#prints("TEXLI", texture_list)
|
|
for texture in texture_list:
|
|
texture_materials[texture] = create_material(texture)
|
|
return texture_materials
|
|
|
|
func create_material(texture_name: String) -> Material:
|
|
# Autoload material if it exists
|
|
var material_dict: Dictionary = {}
|
|
|
|
var material_path: String = "%s/%s.%s" % [map_settings.base_texture_dir, texture_name, map_settings.material_file_extension]
|
|
if not material_path in material_dict and (FileAccess.file_exists(material_path) or FileAccess.file_exists(material_path + ".remap")):
|
|
var loaded_material: Material = load(material_path)
|
|
if loaded_material:
|
|
material_dict[material_path] = loaded_material
|
|
|
|
# If material already exists, use it
|
|
if material_path in material_dict:
|
|
return material_dict[material_path]
|
|
|
|
var material: Material = null
|
|
|
|
if map_settings.default_material:
|
|
material = map_settings.default_material.duplicate()
|
|
else:
|
|
material = StandardMaterial3D.new()
|
|
var texture: Texture2D = load_texture(texture_name)
|
|
if not texture:
|
|
return material
|
|
|
|
if material is StandardMaterial3D:
|
|
material.set_texture(StandardMaterial3D.TEXTURE_ALBEDO, texture)
|
|
elif material is ShaderMaterial && map_settings.default_material_albedo_uniform != "":
|
|
material.set_shader_parameter(map_settings.default_material_albedo_uniform, texture)
|
|
elif material is ORMMaterial3D:
|
|
material.set_texture(ORMMaterial3D.TEXTURE_ALBEDO, texture)
|
|
|
|
var pbr_textures : Dictionary = get_pbr_textures(texture_name)
|
|
|
|
for pbr_suffix in PBRSuffix.values():
|
|
var suffix: int = pbr_suffix
|
|
var tex: Texture2D = pbr_textures[suffix]
|
|
if tex:
|
|
if material is ShaderMaterial:
|
|
material = StandardMaterial3D.new()
|
|
material.set_texture(StandardMaterial3D.TEXTURE_ALBEDO, texture)
|
|
var enable_prop: String = PBR_SUFFIX_PROPERTIES[suffix] if suffix in PBR_SUFFIX_PROPERTIES else ""
|
|
if(enable_prop != ""):
|
|
material.set(enable_prop, true)
|
|
material.set_texture(PBR_SUFFIX_TEXTURES[suffix], tex)
|
|
|
|
material_dict[material_path] = material
|
|
|
|
if (map_settings.save_generated_materials and material
|
|
and texture_name != map_settings.clip_texture
|
|
and texture_name != map_settings.skip_texture
|
|
and texture_name != map_settings.origin_texture
|
|
and texture.resource_path != "res://addons/func_godot/textures/default_texture.png"):
|
|
ResourceSaver.save(material, material_path)
|
|
|
|
return material
|
|
|
|
# PBR texture fetching
|
|
func get_pbr_suffix_pattern(suffix: int) -> String:
|
|
if not suffix in PBR_SUFFIX_NAMES:
|
|
return ''
|
|
|
|
var pattern_setting: String = "%s_map_pattern" % [PBR_SUFFIX_NAMES[suffix]]
|
|
if pattern_setting in map_settings:
|
|
return map_settings.get(pattern_setting)
|
|
|
|
return PBR_SUFFIX_PATTERNS[suffix]
|
|
|
|
func get_pbr_texture(texture: String, suffix: PBRSuffix) -> Texture2D:
|
|
var texture_comps: PackedStringArray = texture.split('/')
|
|
if texture_comps.size() == 0:
|
|
return null
|
|
|
|
for texture_extension in map_settings.texture_file_extensions:
|
|
var path: String = "%s/%s/%s" % [
|
|
map_settings.base_texture_dir,
|
|
'/'.join(texture_comps),
|
|
get_pbr_suffix_pattern(suffix) % [
|
|
texture_comps[-1],
|
|
texture_extension
|
|
]
|
|
]
|
|
|
|
if(FileAccess.file_exists(path)):
|
|
return load(path) as Texture2D
|
|
|
|
return null
|
|
|
|
func get_pbr_textures(texture_name: String) -> Dictionary:
|
|
var pbr_textures: Dictionary = {}
|
|
for pbr_suffix in PBRSuffix.values():
|
|
pbr_textures[pbr_suffix] = get_pbr_texture(texture_name, pbr_suffix)
|
|
return pbr_textures
|