mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 09:19:18 +02:00
Some renaming
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# This file is part of the FidelityFX SDK.
|
||||
#
|
||||
# Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files(the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions :
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
set(CLASSIFIER_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(CLASSIFIER_PERMUTATION_ARGS
|
||||
-DFFX_CLASSIFIER_OPTION_INVERTED_DEPTH={0,1}
|
||||
-DFFX_CLASSIFIER_OPTION_CLASSIFIER_MODE={0,1}
|
||||
)
|
||||
|
||||
set(CLASSIFIER_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/classifier")
|
||||
|
||||
if (NOT CLASSIFIER_SHADER_EXT)
|
||||
set(CLASSIFIER_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB CLASSIFIER_SHADERS
|
||||
"shaders/classifier/ffx_classifier_shadows_pass.${CLASSIFIER_SHADER_EXT}"
|
||||
"shaders/classifier/ffx_classifier_reflections_pass.${CLASSIFIER_SHADER_EXT}")
|
||||
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${CLASSIFIER_BASE_ARGS}" "${CLASSIFIER_API_BASE_ARGS}" "${CLASSIFIER_PERMUTATION_ARGS}" "${CLASSIFIER_INCLUDE_ARGS}"
|
||||
"${CLASSIFIER_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" CLASSIFIER_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${CLASSIFIER_PERMUTATION_OUTPUTS}")
|
||||
102
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_common.h
vendored
Normal file
102
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_common.h
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#define TILE_SIZE_X 8
|
||||
#define TILE_SIZE_Y 4
|
||||
#define k_pushOff 4e-2f
|
||||
#define k_tileSize FfxUInt32x2(TILE_SIZE_X, TILE_SIZE_Y)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// I/O Structures
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
struct Tile
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxUInt16x2 location;
|
||||
#else
|
||||
FfxUInt32x2 location; // Dead code, f32 not supported
|
||||
#endif
|
||||
FfxUInt32 mask;
|
||||
|
||||
FfxFloat32 minT;
|
||||
FfxFloat32 maxT;
|
||||
};
|
||||
|
||||
Tile TileCreate(const FfxUInt32x2 id)
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxUInt16x2 f16ID = FfxUInt16x2(FfxUInt16(id.x), FfxUInt16(id.y));
|
||||
Tile t = { f16ID, 0, k_pushOff, FFX_POSITIVE_INFINITY_FLOAT }; // skyHeight
|
||||
#else
|
||||
Tile t = { id, 0, k_pushOff, FFX_POSITIVE_INFINITY_FLOAT }; //skyHeight
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
FfxUInt32x4 TileToUint(const Tile t)
|
||||
{
|
||||
const FfxUInt32x4 ui = FfxUInt32x4((FfxUInt32(t.location.y) << 16) | FfxUInt32(t.location.x), t.mask, ffxAsUInt32(t.minT), ffxAsUInt32(t.maxT));
|
||||
return ui;
|
||||
}
|
||||
|
||||
Tile TileFromUint(const FfxUInt32x4 ui)
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxUInt16x2 id = FfxUInt16x2(ui.x & 0xffff, (ui.x >> 16) & 0xffff);
|
||||
#else
|
||||
FfxUInt32x2 id;
|
||||
#endif
|
||||
Tile t = { id, ui.y, ffxAsFloat(ui.z), ffxAsFloat(ui.w) };
|
||||
return t;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// helper functions
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
FfxUInt32 LaneIdToBitShift(FfxUInt32x2 localID)
|
||||
{
|
||||
return localID.y * TILE_SIZE_X + localID.x;
|
||||
}
|
||||
|
||||
FfxUInt32 BoolToWaveMask(FfxBoolean b, FfxUInt32x2 localID)
|
||||
{
|
||||
const FfxUInt32 value = FfxUInt32(b) << LaneIdToBitShift(localID);
|
||||
return ffxWaveOr(value);
|
||||
}
|
||||
|
||||
FfxBoolean WaveMaskToBool(FfxUInt32 mask, FfxUInt32x2 localID)
|
||||
{
|
||||
return FfxBoolean((FfxUInt32(1) << LaneIdToBitShift(localID)) & mask);
|
||||
}
|
||||
|
||||
|
||||
#define k_pi 3.1415926535897932384f
|
||||
#define k_2pi 2.0f * k_pi
|
||||
#define k_pi_over_2 0.5f * k_pi
|
||||
|
||||
// made using a modified version of https://www.asawicki.info/news_952_poisson_disc_generator
|
||||
#define k_poissonDiscSampleCountLow 8
|
||||
#define k_poissonDiscSampleCountMid 16
|
||||
#define k_poissonDiscSampleCountHigh 24
|
||||
#define k_poissonDiscSampleCountUltra 32
|
||||
378
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections.h
vendored
Normal file
378
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections.h
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#define TILE_CLASS_FULL_SW 0
|
||||
#define TILE_CLASS_HALF_SW 1
|
||||
#define TILE_CLASS_FULL_HW 2
|
||||
|
||||
#define FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
#include "ffx_classifier_reflections_common.h"
|
||||
|
||||
FfxFloat32x2 Hash22(FfxFloat32x2 p)
|
||||
{
|
||||
FfxFloat32x3 p3 = ffxFract(FfxFloat32x3(p.xyx) * FfxFloat32x3(.1031, .1030, .0973));
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return ffxFract((p3.xx + p3.yz) * p3.zy);
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetRandom(FfxUInt32x2 index)
|
||||
{
|
||||
FfxFloat32 v = 0.152f;
|
||||
FfxFloat32x2 pos = (FfxFloat32x2(index) * v + FfxFloat32(FrameIndex()) / 60.0f * 1500.0f + 50.0f);
|
||||
return Hash22(pos);
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetRandomLastFrame(FfxUInt32x2 index)
|
||||
{
|
||||
FfxFloat32 v = 0.152f;
|
||||
FfxFloat32x2 pos = (FfxFloat32x2(index) * v + FfxFloat32(FrameIndex() - 1) / 60.0f * 1500.0f + 50.0f);
|
||||
return Hash22(pos);
|
||||
}
|
||||
|
||||
FfxBoolean IsSW(FfxFloat32 hitcounter, FfxFloat32 misscounter, FfxFloat32 rnd)
|
||||
{
|
||||
// Turn a random tile full hybrid once in a while to get the opportunity for testing HiZ traversal
|
||||
return rnd <= (+HybridSpawnRate() + hitcounter - misscounter * HybridMissWeight());
|
||||
}
|
||||
|
||||
FfxBoolean IsConverged(FfxUInt32x2 pixel_coordinate, FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat32x2 motion_vector = LoadMotionVector(FfxInt32x2(pixel_coordinate));
|
||||
;
|
||||
return SampleVarianceHistory(uv - motion_vector) < VRTVarianceThreshold();
|
||||
}
|
||||
|
||||
// In case no ray is traced we need to clear the buffers
|
||||
void FillEnvironment(FfxUInt32x2 ray_coord, FfxFloat32 factor)
|
||||
{
|
||||
// Fall back to the environment probe
|
||||
FfxUInt32x2 screen_size = FfxUInt32x2(ReflectionWidth(), ReflectionHeight());
|
||||
FfxFloat32x2 uv = (ray_coord + 0.5) * InverseRenderSize();
|
||||
FfxFloat32x3 world_space_normal = LoadWorldSpaceNormal(FfxInt32x2(ray_coord));
|
||||
FfxFloat32 roughness = LoadRoughnessFromMaterialParametersInput(FfxUInt32x3(ray_coord, 0));
|
||||
FfxFloat32 z = GetInputDepth(ray_coord);
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, z);
|
||||
FfxFloat32x3 view_space_ray = ScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 view_space_ray_direction = normalize(view_space_ray);
|
||||
FfxFloat32x3 view_space_surface_normal = FFX_MATRIX_MULTIPLY(ViewMatrix(), FfxFloat32x4(world_space_normal, 0)).xyz;
|
||||
FfxFloat32x3 view_space_reflected_direction = reflect(view_space_ray_direction, view_space_surface_normal);
|
||||
FfxFloat32x3 world_space_reflected_direction = FFX_MATRIX_MULTIPLY(InvView(), FfxFloat32x4(view_space_reflected_direction, 0)).xyz;
|
||||
FfxFloat32x3 world_space_ray_origin = FFX_MATRIX_MULTIPLY(InvView(), FfxFloat32x4(view_space_ray, 1)).xyz;
|
||||
|
||||
FfxFloat32x3 env_sample = SampleEnvironmentMap(world_space_reflected_direction, sqrt(roughness));
|
||||
|
||||
if (!any(isnan(env_sample)))
|
||||
StoreRadiance(ray_coord, env_sample.xyzz * factor);
|
||||
else
|
||||
StoreRadiance(ray_coord, (0.0f).xxxx);
|
||||
}
|
||||
|
||||
void ZeroBuffers(FfxUInt32x2 dispatch_thread_id)
|
||||
{
|
||||
StoreRadiance(dispatch_thread_id, (0.0f).xxxx);
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetSurfaceReprojection(FfxFloat32x2 uv, FfxFloat32x2 motion_vector)
|
||||
{
|
||||
// Reflector position reprojection
|
||||
FfxFloat32x2 history_uv = uv - motion_vector;
|
||||
return history_uv;
|
||||
}
|
||||
|
||||
FfxBoolean IsBaseRay(FfxUInt32x2 dispatch_thread_id, FfxUInt32 samples_per_quad)
|
||||
{
|
||||
switch (samples_per_quad)
|
||||
{
|
||||
case 1:
|
||||
return ((dispatch_thread_id.x & 1) | (dispatch_thread_id.y & 1)) == 0; // Deactivates 3 out of 4 rays
|
||||
case 2:
|
||||
return (dispatch_thread_id.x & 1) == (dispatch_thread_id.y & 1); // Deactivates 2 out of 4 rays. Keeps diagonal.
|
||||
default: // case 4:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 g_TileCount;
|
||||
FFX_GROUPSHARED FfxInt32 g_TileClass;
|
||||
FFX_GROUPSHARED FfxUInt32 g_SWCount;
|
||||
FFX_GROUPSHARED FfxUInt32 g_SWCountTotal;
|
||||
FFX_GROUPSHARED FfxUInt32 g_base_ray_index_sw;
|
||||
|
||||
void ClassifyTiles(FfxUInt32x2 dispatch_thread_id,
|
||||
FfxUInt32x2 group_thread_id,
|
||||
FfxFloat32 roughness,
|
||||
FfxFloat32x3 view_space_surface_normal,
|
||||
FfxFloat32 depth,
|
||||
FfxInt32x2 screen_size,
|
||||
FfxUInt32 samples_per_quad,
|
||||
FfxBoolean enable_temporal_variance_guided_tracing,
|
||||
FfxBoolean enable_hitcounter,
|
||||
FfxBoolean enable_screen_space_tracing,
|
||||
FfxBoolean enable_hw_ray_tracing)
|
||||
{
|
||||
FfxUInt32 flat_group_thread_id = group_thread_id.x + group_thread_id.y * 8;
|
||||
FfxBoolean is_first_lane_of_wave = ffxWaveIsFirstLane();
|
||||
|
||||
if (group_thread_id.x == 0 && group_thread_id.y == 0)
|
||||
{
|
||||
// Initialize group shared variables
|
||||
g_TileCount = 0;
|
||||
g_SWCount = 0;
|
||||
g_SWCountTotal = 0;
|
||||
g_base_ray_index_sw = 0;
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
// Initialize per 8x8 tile hit counter
|
||||
if (enable_hitcounter)
|
||||
{
|
||||
// In case we do hybrid
|
||||
if (enable_screen_space_tracing && enable_hw_ray_tracing)
|
||||
{
|
||||
// Feedback counters
|
||||
// See Intersect.hlsl
|
||||
FfxUInt32 hitcounter = 0;
|
||||
|
||||
// Use surface motion vectors of one of the 8x8 pixels in the tile to reproject statistics from the previous frame
|
||||
// Helps a lot in movement to sustain temoporal coherence
|
||||
#define FFX_CLASSIFIER_CLASSIFICATION_REPROJECT_HITCOUNTER
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_REPROJECT_HITCOUNTER
|
||||
{
|
||||
// Grab motion vector from a random point in the subgroup
|
||||
FfxFloat32x2 xi = GetRandom(dispatch_thread_id.xy / 8);
|
||||
FfxInt32x2 mix = FfxInt32x2(xi * 8.0f);
|
||||
FfxFloat32x2 motion_vector = LoadMotionVector(FfxInt32x2(dispatch_thread_id) + mix);
|
||||
FfxFloat32x2 uv8 = (FfxFloat32x2(dispatch_thread_id.xy + mix)) / FFX_DNSR_Reflections_RoundUp8(screen_size);
|
||||
FfxFloat32x2 surface_reprojection_uv = GetSurfaceReprojection(uv8, motion_vector);
|
||||
hitcounter = LoadHitCounterHistory(FfxUInt32x2(surface_reprojection_uv * (FFX_DNSR_Reflections_RoundUp8(screen_size) / 8)));
|
||||
}
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_REPROJECT_HITCOUNTER
|
||||
|
||||
// Use 3x3 region to grab the biggest success rate and create a safe band of hybrid rays to hide artefacts in movements
|
||||
#define FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
FfxUInt32 same_pixel_hitcounter = 0;
|
||||
// We need a safe band for some geometry not in the BVH to avoid fireflies
|
||||
const FfxInt32 radius = 1;
|
||||
for (FfxInt32 y = -radius; y <= radius; y++)
|
||||
{
|
||||
for (FfxInt32 x = -radius; x <= radius; x++)
|
||||
{
|
||||
FfxUInt32 pt = LoadHitCounterHistory(dispatch_thread_id.xy / 8 + FfxInt32x2(x, y));
|
||||
if (FFX_Hitcounter_GetSWHits(pt) > FFX_Hitcounter_GetSWHits(same_pixel_hitcounter))
|
||||
same_pixel_hitcounter = pt;
|
||||
}
|
||||
}
|
||||
#else // FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
FfxUInt32 same_pixel_hitcounter = LoadHitCounterHistory(dispatch_thread_id.xy / 8);
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
|
||||
// Again compare with the same pixel and Pick the one with the biggest success rate
|
||||
if (FFX_Hitcounter_GetSWHits(hitcounter) < FFX_Hitcounter_GetSWHits(same_pixel_hitcounter))
|
||||
hitcounter = same_pixel_hitcounter;
|
||||
|
||||
FfxFloat32 rnd = GetRandom(dispatch_thread_id.xy / 8).x;
|
||||
FfxFloat32 rnd_last = GetRandomLastFrame(dispatch_thread_id.xy / 8).x;
|
||||
FfxFloat32 sw_hitcount_new = FfxFloat32(FFX_Hitcounter_GetSWHits(hitcounter));
|
||||
FfxFloat32 sw_hitcount_old = FfxFloat32(FFX_Hitcounter_GetOldSWHits(hitcounter));
|
||||
FfxFloat32 sw_misscount_new = FfxFloat32(FFX_Hitcounter_GetSWMisses(hitcounter));
|
||||
FfxFloat32 sw_misscount_old = FfxFloat32(FFX_Hitcounter_GetOldSWMisses(hitcounter));
|
||||
FfxBoolean new_class = IsSW(sw_hitcount_new, sw_misscount_new, rnd);
|
||||
FfxBoolean old_class = IsSW(sw_hitcount_old, sw_misscount_old, rnd_last);
|
||||
|
||||
// To make transition less obvious we do and extra checkerboard stage
|
||||
if (new_class == old_class)
|
||||
{
|
||||
if (new_class)
|
||||
{
|
||||
g_TileClass = TILE_CLASS_FULL_SW;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_TileClass = TILE_CLASS_FULL_HW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_TileClass = TILE_CLASS_HALF_SW;
|
||||
}
|
||||
sw_hitcount_old = sw_hitcount_new;
|
||||
sw_misscount_old = sw_misscount_new;
|
||||
StoreHitCounter(dispatch_thread_id.xy / 8,
|
||||
(FfxUInt32(clamp(sw_hitcount_old, 0.0f, 255.0f)) << 8) | (FfxUInt32(clamp(sw_misscount_old, 0.0f, 255.0f)) << 24));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_TileClass = TILE_CLASS_FULL_SW;
|
||||
}
|
||||
#endif // FFX_HYBRID_REFLECTIONS
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// First we figure out on a per thread basis if we need to shoot a reflection ray
|
||||
FfxBoolean is_on_screen = (dispatch_thread_id.x < screen_size.x) && (dispatch_thread_id.y < screen_size.y);
|
||||
// Allow for additional engine side checks. For example engines could additionally only cast reflection rays for specific depth ranges
|
||||
FfxBoolean is_surface = !IsBackground(depth);
|
||||
// Don't shoot a ray on very rough surfaces
|
||||
FfxBoolean is_glossy_reflection = is_surface && IsGlossyReflection(roughness);
|
||||
FfxBoolean needs_ray = is_on_screen && is_glossy_reflection;
|
||||
|
||||
// Decide which ray to keep
|
||||
FfxBoolean is_base_ray = IsBaseRay(dispatch_thread_id, samples_per_quad);
|
||||
FfxBoolean is_converged = true;
|
||||
if (enable_temporal_variance_guided_tracing)
|
||||
{
|
||||
FfxFloat32x2 uv = (dispatch_thread_id + 0.5) / screen_size;
|
||||
is_converged = IsConverged(dispatch_thread_id, uv);
|
||||
}
|
||||
|
||||
needs_ray = needs_ray && (is_base_ray || !is_converged);
|
||||
|
||||
// Extra check for back-facing rays, fresnel, mirror etc.
|
||||
if (abs(view_space_surface_normal.z) > ReflectionsBackfacingThreshold())
|
||||
{
|
||||
FillEnvironment(dispatch_thread_id, IBLFactor());
|
||||
needs_ray = false;
|
||||
}
|
||||
|
||||
// We need denoiser even for mirrors since ssr/hw transition ends up creating poping tile firefies.
|
||||
FfxBoolean needs_denoiser = is_glossy_reflection;
|
||||
|
||||
// Next we have to figure out for which pixels that ray is creating the values for. Thus, if we have to copy its value horizontal, vertical or across.
|
||||
FfxBoolean require_copy =
|
||||
!needs_ray && needs_denoiser; // Our pixel only requires a copy if we want to run a denoiser on it but don't want to shoot a ray for it.
|
||||
|
||||
FfxBoolean copy_horizontal = FfxBoolean(ffxWaveXorU1(FfxUInt32(require_copy), 1)) && (samples_per_quad != 4) && is_base_ray; // QuadReadAcrossX
|
||||
FfxBoolean copy_vertical = FfxBoolean(ffxWaveXorU1(FfxUInt32(require_copy), 2)) && (samples_per_quad == 1) && is_base_ray; // QuadReadAcrossY
|
||||
FfxBoolean copy_diagonal = FfxBoolean(ffxWaveXorU1(FfxUInt32(require_copy), 3)) && (samples_per_quad == 1) && is_base_ray; // QuadReadAcrossDiagonal
|
||||
|
||||
FfxBoolean needs_sw_ray = true;
|
||||
|
||||
// In case there's only software rays we don't do hybridization
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
needs_sw_ray = needs_ray && enable_screen_space_tracing;
|
||||
|
||||
FfxBoolean needs_hw_ray = false;
|
||||
if (enable_hw_ray_tracing && roughness < RTRoughnessThreshold())
|
||||
{
|
||||
FfxBoolean checkerboard = ((group_thread_id.x ^ group_thread_id.y) & 1) == 0;
|
||||
needs_sw_ray = needs_sw_ray && ((g_TileClass == TILE_CLASS_FULL_SW ? true : (g_TileClass == TILE_CLASS_HALF_SW ? checkerboard : false)));
|
||||
needs_hw_ray = needs_ray && !needs_sw_ray;
|
||||
}
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
FfxUInt32 local_ray_index_in_wave_sw = ffxWavePrefixCountBits(needs_sw_ray);
|
||||
FfxUInt32 wave_ray_offset_in_group_sw;
|
||||
FfxUInt32 wave_ray_count_sw = ffxWaveActiveCountBits(needs_sw_ray);
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
FfxUInt32 local_ray_index_in_wave_hw = ffxWavePrefixCountBits(needs_hw_ray);
|
||||
FfxUInt32 wave_ray_count_hw = ffxWaveActiveCountBits(needs_hw_ray);
|
||||
FfxUInt32 base_ray_index_hw = 0;
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
if (is_first_lane_of_wave)
|
||||
{
|
||||
if (wave_ray_count_sw > 0)
|
||||
{
|
||||
#ifdef FFX_GLSL
|
||||
wave_ray_offset_in_group_sw = FFX_ATOMIC_ADD(g_SWCount, FfxInt32(wave_ray_count_sw));
|
||||
#else
|
||||
InterlockedAdd(g_SWCount, wave_ray_count_sw, wave_ray_offset_in_group_sw);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
if (wave_ray_count_hw > 0)
|
||||
IncrementRayCounterHW(wave_ray_count_hw, base_ray_index_hw);
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
}
|
||||
|
||||
base_ray_index_hw = ffxWaveReadLaneFirstU1(base_ray_index_hw);
|
||||
wave_ray_offset_in_group_sw = ffxWaveReadLaneFirstU1(wave_ray_offset_in_group_sw);
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
if (flat_group_thread_id == 0 && g_SWCount > 0)
|
||||
{
|
||||
// [IMPORTANT] We need to round up to the multiple of 32 for software rays, because of the atomic increment coalescing optimization
|
||||
g_SWCountTotal = g_SWCount < 32 ? 32 : (g_SWCount > 32 ? 64 : 32);
|
||||
IncrementRayCounterSW(g_SWCountTotal, g_base_ray_index_sw);
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
if (needs_sw_ray)
|
||||
{
|
||||
FfxUInt32 ray_index_sw = g_base_ray_index_sw + wave_ray_offset_in_group_sw + local_ray_index_in_wave_sw;
|
||||
StoreRay(ray_index_sw, dispatch_thread_id, copy_horizontal, copy_vertical, copy_diagonal);
|
||||
}
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
else if (needs_hw_ray)
|
||||
{
|
||||
FfxUInt32 ray_index_hw = base_ray_index_hw + local_ray_index_in_wave_hw;
|
||||
StoreRayHW(ray_index_hw, dispatch_thread_id, copy_horizontal, copy_vertical, copy_diagonal);
|
||||
}
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
if (flat_group_thread_id < g_SWCountTotal - g_SWCount)
|
||||
{
|
||||
// [IMPORTANT] We need to round up to the multiple of 32 for software rays, because of the atomic increment coalescing optimization
|
||||
// Emit helper(dead) lanes to fill up 32 lanes per 8x8 tile
|
||||
FfxUInt32 ray_index_sw = g_base_ray_index_sw + g_SWCount + flat_group_thread_id;
|
||||
StoreRaySWHelper(ray_index_sw);
|
||||
}
|
||||
|
||||
// We only need denoiser if we trace any rays in the tile
|
||||
if (is_first_lane_of_wave && (wave_ray_count_sw > 0
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|| wave_ray_count_hw > 0
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
))
|
||||
{
|
||||
FFX_ATOMIC_ADD(g_TileCount, 1);
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER; // Wait until all waves wrote into g_TileCount
|
||||
|
||||
if (g_TileCount > 0)
|
||||
{
|
||||
if (group_thread_id.x == 0 && group_thread_id.y == 0)
|
||||
{
|
||||
FfxUInt32 tile_index;
|
||||
IncrementDenoiserTileCounter(tile_index);
|
||||
StoreDenoiserTile(tile_index, dispatch_thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!needs_ray && !require_copy) // Discarded for some reason
|
||||
|| (needs_ray && !needs_hw_ray && !needs_sw_ray) // Or needs a ray but was discarded for some other reason
|
||||
)
|
||||
{
|
||||
if (is_surface)
|
||||
{
|
||||
FillEnvironment(dispatch_thread_id, IBLFactor());
|
||||
}
|
||||
else
|
||||
ZeroBuffers(dispatch_thread_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ffx_classifier_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_CB_CLASSIFIER, std140) uniform cbClassifierReflections_t
|
||||
{
|
||||
FfxFloat32Mat4 invViewProjection;
|
||||
FfxFloat32Mat4 projection;
|
||||
FfxFloat32Mat4 invProjection;
|
||||
FfxFloat32Mat4 viewMatrix;
|
||||
FfxFloat32Mat4 invView;
|
||||
FfxFloat32Mat4 prevViewProjection;
|
||||
FfxUInt32x2 renderSize;
|
||||
FfxFloat32x2 inverseRenderSize;
|
||||
FfxFloat32 iblFactor;
|
||||
FfxUInt32 frameIndex;
|
||||
FfxUInt32 samplesPerQuad;
|
||||
FfxUInt32 temporalVarianceGuidedTracingEnabled;
|
||||
FfxFloat32 globalRoughnessThreshold;
|
||||
FfxFloat32 rtRoughnessThreshold;
|
||||
FfxUInt32 mask;
|
||||
FfxUInt32 reflectionWidth;
|
||||
FfxUInt32 reflectionHeight;
|
||||
FfxFloat32 hybridMissWeight;
|
||||
FfxFloat32 hybridSpawnRate;
|
||||
FfxFloat32 vrtVarianceThreshold;
|
||||
FfxFloat32 reflectionsBackfacingThreshold;
|
||||
FfxUInt32 randomSamplesPerPixel;
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
FfxUInt32 roughnessChannel;
|
||||
FfxUInt32 isRoughnessPerceptual;
|
||||
} cbClassifierReflection;
|
||||
|
||||
FfxFloat32Mat4 InvViewProjection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.invViewProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 Projection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.projection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvProjection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.invProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewMatrix()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.viewMatrix;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvView()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.invView;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 PrevViewProjection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.prevViewProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32x2 RenderSize()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.renderSize;
|
||||
#else
|
||||
return FfxUInt32x2(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 InverseRenderSize()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.inverseRenderSize;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 IBLFactor()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.iblFactor;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 FrameIndex()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.frameIndex;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 SamplesPerQuad()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.samplesPerQuad;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxBoolean TemporalVarianceGuidedTracingEnabled()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return FfxBoolean(cbClassifierReflection.temporalVarianceGuidedTracingEnabled);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 RoughnessThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.globalRoughnessThreshold;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 RTRoughnessThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.rtRoughnessThreshold;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 Mask()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.mask;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionWidth()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.reflectionWidth;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionHeight()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.reflectionHeight;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 HybridMissWeight()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.hybridMissWeight;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 HybridSpawnRate()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.hybridSpawnRate;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 VRTVarianceThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.vrtVarianceThreshold;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 ReflectionsBackfacingThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.reflectionsBackfacingThreshold;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 RandomSamplesPerPixel()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.randomSamplesPerPixel;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.motionVectorScale;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.normalsUnpackMul;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.normalsUnpackAdd;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 RoughnessChannel()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.roughnessChannel;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxBoolean IsRoughnessPerceptual()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return FfxBoolean(cbClassifierReflection.isRoughnessPerceptual);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
|
||||
layout (set = 0, binding = 1000) uniform sampler s_EnvironmentMapSampler;
|
||||
layout (set = 0, binding = 1001) uniform sampler s_LinearSampler;
|
||||
|
||||
// SRVs
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_DEPTH
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_DEPTH) uniform texture2D r_input_depth;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS) uniform texture2D r_input_motion_vectors;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_NORMAL
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_NORMAL) uniform texture2D r_input_normal;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS) uniform texture2D r_input_material_parameters;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP) uniform textureCube r_input_environment_map;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_VARIANCE_HISTORY
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_VARIANCE_HISTORY) uniform texture2D r_variance_history;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY
|
||||
layout(set = 0, binding = CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY) uniform utexture2D r_hit_counter_history;
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined CLASSIFIER_BIND_UAV_RADIANCE
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_RADIANCE, rgba32f) uniform image2D rw_radiance;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_LIST
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_RAY_LIST, std430) buffer rw_ray_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_ray_list;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HW_RAY_LIST
|
||||
layout(set = 0, binding = CLASSIFIER_BIND_UAV_HW_RAY_LIST, std430) buffer rw_hw_ray_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_hw_ray_list;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST, std430) buffer rw_denoiser_tile_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_denoiser_tile_list;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_COUNTER
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_RAY_COUNTER, std430) buffer rw_ray_counter_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_ray_counter;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS, r32f) uniform image2D rw_extracted_roughness;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HIT_COUNTER
|
||||
layout(set = 0, binding = CLASSIFIER_BIND_UAV_HIT_COUNTER, r32ui) uniform uimage2D rw_hit_counter;
|
||||
#endif
|
||||
|
||||
|
||||
FfxFloat32x3 LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_NORMAL)
|
||||
return normalize(NormalsUnpackMul() * texelFetch(r_input_normal, pixel_coordinate, 0).xyz + NormalsUnpackAdd());
|
||||
#else
|
||||
return FfxFloat32x3(0.f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x3 SampleEnvironmentMap(FfxFloat32x3 direction, FfxFloat32 preceptualRoughness)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP)
|
||||
FfxInt32x2 cubeSize = textureSize(r_input_environment_map, 0);
|
||||
FfxInt32 maxMipLevel = FfxInt32(log2(FfxFloat32(cubeSize.x > 0 ? cubeSize.x : 1)));
|
||||
FfxFloat32 lod = clamp(preceptualRoughness * FfxFloat32(maxMipLevel), 0.0, FfxFloat32(maxMipLevel));
|
||||
return textureLod(samplerCube(r_input_environment_map, s_EnvironmentMapSampler), direction, lod).xyz * IBLFactor();
|
||||
#else
|
||||
return FfxFloat32x3(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IncrementRayCounterSW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
original_value = atomicAdd(rw_ray_counter.data[0], value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IncrementRayCounterHW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
original_value = atomicAdd(rw_ray_counter.data[4], value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IncrementDenoiserTileCounter(FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
original_value = atomicAdd(rw_ray_counter.data[2], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 PackRayCoords(FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 ray_x_15bit = ray_coord.x & 32767; // 0b111111111111111
|
||||
FfxUInt32 ray_y_14bit = ray_coord.y & 16383; // 0b11111111111111;
|
||||
FfxUInt32 copy_horizontal_1bit = copy_horizontal ? 1 : 0;
|
||||
FfxUInt32 copy_vertical_1bit = copy_vertical ? 1 : 0;
|
||||
FfxUInt32 copy_diagonal_1bit = copy_diagonal ? 1 : 0;
|
||||
|
||||
FfxUInt32 packed = (copy_diagonal_1bit << 31) | (copy_vertical_1bit << 30) | (copy_horizontal_1bit << 29) | (ray_y_14bit << 15) | (ray_x_15bit << 0);
|
||||
return packed;
|
||||
}
|
||||
|
||||
void StoreRay(FfxUInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_ray_list.data[index] = packedRayCoords;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreRaySWHelper(FfxUInt32 index)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
rw_ray_list.data[index] = 0xffffffffu;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreRayHW(FfxUInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_hw_ray_list.data[index] = packedRayCoords;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreDenoiserTile(FfxUInt32 index, FfxUInt32x2 tile_coord)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
rw_denoiser_tile_list.data[index] = ((tile_coord.y & 0xffffu) << 16) | ((tile_coord.x & 0xffffu) << 0); // Store out pixel to trace
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreExtractedRoughness(FfxUInt32x2 coordinate, FfxFloat32 roughness)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS)
|
||||
imageStore(rw_extracted_roughness, FfxInt32x2(coordinate), FfxFloat32x4(roughness));
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 LoadRoughnessFromMaterialParametersInput(FfxUInt32x3 coordinate)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS)
|
||||
FfxFloat32 rawRoughness = texelFetch(r_input_material_parameters, FfxInt32x2(coordinate.xy), FfxInt32(coordinate.z))[RoughnessChannel()];
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 SampleVarianceHistory(FfxFloat32x2 coordinate) /**/
|
||||
{
|
||||
#if defined ( CLASSIFIER_BIND_SRV_VARIANCE_HISTORY )
|
||||
return FfxFloat32(textureLod(sampler2D(r_variance_history, s_LinearSampler), coordinate, 0.0f).x);
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreRadiance(FfxUInt32x2 coordinate, FfxFloat32x4 radiance)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RADIANCE)
|
||||
imageStore(rw_radiance, FfxInt32x2(coordinate), radiance);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 GetInputDepth(FfxUInt32x2 coordinate)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
return texelFetch(r_input_depth, FfxInt32x2(coordinate), 0).r;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreHitCounter(FfxUInt32x2 coordinate, FfxUInt32 value)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_UAV_HIT_COUNTER)
|
||||
imageStore(rw_hit_counter, FfxInt32x2(coordinate), FfxUInt32x4(value));
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 LoadHitCounterHistory(FfxUInt32x2 coordinate)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY)
|
||||
return FfxUInt32(texelFetch(r_hit_counter_history, FfxInt32x2(coordinate), 0).r);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 LoadMotionVector(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
return MotionVectorScale() * texelFetch(r_input_motion_vectors, pixel_coordinate, 0).xy;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
@@ -0,0 +1,477 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ffx_classifier_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic push
|
||||
#pragma dxc diagnostic ignored "-Wambig-lit-shift"
|
||||
#endif //__hlsl_dx_compiler
|
||||
#include "ffx_core.h"
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic pop
|
||||
#endif //__hlsl_dx_compiler
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_CLASSIFIER_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
cbuffer cbClassifierReflection : FFX_CLASSIFIER_DECLARE_CB(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
{
|
||||
FfxFloat32Mat4 invViewProjection;
|
||||
FfxFloat32Mat4 projection;
|
||||
FfxFloat32Mat4 invProjection;
|
||||
FfxFloat32Mat4 viewMatrix;
|
||||
FfxFloat32Mat4 invView;
|
||||
FfxFloat32Mat4 prevViewProjection;
|
||||
FfxUInt32x2 renderSize;
|
||||
FfxFloat32x2 inverseRenderSize;
|
||||
FfxFloat32 iblFactor;
|
||||
FfxUInt32 frameIndex;
|
||||
FfxUInt32 samplesPerQuad;
|
||||
FfxUInt32 temporalVarianceGuidedTracingEnabled;
|
||||
FfxFloat32 globalRoughnessThreshold;
|
||||
FfxFloat32 rtRoughnessThreshold;
|
||||
FfxUInt32 mask;
|
||||
FfxUInt32 reflectionWidth;
|
||||
FfxUInt32 reflectionHeight;
|
||||
FfxFloat32 hybridMissWeight;
|
||||
FfxFloat32 hybridSpawnRate;
|
||||
FfxFloat32 vrtVarianceThreshold;
|
||||
FfxFloat32 reflectionsBackfacingThreshold;
|
||||
FfxUInt32 randomSamplesPerPixel;
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
FfxUInt32 roughnessChannel;
|
||||
FfxUInt32 isRoughnessPerceptual;
|
||||
|
||||
#define FFX_CLASSIFIER_CONSTANT_BUFFER_1_SIZE 120
|
||||
};
|
||||
#else
|
||||
#define invViewProjection 0
|
||||
#define projection 0
|
||||
#define invProjection 0
|
||||
#define viewMatrix 0
|
||||
#define invView 0
|
||||
#define prevViewProjection 0
|
||||
#define renderSize 0
|
||||
#define inverseRenderSize 0
|
||||
#define iblFactor 0
|
||||
#define roughnessThreshold 0
|
||||
#define varianceThreshold 0
|
||||
#define frameIndex 0
|
||||
#define samplesPerQuad 0
|
||||
#define temporalVarianceGuidedTracingEnabled 0
|
||||
#define globalRoughnessThreshold 0
|
||||
#define rtRoughnessThreshold 0
|
||||
#define mask 0
|
||||
#define reflectionWidth 0
|
||||
#define reflectionHeight 0
|
||||
#define hybridMissWeight 0
|
||||
#define hybridSpawnRate 0
|
||||
#define vrtVarianceThreshold 0
|
||||
#define reflectionsBackfacingThreshold 0
|
||||
#define randomSamplesPerPixel 0
|
||||
#define motionVectorScale 0
|
||||
#define normalsUnpackMul 0
|
||||
#define normalsUnpackAdd 0
|
||||
#define roughnessChannel 0
|
||||
#define isRoughnessPerceptual 0
|
||||
#endif
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STRINGIFY(p) FFX_CLASSIFIER_ROOTSIG_STR(p)
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STR(p) #p
|
||||
#define FFX_CLASSIFIER_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_WRAP, " \
|
||||
"comparisonFunc = COMPARISON_ALWAYS, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK, " \
|
||||
"maxAnisotropy = 1), " \
|
||||
"StaticSampler(s1, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"comparisonFunc = COMPARISON_ALWAYS, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK, " \
|
||||
"maxAnisotropy = 1)" )]
|
||||
|
||||
#if defined(FFX_CLASSIFIER_EMBED_ROOTSIG)
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT FFX_CLASSIFIER_ROOTSIG
|
||||
#else
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_CLASSIFIER_EMBED_ROOTSIG
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
SamplerState s_EnvironmentMapSampler : register(s0);
|
||||
SamplerState s_LinearSampler : register(s1);
|
||||
|
||||
FfxFloat32Mat4 InvViewProjection()
|
||||
{
|
||||
return invViewProjection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 Projection()
|
||||
{
|
||||
return projection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvProjection()
|
||||
{
|
||||
return invProjection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewMatrix()
|
||||
{
|
||||
return viewMatrix;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvView()
|
||||
{
|
||||
return invView;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 PrevViewProjection()
|
||||
{
|
||||
return prevViewProjection;
|
||||
}
|
||||
|
||||
FfxUInt32x2 RenderSize()
|
||||
{
|
||||
return renderSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 InverseRenderSize()
|
||||
{
|
||||
return inverseRenderSize;
|
||||
}
|
||||
|
||||
FfxFloat32 IBLFactor()
|
||||
{
|
||||
return iblFactor;
|
||||
}
|
||||
|
||||
FfxFloat32 RoughnessThreshold()
|
||||
{
|
||||
return globalRoughnessThreshold;
|
||||
}
|
||||
|
||||
FfxUInt32 FrameIndex()
|
||||
{
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
FfxUInt32 SamplesPerQuad()
|
||||
{
|
||||
return samplesPerQuad;
|
||||
}
|
||||
|
||||
FfxBoolean TemporalVarianceGuidedTracingEnabled()
|
||||
{
|
||||
return FfxBoolean(temporalVarianceGuidedTracingEnabled);
|
||||
}
|
||||
|
||||
FfxFloat32 RTRoughnessThreshold()
|
||||
{
|
||||
return rtRoughnessThreshold;
|
||||
}
|
||||
|
||||
FfxUInt32 Mask()
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionWidth()
|
||||
{
|
||||
return reflectionWidth;
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionHeight()
|
||||
{
|
||||
return reflectionHeight;
|
||||
}
|
||||
|
||||
FfxFloat32 HybridMissWeight()
|
||||
{
|
||||
return hybridMissWeight;
|
||||
}
|
||||
|
||||
FfxFloat32 HybridSpawnRate()
|
||||
{
|
||||
return hybridSpawnRate;
|
||||
}
|
||||
|
||||
FfxFloat32 VRTVarianceThreshold()
|
||||
{
|
||||
return vrtVarianceThreshold;
|
||||
}
|
||||
|
||||
FfxFloat32 ReflectionsBackfacingThreshold()
|
||||
{
|
||||
return reflectionsBackfacingThreshold;
|
||||
}
|
||||
|
||||
FfxUInt32 RandomSamplesPerPixel()
|
||||
{
|
||||
return randomSamplesPerPixel;
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
return motionVectorScale;
|
||||
}
|
||||
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
return normalsUnpackMul;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
return normalsUnpackAdd;
|
||||
}
|
||||
|
||||
FfxUInt32 RoughnessChannel()
|
||||
{
|
||||
return roughnessChannel;
|
||||
}
|
||||
|
||||
FfxBoolean IsRoughnessPerceptual()
|
||||
{
|
||||
return FfxBoolean(isRoughnessPerceptual);
|
||||
}
|
||||
|
||||
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_DEPTH
|
||||
Texture2D<FfxFloat32> r_input_depth : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_DEPTH);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS
|
||||
Texture2D<FfxFloat32x2> r_input_motion_vectors : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_NORMAL
|
||||
Texture2D<FfxFloat32x3> r_input_normal : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_NORMAL);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS
|
||||
Texture2D<FfxFloat32x4> r_input_material_parameters : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP
|
||||
TextureCube r_input_environment_map : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_VARIANCE_HISTORY
|
||||
Texture2D<FfxFloat32> r_variance_history : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_VARIANCE_HISTORY);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY
|
||||
Texture2D<FfxUInt32> r_hit_counter_history : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY);
|
||||
#endif
|
||||
|
||||
|
||||
// UAVs
|
||||
#if defined CLASSIFIER_BIND_UAV_RADIANCE
|
||||
RWTexture2D<FfxFloat32x4> rw_radiance : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_RADIANCE);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_ray_list : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_RAY_LIST);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HW_RAY_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_hw_ray_list : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_HW_RAY_LIST);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_denoiser_tile_list : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_COUNTER
|
||||
globallycoherent RWStructuredBuffer<FfxUInt32> rw_ray_counter : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_RAY_COUNTER);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS
|
||||
RWTexture2D<FfxFloat32> rw_extracted_roughness : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HIT_COUNTER
|
||||
RWTexture2D<FfxUInt32> rw_hit_counter : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_HIT_COUNTER);
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#endif // #if defined(FFX_HALF)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_NORMAL)
|
||||
FfxFloat32x3 LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return normalize(NormalsUnpackMul() * r_input_normal.Load(FfxInt32x3(pixel_coordinate, 0)).xyz + NormalsUnpackAdd());
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_SRV_INPUT_NORMAL)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP)
|
||||
FfxFloat32x3 SampleEnvironmentMap(FfxFloat32x3 direction, FfxFloat32 preceptualRoughness)
|
||||
{
|
||||
FfxFloat32 Width; FfxFloat32 Height;
|
||||
r_input_environment_map.GetDimensions(Width, Height);
|
||||
FfxInt32 maxMipLevel = FfxInt32(log2(FfxFloat32(Width > 0 ? Width : 1)));
|
||||
FfxFloat32 mip = clamp(preceptualRoughness * FfxFloat32(maxMipLevel), 0.0, FfxFloat32(maxMipLevel));
|
||||
return r_input_environment_map.SampleLevel(s_EnvironmentMapSampler, direction, mip).xyz * IBLFactor();
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
void IncrementRayCounterSW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
InterlockedAdd(rw_ray_counter[0], value, original_value);
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
void IncrementRayCounterHW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
InterlockedAdd(rw_ray_counter[4], value, original_value);
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
void IncrementDenoiserTileCounter(FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
InterlockedAdd(rw_ray_counter[2], 1, original_value);
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
|
||||
FfxUInt32 PackRayCoords(FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 ray_x_15bit = ray_coord.x & 32767; // 0b111111111111111
|
||||
FfxUInt32 ray_y_14bit = ray_coord.y & 16383; // 0b11111111111111;
|
||||
FfxUInt32 copy_horizontal_1bit = copy_horizontal ? 1 : 0;
|
||||
FfxUInt32 copy_vertical_1bit = copy_vertical ? 1 : 0;
|
||||
FfxUInt32 copy_diagonal_1bit = copy_diagonal ? 1 : 0;
|
||||
|
||||
FfxUInt32 packed = (copy_diagonal_1bit << 31) | (copy_vertical_1bit << 30) | (copy_horizontal_1bit << 29) | (ray_y_14bit << 15) | (ray_x_15bit << 0);
|
||||
return packed;
|
||||
}
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
void StoreRay(FfxInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_ray_list[index] = packedRayCoords;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
void StoreRaySWHelper(FfxInt32 index)
|
||||
{
|
||||
rw_ray_list[index] = 0xffffffffu;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_HW_RAY_LIST)
|
||||
void StoreRayHW(FfxInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_hw_ray_list[index] = packedRayCoords;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_HW_RAY_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
void StoreDenoiserTile(FfxInt32 index, FfxUInt32x2 tile_coord)
|
||||
{
|
||||
rw_denoiser_tile_list[index] = ((tile_coord.y & 0xffffu) << 16) | ((tile_coord.x & 0xffffu) << 0); // Store out pixel to trace
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS)
|
||||
void StoreExtractedRoughness(FfxUInt32x2 coordinate, FfxFloat32 roughness)
|
||||
{
|
||||
rw_extracted_roughness[coordinate] = roughness;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS)
|
||||
FfxFloat32 LoadRoughnessFromMaterialParametersInput(FfxUInt32x3 coordinate) /**/
|
||||
{
|
||||
FfxFloat32 rawRoughness = r_input_material_parameters.Load(coordinate)[RoughnessChannel()];
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_VARIANCE_HISTORY)
|
||||
FfxFloat32 SampleVarianceHistory(FfxFloat32x2 coordinate)
|
||||
{
|
||||
return (FfxFloat32)r_variance_history.SampleLevel(s_LinearSampler, coordinate, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_VARIANCE_HISTORY)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RADIANCE)
|
||||
void StoreRadiance(FfxUInt32x2 coordinate, FfxFloat32x4 radiance) /**/
|
||||
{
|
||||
rw_radiance[coordinate] = radiance;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RADIANCE)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32 GetInputDepth(FfxUInt32x2 coordinate)
|
||||
{
|
||||
return r_input_depth[coordinate];
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY)
|
||||
FfxUInt32 LoadHitCounterHistory(FfxUInt32x2 coordinate)
|
||||
{
|
||||
return r_hit_counter_history[coordinate];
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_UAV_HIT_COUNTER)
|
||||
void StoreHitCounter(FfxUInt32x2 coordinate, FfxUInt32 value)
|
||||
{
|
||||
rw_hit_counter[coordinate] = value;
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_UAV_HIT_COUNTER)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
FfxFloat32x2 LoadMotionVector(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return MotionVectorScale() * r_input_motion_vectors.Load(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
118
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_common.h
vendored
Normal file
118
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_common.h
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Use hitcounter feedback
|
||||
#define FFX_CLASSIFIER_FLAGS_USE_HIT_COUNTER (1 << 0)
|
||||
// Traverse in screen space
|
||||
#define FFX_CLASSIFIER_FLAGS_USE_SCREEN_SPACE (1 << 1)
|
||||
// Traverse using HW ray tracing
|
||||
#define FFX_CLASSIFIER_FLAGS_USE_RAY_TRACING (1 << 2)
|
||||
// Iterate BVH to search for the opaque fragment
|
||||
#define FFX_CLASSIFIER_FLAGS_RESOLVE_TRANSPARENT (1 << 3)
|
||||
// Grab radiance from screen space shaded image for ray traced intersections, when possible
|
||||
#define FFX_CLASSIFIER_FLAGS_SHADING_USE_SCREEN (1 << 5)
|
||||
// defines FFX_HSR_OPTION_SHADING_USE_SCREEN
|
||||
|
||||
// Extra flags for debugging
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_0 (1 << 9)
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_1 (1 << 10)
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_2 (1 << 11)
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_3 (1 << 12)
|
||||
|
||||
// Visualization tweaking
|
||||
#define FFX_CLASSIFIER_FLAGS_SHOW_DEBUG_TARGET (1 << 13)
|
||||
#define FFX_CLASSIFIER_FLAGS_SHOW_INTERSECTION (1 << 14)
|
||||
#define FFX_CLASSIFIER_FLAGS_SHOW_REFLECTION_TARGET (1 << 15)
|
||||
#define FFX_CLASSIFIER_FLAGS_APPLY_REFLECTIONS (1 << 16)
|
||||
#define FFX_CLASSIFIER_FLAGS_INTERSECTION_ACCUMULATE (1 << 17)
|
||||
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_WAVES (1 << 18)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_AVG_RADIANCE (1 << 19)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_VARIANCE (1 << 20)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_NUM_SAMPLES (1 << 21)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_RAY_LENGTH (1 << 23)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_REPROJECTION (1 << 25)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_TRANSPARENT_QUERY (1 << 26)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_HIT_COUNTER (1 << 27)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_PRIMARY_RAYS (1 << 28)
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
|
||||
#define FFX_REFLECTIONS_SKY_DISTANCE 100.0f
|
||||
|
||||
// Helper defines for hitcouter and classification
|
||||
#define FFX_HITCOUNTER_SW_HIT_FLAG (1u << 0u)
|
||||
#define FFX_HITCOUNTER_SW_HIT_SHIFT 0u
|
||||
#define FFX_HITCOUNTER_SW_OLD_HIT_SHIFT 8u
|
||||
#define FFX_HITCOUNTER_MASK 0xffu
|
||||
#define FFX_HITCOUNTER_SW_MISS_FLAG (1u << 16u)
|
||||
#define FFX_HITCOUNTER_SW_MISS_SHIFT 16u
|
||||
#define FFX_HITCOUNTER_SW_OLD_MISS_SHIFT 24u
|
||||
|
||||
#define FFX_Hitcounter_GetSWHits(counter) ((counter >> FFX_HITCOUNTER_SW_HIT_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
#define FFX_Hitcounter_GetSWMisses(counter) ((counter >> FFX_HITCOUNTER_SW_MISS_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
#define FFX_Hitcounter_GetOldSWHits(counter) ((counter >> FFX_HITCOUNTER_SW_OLD_HIT_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
#define FFX_Hitcounter_GetOldSWMisses(counter) ((counter >> FFX_HITCOUNTER_SW_OLD_MISS_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
|
||||
//=== Common functions of the HsrSample ===
|
||||
|
||||
void UnpackRayCoords(FfxUInt32 packed, FFX_PARAMETER_OUT FfxUInt32x2 ray_coord, FFX_PARAMETER_OUT FfxBoolean copy_horizontal, FFX_PARAMETER_OUT FfxBoolean copy_vertical, FFX_PARAMETER_OUT FfxBoolean copy_diagonal) {
|
||||
ray_coord.x = (packed >> 0) & 32767; // 0b111111111111111;
|
||||
ray_coord.y = (packed >> 15) & 16383; // 0b11111111111111;
|
||||
copy_horizontal = FfxBoolean((packed >> 29) & 1u);
|
||||
copy_vertical = FfxBoolean((packed >> 30) & 1u);
|
||||
copy_diagonal = FfxBoolean((packed >> 31) & 1u);
|
||||
}
|
||||
|
||||
// Mat must be able to transform origin from texture space to a linear space.
|
||||
FfxFloat32x3 InvProjectPosition(FfxFloat32x3 coord, FfxFloat32Mat4 mat) {
|
||||
coord.y = (1 - coord.y);
|
||||
coord.xy = 2 * coord.xy - 1;
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(mat, FfxFloat32x4(coord, 1));
|
||||
projected.xyz /= projected.w;
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
FfxBoolean IsGlossyReflection(FfxFloat32 roughness) {
|
||||
return roughness < RoughnessThreshold();
|
||||
}
|
||||
|
||||
FfxFloat32x3 ScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord) {
|
||||
return InvProjectPosition(screen_uv_coord, InvProjection());
|
||||
}
|
||||
|
||||
FfxBoolean IsBackground(FfxFloat32 depth)
|
||||
{
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
return depth < 1.e-6f;
|
||||
#else
|
||||
return depth >= (1.0f - 1.e-6f);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Rounds value to the nearest multiple of 8
|
||||
FfxUInt32x2 FFX_DNSR_Reflections_RoundUp8(FfxUInt32x2 value) {
|
||||
FfxUInt32x2 round_down = value & ~7; // 0b111;
|
||||
return FFX_SELECT((round_down == value), value, value + 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
59
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_resources.h
vendored
Normal file
59
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_resources.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_CLASSIFIER_RESOURCES_H
|
||||
#define FFX_CLASSIFIER_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_DEPTH 1
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_NORMAL 2
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_WORK_QUEUE 3
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_WORK_QUEUE_COUNTER 4
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_RAY_HIT 5
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_SHADOW_MAPS 7
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS 8
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_SPECULAR_ROUGHNESS 9
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_ENVIRONMENT_MAP 10
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_VARIANCE_HISTORY 11
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_HIT_COUNTER_HISTORY 12
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_HIT_COUNTER 13
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_RAY_LIST 14
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_HW_RAY_LIST 15
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_EXTRACTED_ROUGHNESS 16
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_RAY_COUNTER 17
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_DENOISER_TILE_LIST 18
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_DEBUG_IMAGE 19
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_RADIANCE 20
|
||||
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT 25 // 21 + FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT
|
||||
#if defined(FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT)
|
||||
static_assert(FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT == 4,
|
||||
"This count represents 21 + FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT. This assert monitors if MAX_SHADOW_MAP_TEXTURES_COUNT has changed");
|
||||
#endif // #if defined(FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT)
|
||||
|
||||
#define FFX_CLASSIFIER_CONSTANTBUFFER_IDENTIFIER_CLASSIFIER 0
|
||||
#define FFX_CLASSIFIER_CONSTANTBUFFER_IDENTIFIER_REFLECTION 1
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //!defined( FFX_CLASSIFIER_RESOURCES_H )
|
||||
221
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows.h
vendored
Normal file
221
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows.h
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/// @defgroup FfxGPUClassifier FidelityFX Classifier
|
||||
/// FidelityFX Classifier GPU documentation
|
||||
///
|
||||
/// @ingroup FfxGPUEffects
|
||||
|
||||
#include "ffx_classifier_common.h"
|
||||
|
||||
struct ClassifyResults
|
||||
{
|
||||
FfxBoolean bIsActiveLane;
|
||||
FfxBoolean bIsInLight;
|
||||
FfxFloat32 minT;
|
||||
FfxFloat32 maxT;
|
||||
};
|
||||
|
||||
ClassifyResults FfxClassify(const FfxUInt32x2 pixelCoord,
|
||||
const FfxBoolean bUseNormal,
|
||||
const FfxBoolean bUseCascadeBlocking)
|
||||
{
|
||||
const FfxBoolean bIsInViewport = all(FFX_LESS_THAN(pixelCoord, TextureSize().xy));
|
||||
const FfxFloat32 depth = FfxClassifierSampleDepth(pixelCoord);
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
FfxBoolean bIsActiveLane = bIsInViewport && (depth > 0.0f);
|
||||
#else
|
||||
FfxBoolean bIsActiveLane = bIsInViewport && (depth < 1.0f);
|
||||
#endif
|
||||
FfxBoolean bIsInLight = FFX_FALSE;
|
||||
FfxFloat32 minT = FFX_POSITIVE_INFINITY_FLOAT;
|
||||
FfxFloat32 maxT = 0.f;
|
||||
|
||||
if (bUseNormal && bIsActiveLane)
|
||||
{
|
||||
const FfxFloat32x3 normal = normalize(FfxClassifierSampleNormal(pixelCoord));
|
||||
const FfxBoolean bIsNormalFacingLight = dot(normal, -LightDir()) > 0;
|
||||
|
||||
bIsActiveLane = bIsActiveLane && bIsNormalFacingLight;
|
||||
}
|
||||
|
||||
if (bUseCascadeBlocking && bIsActiveLane)
|
||||
{
|
||||
const FfxFloat32x2 uv = pixelCoord * TextureSize().zw;
|
||||
const FfxFloat32x4 homogeneous = FFX_MATRIX_MULTIPLY(ViewToWorld(), FfxFloat32x4(2.0f * FfxFloat32x2(uv.x, 1.0f - uv.y) - 1.0f, depth, 1));
|
||||
const FfxFloat32x3 worldPos = homogeneous.xyz / homogeneous.w;
|
||||
|
||||
const FfxFloat32x3 lightViewSpacePos = FFX_MATRIX_MULTIPLY(LightView(), FfxFloat32x4(worldPos, 1)).xyz;
|
||||
|
||||
FfxBoolean bIsInActiveCascade = FFX_FALSE;
|
||||
|
||||
if (bUseCascadeBlocking)
|
||||
{
|
||||
const FfxFloat32 radius = SunSizeLightSpace() * lightViewSpacePos.z;
|
||||
|
||||
FfxFloat32x3 shadowCoord = FfxFloat32x3(0, 0, 0);
|
||||
FfxUInt32 cascadeIndex = 0;
|
||||
for (FfxUInt32 i = 0; i < CascadeCount(); ++i)
|
||||
{
|
||||
shadowCoord = lightViewSpacePos * CascadeScale(i).xyz + CascadeOffset(i).xyz;
|
||||
if (all(FFX_GREATER_THAN(shadowCoord.xy, FfxFloat32x2(0, 0))) && all(FFX_LESS_THAN(shadowCoord.xy, FfxFloat32x2(1, 1))))
|
||||
{
|
||||
cascadeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// grow search area by a pixel to make sure we search a wide enough area
|
||||
// also scale everything from UV to pixel coord for image loads.
|
||||
const FfxFloat32x2 radiusCoord = abs(FfxFloat32x2(radius, radius) * CascadeScale(cascadeIndex).xy) * FfxFloat32x2(CascadeSize(), CascadeSize()) + FfxFloat32x2(1,1);
|
||||
shadowCoord.xy *= CascadeSize();
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
const FfxFloat32 depthCmp = shadowCoord.z + BlockerOffset();
|
||||
#else
|
||||
const FfxFloat32 depthCmp = shadowCoord.z - BlockerOffset();
|
||||
#endif
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
FfxFloat32 maxD = 1;
|
||||
FfxFloat32 minD = 0;
|
||||
FfxFloat32 closetDepth = 1;
|
||||
#else
|
||||
FfxFloat32 maxD = 0;
|
||||
FfxFloat32 minD = 1;
|
||||
FfxFloat32 closetDepth = 0;
|
||||
#endif
|
||||
|
||||
|
||||
// With small shadow maps we will be bound on filtering since the shadow map can end up completely in LO cache
|
||||
// using an image load is faster then a sample in RDNA but we will be losing the benefit of doing some of the ALU
|
||||
// in the filter and getting 4 pixels of data per tap.
|
||||
for (FfxUInt32 x = 0; x < k_poissonDiscSampleCountHigh; ++x)
|
||||
{
|
||||
const FfxFloat32x2 sampleUV = shadowCoord.xy + k_poissonDisc[x] * radiusCoord + 0.5f;
|
||||
|
||||
// UV bounds check
|
||||
if (!(all(FFX_GREATER_THAN_EQUAL(sampleUV.xy, FfxFloat32x2(0, 0))) &&
|
||||
all(FFX_LESS_THAN(sampleUV.xy, FfxFloat32x2(CascadeSize(), CascadeSize())))))
|
||||
continue;
|
||||
const FfxFloat32 pixelDepth = FfxClassifierSampleShadowMap(sampleUV, cascadeIndex);
|
||||
|
||||
// using min and max to reduce number of cmps
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
maxD = min(maxD, pixelDepth);
|
||||
minD = max(minD, pixelDepth);
|
||||
|
||||
// need to find closet point in front of the receiver
|
||||
if (pixelDepth > depthCmp)
|
||||
{
|
||||
closetDepth = min(closetDepth, pixelDepth);
|
||||
}
|
||||
#else
|
||||
maxD = max(maxD, pixelDepth);
|
||||
minD = min(minD, pixelDepth);
|
||||
|
||||
// need to find closet point in front of the receiver
|
||||
if (pixelDepth < depthCmp)
|
||||
{
|
||||
closetDepth = max(closetDepth, pixelDepth);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
const FfxBoolean bIsInShadow = (maxD >= depthCmp);
|
||||
bIsInLight = RejectLitPixels() && (minD <= depthCmp);
|
||||
#else
|
||||
const FfxBoolean bIsInShadow = (maxD <= depthCmp);
|
||||
bIsInLight = RejectLitPixels() && (minD >= depthCmp);
|
||||
#endif
|
||||
bIsInActiveCascade = !bIsInShadow && !bIsInLight;
|
||||
|
||||
if (bIsInActiveCascade && UseCascadesForRayT())
|
||||
{
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
const FfxFloat32 viewMinT = abs(min(shadowCoord.z + closetDepth + BlockerOffset(), 0) / CascadeScale(cascadeIndex).z);
|
||||
const FfxFloat32 viewMaxT = abs((shadowCoord.z + minD - BlockerOffset()) / CascadeScale(cascadeIndex).z);
|
||||
#else
|
||||
const FfxFloat32 viewMinT = abs(max(shadowCoord.z - closetDepth - BlockerOffset(), 0) / CascadeScale(cascadeIndex).z);
|
||||
const FfxFloat32 viewMaxT = abs((shadowCoord.z - minD + BlockerOffset()) / CascadeScale(cascadeIndex).z);
|
||||
#endif
|
||||
|
||||
// if its known that the light view matrix is only a rotation or has uniform scale this can be optimized.
|
||||
minT = length(FFX_MATRIX_MULTIPLY(InverseLightView(), FfxFloat32x4(0, 0, viewMinT, 0)).xyz);
|
||||
maxT = length(FFX_MATRIX_MULTIPLY(InverseLightView(), FfxFloat32x4(0, radius, viewMaxT, 0)).xyz);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bIsActiveLane = bIsActiveLane && bIsInActiveCascade;
|
||||
}
|
||||
|
||||
const ClassifyResults results = { bIsActiveLane, bIsInLight, minT, maxT };
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// Classifier pass entry point.
|
||||
///
|
||||
/// @param LocalThreadId The "flattened" index of a thread within a thread group (SV_GroupIndex).
|
||||
/// @param WorkGroupId Index of the thread group currently executed (SV_GroupID).
|
||||
/// @ingroup FfxGPUClassifier
|
||||
void FfxClassifyShadows(FfxUInt32 LocalThreadId, FfxUInt32x3 WorkGroupId)
|
||||
{
|
||||
const FfxUInt32x2 localID = ffxRemapForWaveReduction(LocalThreadId);
|
||||
const FfxUInt32x2 pixelCoord = WorkGroupId.xy * k_tileSize + localID.xy;
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_CLASSIFIER_MODE == 0
|
||||
ClassifyResults results = FfxClassify(pixelCoord, FFX_TRUE, FFX_FALSE);
|
||||
#endif
|
||||
#if FFX_CLASSIFIER_OPTION_CLASSIFIER_MODE == 1
|
||||
ClassifyResults results = FfxClassify(pixelCoord, FFX_TRUE, FFX_TRUE);
|
||||
#endif
|
||||
Tile currentTile = TileCreate(WorkGroupId.xy);
|
||||
const FfxUInt32 mask = BoolToWaveMask(results.bIsActiveLane, localID);
|
||||
currentTile.mask = mask;
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_CLASSIFIER_MODE == 1
|
||||
if (UseCascadesForRayT())
|
||||
{
|
||||
// At lest one lane must be active for the tile to be written out, so the infinitly and zero will be emoved by the wave min and max.
|
||||
// Otherwise we will get minT to be infinite and maxT to be 0
|
||||
currentTile.minT = max(ffxWaveMin(results.minT), currentTile.minT);
|
||||
currentTile.maxT = min(ffxWaveMax(results.maxT), currentTile.maxT);
|
||||
}
|
||||
#endif
|
||||
|
||||
const FfxUInt32 lightMask = BoolToWaveMask(results.bIsInLight, localID);
|
||||
const FfxBoolean bDiscardTile = (CountBits(mask) <= TileTolerance());
|
||||
|
||||
if (LocalThreadId == 0)
|
||||
{
|
||||
if (!bDiscardTile)
|
||||
{
|
||||
FfxClassifierStoreTile(TileToUint(currentTile));
|
||||
}
|
||||
|
||||
FfxClassifierStoreLightMask(WorkGroupId.xy, lightMask);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ffx_classifier_resources.h"
|
||||
#include "ffx_core.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
|
||||
const FfxFloat32x2 k_poissonDisc[] = {
|
||||
FfxFloat32x2(0.640736f, -0.355205f), FfxFloat32x2(-0.725411f, -0.688316f), FfxFloat32x2(-0.185095f, 0.722648f), FfxFloat32x2(0.770596f, 0.637324f),
|
||||
FfxFloat32x2(-0.921445f, 0.196997f), FfxFloat32x2(0.076571f, -0.98822f), FfxFloat32x2(-0.1348f, -0.0908536f), FfxFloat32x2(0.320109f, 0.257241f),
|
||||
FfxFloat32x2(0.994021f, 0.109193f), FfxFloat32x2(0.304934f, 0.952374f), FfxFloat32x2(-0.698577f, 0.715535f), FfxFloat32x2(0.548701f, -0.836019f),
|
||||
FfxFloat32x2(-0.443159f, 0.296121f), FfxFloat32x2(0.15067f, -0.489731f), FfxFloat32x2(-0.623829f, -0.208167f), FfxFloat32x2(-0.294778f, -0.596545f),
|
||||
FfxFloat32x2(0.334086f, -0.128208f), FfxFloat32x2(-0.0619831f, 0.311747f), FfxFloat32x2(0.166112f, 0.61626f), FfxFloat32x2(-0.289127f, -0.957291f),
|
||||
FfxFloat32x2(-0.98748f, -0.157745f), FfxFloat32x2(0.637501f, 0.0651571f), FfxFloat32x2(0.971376f, -0.237545f), FfxFloat32x2(-0.0170599f, 0.98059f),
|
||||
FfxFloat32x2(-0.442564f, 0.896737f), FfxFloat32x2(0.48619f, 0.518723f), FfxFloat32x2(-0.725272f, 0.419965f), FfxFloat32x2(0.781417f, -0.624009f),
|
||||
FfxFloat32x2(-0.899227f, -0.437482f), FfxFloat32x2(0.769219f, 0.33372f), FfxFloat32x2(-0.414411f, 0.00375378f), FfxFloat32x2(0.262856f, -0.759514f),
|
||||
};
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_CB_CLASSIFIER, std140) uniform cbClassifier_t
|
||||
{
|
||||
FfxFloat32x4 textureSize;
|
||||
FfxFloat32x3 lightDir;
|
||||
FfxFloat32 skyHeight;
|
||||
|
||||
FfxFloat32x4 blockerOffset_cascadeSize_sunSizeLightSpace_pad;
|
||||
FfxUInt32x4 cascadeCount_tileTolerance_pad_pad;
|
||||
FfxFloat32x4 bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd;
|
||||
|
||||
FfxFloat32x4 cascadeScale[4];
|
||||
FfxFloat32x4 cascadeOffset[4];
|
||||
|
||||
// Matrices
|
||||
FfxFloat32Mat4 viewToWorld;
|
||||
FfxFloat32Mat4 lightView;
|
||||
FfxFloat32Mat4 inverseLightView;
|
||||
|
||||
//#define FFX_CLASSIFIER_CONSTANT_BUFFER_1_SIZE 18 + 2 booleans + 32 + 48// Number of 32-bit values
|
||||
} cbClassifier;
|
||||
#endif
|
||||
|
||||
FfxFloat32x4 TextureSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.textureSize;
|
||||
#endif
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
}
|
||||
|
||||
FfxFloat32x3 LightDir()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.lightDir;
|
||||
#endif
|
||||
return FfxFloat32x3(0, 0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32 SkyHeight()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.skyHeight;
|
||||
#endif
|
||||
return FfxFloat32(0);
|
||||
}
|
||||
|
||||
FfxUInt32 CascadeCount()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeCount_tileTolerance_pad_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxUInt32 TileTolerance()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeCount_tileTolerance_pad_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 BlockerOffset()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.blockerOffset_cascadeSize_sunSizeLightSpace_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 CascadeSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.blockerOffset_cascadeSize_sunSizeLightSpace_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 SunSizeLightSpace()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.blockerOffset_cascadeSize_sunSizeLightSpace_pad[2];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxBoolean RejectLitPixels()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return FfxBoolean(cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[0]);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxBoolean UseCascadesForRayT()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return FfxBoolean(cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[1]);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[2];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[3];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeScale(FfxUInt32 index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeScale[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeOffset(FfxUInt32 index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeOffset[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewToWorld()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.viewToWorld;
|
||||
#endif
|
||||
return FfxFloat32Mat4(0);
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 LightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.lightView;
|
||||
#endif
|
||||
return FfxFloat32Mat4(0);
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InverseLightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.inverseLightView;
|
||||
#endif
|
||||
return FfxFloat32Mat4(0);
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
uniform texture2D r_input_depth;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
uniform texture2D r_input_normal;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
uniform texture2D r_input_shadowMap[4];
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES, std430)
|
||||
buffer rwsb_tiles_t
|
||||
{
|
||||
FfxUInt32x4 data[];
|
||||
} rwsb_tiles;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT, std430)
|
||||
coherent buffer rwb_tileCount_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rwb_tileCount;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT, r32ui)
|
||||
uniform uimage2D rwt2d_rayHitResults;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_TEXTURE)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_TEXTURE, rgba32f)
|
||||
uniform image2D rwt2d_output;
|
||||
#endif
|
||||
|
||||
FfxFloat32 FfxClassifierSampleDepth(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
return texelFetch(r_input_depth, ivec2(uiPxPos), 0).r;
|
||||
#else
|
||||
return 0.0;
|
||||
#endif // defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
}
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
FfxFloat32x3 FfxClassifierSampleNormal(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
FfxFloat32x3 normal = texelFetch(r_input_normal, ivec2(uiPxPos), 0).rgb;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
return normalize(normal);
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
FfxFloat32 FfxClassifierSampleShadowMap(FfxFloat32x2 sampleUV, FfxUInt32 cascadeIndex)
|
||||
{
|
||||
nonuniformEXT FfxUInt32 nonUniformCascadeIndex = cascadeIndex;
|
||||
return texelFetch(r_input_shadowMap[nonUniformCascadeIndex], ivec2(sampleUV), 0).r;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
void FfxClassifierStoreLightMask(FfxUInt32x2 index, FfxUInt32 lightMask)
|
||||
{
|
||||
imageStore(rwt2d_rayHitResults, ivec2(index), FfxUInt32x4(~lightMask, 0,0,0));
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
|
||||
FfxUInt32 CountBits(const FfxUInt32 mask)
|
||||
{
|
||||
return bitCount(mask);
|
||||
}
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
void FfxClassifierStoreTile(FfxUInt32x4 uiTile)
|
||||
{
|
||||
uint index = ~0;
|
||||
index = atomicAdd(rwb_tileCount.data[0], 1);
|
||||
rwsb_tiles.data[index] = uiTile;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
@@ -0,0 +1,311 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ffx_classifier_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic push
|
||||
#pragma dxc diagnostic ignored "-Wambig-lit-shift"
|
||||
#endif //__hlsl_dx_compiler
|
||||
#include "ffx_core.h"
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic pop
|
||||
#endif //__hlsl_dx_compiler
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
|
||||
static const FfxFloat32x2 k_poissonDisc[] = {
|
||||
FfxFloat32x2(0.640736f, -0.355205f), FfxFloat32x2(-0.725411f, -0.688316f), FfxFloat32x2(-0.185095f, 0.722648f), FfxFloat32x2(0.770596f, 0.637324f),
|
||||
FfxFloat32x2(-0.921445f, 0.196997f), FfxFloat32x2(0.076571f, -0.98822f), FfxFloat32x2(-0.1348f, -0.0908536f), FfxFloat32x2(0.320109f, 0.257241f),
|
||||
FfxFloat32x2(0.994021f, 0.109193f), FfxFloat32x2(0.304934f, 0.952374f), FfxFloat32x2(-0.698577f, 0.715535f), FfxFloat32x2(0.548701f, -0.836019f),
|
||||
FfxFloat32x2(-0.443159f, 0.296121f), FfxFloat32x2(0.15067f, -0.489731f), FfxFloat32x2(-0.623829f, -0.208167f), FfxFloat32x2(-0.294778f, -0.596545f),
|
||||
FfxFloat32x2(0.334086f, -0.128208f), FfxFloat32x2(-0.0619831f, 0.311747f), FfxFloat32x2(0.166112f, 0.61626f), FfxFloat32x2(-0.289127f, -0.957291f),
|
||||
FfxFloat32x2(-0.98748f, -0.157745f), FfxFloat32x2(0.637501f, 0.0651571f), FfxFloat32x2(0.971376f, -0.237545f), FfxFloat32x2(-0.0170599f, 0.98059f),
|
||||
FfxFloat32x2(-0.442564f, 0.896737f), FfxFloat32x2(0.48619f, 0.518723f), FfxFloat32x2(-0.725272f, 0.419965f), FfxFloat32x2(0.781417f, -0.624009f),
|
||||
FfxFloat32x2(-0.899227f, -0.437482f), FfxFloat32x2(0.769219f, 0.33372f), FfxFloat32x2(-0.414411f, 0.00375378f), FfxFloat32x2(0.262856f, -0.759514f),
|
||||
};
|
||||
|
||||
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
|
||||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_CLASSIFIER_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
cbuffer cbClassifier : FFX_CLASSIFIER_DECLARE_CB(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
{
|
||||
FfxFloat32x4 textureSize;
|
||||
FfxFloat32x3 lightDir;
|
||||
FfxFloat32 skyHeight;
|
||||
|
||||
FfxFloat32x4 blockerOffset_cascadeSize_sunSizeLightSpace_pad;
|
||||
FfxUInt32x4 cascadeCount_tileTolerance_pad_pad;
|
||||
FfxFloat32x4 bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd;
|
||||
|
||||
FfxFloat32x4 cascadeScale[4];
|
||||
FfxFloat32x4 cascadeOffset[4];
|
||||
|
||||
// Matrices
|
||||
FfxFloat32Mat4 viewToWorld;
|
||||
FfxFloat32Mat4 lightView;
|
||||
FfxFloat32Mat4 inverseLightView;
|
||||
|
||||
#define FFX_CLASSIFIER_CONSTANT_BUFFER_1_SIZE 100
|
||||
};
|
||||
#endif
|
||||
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STRINGIFY(p) FFX_CLASSIFIER_ROOTSIG_STR(p)
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STR(p) #p
|
||||
#define FFX_CLASSIFIER_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"comparisonFunc = COMPARISON_NEVER, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK)" )]
|
||||
|
||||
#if defined(FFX_CLASSIFIER_EMBED_ROOTSIG)
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT FFX_CLASSIFIER_ROOTSIG
|
||||
#else
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_CLASSIFIER_EMBED_ROOTSIG
|
||||
|
||||
FfxFloat32x4 TextureSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return textureSize;
|
||||
#endif
|
||||
return FfxFloat32x4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32x3 LightDir()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return lightDir;
|
||||
#endif
|
||||
return FfxFloat32x3(0, 0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32 SkyHeight()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return skyHeight;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxUInt32 CascadeCount()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeCount_tileTolerance_pad_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxUInt32 TileTolerance()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeCount_tileTolerance_pad_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 BlockerOffset()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return blockerOffset_cascadeSize_sunSizeLightSpace_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 CascadeSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return blockerOffset_cascadeSize_sunSizeLightSpace_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 SunSizeLightSpace()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return blockerOffset_cascadeSize_sunSizeLightSpace_pad[2];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxBoolean RejectLitPixels()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[0];
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxBoolean UseCascadesForRayT()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[1];
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[2];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[3];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeScale(int index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeScale[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeOffset(int index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeOffset[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewToWorld()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return viewToWorld;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 LightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return lightView;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InverseLightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return inverseLightView;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH
|
||||
Texture2D<FfxFloat32x4> r_input_depth : FFX_CLASSIFIER_DECLARE_SRV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_DEPTH);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS
|
||||
Texture2D<FfxFloat32x4> r_input_normal : FFX_CLASSIFIER_DECLARE_SRV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_NORMAL);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS
|
||||
Texture2D<FfxFloat32> r_input_shadowMap[4] : FFX_CLASSIFIER_DECLARE_SRV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_SHADOW_MAPS);
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES
|
||||
RWStructuredBuffer<FfxUInt32x4> rwsb_tiles : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_WORK_QUEUE);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT
|
||||
globallycoherent RWStructuredBuffer<FfxUInt32> rwb_tileCount : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_WORK_QUEUE_COUNTER);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT
|
||||
RWTexture2D<FfxUInt32> rwt2d_rayHitResults : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_RAY_HIT);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_TEXTURE
|
||||
RWTexture2D<FfxFloat32x4> rwt2d_output : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_COLOR);
|
||||
#endif
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32 FfxClassifierSampleDepth(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
return r_input_depth[uiPxPos].r;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
FfxFloat32x3 FfxClassifierSampleNormal(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
FfxFloat32x3 normal = r_input_normal[uiPxPos].rgb;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
return normalize(normal);
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
FfxFloat32 FfxClassifierSampleShadowMap(FfxFloat32x2 sampleUV, FfxUInt32 cascadeIndex)
|
||||
{
|
||||
return r_input_shadowMap[NonUniformResourceIndex(cascadeIndex)][FfxUInt32x2(sampleUV)];
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
void FfxClassifierStoreLightMask(FfxUInt32x2 index, FfxUInt32 lightMask)
|
||||
{
|
||||
rwt2d_rayHitResults[index] = ~lightMask;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
|
||||
FfxUInt32 CountBits(const FfxUInt32 mask)
|
||||
{
|
||||
return countbits(mask);
|
||||
}
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
void FfxClassifierStoreTile(FfxUInt32x4 uiTile)
|
||||
{
|
||||
uint index = ~0;
|
||||
InterlockedAdd(rwb_tileCount[0], 1, index);
|
||||
rwsb_tiles[index] = uiTile;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
Reference in New Issue
Block a user