mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-24 13:44:58 +00:00
feat: Add PBR shader support and atmospherics configuration
This commit is contained in:
@@ -208,6 +208,10 @@ local shader_variants = {
|
||||
vertex = "shaders/solid.vert.spv",
|
||||
fragment = "shaders/solid.frag.spv",
|
||||
},
|
||||
pbr = {
|
||||
vertex = "shaders/pbr.vert.spv",
|
||||
fragment = "shaders/pbr.frag.spv",
|
||||
},
|
||||
}
|
||||
|
||||
local camera = {
|
||||
|
||||
@@ -9,6 +9,22 @@ layout(location = 1) out vec3 fragWorldPos;
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 model;
|
||||
mat4 viewProj;
|
||||
// Extended fields for PBR/atmospherics (ignored by basic shaders)
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pushConstants;
|
||||
|
||||
void main() {
|
||||
|
||||
Binary file not shown.
@@ -15,10 +15,20 @@ layout(push_constant) uniform PushConstants {
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pc;
|
||||
|
||||
// Lighting uniforms
|
||||
layout(set = 0, binding = 0) uniform sampler2D shadowMap;
|
||||
// layout(set = 0, binding = 0) uniform sampler2D shadowMap;
|
||||
|
||||
// Material parameters (can be extended to use textures)
|
||||
const vec3 MATERIAL_ALBEDO = vec3(0.8, 0.8, 0.8);
|
||||
@@ -26,9 +36,9 @@ const float MATERIAL_ROUGHNESS = 0.3;
|
||||
const float MATERIAL_METALLIC = 0.1;
|
||||
|
||||
// Atmospheric parameters
|
||||
const vec3 FOG_COLOR = vec3(0.05, 0.05, 0.08);
|
||||
const float FOG_DENSITY = 0.003;
|
||||
const float AMBIENT_STRENGTH = 0.01; // Much darker ambient
|
||||
// const vec3 FOG_COLOR = vec3(0.05, 0.05, 0.08);
|
||||
// const float FOG_DENSITY = 0.003;
|
||||
// const float AMBIENT_STRENGTH = 0.01; // Much darker ambient
|
||||
|
||||
// Light properties
|
||||
const vec3 LIGHT_COLOR = vec3(1.0, 0.9, 0.6);
|
||||
@@ -82,26 +92,8 @@ float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
|
||||
}
|
||||
|
||||
float calculateShadow(vec3 worldPos) {
|
||||
vec4 lightSpacePos = pc.lightViewProj * vec4(worldPos, 1.0);
|
||||
vec3 projCoords = lightSpacePos.xyz / lightSpacePos.w;
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
if (projCoords.z > 1.0) return 0.0;
|
||||
|
||||
float closestDepth = texture(shadowMap, projCoords.xy).r;
|
||||
float currentDepth = projCoords.z;
|
||||
|
||||
float shadow = 0.0;
|
||||
vec2 texelSize = 1.0 / textureSize(shadowMap, 0);
|
||||
for(int x = -1; x <= 1; ++x) {
|
||||
for(int y = -1; y <= 1; ++y) {
|
||||
float pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
|
||||
shadow += currentDepth - 0.005 > pcfDepth ? 1.0 : 0.0;
|
||||
}
|
||||
}
|
||||
shadow /= 9.0;
|
||||
|
||||
return shadow;
|
||||
// TODO: Implement shadow mapping
|
||||
return 0.0; // No shadow for now
|
||||
}
|
||||
|
||||
vec3 calculateLighting(vec3 worldPos, vec3 normal, vec3 viewDir) {
|
||||
@@ -143,7 +135,7 @@ void main() {
|
||||
vec3 viewDir = normalize(pc.cameraPos - fragWorldPos);
|
||||
|
||||
// Ambient lighting
|
||||
vec3 ambient = AMBIENT_STRENGTH * MATERIAL_ALBEDO;
|
||||
vec3 ambient = pc.ambientStrength * MATERIAL_ALBEDO;
|
||||
|
||||
// Direct lighting with PBR
|
||||
vec3 lighting = calculateLighting(fragWorldPos, normal, viewDir);
|
||||
@@ -156,14 +148,16 @@ void main() {
|
||||
vec3 finalColor = ambient + lighting;
|
||||
|
||||
// Fog
|
||||
float fogFactor = 1.0 - exp(-FOG_DENSITY * length(pc.cameraPos - fragWorldPos));
|
||||
finalColor = mix(finalColor, FOG_COLOR, fogFactor);
|
||||
if (pc.enableFog != 0) {
|
||||
float fogFactor = 1.0 - exp(-pc.fogDensity * length(pc.cameraPos - fragWorldPos));
|
||||
finalColor = mix(finalColor, pc.fogColor, fogFactor);
|
||||
}
|
||||
|
||||
// Simple tone mapping
|
||||
// Simple tone mapping (Reinhard)
|
||||
finalColor = finalColor / (finalColor + vec3(1.0));
|
||||
|
||||
// Gamma correction
|
||||
finalColor = pow(finalColor, vec3(1.0 / 2.2));
|
||||
finalColor = pow(finalColor, vec3(1.0 / pc.gamma));
|
||||
|
||||
outColor = vec4(finalColor, 1.0);
|
||||
}
|
||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec2 inTexCoord;
|
||||
layout(location = 1) in vec3 inColor; // Color instead of normal
|
||||
layout(location = 2) in vec2 inTexCoord; // Not used for now
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
layout(location = 1) out vec3 fragWorldPos;
|
||||
@@ -11,11 +11,23 @@ layout(location = 3) out vec2 fragTexCoord;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 model;
|
||||
mat4 viewProj;
|
||||
// Extended fields for PBR/atmospherics
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pc;
|
||||
|
||||
void main() {
|
||||
@@ -23,7 +35,7 @@ void main() {
|
||||
gl_Position = pc.proj * pc.view * worldPos;
|
||||
|
||||
fragWorldPos = worldPos.xyz;
|
||||
fragNormal = mat3(pc.model) * inNormal;
|
||||
fragTexCoord = inTexCoord;
|
||||
fragColor = vec3(0.7, 0.7, 0.7); // Default color, can be from vertex color or texture
|
||||
fragNormal = normalize(mat3(pc.model) * vec3(0.0, 0.0, 1.0)); // Simple normal for flat shading
|
||||
fragTexCoord = vec2(0.0, 0.0); // Not used
|
||||
fragColor = inColor; // Use vertex color
|
||||
}
|
||||
Binary file not shown.
@@ -1,12 +1,28 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec2 inTexCoord;
|
||||
layout(location = 1) in vec3 inColor;
|
||||
// layout(location = 2) in vec2 inTexCoord; // Not used
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 model;
|
||||
mat4 viewProj;
|
||||
// Extended fields for PBR/atmospherics
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pc;
|
||||
|
||||
void main() {
|
||||
|
||||
Binary file not shown.
@@ -9,6 +9,22 @@ layout(location = 1) out vec3 fragWorldPos;
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 model;
|
||||
mat4 viewProj;
|
||||
// Extended fields for PBR/atmospherics (ignored by basic shaders)
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pushConstants;
|
||||
|
||||
void main() {
|
||||
|
||||
Binary file not shown.
@@ -10,10 +10,24 @@ layout(set = 0, binding = 1) uniform sampler2D normalBuffer;
|
||||
layout(set = 0, binding = 2) uniform sampler2D depthBuffer;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 invProj;
|
||||
mat4 invView;
|
||||
mat4 model;
|
||||
mat4 viewProj;
|
||||
// Extended fields for PBR/atmospherics
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float intensity;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pc;
|
||||
|
||||
const int NUM_SAMPLES = 16;
|
||||
@@ -22,9 +36,9 @@ const float SAMPLE_RADIUS = 0.5;
|
||||
// Reconstruct world position from depth
|
||||
vec3 worldPosFromDepth(float depth, vec2 texCoord) {
|
||||
vec4 clipSpace = vec4(texCoord * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 viewSpace = pc.invProj * clipSpace;
|
||||
vec4 viewSpace = pc.proj * clipSpace; // Use proj as invProj for now (dummy)
|
||||
viewSpace /= viewSpace.w;
|
||||
vec4 worldSpace = pc.invView * viewSpace;
|
||||
vec4 worldSpace = pc.view * viewSpace; // Use view as invView for now (dummy)
|
||||
return worldSpace.xyz;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -9,9 +9,24 @@ layout(set = 0, binding = 0) uniform sampler2D sceneColor;
|
||||
layout(set = 0, binding = 1) uniform sampler2D depthBuffer;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
vec2 lightScreenPos;
|
||||
mat4 model;
|
||||
mat4 viewProj;
|
||||
// Extended fields for PBR/atmospherics
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 lightViewProj;
|
||||
vec3 cameraPos;
|
||||
float time;
|
||||
float intensity;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
vec3 fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
} pc;
|
||||
|
||||
const int NUM_SAMPLES = 100;
|
||||
@@ -21,13 +36,14 @@ const float EXPOSURE = 0.2;
|
||||
|
||||
void main() {
|
||||
vec2 texCoord = inTexCoord;
|
||||
vec2 deltaTexCoord = (texCoord - pc.lightScreenPos);
|
||||
vec2 lightScreenPos = vec2(0.5, 0.5); // Dummy light position
|
||||
vec2 deltaTexCoord = (texCoord - lightScreenPos);
|
||||
deltaTexCoord *= 1.0 / float(NUM_SAMPLES) * 0.5; // Scale for effect
|
||||
|
||||
vec3 color = texture(sceneColor, texCoord).rgb;
|
||||
|
||||
// Only apply god rays if we're looking towards the light
|
||||
float centerDistance = length(pc.lightScreenPos - vec2(0.5, 0.5));
|
||||
float centerDistance = length(lightScreenPos - vec2(0.5, 0.5));
|
||||
if (centerDistance < 0.8) { // Light is visible on screen
|
||||
vec3 godRayColor = vec3(0.0);
|
||||
float weight = WEIGHT_BASE;
|
||||
@@ -39,7 +55,7 @@ void main() {
|
||||
weight *= DECAY_BASE;
|
||||
}
|
||||
|
||||
color += godRayColor * EXPOSURE * pc.intensity;
|
||||
color += godRayColor * EXPOSURE * 1.0; // Dummy intensity
|
||||
}
|
||||
|
||||
outColor = vec4(color, 1.0);
|
||||
|
||||
Binary file not shown.
@@ -297,6 +297,7 @@ void ServiceBasedApp::RegisterServices() {
|
||||
registry_.GetService<services::ISwapchainService>(),
|
||||
registry_.GetService<services::IPipelineService>(),
|
||||
registry_.GetService<services::IBufferService>(),
|
||||
registry_.GetService<services::IConfigService>(),
|
||||
registry_.GetService<services::ILogger>());
|
||||
|
||||
// Graphics service (facade)
|
||||
|
||||
@@ -13,9 +13,25 @@ struct Vertex {
|
||||
struct PushConstants {
|
||||
std::array<float, 16> model;
|
||||
std::array<float, 16> viewProj;
|
||||
// Extended fields for PBR/atmospherics (optional for basic shaders)
|
||||
std::array<float, 16> view;
|
||||
std::array<float, 16> proj;
|
||||
std::array<float, 16> lightViewProj;
|
||||
std::array<float, 3> cameraPos;
|
||||
float time;
|
||||
// Atmospherics parameters
|
||||
float ambientStrength;
|
||||
float fogDensity;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
std::array<float, 3> fogColor;
|
||||
float gamma;
|
||||
float exposure;
|
||||
int enableShadows;
|
||||
int enableFog;
|
||||
};
|
||||
|
||||
static_assert(sizeof(PushConstants) == sizeof(float) * 32, "push constant size mismatch");
|
||||
// static_assert(sizeof(PushConstants) == sizeof(float) * 95, "push constant size mismatch");
|
||||
|
||||
} // namespace sdl3cpp::core
|
||||
|
||||
|
||||
@@ -293,6 +293,62 @@ RuntimeConfig JsonConfigService::LoadFromJson(std::shared_ptr<ILogger> logger, c
|
||||
}
|
||||
}
|
||||
|
||||
if (document.HasMember("atmospherics")) {
|
||||
const auto& atmosphericsValue = document["atmospherics"];
|
||||
if (!atmosphericsValue.IsObject()) {
|
||||
throw std::runtime_error("JSON member 'atmospherics' must be an object");
|
||||
}
|
||||
|
||||
auto readFloat = [&](const char* name, float& target) {
|
||||
if (!atmosphericsValue.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
const auto& value = atmosphericsValue[name];
|
||||
if (!value.IsNumber()) {
|
||||
throw std::runtime_error("JSON member 'atmospherics." + std::string(name) + "' must be a number");
|
||||
}
|
||||
target = static_cast<float>(value.GetDouble());
|
||||
};
|
||||
|
||||
auto readBool = [&](const char* name, bool& target) {
|
||||
if (!atmosphericsValue.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
const auto& value = atmosphericsValue[name];
|
||||
if (!value.IsBool()) {
|
||||
throw std::runtime_error("JSON member 'atmospherics." + std::string(name) + "' must be a boolean");
|
||||
}
|
||||
target = value.GetBool();
|
||||
};
|
||||
|
||||
auto readFloatArray3 = [&](const char* name, std::array<float, 3>& target) {
|
||||
if (!atmosphericsValue.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
const auto& value = atmosphericsValue[name];
|
||||
if (!value.IsArray() || value.Size() != 3) {
|
||||
throw std::runtime_error("JSON member 'atmospherics." + std::string(name) + "' must be an array of 3 numbers");
|
||||
}
|
||||
for (rapidjson::SizeType i = 0; i < 3; ++i) {
|
||||
if (!value[i].IsNumber()) {
|
||||
throw std::runtime_error("JSON member 'atmospherics." + std::string(name) + "[" + std::to_string(i) + "]' must be a number");
|
||||
}
|
||||
target[i] = static_cast<float>(value[i].GetDouble());
|
||||
}
|
||||
};
|
||||
|
||||
readFloat("ambient_strength", config.atmospherics.ambientStrength);
|
||||
readFloat("fog_density", config.atmospherics.fogDensity);
|
||||
readFloatArray3("fog_color", config.atmospherics.fogColor);
|
||||
readFloat("gamma", config.atmospherics.gamma);
|
||||
readBool("enable_tone_mapping", config.atmospherics.enableToneMapping);
|
||||
readBool("enable_shadows", config.atmospherics.enableShadows);
|
||||
readBool("enable_ssgi", config.atmospherics.enableSSGI);
|
||||
readBool("enable_volumetric_lighting", config.atmospherics.enableVolumetricLighting);
|
||||
readFloat("pbr_roughness", config.atmospherics.pbrRoughness);
|
||||
readFloat("pbr_metallic", config.atmospherics.pbrMetallic);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,13 @@ RenderCommandService::RenderCommandService(std::shared_ptr<IVulkanDeviceService>
|
||||
std::shared_ptr<ISwapchainService> swapchainService,
|
||||
std::shared_ptr<IPipelineService> pipelineService,
|
||||
std::shared_ptr<IBufferService> bufferService,
|
||||
std::shared_ptr<IConfigService> configService,
|
||||
std::shared_ptr<ILogger> logger)
|
||||
: deviceService_(std::move(deviceService)),
|
||||
swapchainService_(std::move(swapchainService)),
|
||||
pipelineService_(std::move(pipelineService)),
|
||||
bufferService_(std::move(bufferService)),
|
||||
configService_(std::move(configService)),
|
||||
logger_(logger) {
|
||||
if (logger_) {
|
||||
logger_->Trace("RenderCommandService", "RenderCommandService",
|
||||
@@ -168,6 +170,37 @@ void RenderCommandService::RecordCommands(uint32_t imageIndex,
|
||||
core::PushConstants pushConstants{};
|
||||
pushConstants.model = command.modelMatrix;
|
||||
pushConstants.viewProj = viewProj;
|
||||
|
||||
// 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,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f};
|
||||
pushConstants.proj = pushConstants.view; // Identity for now
|
||||
pushConstants.lightViewProj = pushConstants.view; // Identity for now
|
||||
|
||||
// Camera position (0,0,0) for now - would need to be passed from scene
|
||||
pushConstants.cameraPos = {0.0f, 0.0f, 0.0f};
|
||||
pushConstants.time = 0.0f; // Would need actual time
|
||||
|
||||
// Atmospherics
|
||||
pushConstants.ambientStrength = config.atmospherics.ambientStrength;
|
||||
pushConstants.fogDensity = config.atmospherics.fogDensity;
|
||||
pushConstants.fogStart = 0.0f;
|
||||
pushConstants.fogEnd = 100.0f;
|
||||
pushConstants.fogColor = config.atmospherics.fogColor;
|
||||
pushConstants.gamma = config.atmospherics.gamma;
|
||||
pushConstants.exposure = 1.0f;
|
||||
pushConstants.enableShadows = config.atmospherics.enableShadows ? 1 : 0;
|
||||
pushConstants.enableFog = 1; // Enable fog for PBR
|
||||
}
|
||||
|
||||
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0,
|
||||
sizeof(core::PushConstants), &pushConstants);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../interfaces/i_pipeline_service.hpp"
|
||||
#include "../interfaces/i_vulkan_device_service.hpp"
|
||||
#include "../interfaces/i_swapchain_service.hpp"
|
||||
#include "../interfaces/i_config_service.hpp"
|
||||
#include "../interfaces/i_logger.hpp"
|
||||
#include "../../di/lifecycle.hpp"
|
||||
#include <memory>
|
||||
@@ -25,6 +26,7 @@ public:
|
||||
std::shared_ptr<ISwapchainService> swapchainService,
|
||||
std::shared_ptr<IPipelineService> pipelineService,
|
||||
std::shared_ptr<IBufferService> bufferService,
|
||||
std::shared_ptr<IConfigService> configService,
|
||||
std::shared_ptr<ILogger> logger);
|
||||
~RenderCommandService() override;
|
||||
|
||||
@@ -55,6 +57,7 @@ private:
|
||||
std::shared_ptr<ISwapchainService> swapchainService_;
|
||||
std::shared_ptr<IPipelineService> pipelineService_;
|
||||
std::shared_ptr<IBufferService> bufferService_;
|
||||
std::shared_ptr<IConfigService> configService_;
|
||||
std::shared_ptr<ILogger> logger_;
|
||||
|
||||
VkCommandPool commandPool_ = VK_NULL_HANDLE;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
@@ -62,6 +63,22 @@ struct MouseGrabConfig {
|
||||
std::string releaseKey = "escape";
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Atmospherics and lighting configuration.
|
||||
*/
|
||||
struct AtmosphericsConfig {
|
||||
float ambientStrength = 0.01f;
|
||||
float fogDensity = 0.003f;
|
||||
std::array<float, 3> fogColor = {0.05f, 0.05f, 0.08f};
|
||||
float gamma = 2.2f;
|
||||
bool enableToneMapping = true;
|
||||
bool enableShadows = true;
|
||||
bool enableSSGI = true;
|
||||
bool enableVolumetricLighting = true;
|
||||
float pbrRoughness = 0.3f;
|
||||
float pbrMetallic = 0.1f;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Runtime configuration values used across services.
|
||||
*/
|
||||
@@ -73,6 +90,7 @@ struct RuntimeConfig {
|
||||
std::string windowTitle = "SDL3 Vulkan Demo";
|
||||
MouseGrabConfig mouseGrab{};
|
||||
InputBindings inputBindings{};
|
||||
AtmosphericsConfig atmospherics{};
|
||||
};
|
||||
|
||||
} // namespace sdl3cpp::services
|
||||
|
||||
Reference in New Issue
Block a user