Skip to content

perf: optimise ssgi normal#2189

Merged
alandtse merged 1 commit into
devfrom
ssgi-opt
Apr 23, 2026
Merged

perf: optimise ssgi normal#2189
alandtse merged 1 commit into
devfrom
ssgi-opt

Conversation

@doodlum
Copy link
Copy Markdown
Collaborator

@doodlum doodlum commented Apr 22, 2026

Summary by CodeRabbit

  • New Features
    • Introduced normal map prefiltering pipeline with multi-level MIP generation for Screen Space Global Illumination
    • Added dedicated normal texture resource to decouple normal data from normal-roughness texture in GI calculations
    • Expanded GI shader capabilities with improved normal sampling and reconstruction across multiple detail levels
    • Refined VR rendering paths with conditional depth-difference rejection and view/world remapping

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

The pull request implements a normal prefiltering pipeline for Screen Space GI by introducing a dedicated compute shader that generates MIP-level encoded normal maps from the deferred normal/roughness texture. The GI shader now samples from these prefiltered normals instead of deriving them inline, with VR-specific sampling logic conditionally gated.

Changes

Cohort / File(s) Summary
Normal Prefiltering Compute Shader
features/Screen Space GI/Shaders/ScreenSpaceGI/prefilterNormal.cs.hlsl
New compute shader that reconstructs packed normals from MIP 0 and iteratively generates five MIP levels through decode-average-encode cycles using shared memory and barrier synchronization. Outputs to separate UAV targets (u0–u4).
Screen Space GI Shader
features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl
Declares dedicated srcNormal texture (t9) for normal sampling. Moves cross-eye depth-difference rejection and view/world remapping inside VR-conditional blocks. Normal fetches for horizon tests now re-sample from srcNormal with dynamic MIP selection based on radiance level.
C++ Backend
src/Features/ScreenSpaceGI.h, src/Features/ScreenSpaceGI.cpp
Adds GPU resources (texNormal, uavNormal[5] array) and compute shader (prefilterNormalCompute). Integrates prefilter dispatch in rendering pipeline to generate normal MIP chain before GI compute, then binds prefiltered normals as SRV at slot 9.

Sequence Diagram(s)

sequenceDiagram
    participant CPU as CPU Setup
    participant PrefilterCS as Prefilter<br/>Compute Shader
    participant NormalTex as Normal<br/>MIP Textures
    participant GICS as GI<br/>Compute Shader
    
    CPU->>CPU: Create texNormal resource<br/>and UAV array
    CPU->>CPU: Compile prefilterNormalCompute
    Note over CPU: Rendering frame starts
    CPU->>PrefilterCS: Dispatch prefilter compute<br/>(srcNormalRoughness → input)
    PrefilterCS->>PrefilterCS: Decode normals from MIP 0<br/>2×2 neighborhoods
    PrefilterCS->>PrefilterCS: Iteratively filter to<br/>MIPs 1–4
    PrefilterCS->>NormalTex: Write encoded normals<br/>to UAV targets (u0–u4)
    CPU->>GICS: Dispatch GI compute<br/>with prefiltered normals
    GICS->>NormalTex: Sample srcNormal (t9)<br/>with dynamic MIP selection
    GICS->>GICS: Perform horizon tests<br/>and GI sampling
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • alandtse
  • davo0411

Poem

🐰 A prefilter's dream, in MIPs so neat,
Normal maps dancing, samples complete,
Five levels of blur, from coarse to fine,
GI's horizon now reads by design!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'perf: optimise ssgi normal' directly and concisely describes the main objective of the changeset—optimizing normal handling in Screen Space GI (SSGI) through a prefiltering approach.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ssgi-opt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown

No actionable suggestions for changed features.

@doodlum doodlum marked this pull request as ready for review April 22, 2026 22:12
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/Features/ScreenSpaceGI.cpp (1)

328-344: Nit: add texNormal to the debug Buffer Viewer.

The new prefiltered-normal mip chain is a prime candidate for visual inspection during tuning (e.g., verifying MIP encoding looks sane at mip 0 and doesn't degrade catastrophically at higher mips). Consider adding a BUFFER_VIEWER_NODE(texNormal, debugRescale) alongside the existing entries.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Features/ScreenSpaceGI.cpp` around lines 328 - 344, Add the
prefiltered-normal texture to the ImGui Buffer Viewer by inserting
BUFFER_VIEWER_NODE(texNormal, debugRescale) into the TreeNode block so texNormal
appears alongside the other debug entries; locate the ImGui::TreeNode("Buffer
Viewer") block that declares static float debugRescale and append
BUFFER_VIEWER_NODE(texNormal, debugRescale) with the other
BUFFER_VIEWER_NODE(...) calls to enable visual inspection of the normal mip
chain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/Features/ScreenSpaceGI.cpp`:
- Around line 328-344: Add the prefiltered-normal texture to the ImGui Buffer
Viewer by inserting BUFFER_VIEWER_NODE(texNormal, debugRescale) into the
TreeNode block so texNormal appears alongside the other debug entries; locate
the ImGui::TreeNode("Buffer Viewer") block that declares static float
debugRescale and append BUFFER_VIEWER_NODE(texNormal, debugRescale) with the
other BUFFER_VIEWER_NODE(...) calls to enable visual inspection of the normal
mip chain.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 863e315c-fac8-4187-8458-322b3678712d

📥 Commits

Reviewing files that changed from the base of the PR and between 9543ada and 3924588.

📒 Files selected for processing (4)
  • features/Screen Space GI/Shaders/ScreenSpaceGI/gi.cs.hlsl
  • features/Screen Space GI/Shaders/ScreenSpaceGI/prefilterNormal.cs.hlsl
  • src/Features/ScreenSpaceGI.cpp
  • src/Features/ScreenSpaceGI.h

@github-actions
Copy link
Copy Markdown

✅ A pre-release build is available for this PR:
Download

@alandtse
Copy link
Copy Markdown
Collaborator

I don't see any measurable improvement in perf, but ok.

@alandtse alandtse merged commit c1a9256 into dev Apr 23, 2026
22 checks passed
ParticleTroned added a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 2, 2026
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.

2 participants