mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
feat(arena): add grounded lighting and asteroid dressing
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
[gd_scene load_steps=4 format=3]
|
||||
[gd_scene load_steps=7 format=3]
|
||||
|
||||
[ext_resource type="PackedScene" path="res://scenes/arena_base.tscn" id="1_base"]
|
||||
[ext_resource type="Shader" path="res://shaders/sky_asteroid_field.gdshader" id="7_asteroid"]
|
||||
[ext_resource type="PackedScene" path="res://assets/models/nebula_station.glb" id="8_station"]
|
||||
[ext_resource type="PackedScene" path="res://assets/models/nebula_debris.glb" id="9_debris"]
|
||||
[ext_resource type="PackedScene" path="res://assets/models/nebula_planet.glb" id="10_planet"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_asteroid"]
|
||||
shader = ExtResource("7_asteroid")
|
||||
@@ -22,3 +25,30 @@ light_color = Color(1, 0.85, 0.65, 1)
|
||||
light_color = Color(0.55, 0.4, 0.3, 1)
|
||||
|
||||
[node name="Decoration" type="Node3D" parent="."]
|
||||
|
||||
[node name="MiningStationA" parent="Decoration" instance=ExtResource("8_station")]
|
||||
transform = Transform3D(2.1, 0, 0, 0, 2.1, 0, 0, 0, 2.1, 44, 8, -12)
|
||||
rotation = Vector3(0.08, -0.72, 0.02)
|
||||
|
||||
[node name="MiningStationB" parent="Decoration" instance=ExtResource("8_station")]
|
||||
transform = Transform3D(1.45, 0, 0, 0, 1.45, 0, 0, 0, 1.45, -48, 15, 22)
|
||||
rotation = Vector3(-0.06, 1.2, 0.08)
|
||||
|
||||
[node name="AsteroidClusterA" parent="Decoration" instance=ExtResource("9_debris")]
|
||||
transform = Transform3D(2.4, 0, 0, 0, 2.4, 0, 0, 0, 2.4, -35, 12, -25)
|
||||
rotation = Vector3(0.4, 0.9, -0.2)
|
||||
|
||||
[node name="AsteroidClusterB" parent="Decoration" instance=ExtResource("9_debris")]
|
||||
transform = Transform3D(1.7, 0, 0, 0, 1.7, 0, 0, 0, 1.7, 38, 20, 28)
|
||||
rotation = Vector3(-0.25, 2.1, 0.35)
|
||||
|
||||
[node name="AsteroidClusterC" parent="Decoration" instance=ExtResource("9_debris")]
|
||||
transform = Transform3D(1.2, 0, 0, 0, 1.2, 0, 0, 0, 1.2, 18, 7, -48)
|
||||
rotation = Vector3(0.7, -0.5, 0.1)
|
||||
|
||||
[node name="AsteroidClusterD" parent="Decoration" instance=ExtResource("9_debris")]
|
||||
transform = Transform3D(0.9, 0, 0, 0, 0.9, 0, 0, 0, 0.9, -20, 25, 50)
|
||||
rotation = Vector3(-0.3, -1.1, -0.2)
|
||||
|
||||
[node name="DistantPlanet" parent="Decoration" instance=ExtResource("10_planet")]
|
||||
transform = Transform3D(24, 0, 0, 0, 24, 0, 0, 0, 24, 95, 48, -145)
|
||||
|
||||
@@ -31,6 +31,23 @@ adjustment_enabled = true
|
||||
adjustment_brightness = 1.0
|
||||
adjustment_contrast = 1.05
|
||||
adjustment_saturation = 1.08
|
||||
ssao_enabled = true
|
||||
ssao_radius = 2.5
|
||||
ssao_intensity = 2.0
|
||||
ssao_power = 1.5
|
||||
ssao_detail = 0.75
|
||||
ssao_horizon = 0.06
|
||||
ssao_sharpness = 0.98
|
||||
ssao_light_affect = 0.15
|
||||
ssil_enabled = true
|
||||
ssil_radius = 4.0
|
||||
ssil_intensity = 1.25
|
||||
ssil_sharpness = 0.98
|
||||
ssil_normal_rejection = 1.0
|
||||
sdfgi_enabled = true
|
||||
sdfgi_use_occlusion = true
|
||||
sdfgi_bounce_feedback = 0.5
|
||||
sdfgi_read_sky_light = true
|
||||
|
||||
[node name="Arena" type="Node3D"]
|
||||
script = ExtResource("1_iywne")
|
||||
@@ -49,6 +66,44 @@ light_color = Color(0.55, 0.65, 0.85, 1)
|
||||
light_energy = 0.4
|
||||
shadow_enabled = false
|
||||
|
||||
[node name="PitchLights" type="Node3D" parent="."]
|
||||
|
||||
[node name="Team0GoalLight" type="OmniLight3D" parent="PitchLights"]
|
||||
position = Vector3(0, 4.5, 22)
|
||||
light_color = Color(0.48, 0.18, 0.88, 1)
|
||||
light_energy = 5.0
|
||||
light_bake_mode = 1
|
||||
omni_range = 16.0
|
||||
omni_attenuation = 1.35
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="Team1GoalLight" type="OmniLight3D" parent="PitchLights"]
|
||||
position = Vector3(0, 4.5, -22)
|
||||
light_color = Color(0.24, 0.86, 0.42, 1)
|
||||
light_energy = 5.0
|
||||
light_bake_mode = 1
|
||||
omni_range = 16.0
|
||||
omni_attenuation = 1.35
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="MidfieldLightA" type="OmniLight3D" parent="PitchLights"]
|
||||
position = Vector3(-10, 7, 0)
|
||||
light_color = Color(0.38, 0.62, 1, 1)
|
||||
light_energy = 3.5
|
||||
light_bake_mode = 1
|
||||
omni_range = 15.0
|
||||
omni_attenuation = 1.5
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="MidfieldLightB" type="OmniLight3D" parent="PitchLights"]
|
||||
position = Vector3(10, 7, 0)
|
||||
light_color = Color(0.38, 0.62, 1, 1)
|
||||
light_energy = 3.5
|
||||
light_bake_mode = 1
|
||||
omni_range = 15.0
|
||||
omni_attenuation = 1.5
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_base")
|
||||
|
||||
|
||||
@@ -14,11 +14,6 @@ uniform vec3 deck_color : source_color = vec3(0.085, 0.095, 0.122);
|
||||
// Kept close to deck_color on purpose: per-plate variation is meant to break
|
||||
// up a 24x36 m plane, not to reintroduce visible tiling.
|
||||
uniform vec3 panel_color : source_color = vec3(0.104, 0.116, 0.146);
|
||||
// Stand-in for bounce light. The arena is lit by one dim directional plus low
|
||||
// ambient, so hull facing away from it — the goal bulkheads, the fillet caps
|
||||
// either side of each mouth — otherwise crushed to pure black and the whole
|
||||
// end zone read as a void with a goal floating in it.
|
||||
uniform float hull_fill : hint_range(0.0, 2.0) = 0.55;
|
||||
uniform float panel_variation : hint_range(0.0, 1.0) = 0.4;
|
||||
uniform vec3 line_color : source_color = vec3(0.62, 0.78, 1.0);
|
||||
// Must track TeamColors.TEAM_COLORS in scripts/team_colors.gd — shaders can't
|
||||
@@ -47,9 +42,9 @@ uniform float seam_width = 0.22;
|
||||
uniform float end_zone_strength : hint_range(0.0, 1.0) = 0.12;
|
||||
uniform float panel_size = 4.0;
|
||||
uniform float panel_line_width : hint_range(0.0, 0.5) = 0.05;
|
||||
// Deliberately not a high metallic value: this arena is lit by one dim
|
||||
// directional plus low ambient, and a near-metal deck has almost no diffuse
|
||||
// response, which crushed the plating to black.
|
||||
// Deliberately not a high metallic value: the local pitch lights and SDFGI
|
||||
// need enough diffuse response to reveal the plating instead of turning it
|
||||
// into a dark mirror at grazing angles.
|
||||
uniform float deck_metallic : hint_range(0.0, 1.0) = 0.3;
|
||||
uniform float deck_roughness : hint_range(0.0, 1.0) = 0.34;
|
||||
|
||||
@@ -135,8 +130,7 @@ void fragment() {
|
||||
ALBEDO = mix(albedo, line_color, marks);
|
||||
METALLIC = deck_metallic * (1.0 - marks);
|
||||
ROUGHNESS = clamp(mix(rough, 0.5, marks), 0.05, 1.0);
|
||||
EMISSION = albedo * hull_fill
|
||||
+ line_color * marks * line_emission
|
||||
EMISSION = line_color * marks * line_emission
|
||||
+ seam_color * seam * seam_emission
|
||||
+ zone * 0.015 * flat_deck;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ The training pipeline is built — see `TRAINING.md` (self-play PPO via the vend
|
||||
The largest gap between this and a AAA-feeling product is presentation, not code. Sequenced after the above for pragmatic reasons, but this is the highest impact per hour.
|
||||
|
||||
- [ ] **Audio — there is none.** Zero sound files, zero `AudioStreamPlayer` nodes, no bus layout. Needs: engine hum pitched to throttle, turbo whoosh, ball impacts scaled by collision impulse, wall scrapes, goal explosion, crowd bed, UI clicks, countdown beeps, music. Can be driven off `Ship`'s existing telemetry signals.
|
||||
- [ ] SSAO/SSIL in the arena Environments — cheapest single perceived-quality win available; grounds the ships against the deck and gives the fillets and goal recesses real depth.
|
||||
- [x] SSAO/SSIL in the arena Environments — cheapest single perceived-quality win available; grounds the ships against the deck and gives the fillets and goal recesses real depth.
|
||||
- [ ] VFX on anything that moves: `EngineGlowL/R` are static meshes that don't respond to throttle. No thruster plume, turbo flame, ball trail, impact sparks or goal burst. `arena_02` is the only scene with any particles at all.
|
||||
- [ ] Impact feedback — screen shake, hit-stop, flash, controller rumble on ball contact.
|
||||
- [ ] Camera feel in `ship_camera.gd` — fixed distance/height/FOV today. Speed-based FOV widening, turbo kick, impact shake.
|
||||
- [ ] Goal celebration sequence: today it's a `print()` and a label scale-pop. Wants an explosion, team-tinted screen flash, camera cut, slow-mo, title card. `HUDController`'s `ResultOverlay` animation is a reasonable template.
|
||||
- [ ] Local lighting / LightmapGI bake — two directional lights and low ambient, no local lights anywhere. `arena_deck.gdshader`'s `hull_fill` uniform is explicitly a "stand-in for bounce light", i.e. the shader is compensating for lighting that isn't there. The arena is fully static, so a bake is viable; retire `hull_fill` afterwards.
|
||||
- [ ] Dress `arena_03` — its `Decoration` node is empty, while `arena_02` has stations, debris, a planet and volumetric dust.
|
||||
- [x] Local lighting / dynamic GI — four local pitch lights plus SDFGI provide bounce and contact lighting for the runtime-generated arena shell; the shader's `hull_fill` stand-in is retired. (The shell is generated in `_ready`, so it cannot participate in an editor LightmapGI bake.)
|
||||
- [x] Dress `arena_03` — its asteroid field now has mining stations, debris clusters and a distant planet.
|
||||
- [ ] Custom font + a real `Theme` resource for the HUD. The procedural instruments are well-engineered, but `ThemeDB.fallback_font` at 10-13 px reads as a debug overlay.
|
||||
- [ ] Post-processing beyond glow: DoF, motion blur, vignette, chromatic aberration on turbo.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user