Phase 7.1 tuning: reduce saturation, increase contrast, multi-angle screenshots
- Saturation 1.40→1.15, exposure 2.2→1.8 (less oversaturated) - Shadow factor 0.55→0.45 (more contrast between lit and shadow) - Ambient reduced slightly for better contrast - Screenshot mode: 4 camera views (landscape, sideview, topdown, backlit) - AO history reset between view changes (prevents temporal contamination)
This commit is contained in:
parent
55c67686f2
commit
82307269e8
4 changed files with 59 additions and 19 deletions
|
|
@ -107,7 +107,7 @@ void main(uint3 DTid : SV_DispatchThreadID) {
|
||||||
|
|
||||||
float shadowFactor = 1.0;
|
float shadowFactor = 1.0;
|
||||||
if (NdotL <= 0.0) {
|
if (NdotL <= 0.0) {
|
||||||
shadowFactor = 0.55; // back-facing = fully in shadow
|
shadowFactor = 0.45; // back-facing = fully in shadow
|
||||||
} else {
|
} else {
|
||||||
RayDesc ray;
|
RayDesc ray;
|
||||||
ray.Origin = origin;
|
ray.Origin = origin;
|
||||||
|
|
@ -120,7 +120,7 @@ void main(uint3 DTid : SV_DispatchThreadID) {
|
||||||
[loop] while (q.Proceed()) {}
|
[loop] while (q.Proceed()) {}
|
||||||
|
|
||||||
if (q.CommittedStatus() == COMMITTED_TRIANGLE_HIT) {
|
if (q.CommittedStatus() == COMMITTED_TRIANGLE_HIT) {
|
||||||
shadowFactor = 0.55;
|
shadowFactor = 0.45;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,20 +195,47 @@ int APIENTRY wWinMain(
|
||||||
else {
|
else {
|
||||||
application.Run();
|
application.Run();
|
||||||
|
|
||||||
// Screenshot mode: wait for rendering + AO convergence, then capture and quit
|
// Screenshot mode: cycle through multiple camera views
|
||||||
if (renderPath.screenshotMode) {
|
if (renderPath.screenshotMode) {
|
||||||
screenshotFrameCounter++;
|
struct CamView { float x, y, z, pitch, yaw; const char* name; };
|
||||||
// Only start counting convergence frames once we have actual rendered quads
|
static const CamView views[] = {
|
||||||
bool hasRendered = renderPath.renderer.getGpuMeshQuadCount() > 0;
|
{ 270.f, 48.f, 240.f, -0.30f, 0.6f, "landscape" }, // wide terrain, slight down
|
||||||
|
{ 272.f, 44.f, 248.f, -0.20f, 1.0f, "sideview" }, // side angle, ground level
|
||||||
|
{ 268.f, 55.f, 242.f, -0.70f, 0.5f, "topdown" }, // steep top-down
|
||||||
|
{ 275.f, 46.f, 235.f, -0.15f, 2.8f, "backlit" }, // looking toward sun
|
||||||
|
};
|
||||||
|
static const int numViews = sizeof(views) / sizeof(views[0]);
|
||||||
|
static int currentView = 0;
|
||||||
static int convergenceFrames = 0;
|
static int convergenceFrames = 0;
|
||||||
|
static bool waitingForRender = true;
|
||||||
|
|
||||||
|
screenshotFrameCounter++;
|
||||||
|
|
||||||
|
// Set camera for current view on first frame or after capture
|
||||||
|
if (screenshotFrameCounter == 1 || convergenceFrames == 0) {
|
||||||
|
renderPath.setCamera(views[currentView].x, views[currentView].y,
|
||||||
|
views[currentView].z, views[currentView].pitch, views[currentView].yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasRendered = renderPath.renderer.getGpuMeshQuadCount() > 0;
|
||||||
if (hasRendered) convergenceFrames++;
|
if (hasRendered) convergenceFrames++;
|
||||||
// Wait 60 frames after first render for AO temporal convergence
|
|
||||||
if (convergenceFrames == 60) {
|
// Wait 50 frames for AO convergence per view
|
||||||
bool ok = wi::helper::saveTextureToFile(
|
if (convergenceFrames >= 50) {
|
||||||
renderPath.getVoxelRT(), "bvle_screenshot.png");
|
char filename[64];
|
||||||
wi::backlog::post(ok ? "Screenshot saved: bvle_screenshot.png"
|
snprintf(filename, sizeof(filename), "bvle_screenshot_%s.png",
|
||||||
: "Screenshot FAILED");
|
views[currentView].name);
|
||||||
PostQuitMessage(0);
|
wi::helper::saveTextureToFile(renderPath.getVoxelRT(), filename);
|
||||||
|
|
||||||
|
currentView++;
|
||||||
|
if (currentView >= numViews) {
|
||||||
|
PostQuitMessage(0);
|
||||||
|
} else {
|
||||||
|
convergenceFrames = 0;
|
||||||
|
renderPath.setCamera(views[currentView].x, views[currentView].y,
|
||||||
|
views[currentView].z, views[currentView].pitch, views[currentView].yaw);
|
||||||
|
renderPath.resetAOHistory(); // invalidate temporal AO for new view
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1450,15 +1450,15 @@ void VoxelRenderer::render(
|
||||||
cb.bleedMask = (1u << 1) | (1u << 2) | (1u << 4) | (1u << 5);
|
cb.bleedMask = (1u << 1) | (1u << 2) | (1u << 4) | (1u << 5);
|
||||||
cb.resistBleedMask = (1u << 1);
|
cb.resistBleedMask = (1u << 1);
|
||||||
cb.windTime = windTime_;
|
cb.windTime = windTime_;
|
||||||
// Stylized lighting (Phase 7) — Wonderbox-inspired, iteration 4
|
// Stylized lighting (Phase 7) — Wonderbox-inspired
|
||||||
cb.skyAmbient = XMFLOAT4(0.65f, 0.68f, 0.75f, 0.0f); // very high ambient fill
|
cb.skyAmbient = XMFLOAT4(0.50f, 0.55f, 0.65f, 0.0f); // cool sky fill
|
||||||
cb.groundAmbient = XMFLOAT4(0.40f, 0.33f, 0.22f, 0.0f); // warm brown, high fill
|
cb.groundAmbient = XMFLOAT4(0.28f, 0.22f, 0.15f, 0.0f); // warm brown ground
|
||||||
cb.shadowTint = XMFLOAT4(0.55f, 0.45f, 0.72f, 0.0f); // purple-blue shadows
|
cb.shadowTint = XMFLOAT4(0.50f, 0.42f, 0.70f, 0.0f); // purple-blue shadows
|
||||||
cb.fogColor = XMFLOAT4(0.80f, 0.75f, 0.60f, 1.0f); // warm sandy-golden fog
|
cb.fogColor = XMFLOAT4(0.78f, 0.73f, 0.60f, 1.0f); // warm sandy fog
|
||||||
cb.fogParams = XMFLOAT4(0.004f, 0.0f, 0.0f, 0.0f); // fog density
|
cb.fogParams = XMFLOAT4(0.004f, 0.0f, 0.0f, 0.0f); // fog density
|
||||||
cb.rimColor = XMFLOAT4(0.90f, 0.80f, 0.55f, 0.0f); // warm golden rim
|
cb.rimColor = XMFLOAT4(0.90f, 0.80f, 0.55f, 0.0f); // warm golden rim
|
||||||
cb.rimParams = XMFLOAT4(2.5f, 0.45f, 0.0f, 0.0f); // exponent, intensity
|
cb.rimParams = XMFLOAT4(2.5f, 0.45f, 0.0f, 0.0f); // exponent, intensity
|
||||||
cb.toneMapParams = XMFLOAT4(1.40f, 2.2f, 0.0f, 0.0f); // vivid saturation, high exposure
|
cb.toneMapParams = XMFLOAT4(1.15f, 1.8f, 0.0f, 0.0f); // moderate saturation, good exposure
|
||||||
dev->UpdateBuffer(&constantBuffer_, &cb, cmd, sizeof(cb));
|
dev->UpdateBuffer(&constantBuffer_, &cb, cmd, sizeof(cb));
|
||||||
// Save current VP for next frame's temporal reprojection
|
// Save current VP for next frame's temporal reprojection
|
||||||
XMStoreFloat4x4(&prevViewProjection_, vpMatrix);
|
XMStoreFloat4x4(&prevViewProjection_, vpMatrix);
|
||||||
|
|
@ -2780,4 +2780,15 @@ void VoxelRenderPath::Compose(CommandList cmd) const {
|
||||||
wi::font::Draw(stats, fp, cmd);
|
wi::font::Draw(stats, fp, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelRenderPath::setCamera(float x, float y, float z, float pitch, float yaw) {
|
||||||
|
cameraPos = { x, y, z };
|
||||||
|
cameraPitch = pitch;
|
||||||
|
cameraYaw = yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelRenderPath::resetAOHistory() {
|
||||||
|
renderer.aoHistoryValid_ = false;
|
||||||
|
renderer.frameCounter_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace voxel
|
} // namespace voxel
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,8 @@ public:
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
bool debugSmooth = false;
|
bool debugSmooth = false;
|
||||||
bool screenshotMode = false; // CLI "screenshot": auto-position camera, capture, quit
|
bool screenshotMode = false; // CLI "screenshot": auto-position camera, capture, quit
|
||||||
|
void setCamera(float x, float y, float z, float pitch, float yaw);
|
||||||
|
void resetAOHistory(); // invalidate temporal AO after camera jump
|
||||||
|
|
||||||
float cameraSpeed = 50.0f;
|
float cameraSpeed = 50.0f;
|
||||||
float cameraSensitivity = 0.003f;
|
float cameraSensitivity = 0.003f;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue