Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,9 @@ namespace TerrainShadows

float GetTerrainShadow(const float3 worldPos, SamplerState samp)
{
if (SharedData::terraOccSettings.EnableTerrainShadow) {
float2 terraOccUV = GetTerrainShadowUV(worldPos.xy);
float2 shadowHeight = GetTerrainZ(ShadowHeightTexture.SampleLevel(samp, terraOccUV, 0));
#if defined(DEFERRED)
// Sharp shadows
float shadowFraction = saturate(10.0 * (worldPos.z - shadowHeight.y) / (shadowHeight.x - shadowHeight.y));
#else
// Blurry shadows to simulate scattering
float shadowFraction = saturate((worldPos.z - shadowHeight.y) / (shadowHeight.x - shadowHeight.y));
#endif
return shadowFraction;
}

return 1.0;
if (!SharedData::terraOccSettings.EnableTerrainShadow)
return 1.0;
float2 shadowHeight = GetTerrainZ(ShadowHeightTexture.SampleLevel(samp, GetTerrainShadowUV(worldPos.xy), 0));
return saturate((worldPos.z - shadowHeight.y) / (shadowHeight.x - shadowHeight.y));;
Comment on lines +22 to +25

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "*.hlsli" -o -name "*.hlsl" | head -20

Repository: doodlum/skyrim-community-shaders

Length of output: 1417


🏁 Script executed:

find . -type f -path "*TerrainShadows*" | head -20

Repository: doodlum/skyrim-community-shaders

Length of output: 346


🏁 Script executed:

find . -type f -name "*.hlsli" | xargs rg "GetTerrainZ" -A 5 -B 2

Repository: doodlum/skyrim-community-shaders

Length of output: 3742


🏁 Script executed:

cat "./features/Terrain Shadows/Shaders/TerrainShadows/TerrainShadows.hlsli"

Repository: doodlum/skyrim-community-shaders

Length of output: 896


🏁 Script executed:

rg "GetTerrainZ" -A 10 -B 2

Repository: doodlum/skyrim-community-shaders

Length of output: 2057


🏁 Script executed:

rg "ZRange" -A 2 -B 2

Repository: doodlum/skyrim-community-shaders

Length of output: 4817


🏁 Script executed:

rg "terraOccSettings" -l

Repository: doodlum/skyrim-community-shaders

Length of output: 184


🏁 Script executed:

cat "src/Features/TerrainShadows.cpp" | head -100

Repository: doodlum/skyrim-community-shaders

Length of output: 3188


🏁 Script executed:

cat "src/Features/TerrainShadows.h"

Repository: doodlum/skyrim-community-shaders

Length of output: 3178


🏁 Script executed:

rg "max.*1e-5|max.*1e-6|max.*epsilon" -t hlsl -t hlsli

Repository: doodlum/skyrim-community-shaders

Length of output: 104


🏁 Script executed:

rg "shadowHeight|ZRange.y - ZRange.x" -A 3 -B 1

Repository: doodlum/skyrim-community-shaders

Length of output: 3406


🏁 Script executed:

cat "features/Terrain Shadows/Shaders/TerrainShadows/ShadowUpdate.cs.hlsl" | grep -A 5 -B 5 "ZRange.y - ZRange.x"

Repository: doodlum/skyrim-community-shaders

Length of output: 545


🏁 Script executed:

rg "divide.*zero|guard.*division|epsilon.*1e-" -i

Repository: doodlum/skyrim-community-shaders

Length of output: 1260


🏁 Script executed:

grep -r "Math.hlsli\|EPSILON_DIVISION" "features/Terrain Shadows/Shaders/TerrainShadows/"

Repository: doodlum/skyrim-community-shaders

Length of output: 58


🏁 Script executed:

cat "package/Shaders/Common/Math.hlsli" | grep -A 2 "EPSILON"

Repository: doodlum/skyrim-community-shaders

Length of output: 304


Guard against a zero terrain shadow range.

If shadowHeight.x == shadowHeight.y, the division yields NaN and saturate won't recover. Add an epsilon guard to prevent division by zero.

🛡️ Suggested guard
-    float2 shadowHeight = GetTerrainZ(ShadowHeightTexture.SampleLevel(samp, GetTerrainShadowUV(worldPos.xy), 0));
-    return saturate((worldPos.z - shadowHeight.y) / (shadowHeight.x - shadowHeight.y));;
+    float2 shadowHeight = GetTerrainZ(ShadowHeightTexture.SampleLevel(samp, GetTerrainShadowUV(worldPos.xy), 0));
+    float denom = max(shadowHeight.x - shadowHeight.y, 1e-5);
+    return saturate((worldPos.z - shadowHeight.y) / denom);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!SharedData::terraOccSettings.EnableTerrainShadow)
return 1.0;
float2 shadowHeight = GetTerrainZ(ShadowHeightTexture.SampleLevel(samp, GetTerrainShadowUV(worldPos.xy), 0));
return saturate((worldPos.z - shadowHeight.y) / (shadowHeight.x - shadowHeight.y));;
if (!SharedData::terraOccSettings.EnableTerrainShadow)
return 1.0;
float2 shadowHeight = GetTerrainZ(ShadowHeightTexture.SampleLevel(samp, GetTerrainShadowUV(worldPos.xy), 0));
float denom = max(shadowHeight.x - shadowHeight.y, 1e-5);
return saturate((worldPos.z - shadowHeight.y) / denom);
🤖 Prompt for AI Agents
In `@features/Terrain` Shadows/Shaders/TerrainShadows/TerrainShadows.hlsli around
lines 22 - 25, The code can divide by zero when shadowHeight.x equals
shadowHeight.y; in the terrain shadow computation (look for
SharedData::terraOccSettings.EnableTerrainShadow, GetTerrainZ,
ShadowHeightTexture.SampleLevel, GetTerrainShadowUV, and the final saturate call
using worldPos.z), add a small epsilon guard: compute the range as
(shadowHeight.x - shadowHeight.y), replace the division with worldPos.z minus
shadowHeight.y divided by max(range, epsilon) (or early-return a safe value like
1.0 when range is zero) so the saturate call never receives NaN.

}
}