Skip to content
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

feat: QoL skylighting settings and mathematically correct SH scaling #364

Merged
merged 3 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
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
14 changes: 7 additions & 7 deletions features/Skylighting/Shaders/Skylighting/Skylighting.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ struct SkylightingSettings
row_major float4x4 OcclusionViewProj;
float4 OcclusionDir;

float4 PosOffset;
uint4 ArrayOrigin;
float4 PosOffset; // xyz: cell origin in camera model space
uint4 ArrayOrigin; // xyz: array origin, w: max accum frames
int4 ValidMargin;

float4 MixParams; // x: min diffuse visibility, y: diffuse mult, z: min specular visibility, w: specular mult
Expand Down Expand Up @@ -41,7 +41,7 @@ float getFadeOutFactor(float3 positionMS)

sh2 sampleSkylighting(SkylightingSettings params, Texture3D<sh2> probeArray, float3 positionMS, float3 normalWS)
{
const static sh2 unitSH = shEvaluate(float3(0, 0, 1));
const static sh2 unitSH = shEvaluate(float3(0, 0, 1)) * 4.0 * shPI;
sh2 scaledUnitSH = unitSH / (params.MixParams.y + 1e-10);

float3 positionMSAdjusted = positionMS - params.PosOffset;
Expand Down Expand Up @@ -127,13 +127,13 @@ float shHallucinateZH3Irradiance(sh2 sh, float3 normal)
const static float factor = sqrt(5.0f / (16.0f * 3.1415926f));

float3 zonalAxis = normalize(sh.wyz);
float ratio = abs(dot(sh.wyz, zonalAxis)) / sh.x;
float3 zonalL2Coeff = sh.x * (0.08f * ratio + 0.6f * ratio * ratio);
float ratio = abs(dot(sh.wyz * float3(-1, -1, 0), zonalAxis)) / sh.x;
float zonalL2Coeff = sh.x * (0.08f * ratio + 0.6f * ratio * ratio);

float fZ = dot(zonalAxis, normal);
float zhDir = factor * (3.0f * fZ * fZ - 1.0f);

float result = shFuncProductIntegral(sh, shEvaluateCosineLobe(normal));
float result = shFuncProductIntegral(sh, shEvaluateCosineLobe(normal)) / shPI; // cosine lobe integral -> pi

result += 0.25f * zonalL2Coeff * zhDir;

Expand All @@ -150,7 +150,7 @@ sh2 fauxSpecularLobeSH(float3 N, float3 V, float roughness)
float3 dominantDir = normalize(D);

sh2 directional = shEvaluate(dominantDir);
sh2 cosineLobe = shEvaluateCosineLobe(dominantDir);
sh2 cosineLobe = shEvaluateCosineLobe(dominantDir) / PI;
sh2 result = shAdd(shScale(directional, f), shScale(cosineLobe, 1 - f));

return result;
Expand Down
6 changes: 3 additions & 3 deletions features/Skylighting/Shaders/Skylighting/updateProbes.cs.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ SamplerState samplerPointClamp : register(s0);

[numthreads(8, 8, 1)] void main(uint3 dtid
: SV_DispatchThreadID) {
const static float fadeInThreshold = 64;
const static sh2 unitSH = shEvaluate(float3(0, 0, 1));
const float fadeInThreshold = settings.ArrayOrigin.w;
const static sh2 unitSH = shEvaluate(float3(0, 0, 1)) * 4.0 * shPI; // 4 pi from monte carlo

uint3 cellID = (int3(dtid) - settings.ArrayOrigin.xyz) % ARRAY_DIM;
bool isValid = all(cellID >= max(0, settings.ValidMargin.xyz)) && all(cellID <= ARRAY_DIM - 1 + min(0, settings.ValidMargin.xyz)); // check if the cell is newly added
Expand All @@ -41,7 +41,7 @@ SamplerState samplerPointClamp : register(s0);
float occlusionDepth = srcOcclusionDepth.SampleLevel(samplerPointClamp, occlusionUV, 0);
bool visible = cellCentreOS.z < occlusionDepth;

sh2 occlusionSH = shScale(shEvaluate(settings.OcclusionDir.xyz), float(visible));
sh2 occlusionSH = shScale(shEvaluate(settings.OcclusionDir.xyz), float(visible) * 4.0 * shPI);
if (isValid) {
float lerpFactor = rcp(accumFrames);
sh2 prevProbeSH = unitSH;
Expand Down
2 changes: 1 addition & 1 deletion package/Shaders/DeferredCompositeCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Texture3D<sh2> SkylightingProbeArray : register(t9);
sh2 skylighting = sampleSkylighting(skylightingSettings, SkylightingProbeArray, positionMS.xyz, normalWS);
sh2 specularLobe = fauxSpecularLobeSH(normalWS, -V, roughness);

half skylightingSpecular = saturate(shFuncProductIntegral(skylighting, specularLobe));
half skylightingSpecular = shFuncProductIntegral(skylighting, specularLobe);
skylightingSpecular = lerp(skylightingSettings.MixParams.z, 1, saturate(skylightingSpecular * skylightingSettings.MixParams.w));

half3 specularIrradiance = 1;
Expand Down
4 changes: 2 additions & 2 deletions package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
float minWetnessAngle = 0;
minWetnessAngle = saturate(max(minWetnessValue, worldSpaceNormal.z));
# if defined(SKYLIGHTING)
float wetnessOcclusion = saturate(shUnproject(skylightingSH, float3(0, 0, 1)) * 10);
float wetnessOcclusion = pow(saturate(shUnproject(skylightingSH, float3(0, 0, 1))), 2);
doodlum marked this conversation as resolved.
Show resolved Hide resolved
# endif // SKYLIGHTING

float4 raindropInfo = float4(0, 0, 1, 0);
Expand Down Expand Up @@ -1775,7 +1775,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
float3 reflectionDiffuseColor = diffuseColor + directionalAmbientColor;

# if defined(SKYLIGHTING)
float skylightingDiffuse = shHallucinateZH3Irradiance(skylightingSH, worldSpaceNormal);
float skylightingDiffuse = shHallucinateZH3Irradiance(skylightingSH, skylightingSettings.DirectionalDiffuse ? worldSpaceNormal : float3(0, 0, 1));
skylightingDiffuse = lerp(skylightingSettings.MixParams.x, 1, saturate(skylightingDiffuse * skylightingSettings.MixParams.y));
directionalAmbientColor = sRGB2Lin(directionalAmbientColor);
directionalAmbientColor *= skylightingDiffuse;
Expand Down
27 changes: 21 additions & 6 deletions src/Features/Skylighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,28 @@ void Skylighting::DrawSettings()
"Extra darkening depending on surface orientation.\n"
"More physically correct, but may impact the intended visual of certain weathers.");

ImGui::SliderFloat("Diffuse Min Visibility", &settings.MinDiffuseVisibility, 0, 1, "%.2f");
ImGui::SliderFloat("Diffuse Brightness", &settings.DiffuseBrightness, 0.3, 3, "%.1f");
ImGui::SliderFloat("Specular Min Visibility", &settings.MinSpecularVisibility, 0, 1, "%.2f");
ImGui::SliderFloat("Specular Brightness", &settings.SpecularBrightness, 0.3, 3, "%.1f");

ImGui::Separator();

if (ImGui::Button("Rebuild Skylighting")) {
auto& context = State::GetSingleton()->context;
UINT clr[1] = { 0 };
context->ClearUnorderedAccessViewUint(texAccumFramesArray->uav.get(), clr);
}
if (auto _tt = Util::HoverTooltipWrapper())
ImGui::Text("Changes below require rebuilding, a loading screen, or moving away from the current location to apply.");

ImGui::SliderInt("Update Frames", &settings.MaxFrames, 0, 255, "%d", ImGuiSliderFlags_AlwaysClamp);
if (auto _tt = Util::HoverTooltipWrapper())
ImGui::Text("Aggregating over how many frames to build up skylighting.");

ImGui::SliderAngle("Max Zenith Angle", &settings.MaxZenith, 0, 90);
if (auto _tt = Util::HoverTooltipWrapper())
ImGui::Text("Smaller angles creates more focused top-down shadow.");

ImGui::SliderFloat("Diffuse Min Visibility", &settings.MinDiffuseVisibility, 0, 1, "%.2f");
ImGui::SliderFloat("Diffuse Brightness", &settings.DiffuseBrightness, 0, 10, "%.1f");
ImGui::SliderFloat("Specular Min Visibility", &settings.MinSpecularVisibility, 0, 1, "%.2f");
ImGui::SliderFloat("Specular Brightness", &settings.SpecularBrightness, 0, 10, "%.1f");
}

ID3D11PixelShader* Skylighting::GetFoliagePS()
Expand Down Expand Up @@ -211,7 +225,8 @@ void Skylighting::Prepass()
.ArrayOrigin = {
((int)cellID.x - probeArrayDims[0] / 2) % probeArrayDims[0],
((int)cellID.y - probeArrayDims[1] / 2) % probeArrayDims[1],
((int)cellID.z - probeArrayDims[2] / 2) % probeArrayDims[2], 0 },
((int)cellID.z - probeArrayDims[2] / 2) % probeArrayDims[2],
(uint)settings.MaxFrames },
.ValidMargin = { (int)cellIDDiff.x, (int)cellIDDiff.y, (int)cellIDDiff.z },
.MixParams = { settings.MinDiffuseVisibility, settings.DiffuseBrightness, settings.MinSpecularVisibility, settings.SpecularBrightness },
.DirectionalDiffuse = settings.DirectionalDiffuse,
Expand Down
9 changes: 5 additions & 4 deletions src/Features/Skylighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ struct Skylighting : Feature
{
bool DirectionalDiffuse = true;
float MaxZenith = 3.1415926f / 3.f; // 60 deg
int MaxFrames = 64;
float MinDiffuseVisibility = 0.1f;
float DiffuseBrightness = 3;
float MinSpecularVisibility = 0;
float SpecularBrightness = 4;
float DiffuseBrightness = 1.f;
float MinSpecularVisibility = 0.f;
float SpecularBrightness = 1.f;
} settings;

struct SkylightingCB
Expand All @@ -57,7 +58,7 @@ struct Skylighting : Feature

float3 PosOffset; // cell origin in camera model space
float _pad0;
uint ArrayOrigin[4];
uint ArrayOrigin[4]; // xyz: array origin, w: max accum frames
int ValidMargin[4];

float4 MixParams; // x: min diffuse visibility, y: diffuse mult, z: min specular visibility, w: specular mult
Expand Down
Loading