Quality Gate / Quality Gate (pull_request) Successful in 9m4s
Instance twelve Blender-scripted glTF models in the cockpit scene and rebuild the cabin around them: gauge panel, sonar, switch panel, alert box, speaker, porthole, hull wall, caged lamps, gas bottle, handrails and side consoles. Presentation only; no domain, application or world rule changes beyond enabling glow in the test environment. - Needles, alert lamps and sonar screen are driven by the existing snapshots; the alert box now carries SYS/ATTN/ALRM. - Depth dial reads percent of certified depth. - Sonar display restyled as a turquoise holographic relief with a shader grid and height scale; SubViewport matches the glass (960x604). - Cabin lighting retuned: warm pooled lamp light, cool porthole rim, lamp shadows, dial backlight. - Procedural stand-ins removed (bulkhead, tanks, consoles, levers, indicator columns, placeholder pipe run, dial face PNGs). - Tests adapted where nodes disappeared; one assertion removed (pipe_segment_count) until the pipe kit is placed. - Model .glb files are committed without LFS; textures Godot extracts next to them at import are ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
182 lines
4.8 KiB
GDScript
182 lines
4.8 KiB
GDScript
class_name CockpitMaterialPalette
|
|
extends RefCounted
|
|
|
|
const NAVAL_STEEL_TEXTURE_PATH := (
|
|
"res://game/presentation/cockpit/assets/naval_painted_steel_albedo.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 instrument_screen: ShaderMaterial
|
|
var warm_emission: 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)
|
|
instrument_screen = _screen_material()
|
|
warm_emission = _emissive_material(Color(0.96, 0.52, 0.18), 2.4)
|
|
|
|
|
|
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 _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
|