mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 00:20:16 +00:00
Add water refraction toggle with per-frame scene history
Fix VK_ERROR_DEVICE_LOST crash by allocating per-frame scene history images (color + depth) instead of a single shared image that raced between frames in flight. Water refraction can now be toggled via Settings > Video > Water Refraction. Without refraction: richer blue base colors, animated caustic shimmer, and normal-based color shifts give the water visible life. With refraction: clean screen-space refraction with Beer-Lambert absorption. Disabling clears scene history to black for immediate fallback.
This commit is contained in:
parent
7630c7aec7
commit
5a227c0376
8 changed files with 323 additions and 191 deletions
|
|
@ -855,6 +855,14 @@ void Renderer::unregisterPreview(CharacterPreview* preview) {
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer::setWaterRefractionEnabled(bool enabled) {
|
||||
if (waterRenderer) waterRenderer->setRefractionEnabled(enabled);
|
||||
}
|
||||
|
||||
bool Renderer::isWaterRefractionEnabled() const {
|
||||
return waterRenderer && waterRenderer->isRefractionEnabled();
|
||||
}
|
||||
|
||||
void Renderer::setMsaaSamples(VkSampleCountFlagBits samples) {
|
||||
if (!vkCtx) return;
|
||||
|
||||
|
|
@ -1054,20 +1062,27 @@ void Renderer::endFrame() {
|
|||
|
||||
vkCmdEndRenderPass(currentCmd);
|
||||
|
||||
// Scene-history capture is disabled: with MAX_FRAMES_IN_FLIGHT=2, the single
|
||||
// sceneColorImage can race between frame N-1's water shader read and frame N's
|
||||
// transfer write, eventually causing VK_ERROR_DEVICE_LOST. Water renders
|
||||
// without refraction until per-frame scene-history images are implemented.
|
||||
// TODO: allocate per-frame sceneColor/Depth images to fix the race.
|
||||
uint32_t frame = vkCtx->getCurrentFrame();
|
||||
|
||||
// Render water in separate 1x pass (without scene refraction for now)
|
||||
// Capture scene color/depth into per-frame history images for water refraction
|
||||
if (waterRenderer && waterRenderer->isRefractionEnabled() && waterRenderer->hasSurfaces()
|
||||
&& currentImageIndex < vkCtx->getSwapchainImages().size()) {
|
||||
waterRenderer->captureSceneHistory(
|
||||
currentCmd,
|
||||
vkCtx->getSwapchainImages()[currentImageIndex],
|
||||
vkCtx->getDepthCopySourceImage(),
|
||||
vkCtx->getSwapchainExtent(),
|
||||
vkCtx->isDepthCopySourceMsaa(),
|
||||
frame);
|
||||
}
|
||||
|
||||
// Render water in separate 1x pass after MSAA resolve + scene capture
|
||||
bool waterDeferred = waterRenderer && waterRenderer->hasSurfaces() && waterRenderer->hasWater1xPass()
|
||||
&& vkCtx->getMsaaSamples() != VK_SAMPLE_COUNT_1_BIT;
|
||||
if (waterDeferred && camera) {
|
||||
VkExtent2D ext = vkCtx->getSwapchainExtent();
|
||||
uint32_t frame = vkCtx->getCurrentFrame();
|
||||
if (waterRenderer->beginWater1xPass(currentCmd, currentImageIndex, ext)) {
|
||||
waterRenderer->render(currentCmd, perFrameDescSets[frame], *camera, globalTime, true);
|
||||
waterRenderer->render(currentCmd, perFrameDescSets[frame], *camera, globalTime, true, frame);
|
||||
waterRenderer->endWater1xPass(currentCmd);
|
||||
}
|
||||
}
|
||||
|
|
@ -3268,7 +3283,7 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
|||
bool waterDeferred = waterRenderer && waterRenderer->hasWater1xPass()
|
||||
&& vkCtx->getMsaaSamples() != VK_SAMPLE_COUNT_1_BIT;
|
||||
if (waterRenderer && camera && !waterDeferred) {
|
||||
waterRenderer->render(currentCmd, perFrameSet, *camera, globalTime);
|
||||
waterRenderer->render(currentCmd, perFrameSet, *camera, globalTime, false, vkCtx->getCurrentFrame());
|
||||
}
|
||||
|
||||
// Weather particles
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue