feat(cockpit): replace procedural cockpit with twelve scripted models
Quality Gate / Quality Gate (pull_request) Successful in 7m6s
Quality Gate / Quality Gate (pull_request) Successful in 7m6s
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>
This commit is contained in:
1 parent
912123087f
commit
2c1ea50aba
45 files changed
+1353
-1603
No files matched your search
@@ -0,0 +1,157 @@
|
||||
class_name SonarReliefStyle
|
||||
extends RefCounted
|
||||
|
||||
## Single owner of the holographic look of the sonar relief: palette, grid
|
||||
## spacing, line widths and intensities. Display only: nothing here is a
|
||||
## gameplay value.
|
||||
|
||||
## Near-black table the hologram floats on. Black also means "unknown".
|
||||
const COLOR_BACKGROUND := Color("010507")
|
||||
## Height ramp, relative to the scan: dark teal low, cyan mid, pale on peaks.
|
||||
const COLOR_DEEP := Color("06404a")
|
||||
const COLOR_MIDDLE := Color("17b8c4")
|
||||
const COLOR_PEAK := Color("d8fbff")
|
||||
## Metal returns keep one warm accent so an anomaly never reads as terrain.
|
||||
const COLOR_METAL := Color("ff7a2a")
|
||||
const COLOR_VEHICLE := Color("f2ffff")
|
||||
|
||||
## Grid lines follow the sample grid: one minor line every N cells.
|
||||
const GRID_MINOR_CELLS := 2.0
|
||||
const GRID_MAJOR_CELLS := 6.0
|
||||
const GRID_MINOR_WIDTH_PX := 1.2
|
||||
const GRID_MAJOR_WIDTH_PX := 2.2
|
||||
const GRID_MINOR_INTENSITY := 0.30
|
||||
const GRID_MAJOR_INTENSITY := 0.80
|
||||
## Iso-height contours, in fractions of the scan's height span.
|
||||
const CONTOUR_STEP := 0.125
|
||||
const CONTOUR_WIDTH_PX := 1.0
|
||||
const CONTOUR_INTENSITY := 0.20
|
||||
## Translucent surface under the grid and the rim that outlines ridges.
|
||||
const SURFACE_INTENSITY := 0.50
|
||||
const RIM_INTENSITY := 0.35
|
||||
const RIM_POWER := 2.5
|
||||
## How much brighter the peaks' lines are than the deep ones.
|
||||
const PEAK_LINE_BOOST := 0.55
|
||||
|
||||
const _SHADER_CODE := """
|
||||
shader_type spatial;
|
||||
render_mode unshaded, cull_disabled, depth_draw_always;
|
||||
|
||||
uniform vec3 background : source_color;
|
||||
uniform vec3 color_deep : source_color;
|
||||
uniform vec3 color_middle : source_color;
|
||||
uniform vec3 color_peak : source_color;
|
||||
uniform vec3 color_metal : source_color;
|
||||
uniform float grid_minor_cells;
|
||||
uniform float grid_major_cells;
|
||||
uniform float grid_minor_width_px;
|
||||
uniform float grid_major_width_px;
|
||||
uniform float grid_minor_intensity;
|
||||
uniform float grid_major_intensity;
|
||||
uniform float contour_step;
|
||||
uniform float contour_width_px;
|
||||
uniform float contour_intensity;
|
||||
uniform float surface_intensity;
|
||||
uniform float rim_intensity;
|
||||
uniform float rim_power;
|
||||
uniform float peak_line_boost;
|
||||
uniform float opacity = 1.0;
|
||||
|
||||
// Anti-aliased line on every multiple of `spacing`, `width_px` wide on screen.
|
||||
// Fades out when lines would be closer than a few pixels, so it never shimmers.
|
||||
float grid_line(float coordinate, float spacing, float width_px) {
|
||||
float scaled = coordinate / spacing;
|
||||
float pixel = max(fwidth(scaled), 1e-5);
|
||||
float distance_px = abs(fract(scaled - 0.5) - 0.5) / pixel;
|
||||
float line = 1.0 - smoothstep(width_px * 0.5 - 0.5, width_px * 0.5 + 0.5, distance_px);
|
||||
return line * clamp((1.0 / pixel - 2.0) / 3.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
// UV carries (column, row) of the sample grid; COLOR.r the relative height,
|
||||
// COLOR.g the metal flag, COLOR.b the echo intensity.
|
||||
float height = clamp(COLOR.r, 0.0, 1.0);
|
||||
vec3 ramp = mix(color_deep, color_middle, smoothstep(0.0, 0.55, height));
|
||||
ramp = mix(ramp, color_peak, smoothstep(0.55, 1.0, height));
|
||||
// The translucent surface stays in the teal-to-cyan range so peaks do not
|
||||
// wash out to grey; only the lines reach the pale peak colour.
|
||||
vec3 fill = mix(color_deep, color_middle, smoothstep(0.0, 0.85, height));
|
||||
float metal = step(0.5, COLOR.g);
|
||||
ramp = mix(ramp, color_metal, metal);
|
||||
fill = mix(fill, color_metal, metal);
|
||||
|
||||
float minor = max(
|
||||
grid_line(UV.x, grid_minor_cells, grid_minor_width_px),
|
||||
grid_line(UV.y, grid_minor_cells, grid_minor_width_px)
|
||||
);
|
||||
float major = max(
|
||||
grid_line(UV.x, grid_major_cells, grid_major_width_px),
|
||||
grid_line(UV.y, grid_major_cells, grid_major_width_px)
|
||||
);
|
||||
float contour = grid_line(height, contour_step, contour_width_px);
|
||||
float rim = pow(1.0 - abs(dot(normalize(NORMAL), normalize(VIEW))), rim_power);
|
||||
|
||||
float lines = max(minor * grid_minor_intensity, major * grid_major_intensity);
|
||||
lines = max(lines, contour * contour_intensity);
|
||||
lines *= 1.0 + peak_line_boost * height;
|
||||
float surface = surface_intensity * (0.22 + 0.78 * height) * (0.8 + 0.2 * COLOR.b);
|
||||
vec3 glow = fill * (surface + rim * rim_intensity) + ramp * lines;
|
||||
|
||||
ALBEDO = background + glow;
|
||||
//FADE ALPHA = opacity;
|
||||
}
|
||||
"""
|
||||
|
||||
static var _opaque_shader: Shader
|
||||
static var _fading_shader: Shader
|
||||
|
||||
|
||||
## The current scan is opaque: depth-tested, so ridges hide what lies behind
|
||||
## them and nothing depends on draw order. The previous scan fades out with the
|
||||
## same shader, alpha-blended and still writing depth.
|
||||
static func relief_material(fading: bool) -> ShaderMaterial:
|
||||
if _opaque_shader == null:
|
||||
_opaque_shader = Shader.new()
|
||||
_opaque_shader.code = _SHADER_CODE
|
||||
_fading_shader = Shader.new()
|
||||
_fading_shader.code = _SHADER_CODE.replace("//FADE ", "")
|
||||
var material := ShaderMaterial.new()
|
||||
material.shader = _fading_shader if fading else _opaque_shader
|
||||
material.set_shader_parameter("background", COLOR_BACKGROUND)
|
||||
material.set_shader_parameter("color_deep", COLOR_DEEP)
|
||||
material.set_shader_parameter("color_middle", COLOR_MIDDLE)
|
||||
material.set_shader_parameter("color_peak", COLOR_PEAK)
|
||||
material.set_shader_parameter("color_metal", COLOR_METAL)
|
||||
material.set_shader_parameter("grid_minor_cells", GRID_MINOR_CELLS)
|
||||
material.set_shader_parameter("grid_major_cells", GRID_MAJOR_CELLS)
|
||||
material.set_shader_parameter("grid_minor_width_px", GRID_MINOR_WIDTH_PX)
|
||||
material.set_shader_parameter("grid_major_width_px", GRID_MAJOR_WIDTH_PX)
|
||||
material.set_shader_parameter("grid_minor_intensity", GRID_MINOR_INTENSITY)
|
||||
material.set_shader_parameter("grid_major_intensity", GRID_MAJOR_INTENSITY)
|
||||
material.set_shader_parameter("contour_step", CONTOUR_STEP)
|
||||
material.set_shader_parameter("contour_width_px", CONTOUR_WIDTH_PX)
|
||||
material.set_shader_parameter("contour_intensity", CONTOUR_INTENSITY)
|
||||
material.set_shader_parameter("surface_intensity", SURFACE_INTENSITY)
|
||||
material.set_shader_parameter("rim_intensity", RIM_INTENSITY)
|
||||
material.set_shader_parameter("rim_power", RIM_POWER)
|
||||
material.set_shader_parameter("peak_line_boost", PEAK_LINE_BOOST)
|
||||
return material
|
||||
|
||||
|
||||
static func set_opacity(material: ShaderMaterial, opacity: float) -> void:
|
||||
material.set_shader_parameter("opacity", clampf(opacity, 0.0, 1.0))
|
||||
|
||||
|
||||
static func marker_material(color: Color) -> StandardMaterial3D:
|
||||
var material := StandardMaterial3D.new()
|
||||
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
material.albedo_color = color
|
||||
return material
|
||||
|
||||
|
||||
## Colour of a relative height (0 low, 1 peak), for the depth scale legend.
|
||||
static func height_gradient() -> Gradient:
|
||||
var gradient := Gradient.new()
|
||||
gradient.offsets = PackedFloat32Array([0.0, 0.55, 1.0])
|
||||
gradient.colors = PackedColorArray([COLOR_DEEP, COLOR_MIDDLE, COLOR_PEAK])
|
||||
return gradient
|
||||
Reference in new issue
Block a user