feat: ImGui shadow parameters panel with clipboard copy

- Push constant block expanded: 160B → 176B (added vec4 shadowParams)
- shadowParams: x=bias, y=sampleRadius, z=farPlane, w=unused
- Fragment shader: bias and sampleRadius now read from push constants
  (dynamic, adjustable at runtime)
- Shadow.frag: uses pc.shadowParams.z for farPlane (dynamic)
- Slope-dependent bias: bias + bias*2*(1-NdotL) — adaptive
- VulkanRenderer: public ShadowBias, ShadowSampleRadius, ShadowFarPlane properties
- Program.cs: ImGui 'Shadow Parameters' panel with sliders:
  - Light Intensity (0-100), Range (5-100), RGB color
  - Shadow Bias (0.001-0.5), Sample Radius (0.001-0.1), Far Plane (10-120)
  - 'Copy Parameters to Clipboard' button — outputs all values as text
- 227 tests, all pass
This commit is contained in:
emil28092005
2026-06-18 21:48:38 +03:00
parent 8918126c58
commit 29a58d204b
13 changed files with 92 additions and 17 deletions
+57
View File
@@ -59,6 +59,7 @@ class Program
CreateScene(world);
var hasImGui = renderer.GetType().Name == "VulkanRenderer";
VulkanRenderer? vkRenderer = hasImGui ? (VulkanRenderer)renderer : null;
if (hasImGui)
{
ImGui.GetIO().DisplaySize = new System.Numerics.Vector2(window.Width, window.Height);
@@ -170,6 +171,62 @@ class Program
ImGui.Text("WASD: move | RMB: look | Q/E: up/down | Shift: boost");
ImGui.End();
// Shadow parameters panel
ImGui.Begin("Shadow Parameters");
var lightEntity2 = world.Lookup("MainLight");
if ((ulong)lightEntity2.Id != 0)
{
var lightComp = lightEntity2.Get<Light>();
var intensity = lightComp.Intensity;
var range = lightComp.Range;
var colorR = lightComp.Color.X;
var colorG = lightComp.Color.Y;
var colorB = lightComp.Color.Z;
ImGui.SliderFloat("Light Intensity", ref intensity, 0.0f, 100.0f, "%.1f");
ImGui.SliderFloat("Light Range", ref range, 5.0f, 100.0f, "%.1f");
ImGui.SliderFloat("Light R", ref colorR, 0.0f, 1.0f, "%.2f");
ImGui.SliderFloat("Light G", ref colorG, 0.0f, 1.0f, "%.2f");
ImGui.SliderFloat("Light B", ref colorB, 0.0f, 1.0f, "%.2f");
ImGui.Separator();
lightComp.Intensity = intensity;
lightComp.Range = range;
lightComp.Color = new Vector3(colorR, colorG, colorB);
lightEntity2.Set(lightComp);
}
var bias = vkRenderer.ShadowBias;
var sampleRadius = vkRenderer.ShadowSampleRadius;
var farPlane = vkRenderer.ShadowFarPlane;
ImGui.SliderFloat("Shadow Bias", ref bias, 0.001f, 0.5f, "%.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();
vkRenderer.ShadowBias = bias;
vkRenderer.ShadowSampleRadius = sampleRadius;
vkRenderer.ShadowFarPlane = farPlane;
ImGui.Text($"Current: bias={bias:F4} radius={sampleRadius:F4} far={farPlane:F1}");
if (ImGui.Button("Copy Parameters to Clipboard"))
{
var paramsText = $"bias={bias:F4}\nsampleRadius={sampleRadius:F4}\nfarPlane={farPlane:F1}\nshadowMapSize=2048";
var lightEntity3 = world.Lookup("MainLight");
if ((ulong)lightEntity3.Id != 0)
{
var lc = lightEntity3.Get<Light>();
paramsText += $"\nlightIntensity={lc.Intensity:F1}\nlightRange={lc.Range:F1}\nlightColor=({lc.Color.X:F2},{lc.Color.Y:F2},{lc.Color.Z:F2})";
}
ImGui.SetClipboardText(paramsText);
Console.WriteLine("[App] Parameters copied to clipboard:\n" + paramsText);
}
ImGui.End();
renderer.EndImGuiFrame();
}