Skip to content

fix(wetness): reflection angle; clamp puddle roughness#2246

Merged
doodlum merged 1 commit into
devfrom
copilot/fix-wetness-effect-issue
May 5, 2026
Merged

fix(wetness): reflection angle; clamp puddle roughness#2246
doodlum merged 1 commit into
devfrom
copilot/fix-wetness-effect-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 30, 2026

Puddles were hard to see from non-sun-facing angles even with Dynamic Cubemaps enabled.

Root Cause

Two issues in Lighting.hlsl:

1. Deferred GBuffer normal was lerped, not assigned directly. The deferred composite does a single cubemap lookup using whatever normal is in the GBuffer. Lerping screenSpaceNormal toward wetnessNormal by wetnessGlossinessSpecular produces a direction wrong for both contributions — the material's specular (wants the surface normal) and the water film reflection (wants the flat puddle normal). Since wetnessReflectance from GetWetnessIndirectLobeWeights already scales intensity by wetness amount, lerping the direction was double-counting the fade.

2. waterRoughnessSpecular could reach 0 for fully-wet puddles, creating a near-singular GGX retroreflection peak roughly 30–40× stronger when facing the sun than from any other angle. The ripple normal map adds micro-variation but the GGX distribution still peaks sharply at roughness=0.

Fix

Use wetnessNormal directly for the GBuffer normal and waterRoughnessSpecular directly for roughness when wetness is present. Water film reflects from its own surface — wetnessReflectance already encodes how much. Puddles only form on flat surfaces (gated by vertexNormal.z), so the material's residual specular in the combined reflectance sees negligible directional error.

Clamp waterRoughnessSpecular to a named constant wetnessMinPuddleRoughness = 0.05. Real rain water is kept rough by continuous ripple disturbance; 0.05 preserves a visually glossy appearance while distributing the specular lobe across a wider solid angle.

// Before
screenSpaceNormal = lerp(screenSpaceNormal, normalize(WorldToView(wetnessNormal)), wetnessGlossinessSpecular);
material.Roughness = lerp(material.Roughness, waterRoughnessSpecular, wetnessGlossinessSpecular);

waterRoughnessSpecular = saturate(1.0 - wetnessGlossinessSpecular);

// After
// Reflection is from the water film surface; wetnessReflectance scales intensity by wetness amount.
screenSpaceNormal = normalize(WorldToView(wetnessNormal));
material.Roughness = waterRoughnessSpecular;

static const float wetnessMinPuddleRoughness = 0.05;
waterRoughnessSpecular = max(saturate(1.0 - wetnessGlossinessSpecular), wetnessMinPuddleRoughness);

Summary by CodeRabbit

  • Bug Fixes
    • Prevented wet puddles from producing unrealistically shiny highlights by enforcing a minimum roughness, yielding more consistent specular behavior.
    • Improved wetness rendering so puddle normals and surface roughness are applied consistently, resulting in more realistic and stable wet-surface visuals.

Copilot AI linked an issue Apr 30, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Fix wetness effect puddle intensity variance based on orientation fix(wetness): puddle intensity no longer varies with horizontal viewing direction Apr 30, 2026
Copilot AI requested a review from alandtse April 30, 2026 09:13
Comment thread package/Shaders/Common/LightingEval.hlsli Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

No actionable suggestions for changed features.

Copilot AI requested a review from alandtse May 1, 2026 00:20
@alandtse alandtse force-pushed the copilot/fix-wetness-effect-issue branch from 446261f to 98f83a8 Compare May 1, 2026 06:49
@alandtse alandtse changed the title fix(wetness): puddle intensity no longer varies with horizontal viewing direction fix(wetness): correct deferred cubemap reflection and clamp puddle roughness May 1, 2026
@alandtse alandtse changed the title fix(wetness): correct deferred cubemap reflection and clamp puddle roughness fix(wetness): correct reflection; clamp puddle roughness May 1, 2026
@alandtse alandtse changed the title fix(wetness): correct reflection; clamp puddle roughness fix(wetness): reflection angle; clamp puddle roughness May 1, 2026
@alandtse alandtse marked this pull request as ready for review May 1, 2026 06:53
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 94f71356-d838-4918-91d9-709c55f290a1

📥 Commits

Reviewing files that changed from the base of the PR and between 98f83a8 and 6830e65.

📒 Files selected for processing (1)
  • package/Shaders/Lighting.hlsl
🚧 Files skipped from review as they are similar to previous changes (1)
  • package/Shaders/Lighting.hlsl

📝 Walkthrough

Walkthrough

Introduces a minimum puddle roughness constant (0.05) and clamps computed water specular roughness to that minimum; in the wetness branch the shader now overwrites the screen-space normal from the wetness normal and directly sets material.Roughness to the clamped value instead of blending.

Changes

Wetness Puddle Specularity

Layer / File(s) Summary
Constant / Data
package/Shaders/Lighting.hlsl
Adds wetnessMinPuddleRoughness = 0.05 and clamps waterRoughnessSpecular = max(saturate(1.0 - wetnessGlossinessSpecular), wetnessMinPuddleRoughness).
Core Wetness Logic
package/Shaders/Lighting.hlsl
When waterRoughnessSpecular < 1, stop blending; set screenSpaceNormal = normalize(WorldToView(wetnessNormal...)) and material.Roughness = waterRoughnessSpecular directly (replaces previous lerp behavior).
Tests / Docs
none changed
No test or documentation files modified in this diff.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • jiayev
  • davo0411
  • doodlum

Poem

🐰 A puddle once gleamed far too bright,
I nudged its shine down to polite,
With a tiny roughness floor,
The gloss won't dazzle anymore,
Now reflections hop into sight. 🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes both main fixes in the changeset: correcting the reflection angle (screenSpaceNormal assignment) and clamping puddle roughness to a minimum of 0.05.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/fix-wetness-effect-issue

Review rate limit: 5/10 reviews remaining, refill in 25 minutes and 23 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

In the deferred path, the GBuffer normal was lerped between the surface
normal and wetnessNormal by wetnessGlossinessSpecular. The deferred
composite does one cubemap lookup using that normal, so the lerped
direction is wrong for both the material's specular and the water film
reflection. Since wetnessReflectance already scales intensity by wetness
amount, the reflection direction should always be wetnessNormal.
Puddles only form on flat surfaces (gated by vertexNormal.z), so the
material's residual specular in the combined reflectance sees negligible
directional error.

Also clamp waterRoughnessSpecular to wetnessMinPuddleRoughness (0.05).
Without a floor, max-wet puddles reach roughness=0, creating a GGX
retroreflection peak roughly 30-40x stronger when facing the sun than
from other angles. Real rain water is kept rough by continuous ripple
disturbance; 0.05 preserves a visually glossy appearance while
distributing the specular lobe across a wider solid angle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alandtse alandtse force-pushed the copilot/fix-wetness-effect-issue branch from 98f83a8 to 6830e65 Compare May 3, 2026 09:41
@doodlum doodlum merged commit c584a2c into dev May 5, 2026
14 checks passed
SkrubbySkrubInAShrub pushed a commit that referenced this pull request May 14, 2026
Co-authored-by: Alan Tse <alandtse@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
ParticleTroned pushed a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 15, 2026
…ders#2246)

Co-authored-by: Alan Tse <alandtse@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
ParticleTroned pushed a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 16, 2026
…ders#2246)

Co-authored-by: Alan Tse <alandtse@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wetness Effect puddle effects intensity vary based on orientation

5 participants