feat: adjustable ambient lighting via ImGui sliders

- SceneUBO expanded: added vec4 ambientColor at offset 400
- UBO size: 448 → 464 bytes
- Fragment shader: ambient from UBO instead of hardcoded constant
- VulkanRenderer: AmbientColor property (default 0.01, 0.01, 0.02)
- ImGui: R/G/B sliders for ambient (0.0-0.5 range)
- Packed at offset 400 after 4 shadowParams (64 bytes at 336)
This commit is contained in:
emil28092005
2026-06-19 09:34:09 +03:00
parent 9555de60ef
commit 74dcc45543
7 changed files with 15 additions and 2 deletions
Binary file not shown.
Binary file not shown.
+7
View File
@@ -281,14 +281,21 @@ class Program
var bias = vkRenderer.ShadowBias; var bias = vkRenderer.ShadowBias;
var sampleRadius = vkRenderer.ShadowSampleRadius; var sampleRadius = vkRenderer.ShadowSampleRadius;
var farPlane = vkRenderer.ShadowFarPlane; var farPlane = vkRenderer.ShadowFarPlane;
var ambient = vkRenderer.AmbientColor;
ImGui.SliderFloat("Shadow Bias", ref bias, 0.0001f, 0.1f, "%.4f"); ImGui.SliderFloat("Shadow Bias", ref bias, 0.0001f, 0.1f, "%.4f");
ImGui.SliderFloat("Sample Radius", ref sampleRadius, 0.001f, 0.1f, "%.4f"); ImGui.SliderFloat("Sample Radius", ref sampleRadius, 0.001f, 0.1f, "%.4f");
ImGui.SliderFloat("Far Plane", ref farPlane, 10.0f, 120.0f, "%.1f"); ImGui.SliderFloat("Far Plane", ref farPlane, 10.0f, 120.0f, "%.1f");
ImGui.Separator();
ImGui.Text("Ambient Light");
ImGui.SliderFloat("Ambient R", ref ambient.X, 0.0f, 0.5f, "%.3f");
ImGui.SliderFloat("Ambient G", ref ambient.Y, 0.0f, 0.5f, "%.3f");
ImGui.SliderFloat("Ambient B", ref ambient.Z, 0.0f, 0.5f, "%.3f");
vkRenderer.ShadowBias = bias; vkRenderer.ShadowBias = bias;
vkRenderer.ShadowSampleRadius = sampleRadius; vkRenderer.ShadowSampleRadius = sampleRadius;
vkRenderer.ShadowFarPlane = farPlane; vkRenderer.ShadowFarPlane = farPlane;
vkRenderer.AmbientColor = ambient;
ImGui.Text($"Current: bias={bias:F4} radius={sampleRadius:F4} far={farPlane:F1}"); ImGui.Text($"Current: bias={bias:F4} radius={sampleRadius:F4} far={farPlane:F1}");
@@ -18,6 +18,7 @@ layout(set = 0, binding = 0) uniform SceneUBO {
vec2 padding; vec2 padding;
LightData lights[8]; LightData lights[8];
vec4 shadowParams[4]; vec4 shadowParams[4];
vec4 ambientColor; // xyz = ambient color, w = unused
} scene; } scene;
layout(set = 0, binding = 1) uniform samplerCubeArray shadowArray; layout(set = 0, binding = 1) uniform samplerCubeArray shadowArray;
@@ -151,7 +152,7 @@ void main()
float roughness = 0.5; float roughness = 0.5;
float metallic = 0.1; float metallic = 0.1;
vec3 color = AMBIENT * albedo; vec3 color = scene.ambientColor.xyz * albedo;
for (int i = 0; i < scene.numLights; i++) for (int i = 0; i < scene.numLights; i++)
{ {
Binary file not shown.
@@ -5,7 +5,7 @@ namespace Engine.Graphics.Vulkan;
internal sealed unsafe class VulkanFrameResources : IDisposable internal sealed unsafe class VulkanFrameResources : IDisposable
{ {
public const int MaxFramesInFlight = 2; public const int MaxFramesInFlight = 2;
public const ulong UboSize = 448; public const ulong UboSize = 464;
public VkCommandPool CommandPool; public VkCommandPool CommandPool;
public VkCommandBuffer[] CommandBuffers = new VkCommandBuffer[MaxFramesInFlight]; public VkCommandBuffer[] CommandBuffers = new VkCommandBuffer[MaxFramesInFlight];
@@ -32,6 +32,7 @@ public sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreensh
public float ShadowBias { get; set; } = 0.0001f; public float ShadowBias { get; set; } = 0.0001f;
public float ShadowSampleRadius { get; set; } = 0.015f; public float ShadowSampleRadius { get; set; } = 0.015f;
public float ShadowFarPlane { get; set; } = 60.0f; public float ShadowFarPlane { get; set; } = 60.0f;
public Vector3 AmbientColor { get; set; } = new(0.01f, 0.01f, 0.02f);
public bool IsRecording { get; set; } public bool IsRecording { get; set; }
public byte[]? CapturedFrame { get; private set; } public byte[]? CapturedFrame { get; private set; }
@@ -227,6 +228,10 @@ public sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreensh
System.Buffer.MemoryCopy(&sp, uboData + 336 + i * 16, 16, 16); System.Buffer.MemoryCopy(&sp, uboData + 336 + i * 16, 16, 16);
} }
// Ambient color at offset 400 (after 4 shadowParams = 64 bytes)
var ambient = new Vector4(AmbientColor, 0);
System.Buffer.MemoryCopy(&ambient, uboData + 400, 16, 16);
// Compute light view-proj for each shadow light // Compute light view-proj for each shadow light
var lightViewProjs = new Matrix4x4[numShadowLights]; var lightViewProjs = new Matrix4x4[numShadowLights];
for (int i = 0; i < numShadowLights; i++) for (int i = 0; i < numShadowLights; i++)