diff --git a/RtxOptions.md b/RtxOptions.md
index 7eca878a..4bdde000 100644
--- a/RtxOptions.md
+++ b/RtxOptions.md
@@ -207,8 +207,9 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
|rtx.enableCullingInSecondaryRays|bool|False|Enable front/backface culling for opaque objects\. Objects with alpha blend or alpha test are not culled\. Only applies in secondary rays, defaults to off\. Generally helps with light bleeding from objects that aren't watertight\.|
|rtx.enableDLSSEnhancement|bool|True|Enhances lighting details when DLSS is on\.|
|rtx.enableDecalMaterialBlending|bool|True|A flag to enable or disable material blending on decals\.
This should generally always be enabled when decals are in use as this allows decals to be blended down on to the surface they sit slightly above which results in more convincing decals rendering\.|
+|rtx.enableDirectAlphaBlendShadows|bool|True|Calculate shadows for semi\-transparent materials \(alpha blended\) in direct lighting\. In engineering terms: include OBJECT\_MASK\_ALPHA\_BLEND into primary visibility rays\.|
|rtx.enableDirectLighting|bool|True|Enables direct lighting \(lighting directly from lights on to a surface\) on surfaces when set to true, otherwise disables it\.|
-|rtx.enableDirectTranslucentShadows|bool|False|Include OBJECT\_MASK\_TRANSLUCENT into primary visibility rays\.|
+|rtx.enableDirectTranslucentShadows|bool|False|Calculate coloured shadows for translucent materials \(i\.e\. glass, water\) in direct lighting\. In engineering terms: include OBJECT\_MASK\_TRANSLUCENT into primary visibility rays\.|
|rtx.enableEmissiveBlendEmissiveOverride|bool|True|Override typical material emissive information on draw calls with any emissive blending modes to emulate their original look more accurately\.|
|rtx.enableEmissiveBlendModeTranslation|bool|True|Treat incoming semi/additive D3D blend modes as emissive\.|
|rtx.enableFallbackLightShaping|bool|False|Enables light shaping on the fallback light \(only used for non\-Distant light types\)\.|
@@ -219,7 +220,8 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
|rtx.enableFogMaxDistanceRemap|bool|True|A flag to enable or disable remapping fixed function fox's max distance\. Only takes effect when fog remapping in general is enabled\.
Enables or disables remapping functionality relating to the max distance parameter of fixed function fog\.
This allows dynamic changes to the game's fog max distance to be reflected somewhat in the volumetrics system\. Overrides the specified volumetric transmittance measurement distance\.|
|rtx.enableFogRemap|bool|False|A flag to enable or disable fixed function fog remapping\. Only takes effect when volumetrics are enabled\.
Typically many old games used fixed function fog for various effects and while sometimes this fog can be replaced with proper volumetrics globally, other times require some amount of dynamic behavior controlled by the game\.
When enabled this option allows for remapping of fixed function fog parameters from the game to volumetric parameters to accomodate this dynamic need\.|
|rtx.enableIndexBufferMemoization|bool|True|CPU performance optimization, should generally be enabled\. Will reduce main thread time by caching processIndexBuffer operations and reusing when possible, this will come at the expense of some CPU RAM\.|
-|rtx.enableIndirectTranslucentShadows|bool|False|Include OBJECT\_MASK\_TRANSLUCENT into secondary visibility rays\.|
+|rtx.enableIndirectAlphaBlendShadows|bool|True|Calculate shadows for semi\-transparent \(alpha blended\) objects in indirect lighting \(i\.e\. reflections and GI\)\. In engineering terms: include OBJECT\_MASK\_ALPHA\_BLEND into secondary visibility rays\.|
+|rtx.enableIndirectTranslucentShadows|bool|False|Calculate coloured shadows for translucent materials \(i\.e\. glass, water\) in indirect lighting \(i\.e\. reflections and GI\)\. In engineering terms: include OBJECT\_MASK\_TRANSLUCENT into secondary visibility rays\.|
|rtx.enableInstanceDebuggingTools|bool|False|NOTE: This will disable temporal correllation for instances, but allow the use of instance developer debug tools|
|rtx.enableMultiStageTextureFactorBlending|bool|True|Support texture factor blending in stage 1~7\. Currently only support 1 additional blending stage, more than 1 additional blending stages will be ignored\.|
|rtx.enableNearPlaneOverride|bool|False|A flag to enable or disable the Camera's near plane override feature\.
Since the camera is not used directly for ray tracing the near plane the application uses typically does not matter, but for certain matrix\-based operations \(such as temporal reprojection or voxel grid projection\) it is still relevant\.
The issue arises when geometry is ray traced that is behind where the chosen Camera's near plane is located, typically common on viewmodels especially with how they are ray traced, causing graphical artifacts and other issues\.
This option helps correct this issue by overriding the near plane value to else \(usually smaller\) to sit behind the objects in question \(such as the view model\)\. As such this option should usually be enabled on games with viewmodels\.
Do note that when adjusting the near plane the larger the relative magnitude gap between the near and far plane the worse the precision of matrix operations will be, so the near plane should be set as high as possible even when overriding\.|
diff --git a/src/dxvk/imgui/dxvk_imgui.cpp b/src/dxvk/imgui/dxvk_imgui.cpp
index 26c9cafe..b107681f 100644
--- a/src/dxvk/imgui/dxvk_imgui.cpp
+++ b/src/dxvk/imgui/dxvk_imgui.cpp
@@ -2665,7 +2665,9 @@ namespace dxvk {
ImGui::DragInt("Max Secondary Interactions", &RtxOptions::Get()->secondaryRayMaxInteractionsObject(), 1.0f, 1, 255, "%d", sliderFlags);
ImGui::Checkbox("Separate Unordered Approximations", &RtxOptions::Get()->enableSeparateUnorderedApproximationsObject());
ImGui::Checkbox("Direct Translucent Shadows", &RtxOptions::Get()->enableDirectTranslucentShadowsObject());
+ ImGui::Checkbox("Direct Alpha Blended Shadows", &RtxOptions::Get()->enableDirectAlphaBlendShadowsObject());
ImGui::Checkbox("Indirect Translucent Shadows", &RtxOptions::Get()->enableIndirectTranslucentShadowsObject());
+ ImGui::Checkbox("Indirect Alpha Blended Shadows", &RtxOptions::Get()->enableIndirectAlphaBlendShadowsObject());
ImGui::Checkbox("Decal Material Blending", &RtxOptions::Get()->enableDecalMaterialBlendingObject());
ImGui::Checkbox("Billboard Orientation Correction", &RtxOptions::Get()->enableBillboardOrientationCorrectionObject());
if (RtxOptions::Get()->enableBillboardOrientationCorrection()) {
diff --git a/src/dxvk/rtx_render/rtx_context.cpp b/src/dxvk/rtx_render/rtx_context.cpp
index 0195bd40..5bd4540b 100644
--- a/src/dxvk/rtx_render/rtx_context.cpp
+++ b/src/dxvk/rtx_render/rtx_context.cpp
@@ -942,8 +942,10 @@ namespace dxvk {
constants.enableDirectLighting = RtxOptions::Get()->isDirectLightingEnabled();
constants.enableStochasticAlphaBlend = m_common->metaComposite().enableStochasticAlphaBlend();
constants.enableSeparateUnorderedApproximations = RtxOptions::Get()->enableSeparateUnorderedApproximations() && getResourceManager().getTLAS(Tlas::Unordered).accelStructure != nullptr;
- constants.enableDirectTranslucentShadows = RtxOptions::Get()->areDirectTranslucentShadowsEnabled();
- constants.enableIndirectTranslucentShadows = RtxOptions::Get()->areIndirectTranslucentShadowsEnabled();
+ constants.enableDirectTranslucentShadows = RtxOptions::enableDirectTranslucentShadows();
+ constants.enableDirectAlphaBlendShadows = RtxOptions::enableDirectAlphaBlendShadows();
+ constants.enableIndirectTranslucentShadows = RtxOptions::enableIndirectTranslucentShadows();
+ constants.enableIndirectAlphaBlendShadows = RtxOptions::enableIndirectAlphaBlendShadows();
constants.enableRussianRoulette = RtxOptions::Get()->isRussianRouletteEnabled();
constants.enableDemodulateRoughness = m_common->metaDemodulate().demodulateRoughness();
constants.enableReplaceDirectSpecularHitTWithIndirectSpecularHitT = RtxOptions::Get()->isReplaceDirectSpecularHitTWithIndirectSpecularHitTEnabled();
diff --git a/src/dxvk/rtx_render/rtx_instance_manager.cpp b/src/dxvk/rtx_render/rtx_instance_manager.cpp
index 7868b3dd..deb8f44a 100644
--- a/src/dxvk/rtx_render/rtx_instance_manager.cpp
+++ b/src/dxvk/rtx_render/rtx_instance_manager.cpp
@@ -1122,7 +1122,7 @@ namespace dxvk {
// Portal
mask |= OBJECT_MASK_PORTAL;
} else {
- mask |= OBJECT_MASK_OPAQUE;
+ mask |= currentInstance.surface.alphaState.isBlendingDisabled ? OBJECT_MASK_OPAQUE : OBJECT_MASK_ALPHA_BLEND;
}
}
}
diff --git a/src/dxvk/rtx_render/rtx_options.h b/src/dxvk/rtx_render/rtx_options.h
index 8d4862af..584340e6 100644
--- a/src/dxvk/rtx_render/rtx_options.h
+++ b/src/dxvk/rtx_render/rtx_options.h
@@ -490,8 +490,10 @@ namespace dxvk {
"Do note however the unordered nature of this resolving method may result in visual artifacts with large numbers of stacked particles due to difficulty in determining the intended order.\n"
"Additionally, unordered approximations will only be done on the first indirect ray bounce (as particles matter less in higher bounces), and only if enabled by its corresponding setting.");
RTX_OPTION("rtx", bool, trackParticleObjects, true, "Track last frame's corresponding particle object.");
- RTX_OPTION("rtx", bool, enableDirectTranslucentShadows, false, "Include OBJECT_MASK_TRANSLUCENT into primary visibility rays.");
- RTX_OPTION("rtx", bool, enableIndirectTranslucentShadows, false, "Include OBJECT_MASK_TRANSLUCENT into secondary visibility rays.");
+ RTX_OPTION_ENV("rtx", bool, enableDirectTranslucentShadows, false, "RTX_ENABLE_DIRECT_TRANSLUCENT_SHADOWS", "Calculate coloured shadows for translucent materials (i.e. glass, water) in direct lighting. In engineering terms: include OBJECT_MASK_TRANSLUCENT into primary visibility rays.");
+ RTX_OPTION_ENV("rtx", bool, enableDirectAlphaBlendShadows, true, "RTX_ENABLE_DIRECT_ALPHABLEND_SHADOWS", "Calculate shadows for semi-transparent materials (alpha blended) in direct lighting. In engineering terms: include OBJECT_MASK_ALPHA_BLEND into primary visibility rays.");
+ RTX_OPTION_ENV("rtx", bool, enableIndirectTranslucentShadows, false, "RTX_ENABLE_INDIRECT_TRANSLUCENT_SHADOWS", "Calculate coloured shadows for translucent materials (i.e. glass, water) in indirect lighting (i.e. reflections and GI). In engineering terms: include OBJECT_MASK_TRANSLUCENT into secondary visibility rays.");
+ RTX_OPTION_ENV("rtx", bool, enableIndirectAlphaBlendShadows, true, "RTX_ENABLE_INDIRECT_ALPHABLEND_SHADOWS", "Calculate shadows for semi-transparent (alpha blended) objects in indirect lighting (i.e. reflections and GI). In engineering terms: include OBJECT_MASK_ALPHA_BLEND into secondary visibility rays.");
RTX_OPTION("rtx", float, resolveTransparencyThreshold, 1.0f / 255.0f, "A threshold for which any opacity value below is considered totally transparent and may be safely skipped without as significant of a performance cost.");
RTX_OPTION("rtx", float, resolveOpaquenessThreshold, 254.0f / 255.0f, "A threshold for which any opacity value above is considered totally opaque.");
@@ -1325,8 +1327,6 @@ namespace dxvk {
uint8_t getPrimaryRayMaxInteractions() const { return primaryRayMaxInteractions(); }
uint8_t getPSRRayMaxInteractions() const { return psrRayMaxInteractions(); }
uint8_t getSecondaryRayMaxInteractions() const { return secondaryRayMaxInteractions(); }
- bool areDirectTranslucentShadowsEnabled() const { return enableDirectTranslucentShadows(); }
- bool areIndirectTranslucentShadowsEnabled() const { return enableIndirectTranslucentShadows(); }
float getResolveTransparencyThreshold() const { return resolveTransparencyThreshold(); }
float getResolveOpaquenessThreshold() const { return resolveOpaquenessThreshold(); }
diff --git a/src/dxvk/shaders/rtx/algorithm/integrator.slangh b/src/dxvk/shaders/rtx/algorithm/integrator.slangh
index 21b78ee6..24d2dc44 100644
--- a/src/dxvk/shaders/rtx/algorithm/integrator.slangh
+++ b/src/dxvk/shaders/rtx/algorithm/integrator.slangh
@@ -231,7 +231,8 @@ bool evalNEESecondary(
// Setup and trace the visibility ray
uint8_t rayMask = OBJECT_MASK_OPAQUE | (objectMask & OBJECT_MASK_ALL_DYNAMIC);
- if (cb.enableIndirectTranslucentShadows) rayMask |= OBJECT_MASK_TRANSLUCENT;
+ rayMask |= (cb.enableIndirectTranslucentShadows) ? OBJECT_MASK_TRANSLUCENT : 0;
+ rayMask |= (cb.enableIndirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
const bool isSubsurface = isSubsurfaceMaterial(opaqueSurfaceMaterialInteraction);
diff --git a/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh b/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh
index c084fd4a..97fd6074 100644
--- a/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh
+++ b/src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh
@@ -58,7 +58,8 @@ void evalNEEPrimary(
// Setup and trace the visibility ray
uint8_t rayMask = OBJECT_MASK_OPAQUE | (geometryFlags.objectMask & OBJECT_MASK_ALL_DYNAMIC);
- if (cb.enableDirectTranslucentShadows) rayMask |= OBJECT_MASK_TRANSLUCENT;
+ rayMask |= (cb.enableDirectTranslucentShadows) ? OBJECT_MASK_TRANSLUCENT : 0;
+ rayMask |= (cb.enableDirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
// We can encounter a POM surface during resolving (as it's a shared function) but if direct lighting for POM
// is disabled, we must also handle that user choice gracefully.
diff --git a/src/dxvk/shaders/rtx/algorithm/rtxdi/RtxdiApplicationBridge.slangh b/src/dxvk/shaders/rtx/algorithm/rtxdi/RtxdiApplicationBridge.slangh
index dbaf7b9e..0b38f740 100644
--- a/src/dxvk/shaders/rtx/algorithm/rtxdi/RtxdiApplicationBridge.slangh
+++ b/src/dxvk/shaders/rtx/algorithm/rtxdi/RtxdiApplicationBridge.slangh
@@ -711,7 +711,8 @@ bool RAB_TraceLightSampleVisibility(RAB_Surface surface, RAB_LightSample lightSa
}
uint8_t rayMask = OBJECT_MASK_OPAQUE | (surface.objectMask & OBJECT_MASK_ALL_DYNAMIC);
- if (cb.enableDirectTranslucentShadows) rayMask |= OBJECT_MASK_TRANSLUCENT;
+ rayMask |= (cb.enableDirectTranslucentShadows) ? OBJECT_MASK_TRANSLUCENT : 0;
+ rayMask |= (cb.enableDirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
const bool isSubsurface = isSubsurfaceMaterial(surface.opaqueSurfaceMaterialInteraction);
@@ -734,7 +735,8 @@ bool RAB_TraceGISampleVisibility(RAB_Surface surface, RAB_Surface neighborSurfac
uint8_t portalID = ReSTIRGI_PortalID2BitTo8Bit(reservoir.getPortalID());
if (portalID == RTXDI_INVALID_PORTAL_INDEX || portalID < numPortals)
{
- const uint8_t rayMask = OBJECT_MASK_OPAQUE | (surface.objectMask & OBJECT_MASK_ALL_DYNAMIC);
+ uint8_t rayMask = OBJECT_MASK_OPAQUE | (surface.objectMask & OBJECT_MASK_ALL_DYNAMIC);
+ rayMask |= (cb.enableIndirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
const float3 dstPosition = reservoir.getVisibilityPoint(neighborSurface.minimalSurfaceInteraction.position);
diff --git a/src/dxvk/shaders/rtx/algorithm/volume_integrator_helpers.slangh b/src/dxvk/shaders/rtx/algorithm/volume_integrator_helpers.slangh
index f2710f8f..5c973937 100644
--- a/src/dxvk/shaders/rtx/algorithm/volume_integrator_helpers.slangh
+++ b/src/dxvk/shaders/rtx/algorithm/volume_integrator_helpers.slangh
@@ -29,7 +29,7 @@ VisibilityResult evalVolumeNEEVisibility(
// to cast rays through them (as this would be expensive). We may want to add a bit more nuance here in the future to allow
// approximations of glass as large glass objects should ideally cast tinted shadows into particles, but we currently do not
// have a way to discriminate between translucency and opacity (and have no more bits available at least for now for this).
- uint8_t rayMask = OBJECT_MASK_OPAQUE;
+ uint8_t rayMask = OBJECT_MASK_OPAQUE | OBJECT_MASK_ALPHA_BLEND;
// Note: Culling disabled via visibilityModeDisableCulling to avoid light leaking through geometry as this is especially
// bad in volumetrics due to how the voxels leak through walls to begin with. Other NEE does not disable culling like this
diff --git a/src/dxvk/shaders/rtx/pass/instance_definitions.h b/src/dxvk/shaders/rtx/pass/instance_definitions.h
index 3bd9605a..1794a19f 100644
--- a/src/dxvk/shaders/rtx/pass/instance_definitions.h
+++ b/src/dxvk/shaders/rtx/pass/instance_definitions.h
@@ -70,6 +70,7 @@
#define OBJECT_MASK_TRANSLUCENT (1 << 0)
#define OBJECT_MASK_PORTAL (1 << 1)
+#define OBJECT_MASK_ALPHA_BLEND (1 << 2)
#define OBJECT_MASK_OPAQUE (1 << 3)
// Instances to be drawn and visible in ViewModel pass only
@@ -91,7 +92,7 @@
// Note: Sky excluded as often it should not be traced against when calculating visibility.
// ViewModel is excluded
-#define OBJECT_MASK_ALL_STANDARD (OBJECT_MASK_TRANSLUCENT | OBJECT_MASK_PORTAL | OBJECT_MASK_OPAQUE)
+#define OBJECT_MASK_ALL_STANDARD (OBJECT_MASK_TRANSLUCENT | OBJECT_MASK_PORTAL | OBJECT_MASK_OPAQUE | OBJECT_MASK_ALPHA_BLEND)
#define OBJECT_MASK_ALL (OBJECT_MASK_ALL_STANDARD)
/****************************** ~Instance Mask - Ordered TLAS ************************************************/
diff --git a/src/dxvk/shaders/rtx/pass/integrate/integrate_nee.comp.slang b/src/dxvk/shaders/rtx/pass/integrate/integrate_nee.comp.slang
index 65176c84..d3c21a1c 100644
--- a/src/dxvk/shaders/rtx/pass/integrate/integrate_nee.comp.slang
+++ b/src/dxvk/shaders/rtx/pass/integrate/integrate_nee.comp.slang
@@ -152,6 +152,8 @@ void main(uint2 threadIndex : SV_DispatchThreadID, uint2 LocalIndex : SV_GroupTh
evaluateUnshadowedLight(lightSample, opaqueSurfaceMaterialInteraction, minimalRayInteraction, inputDirection, diffuseLight, specularLight);
uint8_t rayMask = OBJECT_MASK_OPAQUE | (geometryFlags.objectMask & OBJECT_MASK_ALL_DYNAMIC);
+ rayMask |= (cb.enableIndirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
+
bool pomOpaqueSurfaceEncountered = cb.pomEnableNEECache && opaqueSurfaceMaterialInteractionHasHeightTexture(opaqueSurfaceMaterialInteraction);
isVisible = evalNEESecondary(
lightSample, invalidRayPortalIndex, surface.portalSpace, rayMask, pomOpaqueSurfaceEncountered,
diff --git a/src/dxvk/shaders/rtx/pass/raytrace_args.h b/src/dxvk/shaders/rtx/pass/raytrace_args.h
index adcaf8a2..ff74eb0c 100644
--- a/src/dxvk/shaders/rtx/pass/raytrace_args.h
+++ b/src/dxvk/shaders/rtx/pass/raytrace_args.h
@@ -225,8 +225,10 @@ struct RaytraceArgs {
uint enableSecondaryBounces;
uint enableSeparateUnorderedApproximations;
uint enableStochasticAlphaBlend;
- uint enableDirectTranslucentShadows;
- uint enableIndirectTranslucentShadows;
+ uint16_t enableDirectTranslucentShadows;
+ uint16_t enableDirectAlphaBlendShadows;
+ uint16_t enableIndirectTranslucentShadows;
+ uint16_t enableIndirectAlphaBlendShadows;
uint enableFirstBounceLobeProbabilityDithering;
uint enableUnorderedResolveInIndirectRays;
uint enableProbabilisticUnorderedResolveInIndirectRays;
diff --git a/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_final_shading.comp.slang b/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_final_shading.comp.slang
index dc6f727b..5772bd97 100644
--- a/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_final_shading.comp.slang
+++ b/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_final_shading.comp.slang
@@ -173,6 +173,7 @@ void main(uint2 threadIndex : SV_DispatchThreadID, uint2 LocalIndex : SV_GroupTh
if (portalID == invalidRayPortalIndex || portalID < cb.numActiveRayPortals)
{
uint8_t rayMask = OBJECT_MASK_OPAQUE | (geometryFlags.objectMask & OBJECT_MASK_ALL_DYNAMIC);
+ rayMask |= (cb.enableIndirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
// Use non-zero cone spread angle to reduce noise if there are alpha tested objects, like the fences in the portal game.
// The value is based on experiment. If incorrect shadows are observed, a smaller value should be used.
diff --git a/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_temporal_reuse.comp.slang b/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_temporal_reuse.comp.slang
index 70406c3f..e27ff866 100644
--- a/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_temporal_reuse.comp.slang
+++ b/src/dxvk/shaders/rtx/pass/rtxdi/restir_gi_temporal_reuse.comp.slang
@@ -234,6 +234,8 @@ void main(int2 thread_id : SV_DispatchThreadID)
// Calculate reflection hit T
uint8_t backupPortalID = RTXDI_INVALID_PORTAL_INDEX;
uint8_t rayMask = OBJECT_MASK_OPAQUE | (surface.objectMask & OBJECT_MASK_ALL_DYNAMIC);
+ rayMask |= (cb.enableIndirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
+
const float infiniteHitT = 1e5;
float3 dstPosition = worldPos + reflectionVector * infiniteHitT;
VisibilityResult visibility = traceVisibilityRay(surface.minimalSurfaceInteraction,
diff --git a/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_compute_gradients.comp.slang b/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_compute_gradients.comp.slang
index 6c67c07c..818bc578 100644
--- a/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_compute_gradients.comp.slang
+++ b/src/dxvk/shaders/rtx/pass/rtxdi/rtxdi_compute_gradients.comp.slang
@@ -36,7 +36,8 @@ float getSurfaceIlluminance(
// Setup and trace the visibility ray
uint8_t rayMask = OBJECT_MASK_OPAQUE | (objectMask & OBJECT_MASK_ALL_DYNAMIC);
- if (cb.enableDirectTranslucentShadows) rayMask |= OBJECT_MASK_TRANSLUCENT;
+ rayMask |= (cb.enableDirectTranslucentShadows) ? OBJECT_MASK_TRANSLUCENT : 0;
+ rayMask |= (cb.enableDirectAlphaBlendShadows) ? OBJECT_MASK_ALPHA_BLEND : 0;
VisibilityResult visibility = traceVisibilityRay(minimalSurfaceInteraction,
lightSample.position, rayMask,