Files
Ransom-s-wake/game/presentation/cockpit/cockpit_material_palette.gd
T
chindit 912123087f
Quality Gate / Quality Gate (push) Successful in 2m55s
Initialize Godot imports in quality gate
2026-10-06 08:43:39 +02:00

252 lines
7.5 KiB
GDScript

class_name CockpitMaterialPalette
extends RefCounted
const NAVAL_STEEL_TEXTURE_PATH := (
"res://game/presentation/cockpit/assets/naval_painted_steel_albedo.png"
)
const OXYGEN_GAUGE_FACE_TEXTURE_PATH := (
"res://game/presentation/cockpit/assets/oxygen_gauge_face_albedo_v2.png"
)
const BATTERY_GAUGE_FACE_TEXTURE_PATH := (
"res://game/presentation/cockpit/assets/battery_gauge_face_albedo_v2.png"
)
const HULL_GAUGE_FACE_TEXTURE_PATH := (
"res://game/presentation/cockpit/assets/hull_gauge_face_albedo_v2.png"
)
const DEPTH_GAUGE_FACE_TEXTURE_PATH := (
"res://game/presentation/cockpit/assets/depth_gauge_face_albedo_v2.png"
)
var painted_steel: Material
var dark_steel: Material
var overhead_steel: StandardMaterial3D
var brushed_steel: StandardMaterial3D
var brass: Material
var copper: Material
var rubber: Material
var oxygen_gauge_face: StandardMaterial3D
var battery_gauge_face: StandardMaterial3D
var hull_gauge_face: StandardMaterial3D
var depth_gauge_face: StandardMaterial3D
var gauge_glass: StandardMaterial3D
var needle_paint: StandardMaterial3D
var instrument_screen: ShaderMaterial
var warm_emission: StandardMaterial3D
var safety_yellow: StandardMaterial3D
var signal_red: StandardMaterial3D
var indicator_green: StandardMaterial3D
var indicator_amber: StandardMaterial3D
var indicator_red: StandardMaterial3D
var sonar_grid: StandardMaterial3D
var warm_glass: StandardMaterial3D
func _init() -> void:
painted_steel = _weathered_material(
Color(0.045, 0.12, 0.125),
Color(0.16, 0.18, 0.17),
0.52,
0.58,
0.13
)
dark_steel = _weathered_material(
Color(0.045, 0.055, 0.055),
Color(0.22, 0.24, 0.22),
0.78,
0.44,
0.08
)
overhead_steel = _textured_material(
_load_texture(NAVAL_STEEL_TEXTURE_PATH),
Color(0.88, 0.91, 0.88),
0.64,
0.56,
Vector3(1.6, 1.6, 1.6)
)
brushed_steel = _plain_material(Color(0.42, 0.44, 0.42), 0.82, 0.30)
brass = _weathered_material(
Color(0.28, 0.18, 0.045),
Color(0.08, 0.16, 0.13),
0.74,
0.38,
0.17
)
copper = _weathered_material(
Color(0.34, 0.12, 0.045),
Color(0.055, 0.18, 0.15),
0.72,
0.42,
0.12
)
rubber = _plain_material(Color(0.012, 0.018, 0.018), 0.0, 0.92)
oxygen_gauge_face = _dedicated_gauge_material(OXYGEN_GAUGE_FACE_TEXTURE_PATH)
battery_gauge_face = _dedicated_gauge_material(BATTERY_GAUGE_FACE_TEXTURE_PATH)
hull_gauge_face = _dedicated_gauge_material(HULL_GAUGE_FACE_TEXTURE_PATH)
depth_gauge_face = _dedicated_gauge_material(DEPTH_GAUGE_FACE_TEXTURE_PATH)
gauge_glass = _glass_material()
needle_paint = _plain_material(Color(0.68, 0.055, 0.022), 0.12, 0.44)
instrument_screen = _screen_material()
warm_emission = _emissive_material(Color(0.96, 0.52, 0.18), 2.4)
safety_yellow = _plain_material(Color(0.48, 0.31, 0.035), 0.48, 0.53)
signal_red = _plain_material(Color(0.42, 0.025, 0.015), 0.38, 0.48)
indicator_green = _emissive_material(Color(0.05, 0.82, 0.24), 2.8)
indicator_amber = _emissive_material(Color(1.0, 0.43, 0.035), 2.8)
indicator_red = _emissive_material(Color(0.9, 0.045, 0.018), 2.8)
sonar_grid = _emissive_material(Color(0.02, 0.20, 0.22), 0.55)
warm_glass = _warm_glass_material()
func _weathered_material(
base_color: Color,
worn_color: Color,
metallic: float,
roughness: float,
wear_amount: float
) -> ShaderMaterial:
var shader := Shader.new()
shader.code = """
shader_type spatial;
render_mode diffuse_burley, specular_schlick_ggx;
uniform vec4 base_color : source_color;
uniform vec4 worn_color : source_color;
uniform float metallic_value : hint_range(0.0, 1.0);
uniform float roughness_value : hint_range(0.0, 1.0);
uniform float wear_amount : hint_range(0.0, 0.4);
float hash21(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
}
float value_noise(vec2 p) {
vec2 cell = floor(p);
vec2 local = fract(p);
local = local * local * (3.0 - 2.0 * local);
float a = hash21(cell);
float b = hash21(cell + vec2(1.0, 0.0));
float c = hash21(cell + vec2(0.0, 1.0));
float d = hash21(cell + vec2(1.0, 1.0));
return mix(mix(a, b, local.x), mix(c, d, local.x), local.y);
}
void fragment() {
float broad = value_noise(UV * 11.0);
float grain = value_noise(UV * 73.0 + vec2(4.2, 8.7));
float wear = smoothstep(0.76, 1.0, broad) * wear_amount;
ALBEDO = mix(base_color.rgb * mix(0.78, 1.08, broad), worn_color.rgb, wear);
METALLIC = metallic_value;
ROUGHNESS = clamp(roughness_value + (grain - 0.5) * 0.22, 0.16, 0.96);
}
"""
var material := ShaderMaterial.new()
material.shader = shader
material.set_shader_parameter("base_color", base_color)
material.set_shader_parameter("worn_color", worn_color)
material.set_shader_parameter("metallic_value", metallic)
material.set_shader_parameter("roughness_value", roughness)
material.set_shader_parameter("wear_amount", wear_amount)
return material
func _plain_material(
color: Color,
metallic: float,
roughness: float
) -> StandardMaterial3D:
var material := StandardMaterial3D.new()
material.albedo_color = color
material.metallic = metallic
material.roughness = roughness
return material
func _textured_material(
texture: Texture2D,
tint: Color,
metallic: float,
roughness: float,
uv_scale: Vector3 = Vector3.ONE
) -> StandardMaterial3D:
var material := StandardMaterial3D.new()
material.albedo_color = tint
material.albedo_texture = texture
material.metallic = metallic
material.roughness = roughness
material.uv1_scale = uv_scale
material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC
return material
func _load_texture(resource_path: String) -> Texture2D:
var texture := ResourceLoader.load(resource_path, "Texture2D") as Texture2D
if texture == null:
push_error("Unable to load cockpit texture: %s" % resource_path)
return null
return texture
func _dedicated_gauge_material(resource_path: String) -> StandardMaterial3D:
var material := _textured_material(
_load_texture(resource_path),
Color(0.94, 0.92, 0.86),
0.02,
0.66
)
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
return material
func _glass_material() -> StandardMaterial3D:
var material := StandardMaterial3D.new()
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
material.albedo_color = Color(0.42, 0.68, 0.66, 0.13)
material.metallic = 0.12
material.roughness = 0.08
material.cull_mode = BaseMaterial3D.CULL_DISABLED
return material
func _screen_material() -> ShaderMaterial:
var shader := Shader.new()
shader.code = """
shader_type spatial;
render_mode diffuse_burley, specular_schlick_ggx;
void fragment() {
vec2 centered = UV - vec2(0.5);
float vignette = 1.0 - smoothstep(0.28, 0.72, length(centered));
float scanline = 0.94 + 0.06 * sin(UV.y * 720.0);
float edge = mix(0.68, 1.0, vignette);
vec3 phosphor = vec3(0.025, 0.105, 0.11) * edge * scanline;
ALBEDO = phosphor;
EMISSION = phosphor * 0.38;
METALLIC = 0.08;
ROUGHNESS = 0.18;
SPECULAR = 0.82;
}
"""
var material := ShaderMaterial.new()
material.shader = shader
return material
func _emissive_material(color: Color, energy: float) -> StandardMaterial3D:
var material := StandardMaterial3D.new()
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
material.albedo_color = color
material.emission_enabled = true
material.emission = color
material.emission_energy_multiplier = energy
return material
func _warm_glass_material() -> StandardMaterial3D:
var material := StandardMaterial3D.new()
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
material.albedo_color = Color(1.0, 0.48, 0.12, 0.72)
material.roughness = 0.18
material.emission_enabled = true
material.emission = Color(1.0, 0.28, 0.045)
material.emission_energy_multiplier = 2.6
return material