Skip to content

Commit c5f0174

Browse files
committed
Fixed unmarked non-uniform resource access while rendering particles. Other minor fixes and polish.
* Disabled the groupshared optimization for `LightLinkedListStats.cs.hlsl` on all GPUs rather than just Intel. Saw issues with it on AMD as well, need to investigate more. * Switched to a more typical B8G8R8A8_UNORM swapchain, the R16G16B16A16_FLOAT caused issues on my laptop. (It seemingly can't decide whether to present it as sRGB or linear.) * Fixed the velocity direction bias getting clamped to 0 in the particle system editor and added the missing label for spawn point variance.
1 parent b06a9ad commit c5f0174

File tree

6 files changed

+34
-16
lines changed

6 files changed

+34
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Various debug visualizations, settings, and tools can be accessed using the UI.
3434

3535
Building should be as simple as opening `ThreeL.sln` in Visual Studio 2022 and pressing F5.
3636

37-
 
37+
### Build Configurations
3838

3939
ThreeL has three build configrations:
4040

ThreeL/ResourceManager.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ ResourceManager::ResourceManager(GraphicsCore& graphics)
3232
ShaderBlobs lightLinkedListDebugPs = hlslCompiler.CompileShader(L"Shaders/LightLinkedListDebug.ps.hlsl", L"PsMain", L"ps_6_0");
3333

3434
std::vector<std::wstring> lightLinkedListStatsCsDefines;
35-
if (Graphics.IsIntel())
36-
lightLinkedListStatsCsDefines.push_back(L"NO_GROUPSHARED"); // My Intel UHD 620 is choking on the groupshared optimization in this shader.
35+
// My Intel UHD 620 is choking on the groupshared optimization in this shader.
36+
// I've also seen a AMD RX 6700 XT choking on this in a different way (light count is randomly corrupted), so let's just disable the optimization for now.
37+
//if (Graphics.IsIntel())
38+
lightLinkedListStatsCsDefines.push_back(L"NO_GROUPSHARED");
3739
ShaderBlobs lightLinkedListStatsCs = hlslCompiler.CompileShader(L"Shaders/LightLinkedListStats.cs.hlsl", L"Main", L"cs_6_0", lightLinkedListStatsCsDefines);
3840

3941
ShaderBlobs lightSpritesVs = hlslCompiler.CompileShader(L"Shaders/LightSprites.hlsl", L"VsMain", L"vs_6_0");

ThreeL/Shaders/Pbr.hlsl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ struct Brdf
195195
// attenuation is approaching zero at that point. Basically this shows dim solid light for areas covered by the light linked list
196196
// and bright in areas actually covered by the light. It also indirectly shows light checks lost due to depth errors.
197197
// In other words, this shows that RangeExtension in LightLinkedListFill.hlsl is being calculated correctly.
198-
#if DEBUG_LIGHT_BOUNDARIES
198+
#ifdef DEBUG_LIGHT_BOUNDARIES
199199
lightAttenuation = distanceSquared < rangeSquared ? 1.f : 0.25f;
200200
Diffuse += light.Color * lightAttenuation;
201201
#else
@@ -208,6 +208,16 @@ struct Brdf
208208
}
209209
};
210210

211+
float4 SampleBindlessTexture(uint textureIndex, uint samplerIndex, float2 uv)
212+
{
213+
// Particles are instanced, which means differen pixel shader invocations get different material IDs which means potentially non-uniform resource indicies
214+
#ifdef PBR_IS_PARTICLE
215+
return g_Textures[NonUniformResourceIndex(textureIndex)].Sample(g_Samplers[NonUniformResourceIndex(samplerIndex)], uv);
216+
#else
217+
return g_Textures[textureIndex].Sample(g_Samplers[samplerIndex], uv);
218+
#endif
219+
}
220+
211221
[RootSignature(PBR_ROOT_SIGNATURE)]
212222
float4 PsMain(PsInput input, bool isFrontFace: SV_IsFrontFace) : SV_Target
213223
{
@@ -224,7 +234,7 @@ float4 PsMain(PsInput input, bool isFrontFace: SV_IsFrontFace) : SV_Target
224234
float4 baseColor = input.Color * material.BaseColorFactor;
225235

226236
if (material.BaseColorTexture != DISABLED_BUFFER)
227-
{ baseColor *= g_Textures[material.BaseColorTexture].Sample(g_Samplers[material.BaseColorTextureSampler], input.Uv0); }
237+
{ baseColor *= SampleBindlessTexture(material.BaseColorTexture, material.BaseColorTextureSampler, input.Uv0); }
228238

229239
// Only base color affects alpha so alpha cutoff can be applied at this point
230240
if (baseColor.a < material.AlphaCutoff)
@@ -236,7 +246,7 @@ float4 PsMain(PsInput input, bool isFrontFace: SV_IsFrontFace) : SV_Target
236246

237247
if (material.MealicRoughnessTexture != DISABLED_BUFFER)
238248
{
239-
float4 mr = g_Textures[material.MealicRoughnessTexture].Sample(g_Samplers[material.MetalicRoughnessTextureSampler], input.Uv0);
249+
float4 mr = SampleBindlessTexture(material.MealicRoughnessTexture, material.MetalicRoughnessTextureSampler, input.Uv0);
240250
metalness *= mr.b;
241251
roughness *= mr.g;
242252
}
@@ -260,7 +270,7 @@ float4 PsMain(PsInput input, bool isFrontFace: SV_IsFrontFace) : SV_Target
260270

261271
float3x3 tangentFrame = float3x3(tangent, bitangent, normal);
262272

263-
float3 textureNormal = g_Textures[material.NormalTexture].Sample(g_Samplers[material.NormalTextureSampler], input.Uv0).rgb;
273+
float3 textureNormal = SampleBindlessTexture(material.NormalTexture, material.NormalTextureSampler, input.Uv0).rgb;
264274
textureNormal = textureNormal * 2.f - 1.f;
265275
textureNormal *= float3(material.NormalTextureScale.xx, 1.f);
266276
textureNormal = normalize(textureNormal);
@@ -271,7 +281,7 @@ float4 PsMain(PsInput input, bool isFrontFace: SV_IsFrontFace) : SV_Target
271281
float3 emissive = material.EmissiveFactor;
272282

273283
if (material.EmissiveTexture != DISABLED_BUFFER)
274-
{ emissive *= g_Textures[material.EmissiveTexture].Sample(g_Samplers[material.EmissiveTextureSampler], input.Uv0).rgb; }
284+
{ emissive *= SampleBindlessTexture(material.EmissiveTexture, material.EmissiveTextureSampler, input.Uv0).rgb; }
275285

276286
//=================================================================================================================
277287
// PBR calculations

ThreeL/SwapChain.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ SwapChain::SwapChain(GraphicsCore& graphicsCore, Window& window)
9393
InitializeBackBuffers();
9494

9595
// Register WndProc to handle resizing
96-
m_WndProcHandle = window.AddWndProc([&](HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
96+
m_WndProcHandle = window.AddWndProc([&](HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -> std::optional<LRESULT>
9797
{
9898
if (message == WM_WINDOWPOSCHANGED)
9999
{
@@ -106,10 +106,10 @@ SwapChain::SwapChain(GraphicsCore& graphicsCore, Window& window)
106106
Resize(newSize);
107107
}
108108

109-
return std::optional<LRESULT>(0);
109+
return 0;
110110
}
111111

112-
return std::optional<LRESULT>();
112+
return { };
113113
});
114114
}
115115

@@ -161,7 +161,6 @@ void SwapChain::Present(PresentMode mode)
161161
m_SyncPoints[m_CurrentBackBufferIndex].Wait();
162162
}
163163

164-
165164
void SwapChain::Resize(uint2 size)
166165
{
167166
Assert((size > uint2::Zero).All() && "The swap chain size must be positive and non-zero!");

ThreeL/SwapChain.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ enum class PresentMode
1717
class SwapChain
1818
{
1919
public:
20-
static const DXGI_FORMAT BACK_BUFFER_FORMAT = DXGI_FORMAT_R16G16B16A16_FLOAT;
20+
// My laptop misbehaves when DXGI_FORMAT_R16G16B16A16_FLOAT
21+
// Documentation on using this format for swapchains is scant, so it's unclear if this is due to
22+
// something we're doing wrong or something maybe Intel's drivers are doing wrong.
23+
// Regardless, we weren't really taking advantage of the increased precision anyway.
24+
// In the future I might implement proper HDR support (either for rendering or presenting), but first I probably need to acquire a decent HDR monitor.
25+
//static const DXGI_FORMAT BACK_BUFFER_FORMAT = DXGI_FORMAT_R16G16B16A16_FLOAT;
26+
static const DXGI_FORMAT BACK_BUFFER_FORMAT = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
2127
static const uint32_t BACK_BUFFER_COUNT = 3;
2228

2329
private:

ThreeL/Ui.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,16 @@ void Ui::SubmitParticleSystemEditor(ComputeContext& context, ParticleSystem& par
160160
ImGui::DragFloat("Y##VelocityDirectionVariance", &particleSystemDefinition.VelocityDirectionVariance.y, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
161161
ImGui::DragFloat("Z##VelocityDirectionVariance", &particleSystemDefinition.VelocityDirectionVariance.z, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
162162
ImGui::Text("Velocity direction bias");
163-
ImGui::DragFloat("X##VelocityDirectionBias", &particleSystemDefinition.VelocityDirectionBias.x, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
164-
ImGui::DragFloat("Y##VelocityDirectionBias", &particleSystemDefinition.VelocityDirectionBias.y, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
165-
ImGui::DragFloat("Z##VelocityDirectionBias", &particleSystemDefinition.VelocityDirectionBias.z, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
163+
ImGui::DragFloat("X##VelocityDirectionBias", &particleSystemDefinition.VelocityDirectionBias.x, 0.01f, -FLT_MAX, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
164+
ImGui::DragFloat("Y##VelocityDirectionBias", &particleSystemDefinition.VelocityDirectionBias.y, 0.01f, -FLT_MAX, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
165+
ImGui::DragFloat("Z##VelocityDirectionBias", &particleSystemDefinition.VelocityDirectionBias.z, 0.01f, -FLT_MAX, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
166166
ImGui::Text("Velocity magnitude");
167167
ImGui::DragFloatRange2("Linear", &particleSystemDefinition.VelocityMagnitudeMin, &particleSystemDefinition.VelocityMagnitudeMax, 0.01f);
168168
ImGui::DragFloatRange2("Angular", &particleSystemDefinition.AngularVelocityMin, &particleSystemDefinition.AngularVelocityMax, 0.01f, 0.f, 0.f, "%.3f rad/s");
169169

170170
ImGui::SeparatorText("Spawn point");
171171
ImGui::Checkbox("Show spawn point gizmo", &ShowParticleSystemGizmo);
172+
ImGui::Text("Spawn point variance");
172173
ImGui::DragFloat("X##SpawnPointVariance", &particleSystemDefinition.SpawnPointVariance.x, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
173174
ImGui::DragFloat("Y##SpawnPointVariance", &particleSystemDefinition.SpawnPointVariance.y, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
174175
ImGui::DragFloat("Z##SpawnPointVariance", &particleSystemDefinition.SpawnPointVariance.z, 0.01f, 0.f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);

0 commit comments

Comments
 (0)