Skip to content

Commit

Permalink
Merge branch 'dev/adunn/exclude_alpha_shadows' into 'main'
Browse files Browse the repository at this point in the history
Allow users to disable semi-transparent shadows for direction/indirect lighting to improve performance.

See merge request lightspeedrtx/dxvk-remix-nv!1138
  • Loading branch information
AlexDunn committed Nov 20, 2024
2 parents 32e26ff + a88a588 commit 4a713fd
Show file tree
Hide file tree
Showing 15 changed files with 37 additions and 18 deletions.
6 changes: 4 additions & 2 deletions RtxOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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\.<br>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\)\.|
Expand All @@ -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\.<br>Enables or disables remapping functionality relating to the max distance parameter of fixed function fog\.<br>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\.<br>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\.<br>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\.<br>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\.<br>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\.<br>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\.<br>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\.|
Expand Down
2 changes: 2 additions & 0 deletions src/dxvk/imgui/dxvk_imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
6 changes: 4 additions & 2 deletions src/dxvk/rtx_render/rtx_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/dxvk/rtx_render/rtx_instance_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/dxvk/rtx_render/rtx_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down Expand Up @@ -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(); }

Expand Down
3 changes: 2 additions & 1 deletion src/dxvk/shaders/rtx/algorithm/integrator.slangh
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 2 additions & 1 deletion src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/dxvk/shaders/rtx/pass/instance_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ************************************************/
Expand Down
2 changes: 2 additions & 0 deletions src/dxvk/shaders/rtx/pass/integrate/integrate_nee.comp.slang
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions src/dxvk/shaders/rtx/pass/raytrace_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<visibilityModeAccurateHitDistance>(surface.minimalSurfaceInteraction,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<visibilityModeEnableTranslucentMaterials | visibilityModeEnableSubsurfaceMaterials>(minimalSurfaceInteraction,
lightSample.position, rayMask,
Expand Down

0 comments on commit 4a713fd

Please sign in to comment.