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 sampleRadius = vkRenderer.ShadowSampleRadius;
var farPlane = vkRenderer.ShadowFarPlane;
var ambient = vkRenderer.AmbientColor;
ImGui.SliderFloat("Shadow Bias", ref bias, 0.0001f, 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.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.ShadowSampleRadius = sampleRadius;
vkRenderer.ShadowFarPlane = farPlane;
vkRenderer.AmbientColor = ambient;
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;
LightData lights[8];
vec4 shadowParams[4];
vec4 ambientColor; // xyz = ambient color, w = unused
} scene;
layout(set = 0, binding = 1) uniform samplerCubeArray shadowArray;
@@ -151,7 +152,7 @@ void main()
float roughness = 0.5;
float metallic = 0.1;
vec3 color = AMBIENT * albedo;
vec3 color = scene.ambientColor.xyz * albedo;
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
{
public const int MaxFramesInFlight = 2;
public const ulong UboSize = 448;
public const ulong UboSize = 464;
public VkCommandPool CommandPool;
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 ShadowSampleRadius { get; set; } = 0.015f;
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 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);
}
// 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
var lightViewProjs = new Matrix4x4[numShadowLights];
for (int i = 0; i < numShadowLights; i++)