Skip to content

Commit c6c7f88

Browse files
Add support for ray-traced reflections in SpecularReflectionsFeatureProcessor (o3de#17588)
Signed-off-by: Markus Prettner <[email protected]>
1 parent 377cb88 commit c6c7f88

File tree

10 files changed

+60
-29
lines changed

10 files changed

+60
-29
lines changed

Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionScreenSpaceRayTracingClosestHit.azsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ void ClosestHit(inout PayloadData payload, BuiltInTriangleIntersectionAttributes
3535
float3 cameraToHit = normalize(positionWS - ViewSrg::m_worldPosition);
3636
bool behindCamera = dot(cameraToHit, -ViewSrg::m_viewMatrix[2].xyz) <= 0.0f;
3737

38-
payload.m_offScreen = offScreen || behindCamera;
39-
if (payload.m_offScreen && !RayTracingGlobalSrg::m_rayTraceFallbackData)
38+
payload.m_offScreen = offScreen || behindCamera || IsRayTracingOverrideEnabled();
39+
if (payload.m_offScreen && !IsRayTracingFallbackEnabled())
4040
{
4141
// the hit is offscreen and we're not raytracing fallback data, report this as a miss
4242
payload.m_hitT = -1.0f;
@@ -108,7 +108,7 @@ void ClosestHit(inout PayloadData payload, BuiltInTriangleIntersectionAttributes
108108
payload.m_obstructed = (secondaryPayload.m_hitT >= 0.0f);
109109
}
110110

111-
if (payload.m_obstructed && !RayTracingGlobalSrg::m_rayTraceFallbackData)
111+
if (payload.m_obstructed && !IsRayTracingFallbackEnabled())
112112
{
113113
// the hit is obstructed and we're not raytracing fallback data, report this as a miss
114114
payload.m_hitT = -1.0f;

Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionScreenSpaceRayTracingCommon.azsli

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ struct PayloadData
3838
bool m_lightVisibilityTrace;
3939
};
4040

41+
enum class ReflectionMethod
42+
{
43+
ScreenSpace,
44+
Hybrid,
45+
HybridWithFallback,
46+
RayTracing
47+
};
48+
4149
ShaderResourceGroup RayTracingGlobalSrg : SRG_RayTracingGlobal
4250
{
4351
Texture2DMS<float> m_depth;
@@ -53,7 +61,7 @@ ShaderResourceGroup RayTracingGlobalSrg : SRG_RayTracingGlobal
5361
float m_invOutputScale;
5462
float m_maxRayLength;
5563
float m_maxRoughness;
56-
bool m_rayTraceFallbackData;
64+
uint m_reflectionMethod;
5765
bool m_rayTraceFallbackSpecular;
5866

5967
Sampler PointSampler
@@ -696,3 +704,15 @@ float3 GetIblSpecular(
696704

697705
return outSpecular;
698706
}
707+
708+
bool IsRayTracingFallbackEnabled()
709+
{
710+
ReflectionMethod reflectionMethod = (ReflectionMethod)RayTracingGlobalSrg::m_reflectionMethod;
711+
return reflectionMethod == ReflectionMethod::HybridWithFallback || reflectionMethod == ReflectionMethod::RayTracing;
712+
}
713+
714+
bool IsRayTracingOverrideEnabled()
715+
{
716+
ReflectionMethod reflectionMethod = (ReflectionMethod)RayTracingGlobalSrg::m_reflectionMethod;
717+
return reflectionMethod == ReflectionMethod::RayTracing;
718+
}

Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionScreenSpaceRayTracingMiss.azsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void Miss(inout PayloadData payload)
2222
return;
2323
}
2424

25-
if (RayTracingGlobalSrg::m_rayTraceFallbackData)
25+
if (IsRayTracingFallbackEnabled())
2626
{
2727
// query mip0 of the global cubemap for the fallback color
2828
float3 sampleDir = mul(WorldRayDirection(), (float3x3)SceneSrg::m_cubemapRotationMatrix);

Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SpecularReflections/SpecularReflectionsFeatureProcessorInterface.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ namespace AZ
2020
AZ_RTTI(SSROptions, "{A3DE7EDD-3680-458F-A69C-FE7550B75652}");
2121
AZ_CLASS_ALLOCATOR(SSROptions, SystemAllocator, 0);
2222

23+
enum class ReflectionMethod
24+
{
25+
ScreenSpace,
26+
Hybrid,
27+
HybridWithFallback,
28+
RayTracing
29+
};
30+
2331
static void Reflect(ReflectContext* context)
2432
{
2533
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
@@ -33,8 +41,7 @@ namespace AZ
3341
->Field("MaxRoughness", &SSROptions::m_maxRoughness)
3442
->Field("RoughnessBias", &SSROptions::m_roughnessBias)
3543
->Field("HalfResolution", &SSROptions::m_halfResolution)
36-
->Field("RayTracing", &SSROptions::m_rayTracing)
37-
->Field("RayTraceFallbackData", &SSROptions::m_rayTraceFallbackData)
44+
->Field("ReflectionMethod", &SSROptions::m_reflectionMethod)
3845
->Field("RayTraceFallbackSpecular", &SSROptions::m_rayTraceFallbackSpecular)
3946
->Field("TemporalFiltering", &SSROptions::m_temporalFiltering)
4047
->Field("TemporalFilteringStrength", &SSROptions::m_temporalFilteringStrength)
@@ -45,8 +52,8 @@ namespace AZ
4552
}
4653

4754
bool IsEnabled() const { return m_enable; }
48-
bool IsRayTracingEnabled() const { return m_enable && m_rayTracing; }
49-
bool IsRayTracingFallbackEnabled() const { return m_enable && m_rayTracing && m_rayTraceFallbackData; }
55+
bool IsRayTracingEnabled() const { return m_enable && m_reflectionMethod != ReflectionMethod::ScreenSpace; }
56+
bool IsRayTracingFallbackEnabled() const { return IsRayTracingEnabled() && m_reflectionMethod != ReflectionMethod::Hybrid; }
5057
bool IsLuminanceClampEnabled() const { return m_enable && m_luminanceClamp; }
5158
bool IsTemporalFilteringEnabled() const { return m_enable && m_temporalFiltering; }
5259
float GetOutputScale() const { return m_halfResolution ? 0.5f : 1.0f; }
@@ -58,8 +65,7 @@ namespace AZ
5865
float m_maxRoughness = 0.31f;
5966
float m_roughnessBias = 0.0f;
6067
bool m_halfResolution = true;
61-
bool m_rayTracing = true;
62-
bool m_rayTraceFallbackData = true;
68+
ReflectionMethod m_reflectionMethod = ReflectionMethod::HybridWithFallback;
6369
bool m_rayTraceFallbackSpecular = false;
6470
bool m_temporalFiltering = true;
6571
float m_temporalFilteringStrength = 1.0f;

Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceFilterPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ namespace AZ
102102
m_shaderResourceGroup->SetConstant(m_outputHeightNameIndex, outputImageDescriptor.m_size.m_height);
103103
m_shaderResourceGroup->SetConstant(m_mipLevelsNameIndex, aznumeric_cast<uint32_t>(reflectionImageDescriptor.m_mipLevels));
104104
m_shaderResourceGroup->SetConstant(m_coneTracingNameIndex, ssrOptions.m_coneTracing);
105-
m_shaderResourceGroup->SetConstant(m_rayTracingNameIndex, ssrOptions.m_rayTracing);
105+
m_shaderResourceGroup->SetConstant(m_rayTracingNameIndex, ssrOptions.IsRayTracingEnabled());
106106
m_shaderResourceGroup->SetConstant(m_temporalFilteringNameIndex, ssrOptions.m_temporalFiltering);
107107
m_shaderResourceGroup->SetConstant(m_invTemporalFilteringStrengthNameIndex, 1.0f / ssrOptions.m_temporalFilteringStrength);
108108
m_shaderResourceGroup->SetConstant(m_maxRoughnessNameIndex, ssrOptions.m_maxRoughness);

Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceTracePass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ namespace AZ
7676
m_shaderResourceGroup->SetConstant(m_invOutputScaleNameIndex, 1.0f / ssrOptions.GetOutputScale());
7777
m_shaderResourceGroup->SetConstant(m_outputWidthNameIndex, outputImageSize.m_width);
7878
m_shaderResourceGroup->SetConstant(m_outputHeightNameIndex, outputImageSize.m_height);
79-
m_shaderResourceGroup->SetConstant(m_rayTracingEnabledNameIndex, ssrOptions.m_rayTracing);
80-
m_shaderResourceGroup->SetConstant(m_rayTraceFallbackDataNameIndex, ssrOptions.m_rayTraceFallbackData);
79+
m_shaderResourceGroup->SetConstant(m_rayTracingEnabledNameIndex, ssrOptions.IsRayTracingEnabled());
80+
m_shaderResourceGroup->SetConstant(m_rayTraceFallbackDataNameIndex, ssrOptions.IsRayTracingFallbackEnabled());
8181
m_shaderResourceGroup->SetConstant(m_maxRayDistanceNameIndex, ssrOptions.m_maxRayDistance);
8282
m_shaderResourceGroup->SetConstant(m_maxDepthThresholdNameIndex, ssrOptions.m_maxDepthThreshold);
8383
m_shaderResourceGroup->SetConstant(m_maxRoughnessNameIndex, ssrOptions.m_maxRoughness);

Gems/Atom/Feature/Common/Code/Source/SpecularReflections/SpecularReflectionsFeatureProcessor.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ namespace AZ
6060
RHI::Ptr<RHI::Device> device = rhiSystem->GetDevice();
6161

6262
// disable raytracing if the platform does not support it
63-
m_ssrOptions.m_rayTracing &= device->GetFeatures().m_rayTracing;
63+
if (!device->GetFeatures().m_rayTracing)
64+
{
65+
m_ssrOptions.m_reflectionMethod = SSROptions::ReflectionMethod::ScreenSpace;
66+
}
6467

6568
// determine size multiplier to pass to the shaders
6669
float sizeMultiplier = m_ssrOptions.m_halfResolution ? 0.5f : 1.0f;
@@ -121,9 +124,9 @@ namespace AZ
121124
AZ::RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this, sizeMultiplier](AZ::RPI::Pass* pass) -> AZ::RPI::PassFilterExecutionFlow
122125
{
123126
// enable/disable
124-
pass->SetEnabled(m_ssrOptions.m_rayTracing);
127+
pass->SetEnabled(m_ssrOptions.IsRayTracingEnabled());
125128

126-
if (m_ssrOptions.m_rayTracing)
129+
if (m_ssrOptions.IsRayTracingEnabled())
127130
{
128131
// options
129132
RayTracingPass* rayTracingPass = azrtti_cast<RayTracingPass*>(pass);
@@ -133,7 +136,7 @@ namespace AZ
133136

134137
rayTracingPassSrg->SetConstant(m_invOutputScaleNameIndex, 1.0f / m_ssrOptions.GetOutputScale());
135138
rayTracingPassSrg->SetConstant(m_maxRoughnessNameIndex, m_ssrOptions.m_maxRoughness);
136-
rayTracingPassSrg->SetConstant(m_rayTraceFallbackDataNameIndex, m_ssrOptions.m_rayTraceFallbackData);
139+
rayTracingPassSrg->SetConstant(m_reflectionMethodNameIndex, m_ssrOptions.m_reflectionMethod);
137140
rayTracingPassSrg->SetConstant(m_rayTraceFallbackSpecularNameIndex, m_ssrOptions.m_rayTraceFallbackSpecular);
138141

139142
// size multiplier

Gems/Atom/Feature/Common/Code/Source/SpecularReflections/SpecularReflectionsFeatureProcessor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace AZ
4646

4747
RHI::ShaderInputNameIndex m_invOutputScaleNameIndex = "m_invOutputScale";
4848
RHI::ShaderInputNameIndex m_maxRoughnessNameIndex = "m_maxRoughness";
49-
RHI::ShaderInputNameIndex m_rayTraceFallbackDataNameIndex = "m_rayTraceFallbackData";
49+
RHI::ShaderInputNameIndex m_reflectionMethodNameIndex = "m_reflectionMethod";
5050
RHI::ShaderInputNameIndex m_rayTraceFallbackSpecularNameIndex = "m_rayTraceFallbackSpecular";
5151
};
5252
} // namespace Render

Gems/AtomLyIntegration/CommonFeatures/Code/Source/SpecularReflections/SpecularReflectionsComponentConfig.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,16 @@ namespace AZ
5353
->Attribute(AZ::Edit::Attributes::Step, 0.1f)
5454
->DataElement(Edit::UIHandlers::CheckBox, &SSROptions::m_halfResolution, "Half Resolution", "Use half resolution in the reflected image, improves performance but may increase artifacts during camera motion")
5555
->Attribute(AZ::Edit::Attributes::Visibility, &SSROptions::IsEnabled)
56-
->ClassElement(AZ::Edit::ClassElements::Group, "Ray Tracing")
57-
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
58-
->DataElement(Edit::UIHandlers::CheckBox, &SSROptions::m_rayTracing, "Hardware Ray Tracing", "Enable Hardware Ray Tracing for Hybrid SSR-RT, which improves hit detection quality and provides fallback data for occluded or off-screen surfaces")
59-
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::EntireTree)
60-
->Attribute(AZ::Edit::Attributes::Visibility, &SSROptions::IsEnabled)
61-
->DataElement(Edit::UIHandlers::CheckBox, &SSROptions::m_rayTraceFallbackData, "Ray Trace Fallback Data", "Generate fallback image data using hardware raytracing when the hit point is off-screen of obstructed by an object closer to the camera")
56+
->DataElement(Edit::UIHandlers::ComboBox, &SSROptions::m_reflectionMethod, "Reflection Method",
57+
"Screen-space: Use screen-space reflections only\n\n"
58+
"Hybrid SSR-RT: Use ray tracing for hit detection and screen-space data for surface evaluation\n\n"
59+
"Hybrid SSR-RT + Ray Tracing fallback: Use screen-space reflection data when available and ray tracing when not\n\n"
60+
"Ray Tracing: Use hardware ray tracing only")
6261
->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::EntireTree)
63-
->Attribute(AZ::Edit::Attributes::Visibility, &SSROptions::IsRayTracingEnabled)
62+
->EnumAttribute(SSROptions::ReflectionMethod::ScreenSpace, "Screen Space")
63+
->EnumAttribute(SSROptions::ReflectionMethod::Hybrid, "Hybrid SSR-RT")
64+
->EnumAttribute(SSROptions::ReflectionMethod::HybridWithFallback, "Hybrid SSR-RT + Ray Tracing fallback")
65+
->EnumAttribute(SSROptions::ReflectionMethod::RayTracing, "Ray Tracing")
6466
->DataElement(Edit::UIHandlers::CheckBox, &SSROptions::m_rayTraceFallbackSpecular, "Apply Fallback Specular Lighting", "Apply specular lighting in the fallback image, improves fallback image accuracy but may reduce performance and increase artifacts")
6567
->Attribute(AZ::Edit::Attributes::Visibility, &SSROptions::IsRayTracingFallbackEnabled)
6668
->ClassElement(AZ::Edit::ClassElements::Group, "Temporal Filtering")

Gems/DiffuseProbeGrid/Code/Source/Render/DiffuseProbeGridFeatureProcessor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ namespace AZ
159159
if (m_specularReflectionsFeatureProcessor)
160160
{
161161
const SSROptions& ssrOptions = m_specularReflectionsFeatureProcessor->GetSSROptions();
162-
m_ssrRayTracingEnabled = ssrOptions.m_rayTracing;
162+
m_ssrRayTracingEnabled = ssrOptions.IsRayTracingEnabled();
163163
}
164164

165165
EnableSceneNotification();
@@ -258,9 +258,9 @@ namespace AZ
258258
if (m_specularReflectionsFeatureProcessor)
259259
{
260260
const SSROptions& ssrOptions = m_specularReflectionsFeatureProcessor->GetSSROptions();
261-
if (m_ssrRayTracingEnabled != ssrOptions.m_rayTracing)
261+
if (m_ssrRayTracingEnabled != ssrOptions.IsRayTracingEnabled())
262262
{
263-
m_ssrRayTracingEnabled = ssrOptions.m_rayTracing;
263+
m_ssrRayTracingEnabled = ssrOptions.IsRayTracingEnabled();
264264

265265
AZStd::vector<Name> passHierarchy = { Name("ReflectionScreenSpacePass"), Name("DiffuseProbeGridQueryFullscreenWithAlbedoPass") };
266266
RPI::PassFilter passFilter = RPI::PassFilter::CreateWithPassHierarchy(passHierarchy);

0 commit comments

Comments
 (0)