Skip to content

chore(grass): improve sss#2183

Merged
alandtse merged 7 commits into
devfrom
feat/grass-skylighting-sss
May 2, 2026
Merged

chore(grass): improve sss#2183
alandtse merged 7 commits into
devfrom
feat/grass-skylighting-sss

Conversation

@doodlum
Copy link
Copy Markdown
Collaborator

@doodlum doodlum commented Apr 22, 2026

Summary by CodeRabbit

  • Improvements
    • Cleaner grass edge lighting and more consistent normals for better silhouette highlights.
    • Linearized vertex tinting for reduced banding and more accurate grass colors under lighting.
    • Refined subsurface scattering and diffuse blending for more natural, stable soft-lighting on grass.
    • More accurate per-light skylight and directional contribution handling for improved multi-light consistency.

Remap skylightingNormal z into [0,1] before cosine-lobe evaluation so
backlit grass retains ambient response. Divide out vertex AO from the
skylighting term (clamped to prevent blowup), producing a clean
min(skylighting, vertexAO) relationship.

Replace additive sss/subsurfaceColor split with a saturated albedo
lerp toward full-luma (dot(albedo, 1/3)) gated by VertexNormal.w.
Drop the manual normal.z clamp in complex grass since the
skylightingNormal remap handles it.

Requires the Skylighting::Sample API refactor.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

Removed conditional normal.z clamping/renormalization when Permutation::ExtraFlags::GrassSphereNormal is not set, linearized vertex color usage, and reworked non‑PBR grass subsurface initialization and per‑light accumulation in package/Shaders/RunGrass.hlsl. Non-grass PS path also drops the normal.z clamp and uses linearized vertex color.

Changes

Grass shader math

Layer / File(s) Summary
Normal handling
package/Shaders/RunGrass.hlsl
Removed the normal.z max-to-0 clamp + renormalize path in the GrassSphereNormal-disabled branch; retained only backface normal sign flip.
Vertex color linearization
package/Shaders/RunGrass.hlsl
Switched vertexColor to Color::ColorToLinear(input.VertexColor.xyz) for albedo, skylight/AO and diffuse usage in both grass and non-grass PS paths.
Albedo / subsurface init (non-PBR)
package/Shaders/RunGrass.hlsl
Albedo set to baseColor.xyz * vertexColor (no max(0,...)). subsurfaceColor is now initialized from directional light as dirLightColor * dirDetailedShadow * saturate(-dirLightAngle) * Color::VanillaNormalization().
Per-light accumulation
package/Shaders/RunGrass.hlsl
Clustered/point lights add lightColor * saturate(-lightAngle) * Color::VanillaNormalization() into subsurfaceColor (no separate sss accumulation).
Final diffuse/subsurface combine
package/Shaders/RunGrass.hlsl
Final subsurface contribution changed from max(0, sss * subsurfaceColor * ...) to subsurfaceColor * albedo * SubsurfaceScatteringAmount; diffuseColor *= albedo remains.
Non-grass PS minor cleanup
package/Shaders/RunGrass.hlsl
Removed extra normal.z clamp/renormalize in the non-grass pixel shader and linearized input.VertexColor for skylighting/AO and albedo use.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • SkrubbySkrubInAShrub
  • jiayev
  • davo0411

Poem

🐇
I nibble code beneath the dawn,
Normals straight, no clamps upon,
Colors linear, light flows mild,
Grass breathes softer, pixel‑wild,
A tiny hop—rendering's bright!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
Title check ✅ Passed The title 'chore(grass): improve sss' directly relates to the main changes in the pull request, which focus on improving subsurface scattering (sss) implementation in grass shaders through better lighting calculations and color linearization.

✏️ 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 feat/grass-skylighting-sss

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 and others added 2 commits April 22, 2026 12:50
Linearize input.VertexColor at the point of use so it composes
correctly with the already-linear baseColor. Both main()
functions treat vertexColor as linear from here on, which lets
the albedo expression drop the redundant outer saturate and
double linearization.

Re-express subsurface scattering as two clearer quantities:
subsurfaceColor accumulates the backlit light-direction terms,
and subsurfaceAlbedo bakes the VertexNormal.w weighting into
albedo so the final diffuse blend is a simple product. Rename
the old sss accumulator accordingly.

Drop the post-frontFace normal.z clamp in the !GrassSphereNormal
branch since the backface flip and later normalization already
produce a valid outward-facing normal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@doodlum doodlum changed the title feat(grass): sss/skylighting improvements feat(grass): sss improvements Apr 22, 2026
@doodlum doodlum changed the title feat(grass): sss improvements chore(grass): sss improvements Apr 22, 2026
@doodlum doodlum marked this pull request as ready for review April 22, 2026 15:20
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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@package/Shaders/RunGrass.hlsl`:
- Line 728: The point-light subsurface scattering accumulation (the
subsurfaceColor += lightColor * saturate(-lightAngle) statement) is missing the
Color::VanillaNormalization() factor and should be made consistent with the
directional SSS initializer; update that line to multiply by
Color::VanillaNormalization() so point-light SSS uses the same normalization as
the directional path (keep the diffuseColor += subsurfaceColor * albedo *
SubsurfaceScatteringAmount usage unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 33f33227-5ec9-46bd-b04a-201460f527da

📥 Commits

Reviewing files that changed from the base of the PR and between 025a91e and b76cec9.

📒 Files selected for processing (1)
  • package/Shaders/RunGrass.hlsl

Comment thread package/Shaders/RunGrass.hlsl Outdated
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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@package/Shaders/RunGrass.hlsl`:
- Around line 781-782: The subsurface scattering term is being multiplied by
albedo before the final albedo application, causing double-albedo attenuation;
in RunGrass.hlsl locate the diffuse accumulation where diffuseColor,
subsurfaceColor, albedo and
SharedData::grassLightingSettings.SubsurfaceScatteringAmount are used and remove
the pre-multiplication by albedo so the SSS contribution is added as
subsurfaceColor * SharedData::grassLightingSettings.SubsurfaceScatteringAmount
(letting the existing diffuseColor *= albedo line apply albedo once to the whole
diffuse result).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 26cb22e2-396a-4a9d-a3f3-0a3b6e011208

📥 Commits

Reviewing files that changed from the base of the PR and between b76cec9 and d424229.

📒 Files selected for processing (1)
  • package/Shaders/RunGrass.hlsl

Comment thread package/Shaders/RunGrass.hlsl
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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@package/Shaders/RunGrass.hlsl`:
- Line 644: The subsurfaceColor calculation uses an undefined variable
dirSoftShadow; replace dirSoftShadow with the existing dirDetailedShadow so the
expression becomes consistent with other shadow uses—update the subsurfaceColor
assignment (which references dirLightColor, dirLightAngle and
Color::VanillaNormalization()) to multiply by dirDetailedShadow instead of
dirSoftShadow in RunGrass.hlsl.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bbdc462d-0f4a-4944-b046-b919017e3869

📥 Commits

Reviewing files that changed from the base of the PR and between d424229 and d3d343a.

📒 Files selected for processing (1)
  • package/Shaders/RunGrass.hlsl

Comment thread package/Shaders/RunGrass.hlsl Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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.

♻️ Duplicate comments (1)
package/Shaders/RunGrass.hlsl (1)

750-751: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

SSS is still getting albedo-applied twice.

At Line 750, subsurfaceColor is pre-multiplied by albedo, then Line 751 multiplies the whole diffuseColor by albedo again. This over-attenuates backlighting.

Proposed fix
-	diffuseColor += subsurfaceColor * albedo * SharedData::grassLightingSettings.SubsurfaceScatteringAmount;
+	diffuseColor += subsurfaceColor * SharedData::grassLightingSettings.SubsurfaceScatteringAmount;
	diffuseColor *= albedo;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package/Shaders/RunGrass.hlsl` around lines 750 - 751, subsurface scattering
is being multiplied by albedo twice: adjust the SSS accumulation so albedo is
only applied once; specifically, in the block that updates diffuseColor (the
lines using subsurfaceColor, albedo, and
SharedData::grassLightingSettings.SubsurfaceScatteringAmount), remove the extra
multiplication by albedo on the subsurface term (i.e. compute the SSS
contribution as subsurfaceColor *
SharedData::grassLightingSettings.SubsurfaceScatteringAmount and then keep the
existing diffuseColor *= albedo), ensuring subsurfaceColor, albedo,
diffuseColor, and SharedData::grassLightingSettings.SubsurfaceScatteringAmount
are the referenced symbols.
🧹 Nitpick comments (2)
package/Shaders/RunGrass.hlsl (2)

469-952: Please run hlslkit validation for the touched grass PS permutations before merge.

Given the shader-math/control-flow updates, a targeted hlslkit compile/validation pass for relevant defines (GRASS_LIGHTING, TRUE_PBR, LIGHT_LIMIT_FIX, SKYLIGHTING, VR/non-VR) would reduce regression risk.

As per coding guidelines "**/*.hlsl: Use hlslkit for shader validation and compilation during targeted development testing and before deployment".

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

In `@package/Shaders/RunGrass.hlsl` around lines 469 - 952, PR requests hlslkit
validation for the modified grass pixel shader permutations; run targeted shader
compilation to catch regressions. Reproduce and validate all touched PS
permutations by running hlslkit (or your project's shader validation runner)
against the updated PS functions (main in RunGrass.hlsl) with the relevant
define combinations: TRUE_PBR on/off, LIGHT_LIMIT_FIX on/off (and LLFDEBUG),
SKYLIGHTING on/off, GRASS_LIGHTING tweaks, VR vs non-VR, and permutations that
affect backface handling (check Permutation::ExtraShaderDescriptor /
GrassSphereNormal) and Normal/TBN code paths (GrassLighting::TransformNormal,
GrassLighting::CalculateTBN); fix any compile errors or warnings, and ensure
runtime changes (specColor/specular paths, shadowColor usage,
Random::InterleavedGradientNoise, and stereo eyeIndex usage) behave correctly
before merging.

1-1: ⚡ Quick win

PR metadata suggestion: title type and issue linkage could be clearer.

Current title chore(grass): sss improvements is valid conventional format, but this looks behavior-affecting; consider fix(grass): correct sss lighting weighting (or feat(grass): refine sss lighting) and add an issue keyword if applicable (Fixes #... / Addresses #...).

As per coding guidelines "When reviewing PRs, please provide suggestions for: Conventional Commit Titles ... Issue References ...".

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

In `@package/Shaders/RunGrass.hlsl` at line 1, Update the PR metadata: change the
commit title from "chore(grass): sss improvements" to a behavior-reflecting type
such as "fix(grass): correct sss lighting weighting" (or "feat(grass): refine
sss lighting" if intentionally additive) and add an issue reference like "Fixes
#<issue-number>" or "Addresses #<issue-number>" if one exists; mention the
affected shader (RunGrass.hlsl / the SSS lighting changes) in the PR description
so reviewers understand the scope.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@package/Shaders/RunGrass.hlsl`:
- Around line 750-751: subsurface scattering is being multiplied by albedo
twice: adjust the SSS accumulation so albedo is only applied once; specifically,
in the block that updates diffuseColor (the lines using subsurfaceColor, albedo,
and SharedData::grassLightingSettings.SubsurfaceScatteringAmount), remove the
extra multiplication by albedo on the subsurface term (i.e. compute the SSS
contribution as subsurfaceColor *
SharedData::grassLightingSettings.SubsurfaceScatteringAmount and then keep the
existing diffuseColor *= albedo), ensuring subsurfaceColor, albedo,
diffuseColor, and SharedData::grassLightingSettings.SubsurfaceScatteringAmount
are the referenced symbols.

---

Nitpick comments:
In `@package/Shaders/RunGrass.hlsl`:
- Around line 469-952: PR requests hlslkit validation for the modified grass
pixel shader permutations; run targeted shader compilation to catch regressions.
Reproduce and validate all touched PS permutations by running hlslkit (or your
project's shader validation runner) against the updated PS functions (main in
RunGrass.hlsl) with the relevant define combinations: TRUE_PBR on/off,
LIGHT_LIMIT_FIX on/off (and LLFDEBUG), SKYLIGHTING on/off, GRASS_LIGHTING
tweaks, VR vs non-VR, and permutations that affect backface handling (check
Permutation::ExtraShaderDescriptor / GrassSphereNormal) and Normal/TBN code
paths (GrassLighting::TransformNormal, GrassLighting::CalculateTBN); fix any
compile errors or warnings, and ensure runtime changes (specColor/specular
paths, shadowColor usage, Random::InterleavedGradientNoise, and stereo eyeIndex
usage) behave correctly before merging.
- Line 1: Update the PR metadata: change the commit title from "chore(grass):
sss improvements" to a behavior-reflecting type such as "fix(grass): correct sss
lighting weighting" (or "feat(grass): refine sss lighting" if intentionally
additive) and add an issue reference like "Fixes #<issue-number>" or "Addresses
#<issue-number>" if one exists; mention the affected shader (RunGrass.hlsl / the
SSS lighting changes) in the PR description so reviewers understand the scope.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 063f360f-04a1-4fc3-b0bb-3b2af647c7a5

📥 Commits

Reviewing files that changed from the base of the PR and between d3d343a and ed6edaa.

📒 Files selected for processing (1)
  • package/Shaders/RunGrass.hlsl

@alandtse alandtse changed the title chore(grass): sss improvements chore(grass): improve sss May 2, 2026
@alandtse alandtse merged commit 5d23cea into dev May 2, 2026
16 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 9, 2026
ParticleTroned added a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 15, 2026
Adapted from PR community-shaders#2183 and the newer dev grass color, skylighting, and SSS model while preserving this branch's existing water, terrain/cloud shadow, and no-height-fog paths.
ParticleTroned added a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 15, 2026
Adapted from PR community-shaders#2183 and the newer dev grass color, skylighting, and SSS model while preserving this branch's existing water, terrain/cloud shadow, and no-height-fog paths.
ParticleTroned added a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 16, 2026
Adapted from PR community-shaders#2183 and the newer dev grass color, skylighting, and SSS model while preserving this branch's existing water, terrain/cloud shadow, and no-height-fog paths.
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