-
Notifications
You must be signed in to change notification settings - Fork 89
feat: linear lighting #1359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
feat: linear lighting #1359
Changes from 122 commits
0148389
b91ead8
b5a6fea
7f305f5
ebd04c8
f7295cc
45d8b5f
c60e7bf
4d520e5
e5da64e
e4c4c1d
208411a
3fce82b
c3d39ad
432c87f
b8cb29f
d359396
7eae436
979d7fc
3b53269
5114ce7
00fffa3
ec4c68b
9d6815d
f21266d
74a1c46
63b7ded
a3ced52
c30aaa5
1599704
fc01e60
d811e96
a1a3f82
b5fd6d1
e6b3cc7
9f54e09
3ede393
314aaf3
28bd4a6
d4d4dfa
579a11e
fdfcb4b
0e96ff7
ddb55e3
7dbe301
e3416be
7475d63
a8c639f
52f6652
3ffd38c
0988b84
5d96ccc
5df25a9
5b1c8a9
c652501
227d0e2
18dffad
7bf4524
0fd42f9
8b698fd
fc936f5
43e5d4b
4a753fe
9505178
fe8c617
4ad8320
d5b61c4
d1a9740
c1497ee
d9f136f
7fa6387
7e1bd58
f322c32
299136c
807e409
a49fb96
98b4e65
c62a82a
b0457f4
f70c8bc
fef77d1
8f58636
1216d15
efa78d9
aac2653
a03955a
4296e85
046d2b8
3aa9555
7e6fc9f
8cc0265
9ede370
d144657
055fdb2
50c5f93
e85e804
0e85989
d287991
7e8e762
56f5eea
b2c257c
e0c2277
dd44727
7121e9b
b0a3389
7cfd09f
cf2708c
d035c62
e22eef2
e8b5dad
595bcf8
0df2b7f
a6ae417
9e3a32e
05a8e87
f3c5330
02f48d8
c653e86
89f8529
5bd7fb5
412c7ba
da9dff7
4048045
16a0bab
479d168
35af3fa
35cbd8d
4b1e6b0
91ef169
fb1ad25
3a3fb73
a28cc84
a1e9d3c
b1492b1
5c09511
d884740
779d001
8568c29
6059727
251f745
25f57f9
bbd30ad
be553de
c9f8a74
959183a
61f81f4
ca5846f
ebac71b
1c79373
299a884
6c7fc3a
0171f74
a98f47e
44b70c0
48f3fb0
b3ff8ea
20c0ffa
835e9ed
ab1beab
6b013ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| #include "Common/Color.hlsli" | ||
| #include "Common/SharedData.hlsli" | ||
|
|
||
| TextureCube<float4> EnvCaptureTexture : register(t0); | ||
| TextureCube<float4> ReflectionsTexture : register(t1); | ||
|
|
@@ -90,11 +91,11 @@ float3 GetSamplingVector(uint3 ThreadID, in RWTexture2DArray<float4> OutputTextu | |
| } | ||
|
|
||
| #if defined(REFLECTIONS) | ||
| color.rgb = lerp(color.rgb, Color::GammaToLinear(ReflectionsTexture.SampleLevel(LinearSampler, uv, 0.0).rgb), saturate(mipLevel / 7.0)); | ||
| color.rgb = lerp(color.rgb, Color::IrradianceToLinear(ReflectionsTexture.SampleLevel(LinearSampler, uv, 0.0).rgb), saturate(mipLevel / 7.0)); | ||
| #else | ||
| color.rgb = lerp(color.rgb, color.rgb * DefaultCubemap.SampleLevel(LinearSampler, uv, 0.0).xyz, saturate(mipLevel / 7.0)); | ||
| #endif | ||
|
|
||
| color.rgb = Color::LinearToGamma(color.rgb); | ||
| color.rgb = Color::IrradianceToGamma(color.rgb); | ||
| EnvInferredTexture[ThreadID] = max(0, color); | ||
| } | ||
|
Comment on lines
93
to
101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Accumulate in linear space; decode all samples before blending. Currently, EnvCaptureTexture samples are accumulated in their encoded space, and only the REFLECTIONS blend sample is decoded. To preserve energy correctness under linear lighting, decode all sampled colors to linear before accumulation and encode once at the end. Minimal change within this hunk: ensure default cubemap sample is decoded before use. -#else
- color.rgb = lerp(color.rgb, color.rgb * DefaultCubemap.SampleLevel(LinearSampler, uv, 0.0).xyz, saturate(mipLevel / 7.0));
-#endif
+#else
+ const float3 defaultCubemap = Color::IrradianceToLinear(DefaultCubemap.SampleLevel(LinearSampler, uv, 0.0).xyz);
+ color.rgb = lerp(color.rgb, color.rgb * defaultCubemap, saturate(mipLevel / 7.0));
+#endifAdditionally, apply these changes outside the selected range to fully linearize accumulation (illustrative snippet): // After line 53:
float4 color = EnvCaptureTexture.SampleLevel(LinearSampler, uv, 0);
color.rgb = Color::IrradianceToLinear(color.rgb);
// In the loop when sampling tempColor:
tempColor = EnvCaptureTexture.SampleLevel(LinearSampler, uv, mipLevel);
tempColor.rgb = Color::IrradianceToLinear(tempColor.rgb);
// For the 6 face fallback:
tempColor += EnvCaptureTexture.SampleLevel(LinearSampler, float3(-1.0, 0.0, 0.0), 9);
tempColor.rgb = Color::IrradianceToLinear(tempColor.rgb);
// ...repeat for each sample, converting .rgb only
// Encode once at the end (your existing line 99 already does this):
color.rgb = Color::IrradianceToGamma(color.rgb);🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| [Info] | ||
| Version = 1-0-0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -142,7 +142,7 @@ void readHistory( | |
|
|
||
| half3 radiance = 0; | ||
| #ifdef GI | ||
| radiance = Color::GammaToLinear(FULLRES_LOAD(srcDiffuse, pixCoord, uv * frameScale, samplerLinearClamp).rgb * GIStrength); | ||
| radiance = Color::RadianceToLinear(FULLRES_LOAD(srcDiffuse, pixCoord, uv * frameScale, samplerLinearClamp).rgb * GIStrength); | ||
| # ifdef GI_BOUNCE | ||
|
||
| radiance += prev_ambient.rgb * GIBounceFade; | ||
| # endif | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,7 @@ cbuffer PerFrameSSS : register(b1) | |
| bool humanProfile = MaskTexture[DTid.xy].y > 0.0; | ||
|
|
||
| float4 color = SSSSBlurCS(DTid.xy, texCoord, float2(0.0, 1.0), sssAmount, humanProfile); | ||
| color.rgb = Color::LinearToGamma(color.rgb); | ||
| color.rgb = Color::IrradianceToGamma(color.rgb); | ||
| SSSRW[DTid.xy] = float4(color.rgb, 1.0); | ||
| } | ||
|
Comment on lines
+66
to
68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainClamp before gamma encode; verify final-space expectation for SSS output.
Proposed fix: - color.rgb = Color::IrradianceToGamma(color.rgb);
+ // Avoid gamma on negatives; mirrors HORIZONTAL clamping behavior
+ color.rgb = Color::IrradianceToGamma(max(0, color.rgb));To verify usage and avoid double-encoding, search SSS outputs/consumers: 🏁 Script executed: #!/bin/bash
rg -n -A2 -B2 $'SSSRW\\s*\\['
rg -n -A4 -B2 'SeparableSSS' features packageLength of output: 2035 Clamp before gamma conversion in vertical SSS pass
Proposed diff in features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSSCS.hlsl: - color.rgb = Color::IrradianceToGamma(color.rgb);
+ // Mirror horizontal clamp: avoid gamma on negative samples
+ color.rgb = Color::IrradianceToGamma(max(0, color.rgb));🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -62,22 +62,29 @@ void SampleSSGI(uint2 pixCoord, float3 normalWS, out float ao, out float3 il) | |||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| #if defined(IBL) | ||||||||||||||||||||||||||||||||||||||||
| if (SharedData::iblSettings.EnableDiffuseIBL) { | ||||||||||||||||||||||||||||||||||||||||
| directionalAmbientColor *= SharedData::iblSettings.DALCAmount; | ||||||||||||||||||||||||||||||||||||||||
| directionalAmbientColor = SharedData::iblSettings.DALCAmount * Color::Ambient(directionalAmbientColor); | ||||||||||||||||||||||||||||||||||||||||
| directionalAmbientColor += Color::Saturation(ImageBasedLighting::GetDiffuseIBL(-normalWS), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| float3 linAlbedo = Color::GammaToLinear(albedo); | ||||||||||||||||||||||||||||||||||||||||
| float3 linDirectionalAmbientColor = Color::GammaToLinear(directionalAmbientColor); | ||||||||||||||||||||||||||||||||||||||||
| float3 linAlbedo = albedo; | ||||||||||||||||||||||||||||||||||||||||
| float3 linDirectionalAmbientColor = directionalAmbientColor; | ||||||||||||||||||||||||||||||||||||||||
| float3 linDiffuseColor = diffuseColor; | ||||||||||||||||||||||||||||||||||||||||
| if (!SharedData::linearLightingSettings.enableLinearLighting) { | ||||||||||||||||||||||||||||||||||||||||
| linAlbedo = Color::GammaToLinear(linAlbedo); | ||||||||||||||||||||||||||||||||||||||||
| linDirectionalAmbientColor = Color::GammaToLinear(linDirectionalAmbientColor); | ||||||||||||||||||||||||||||||||||||||||
| linDiffuseColor = Color::GammaToLinear(linDiffuseColor); | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| linDirectionalAmbientColor = Color::Ambient(linDirectionalAmbientColor); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| #if defined(IBL) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
| float3 linAlbedo = albedo; | |
| float3 linDirectionalAmbientColor = directionalAmbientColor; | |
| float3 linDiffuseColor = diffuseColor; | |
| if (!SharedData::linearLightingSettings.enableLinearLighting) { | |
| linAlbedo = Color::GammaToLinear(linAlbedo); | |
| linDirectionalAmbientColor = Color::GammaToLinear(linDirectionalAmbientColor); | |
| linDiffuseColor = Color::GammaToLinear(linDiffuseColor); | |
| } else { | |
| linDirectionalAmbientColor = Color::Ambient(linDirectionalAmbientColor); | |
| } | |
| #if defined(IBL) | |
| float3 linAlbedo = Color::ColorToLinear(albedo); | |
| float3 linDirectionalAmbientColor = SharedData::linearLightingSettings.enableLinearLighting | |
| ? Color::Ambient(directionalAmbientColor) | |
| : Color::GammaToLinear(directionalAmbientColor); | |
| float3 linDiffuseColor = SharedData::linearLightingSettings.enableLinearLighting | |
| ? diffuseColor | |
| : Color::GammaToLinear(diffuseColor); | |
| #if defined(IBL) |
🤖 Prompt for AI Agents
In package/Shaders/AmbientCompositeCS.hlsl around lines 70 to 80, the code
inconsistently decodes albedo and related colors by mixing gamma and semantic
spaces, which can cause incorrect lighting results. Replace the use of
Color::GammaToLinear with Color::ColorToLinear (or a dedicated Diffuse-to-Linear
conversion) for all lin* variables regardless of the linear lighting setting,
and consolidate the decoding logic in one place to ensure consistent domain
decoding.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
linAmbient formula mixes domains; compute from decoded terms.
Color::IrradianceToLinear(albedo * directionalAmbientColor) applies an irradiance decode to a reflectance*irradiance product. Instead multiply decoded quantities.
Apply:
- float3 linAmbient = Color::IrradianceToLinear(albedo * directionalAmbientColor);
+ float3 linAmbient = linAlbedo * linDirectionalAmbientColor;📝 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.
| float3 linAmbient = Color::IrradianceToLinear(albedo * directionalAmbientColor); | |
| float3 linAmbient = linAlbedo * linDirectionalAmbientColor; |
🤖 Prompt for AI Agents
In package/Shaders/AmbientCompositeCS.hlsl at line 87, the calculation of
linAmbient incorrectly applies irradiance decoding to a product of albedo and
directionalAmbientColor. To fix this, decode albedo and directionalAmbientColor
separately before multiplying them, ensuring both terms are in the correct
linear domain prior to multiplication.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compute and accumulate ambient in linear; encode once at the end.
Currently you convert both diffuse and ambient back to gamma and then multiply by (gamma) albedo, leaving linAmbient unused. This mixes spaces and defeats linear-lighting intent.
Apply:
- linAmbient *= visibility;
- diffuseColor = Color::IrradianceToGamma(linDiffuseColor);
- directionalAmbientColor = Color::IrradianceToGamma(linDirectionalAmbientColor * visibility);
- diffuseColor = diffuseColor + directionalAmbientColor * albedo;
+ linAmbient *= visibility;
+ linDiffuseColor += linAmbient;
+ diffuseColor = Color::IrradianceToGamma(linDiffuseColor);🤖 Prompt for AI Agents
In package/Shaders/AmbientCompositeCS.hlsl around lines 149 to 154, the code
converts diffuse and ambient colors to gamma space before multiplying by albedo,
which is incorrect because albedo is in gamma space and linAmbient is unused. To
fix this, keep all ambient and diffuse lighting calculations in linear space,
accumulate them linearly, multiply by the linear albedo, and only convert the
final color to gamma space once at the end.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSGI writeback mixes spaces; write linear delta.
originalDiffuseColor is linear, but diffuseColor is gamma after re-encoding above. Converting a mixed-space difference with IrradianceToLinear is incorrect.
Apply:
- DiffuseAmbientRW[dispatchID.xy] = Color::IrradianceToLinear(diffuseColor - originalDiffuseColor);
+ DiffuseAmbientRW[dispatchID.xy] = linDiffuseColor - originalDiffuseColor;🤖 Prompt for AI Agents
In package/Shaders/AmbientCompositeCS.hlsl at lines 156-157, the code
incorrectly applies IrradianceToLinear to the difference between a gamma-space
diffuseColor and a linear originalDiffuseColor, causing a mixed-space
calculation. To fix this, convert diffuseColor back to linear space before
subtracting originalDiffuseColor, then write the linear delta without reapplying
IrradianceToLinear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Missing .xyz on SampleLevel result passed to IrradianceToLinear
This call differs from the others and passes a float4 to a function expecting float3 (or unintentionally includes alpha). Fix to maintain type and semantic consistency.
📝 Committable suggestion
🤖 Prompt for AI Agents