Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions features/Upscaling/Shaders/Upscaling/UnderwaterMaskUpscalePS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ PS_OUTPUT main(PS_INPUT input)
// itself, which always maps to the center tile (12).
float waterHeight = SharedData::GetWaterData(float3(0, 0, 0), eyeIndex).w;

// Tile sentinel: try TESWaterSystem fallback. WaterSystemHeight is valid only when
// playerUnderwater == true (fully submerged); it is stored eye-0 camera-relative so
// the same per-eye correction as GetWaterData applies.
if (waterHeight <= WATER_HEIGHT_NO_TILE_SENTINEL) {
float sysHeight = SharedData::WaterSystemHeight;
if (sysHeight > WATER_HEIGHT_NO_TILE_SENTINEL)
waterHeight = sysHeight + FrameBuffer::CameraPosAdjust[0].z - FrameBuffer::CameraPosAdjust[eyeIndex].z;
}

// GetWaterData returns INT_MIN (~-2.147e9) when the tile is outside the 5x5 grid.
if (waterHeight > WATER_HEIGHT_NO_TILE_SENTINEL) {
// Unpack from side-by-side stereo layout to per-eye UV [0, 1]
Expand Down Expand Up @@ -112,9 +121,10 @@ PS_OUTPUT main(PS_INPUT input)
}
return psout;
}
// No water tile in range: fall through to the standard sampler path.
// No water tile or system height available: fall through to the standard sampler path.
// The left-eye result from the vanilla mask is still accurate here; the right-eye
// will be approximate, but in the absence of nearby water the visual impact is nil.
// will be approximate, but both sources failing implies no nearby water so the
// visual impact is nil.
# endif

// Upscale using linear sampling with jitter-corrected coordinates
Expand Down
10 changes: 5 additions & 5 deletions package/Shaders/Common/SharedData.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ namespace SharedData
float Timer;
uint FrameCount;
uint FrameCountAlwaysActive;
bool InInterior; // If the area lacks a directional shadow light e.g. the sun or moon
bool InMapMenu; // If the world/local map is open (note that the renderer is still deferred here)
bool HideSky; // HideSky flag in WorldSpace, e.g. Blackreach
float MipBias; // Offset to mip level for TAA sharpness
float pad0;
bool InInterior; // If the area lacks a directional shadow light e.g. the sun or moon
bool InMapMenu; // If the world/local map is open (note that the renderer is still deferred here)
bool HideSky; // HideSky flag in WorldSpace, e.g. Blackreach
float MipBias; // Offset to mip level for TAA sharpness
float WaterSystemHeight; // TES::GetWaterHeight at eye-0 in camera-relative Z; -FLT_MAX when no water body found (VR only)
float4 AmbientSHR;
float4 AmbientSHG;
float4 AmbientSHB;
Expand Down
18 changes: 18 additions & 0 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,24 @@ void State::UpdateSharedData([[maybe_unused]] bool a_inWorld, [[maybe_unused]] b
}
}

// Fallback water height for the VR analytical mask when tile 12 returns the sentinel.
// Uses player->GetWaterHeight() (reads relevantWaterHeight from LOADED_REF_DATA) gated by
// underwaterCount > 0 so it is only set when the player is actually in a water body.
// Covers both interior water (where TES::GetWaterHeight returns -NI_INFINITY) and exterior
// partial submersion. Stored as eye-0 camera-relative Z to match WaterData[].w.
data.WaterSystemHeight = -RE::NI_INFINITY;
if (globals::game::isVR) {
if (auto player = globals::game::player) {
if (player->loadedData && player->loadedData->underwaterCount > 0) {
float worldHeight = player->GetWaterHeight();
if (worldHeight > -RE::NI_INFINITY) {
auto eye0Pos = Util::GetEyePosition(0);
data.WaterSystemHeight = worldHeight - eye0Pos.z;
}
}
}
}

Comment thread
alandtse marked this conversation as resolved.
data.InInterior = Util::IsInterior();

if (globals::game::sky)
Expand Down
2 changes: 1 addition & 1 deletion src/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ class State
uint InMapMenu;
uint HideSky;
float MipBias;
float pad0; // unused; must match SharedData.hlsli cbuffer (AmbientSHR 16-byte alignment)
float WaterSystemHeight; // TES::GetWaterHeight at eye-0 in camera-relative Z; -NI_INFINITY when no water body found (VR only)
float4 AmbientSHR;
float4 AmbientSHG;
float4 AmbientSHB;
Expand Down
4 changes: 3 additions & 1 deletion src/Utils/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ namespace Util
data.z *= color.blue;
}

data.w = cell->GetExteriorWaterHeight() - position.z;
float cellWaterHeight;
if (cell->GetWaterHeight(position, cellWaterHeight))
data.w = cellWaterHeight - position.z;

return data;
}
Expand Down
Loading