Skip to content

Commit

Permalink
Merge branch 'sultimt/ignore-last' into 'main'
Browse files Browse the repository at this point in the history
Generalize ignore for non-primary textures

See merge request lightspeedrtx/dxvk-remix-nv!499
  • Loading branch information
sultim-t-nv committed Oct 3, 2023
2 parents d20988e + b419c2c commit 81cbd89
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 30 deletions.
1 change: 1 addition & 0 deletions RtxOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
|rtx.ignoreGameDirectionalLights|bool|False|Ignores any directional lights coming from the original game \(lights added via toolkit still work\)\.|
|rtx.ignoreGamePointLights|bool|False|Ignores any point lights coming from the original game \(lights added via toolkit still work\)\.|
|rtx.ignoreGameSpotLights|bool|False|Ignores any spot lights coming from the original game \(lights added via toolkit still work\)\.|
|rtx.ignoreLastTextureStage|bool|False|Removes the last texture bound to a draw call, when using fixed\-function pipeline\. Primary textures are untouched\.<br>Might be set to true, if a game applies a lightmap as last shading step, to omit the original lightmap data\.|
|rtx.indirectRaySpreadAngleFactor|float|0.05|A tuning factor applied to the spread angle calculated from the sampled lobe solid angle PDF\. Should be 0\-1\.<br>This scaled spread angle is used to widen a ray's cone angle after indirect lighting BRDF samples to essentially prefilter the effects of the BRDF lobe's spread which potentially may reduce noise from indirect rays \(e\.g\. reflections\)\.<br>Prefiltering will overblur detail however compared to the ground truth of casting multiple samples especially given this calculated spread angle is a basic approximation and ray cones to begin with are a simple approximation for ray pixel footprint\.<br>As such rather than using the spread angle fully this spread angle factor allows it to be scaled down to something more narrow so that overblurring can be minimized\. Similarly, setting this factor to 0 disables this cone angle widening feature\.|
|rtx.initializer.asyncAssetLoading|bool|True||
|rtx.initializer.asyncShaderFinalizing|bool|True||
Expand Down
1 change: 1 addition & 0 deletions documentation/TerrainSystem.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Terrain System

Terrain is handled by baking original game draw calls into a single material for the terrain. This bakes multiple layers of terrain as the original game composited them into a single material. Then during ray tracing the surfaces associated with terrain textures sample from the shared terrain material rather than from different material layers. Textures that are to be considered as terrain need to be tagged as [rtx.terrainTextures](../RtxOptions.md). The baking is done along a single geometric direction. Namely it bakes material projecting downwards onto a terrain plane and, therefore, only multi-layer surfaces that are horizontal for the most part should be tagged as terrain textures. Some vertical slope is acceptable, though the steeper the slope the larger terrain resolution is needed to reconstruct the full detail of the input textures during ray tracing. The vertical axis in the game is determined via [rtx.zUp](../RtxOptions.md) option. Terrain baker's texture resolution is keyed off from [rtx.sceneScale](../RtxOptions.md). Additionally, to remove original game's lighting data from the baked terrain, undesired textures can be marked as 'ignored' or 'lightmap'. This is beneficial, as the illumination needs to be handled by ray tracing alone, and a game's original lighting solution should be avoided.
Some games blend lightmaps on top of base textures in a single draw call, and in that case, enabling [rtx.ignoreLastTextureStage](../RtxOptions.md) (Game Setup -> Parameter Tuning -> Texture Parameters -> Ignore last texture stage) might be useful to automatically ignore such lightmaps, however, a game might bind not only a lightmap to the last texture stage but also some actual color textures, so the option should be used with care.

Game authoring steps:
- set [rtx.zUp](../RtxOptions.md)
Expand Down
49 changes: 19 additions & 30 deletions src/d3d9/d3d9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7005,20 +7005,6 @@ namespace dxvk {
}
};

// NV-DXVK start: ignored textures for terrain
auto getTextureHashForStage = [this](uint32_t stageIdx) {
if (const auto tex = GetCommonTexture(m_state.textures[stageIdx])) {
return tex->GetImage()->getHash();
}
return kEmptyHash;
};
auto isTerrainTextureAtStage = [&getTextureHashForStage](uint32_t stageIdx) {
XXH64_hash_t texHash = getTextureHashForStage(stageIdx);
return texHash != kEmptyHash && lookupHash(RtxOptions::terrainTextures(), texHash);
};
bool primaryTextureStageIsTerrain = false;
// NV-DXVK end

D3D9FFShaderKeyFS key;

uint32_t textureID = 0;
Expand All @@ -7040,12 +7026,6 @@ namespace dxvk {
break;
}

// NV-DXVK start: ignored textures for terrain
if (RtxOptions::Get()->enableRaytracing() && TerrainBaker::needsTerrainBaking()) {
primaryTextureStageIsTerrain = primaryTextureStageIsTerrain || isTerrainTextureAtStage(idx);
}
// NV-DXVK end

stage.ColorOp = data[DXVK_TSS_COLOROP];
stage.AlphaOp = data[DXVK_TSS_ALPHAOP];

Expand All @@ -7068,21 +7048,30 @@ namespace dxvk {
stage.ProjectedCount = (ttff & D3DTTFF_PROJECTED) ? count : 0;
}

// NV-DXVK start: ignored textures for terrain
// NOTE: The terrain baker reuses a draw call from rasterization with its
// NV-DXVK start: ignored secondary textures
// NOTE: The terrain baker and sky reuse a draw call from rasterization with its
// bound textures and other effects like fixed function texture stages.
// However, we also would like to skip textures marked as ignored / lightmap for the terrain baker,
// However, we also would like to skip textures marked as ignored / lightmap for those techniques,
// so a corresponding texture stage needs to be skipped in the draw call.
// This involves modifying D3D9FFShaderKeyFS, by which DXVK chooses a pixel shader for a draw call.
// And because of that draw call re-usage, the checks are done here.
if (primaryTextureStageIsTerrain && idx > 1) {
auto shouldOmitTextureAtStage = [&getTextureHashForStage](uint32_t stageIdx) {
XXH64_hash_t texHash = getTextureHashForStage(stageIdx);
return texHash != kEmptyHash
&& (lookupHash(RtxOptions::ignoreTextures(), texHash) || lookupHash(RtxOptions::lightmapTextures(), texHash));
// And because of that draw call re-usage, the checks are done here, and not in d3d9_rtx.
if (idx > 1 && RtxOptions::Get()->enableRaytracing()) {
auto shouldOmitTextureAtStage = [this](uint32_t stageIdx, bool isLast) {
if (const auto tex = GetCommonTexture(m_state.textures[stageIdx])) {
XXH64_hash_t texHash = tex->GetImage()->getHash();
if (texHash != kEmptyHash) {
if (isLast && RtxOptions::ignoreLastTextureStage()) {
return true;
}
if (lookupHash(RtxOptions::ignoreTextures(), texHash) || lookupHash(RtxOptions::lightmapTextures(), texHash)) {
return true;
}
}
}
return false;
};
const uint32_t lastStageIdx = idx - 1;
if (shouldOmitTextureAtStage(lastStageIdx)) {
if (shouldOmitTextureAtStage(lastStageIdx, true)) {
D3D9FFShaderStage& lastStage = key.Stages[lastStageIdx];
// make default
memset(&lastStage, 0, sizeof(D3D9FFShaderStage));
Expand Down
1 change: 1 addition & 0 deletions src/dxvk/imgui/dxvk_imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,7 @@ namespace dxvk {
ImGui::Indent();
ImGui::DragFloat("Force Cutout Alpha", &RtxOptions::Get()->forceCutoutAlphaObject(), 0.01f, 0.0f, 1.0f, "%.3f", sliderFlags);
ImGui::DragFloat("World Space UI Background Offset", &RtxOptions::Get()->worldSpaceUiBackgroundOffsetObject(), 0.01f, -FLT_MAX, FLT_MAX, "%.3f", sliderFlags);
ImGui::Checkbox("Ignore last texture stage", &RtxOptions::ignoreLastTextureStageObject());
ImGui::Unindent();
}

Expand Down
4 changes: 4 additions & 0 deletions src/dxvk/rtx_render/rtx_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,10 @@ namespace dxvk {
RTX_OPTION("rtx", bool, useBuffersDirectly, true, "When enabled Remix will use the incoming vertex buffers directly where possible instead of copying data. Note: setting the d3d9.allowDiscard to False will disable this option.");
RTX_OPTION("rtx", bool, alwaysCopyDecalGeometries, true, "When set to True tells the geometry processor to always copy decals geometry. This is an optimization flag to experiment with when rtx.useBuffersDirectly is True.");

RTX_OPTION("rtx", bool, ignoreLastTextureStage, false,
"Removes the last texture bound to a draw call, when using fixed-function pipeline. Primary textures are untouched.\n"
"Might be set to true, if a game applies a lightmap as last shading step, to omit the original lightmap data.");

// Automation Options
struct Automation {
RTX_OPTION_FLAG_ENV("rtx.automation", bool, disableBlockingDialogBoxes, false, RtxOptionFlags::NoSave, "RTX_AUTOMATION_DISABLE_BLOCKING_DIALOG_BOXES",
Expand Down

0 comments on commit 81cbd89

Please sign in to comment.