From 1f3e48ae27099bd60da02dffe60a359586dded07 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Tue, 6 Jan 2026 01:07:26 +0000 Subject: [PATCH] feat(atmospherics): Add sky color configuration and apply in rendering --- config/seed_runtime.json | 1 + scripts/cube_logic.lua | 64 +++++++++++++++++++- src/services/impl/json_config_service.cpp | 1 + src/services/impl/render_command_service.cpp | 14 +++-- src/services/interfaces/config_types.hpp | 1 + 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/config/seed_runtime.json b/config/seed_runtime.json index a82bb2b..78e8a5f 100644 --- a/config/seed_runtime.json +++ b/config/seed_runtime.json @@ -64,6 +64,7 @@ "ambient_strength": 0.01, "fog_density": 0.003, "fog_color": [0.05, 0.05, 0.08], + "sky_color": [0.04, 0.05, 0.08], "gamma": 2.2, "exposure": 1.0, "enable_tone_mapping": true, diff --git a/scripts/cube_logic.lua b/scripts/cube_logic.lua index a1f112a..a6e2060 100644 --- a/scripts/cube_logic.lua +++ b/scripts/cube_logic.lua @@ -9,6 +9,7 @@ local cube_mesh_info = { local cube_vertices = {} local cube_indices = {} local cube_indices_double_sided = {} +local skybox_color = {0.04, 0.05, 0.08} local function build_double_sided_indices(indices) local doubled = {} @@ -224,6 +225,29 @@ if cube_mesh_info.loaded then end end +local function resolve_color3(value, fallback) + if type(value) == "table" then + local r = tonumber(value[1]) + local g = tonumber(value[2]) + local b = tonumber(value[3]) + if r and g and b then + return {r, g, b} + end + end + return {fallback[1], fallback[2], fallback[3]} +end + +local function apply_skybox_color_from_config() + if type(config) ~= "table" then + return + end + local atmospherics = config.atmospherics + if type(atmospherics) ~= "table" then + return + end + skybox_color = resolve_color3(atmospherics.sky_color, skybox_color) +end + local function build_static_shader_variants() local fallback_vertex_source = [[ #version 450 @@ -294,6 +318,10 @@ void main() { vertex_source = fallback_vertex_source, fragment_source = fallback_fragment_source, }, + skybox = { + vertex_source = fallback_vertex_source, + fragment_source = fallback_fragment_source, + }, } end @@ -306,19 +334,36 @@ local function count_shader_variants(variants) end local function build_shader_variants() + apply_skybox_color_from_config() + local ok, toolkit = pcall(require, "shader_toolkit") if not ok then log_debug("Shader toolkit unavailable: %s", tostring(toolkit)) return build_static_shader_variants() end + local output_mode = "source" + local compile = false local ok_generate, generated = pcall(toolkit.generate_cube_demo_variants, - {compile = false, output_mode = "source"}) + {compile = compile, output_mode = output_mode}) if not ok_generate then log_debug("Shader generation failed: %s", tostring(generated)) return build_static_shader_variants() end + local ok_skybox, skybox_variant = pcall(toolkit.generate_variant, { + key = "skybox", + template = "solid_color", + output_mode = output_mode, + compile = compile, + parameters = {color = skybox_color}, + }) + if ok_skybox then + generated.skybox = skybox_variant + else + log_debug("Skybox shader generation failed: %s", tostring(skybox_variant)) + end + log_debug("Generated %d shader variants", count_shader_variants(generated)) return generated end @@ -642,6 +687,22 @@ local function create_static_cube(position, scale, color, shader_key) } end +local function create_skybox() + local skybox_scale = camera.far * 0.85 + local function compute_model_matrix() + local translation = math3d.translation(camera.position[1], camera.position[2], camera.position[3]) + local scaling = scale_matrix(skybox_scale, skybox_scale, skybox_scale) + return math3d.multiply(translation, scaling) + end + + return { + vertices = apply_color_to_vertices(skybox_color), + indices = (#cube_indices_double_sided > 0) and cube_indices_double_sided or cube_indices, + compute_model_matrix = compute_model_matrix, + shader_key = "skybox", + } +end + local function create_spinning_cube() log_debug("Spinning cube shader=default (rainbow wrap)") local function compute_model_matrix(time) @@ -830,6 +891,7 @@ end function get_scene_objects() local objects = {} + objects[#objects + 1] = create_skybox() for i = 1, #room_objects do objects[#objects + 1] = room_objects[i] end diff --git a/src/services/impl/json_config_service.cpp b/src/services/impl/json_config_service.cpp index cb5d26f..5e8e93b 100644 --- a/src/services/impl/json_config_service.cpp +++ b/src/services/impl/json_config_service.cpp @@ -352,6 +352,7 @@ RuntimeConfig JsonConfigService::LoadFromJson(std::shared_ptr logger, readFloat("ambient_strength", config.atmospherics.ambientStrength); readFloat("fog_density", config.atmospherics.fogDensity); readFloatArray3("fog_color", config.atmospherics.fogColor); + readFloatArray3("sky_color", config.atmospherics.skyColor); readFloat("gamma", config.atmospherics.gamma); readFloat("exposure", config.atmospherics.exposure); readBool("enable_tone_mapping", config.atmospherics.enableToneMapping); diff --git a/src/services/impl/render_command_service.cpp b/src/services/impl/render_command_service.cpp index 6bad2d4..9bc3bfe 100644 --- a/src/services/impl/render_command_service.cpp +++ b/src/services/impl/render_command_service.cpp @@ -126,10 +126,19 @@ void RenderCommandService::RecordCommands(uint32_t imageIndex, renderPassInfo.renderArea.offset = {0, 0}; renderPassInfo.renderArea.extent = extent; + const auto& config = configService_->GetConfig(); std::array clearValues{}; - clearValues[0].color = {{0.1f, 0.1f, 0.15f, 1.0f}}; // Color clear + const auto& skyColor = config.atmospherics.skyColor; + clearValues[0].color = {{skyColor[0], skyColor[1], skyColor[2], 1.0f}}; // Skybox clear clearValues[1].depthStencil = {1.0f, 0}; // Depth clear + if (logger_) { + logger_->Trace("RenderCommandService", "RecordCommands", + "clearColor=" + std::to_string(skyColor[0]) + "," + + std::to_string(skyColor[1]) + "," + + std::to_string(skyColor[2])); + } + renderPassInfo.clearValueCount = static_cast(clearValues.size()); renderPassInfo.pClearValues = clearValues.data(); @@ -181,9 +190,6 @@ void RenderCommandService::RecordCommands(uint32_t imageIndex, // For PBR shaders, populate extended push constants if (command.shaderKey.find("pbr") != std::string::npos) { - // Get atmospherics config - auto config = configService_->GetConfig(); - // For now, use identity for view and proj (since viewProj is already combined) // In a full implementation, we'd need separate view/proj matrices pushConstants.view = {1.0f, 0.0f, 0.0f, 0.0f, diff --git a/src/services/interfaces/config_types.hpp b/src/services/interfaces/config_types.hpp index 3073b5e..b9f56bd 100644 --- a/src/services/interfaces/config_types.hpp +++ b/src/services/interfaces/config_types.hpp @@ -70,6 +70,7 @@ struct AtmosphericsConfig { float ambientStrength = 0.01f; float fogDensity = 0.003f; std::array fogColor = {0.05f, 0.05f, 0.08f}; + std::array skyColor = {0.1f, 0.1f, 0.15f}; float gamma = 2.2f; float exposure = 1.0f; bool enableToneMapping = true;