199 lines
8.6 KiB
C
199 lines
8.6 KiB
C
// 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_BRIXELIZER_DEBUG_VISUALIZATION_H
|
|
#define FFX_BRIXELIZER_DEBUG_VISUALIZATION_H
|
|
|
|
#include "ffx_brixelizer_host_gpu_shared.h"
|
|
|
|
#define FFX_BRIXELIZER_TRAVERSAL_EPS (GetDebugInfoPreviewSDFSolveEpsilon() / FfxFloat32(8.0))
|
|
|
|
#include "ffx_brixelizer_trace_ops.h"
|
|
|
|
// XXX -- tmp
|
|
FfxUInt32 FfxBrixelizerGetVoxelCascade(FfxUInt32 voxel_id)
|
|
{
|
|
return voxel_id >> FFX_BRIXELIZER_CASCADE_ID_SHIFT;
|
|
}
|
|
|
|
#define FLT_INF 1e30f
|
|
|
|
// By Morgan McGuire @morgan3d, http://graphicscodex.com
|
|
// Reuse permitted under the BSD license.
|
|
// https://www.shadertoy.com/view/4dsSzr
|
|
FfxFloat32x3 FFX_HeatmapGradient(FfxFloat32 t)
|
|
{
|
|
return clamp((pow(t, 1.5) * 0.8 + 0.2) * FfxFloat32x3(smoothstep(0.0, 0.35, t) + t * 0.5, smoothstep(0.5, 1.0, t), max(1.0 - t * 1.7, t * 7.0 - 6.0)), 0.0, 1.0);
|
|
}
|
|
|
|
// License?
|
|
FfxFloat32x3 FFX_RandomColor(FfxFloat32x2 uv) {
|
|
uv = ffxFract(uv * FfxFloat32(15.718281828459045));
|
|
FfxFloat32x3 seeds = FfxFloat32x3(FfxFloat32(0.123), FfxFloat32(0.456), FfxFloat32(0.789));
|
|
seeds = ffxFract((uv.x + FfxFloat32(0.5718281828459045) + seeds) * ((seeds + FFX_MODULO(uv.x, FfxFloat32(0.141592653589793))) * FfxFloat32(27.61803398875) + FfxFloat32(4.718281828459045)));
|
|
seeds = ffxFract((uv.y + FfxFloat32(0.5718281828459045) + seeds) * ((seeds + FFX_MODULO(uv.y, FfxFloat32(0.141592653589793))) * FfxFloat32(27.61803398875) + FfxFloat32(4.718281828459045)));
|
|
seeds = ffxFract((FfxFloat32(0.5718281828459045) + seeds) * ((seeds + FFX_MODULO(uv.x, FfxFloat32(0.141592653589793))) * FfxFloat32(27.61803398875) + FfxFloat32(4.718281828459045)));
|
|
return seeds;
|
|
}
|
|
|
|
FfxFloat32x3 FFX_ViewSpaceToWorldSpace(FfxFloat32x4 view_space_coord)
|
|
{
|
|
return FFX_TRANSFORM_VECTOR(GetDebugInfoInvView(), view_space_coord).xyz;
|
|
}
|
|
|
|
FfxFloat32x3 FFX_InvProjectPosition(FfxFloat32x3 coord, FfxFloat32x4x4 mat)
|
|
{
|
|
coord.y = (FfxFloat32(1.0) - coord.y);
|
|
coord.xy = FfxFloat32(2.0) * coord.xy - 1;
|
|
FfxFloat32x4 projected = FFX_TRANSFORM_VECTOR(mat, FfxFloat32x4(coord, 1));
|
|
projected.xyz /= projected.w;
|
|
return projected.xyz;
|
|
}
|
|
|
|
FfxFloat32x3 FFX_ScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord)
|
|
{
|
|
return FFX_InvProjectPosition(screen_uv_coord, GetDebugInfoInvProj());
|
|
}
|
|
|
|
FfxFloat32 FFX_HitEdgeDist(FfxFloat32x3 hit, FfxFloat32x3 boxMin, FfxFloat32x3 boxMax)
|
|
{
|
|
FfxFloat32x3 a = min(abs(hit - boxMin), abs(hit - boxMax));
|
|
return min(min(a.x + a.y, a.x + a.z), a.y + a.z);
|
|
}
|
|
|
|
// modified from inigo quilez
|
|
FfxFloat32 FFX_BoxHitDist(FfxUInt32x2 tid, FfxFloat32x3 ro, FfxFloat32x3 rd, FfxFloat32x3 boxMin, FfxFloat32x3 boxMax)
|
|
{
|
|
FfxFloat32x3 halfSize = (boxMax - boxMin) / 2.0f;
|
|
FfxFloat32x3 center = boxMin + halfSize;
|
|
FfxFloat32x3 rop = ro - center;
|
|
FfxFloat32x3 ird = 1.0f / rd;
|
|
FfxFloat32x3 n = rop * ird;
|
|
FfxFloat32x3 k = abs(ird) * halfSize;
|
|
FfxFloat32x3 t1 = -n - k;
|
|
FfxFloat32x3 t2 = -n + k;
|
|
|
|
FfxFloat32 tNear = max(max(t1.x, t1.y), t1.z);
|
|
FfxFloat32 tFar = min(min(t2.x, t2.y), t2.z);
|
|
|
|
if (tNear > tFar || tFar < 0.0f) return FLT_INF;
|
|
|
|
FfxFloat32 nearEdgeDist = FFX_HitEdgeDist(ro + tNear * rd, boxMin, boxMax);
|
|
FfxFloat32 farEdgeDist = FFX_HitEdgeDist(ro + tFar * rd, boxMin, boxMax);
|
|
|
|
const FfxFloat32 nearClip = 0.1f;
|
|
if (tNear > nearClip && nearEdgeDist / tNear < 0.001f) {
|
|
return tNear;
|
|
} else if (tFar > nearClip && farEdgeDist / tFar < 0.001f) {
|
|
return tFar;
|
|
}
|
|
return FLT_INF;
|
|
}
|
|
|
|
void FfxBrixelizerDebugVisualization(FfxUInt32x2 tid)
|
|
{
|
|
FfxUInt32 width, height;
|
|
GetDebugOutputDimensions(width, height);
|
|
FfxFloat32x2 uv = (FfxFloat32x2(tid.xy) + FfxFloat32(0.5).xx) / FfxFloat32x2(width, height);
|
|
|
|
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, FfxFloat32(0.5));
|
|
FfxFloat32x3 view_space_ray = FFX_ScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
|
FfxFloat32x3 view_space_ray_direction = normalize(view_space_ray);
|
|
FfxFloat32x3 ray_direction = normalize(FFX_ViewSpaceToWorldSpace(FfxFloat32x4(view_space_ray_direction, FfxFloat32(0.0))));
|
|
FfxFloat32x3 ray_origin = FFX_ViewSpaceToWorldSpace(FfxFloat32x4(0.0, 0.0, 0.0, 1.0));
|
|
|
|
FfxBrixelizerRayDesc ray_desc;
|
|
ray_desc.start_cascade_id = GetDebugInfoStartCascadeIndex();
|
|
ray_desc.end_cascade_id = GetDebugInfoEndCascadeIndex();
|
|
ray_desc.t_min = GetDebugInfoTMin();
|
|
ray_desc.t_max = GetDebugInfoTMax();
|
|
ray_desc.origin = ray_origin;
|
|
ray_desc.direction = ray_direction;
|
|
|
|
FfxBrixelizerHitRaw hit_payload;
|
|
FfxBoolean hit = FfxBrixelizerTraverseRaw(ray_desc, hit_payload);
|
|
FfxFloat32 hit_dist = FLT_INF;
|
|
FfxFloat32x3 out_color = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
|
|
|
if (hit) {
|
|
hit_dist = hit_payload.t;
|
|
switch (GetDebugInfoDebugState()) {
|
|
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_DISTANCE: {
|
|
FfxFloat32 dist = (hit_payload.t - ray_desc.t_min) / (ray_desc.t_max - ray_desc.t_min);
|
|
out_color = FfxFloat32x3(0.0f, smoothstep(0.0f, 1.0f, dist), smoothstep(0.0f, 1.0f, 1.0f - dist));
|
|
break;
|
|
}
|
|
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_UVW: {
|
|
FfxFloat32x3 uvw = FfxFloat32x3(
|
|
FfxBrixelizerUnpackUnsigned8Bits((hit_payload.uvwc >> 0) & 0xff),
|
|
FfxBrixelizerUnpackUnsigned8Bits((hit_payload.uvwc >> 8) & 0xff),
|
|
FfxBrixelizerUnpackUnsigned8Bits((hit_payload.uvwc >> 16) & 0xff)
|
|
);
|
|
out_color = uvw;
|
|
break;
|
|
}
|
|
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_ITERATIONS:
|
|
out_color = FFX_HeatmapGradient(FfxFloat32(hit_payload.iter_count) / FfxFloat32(64));
|
|
break;
|
|
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_GRAD: {
|
|
out_color = FfxBrixelizerGetHitNormal(hit_payload) * FfxFloat32(0.5) + FfxFloat32(0.5);
|
|
break;
|
|
}
|
|
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_BRICK_ID:
|
|
out_color = FFX_RandomColor(FfxFloat32x2(FfxFloat32(hit_payload.brick_id % 256) / FfxFloat32(256.0), FfxFloat32((hit_payload.brick_id / 256) % 256) / FfxFloat32(256.0)));
|
|
break;
|
|
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_CASCADE_ID: {
|
|
FfxUInt32 voxel_id = LoadBricksVoxelMap(FfxBrixelizerBrickGetIndex(hit_payload.brick_id));
|
|
FfxUInt32 cascade_id = FfxBrixelizerGetVoxelCascade(voxel_id);
|
|
out_color = FFX_RandomColor(FfxFloat32x2(FfxFloat32(cascade_id % 256) / FfxFloat32(256.0), FfxFloat32((cascade_id / 256) % 256) / FfxFloat32(256.0)));
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
out_color = FFX_HeatmapGradient(FfxFloat32(hit_payload.iter_count) / FfxFloat32(64));
|
|
}
|
|
|
|
FfxFloat32 aabb_hit_dist = FLT_INF;
|
|
FfxFloat32x3 aabb_color = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
|
|
|
FfxUInt32 num_debug_aabbs = min(GetDebugInfoMaxAABBs(), LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_NUM_DEBUG_AABBS));
|
|
|
|
for (FfxUInt32 i = 0; i < num_debug_aabbs; ++i) {
|
|
FfxBrixelizerDebugAABB aabb = GetDebugAABB(i);
|
|
|
|
FfxFloat32 this_hit_dist = FFX_BoxHitDist(tid, ray_desc.origin, ray_desc.direction, aabb.aabbMin, aabb.aabbMax);
|
|
if (this_hit_dist < aabb_hit_dist) {
|
|
aabb_hit_dist = this_hit_dist;
|
|
aabb_color = aabb.color;
|
|
}
|
|
}
|
|
|
|
if (aabb_hit_dist < hit_dist) {
|
|
out_color = aabb_color;
|
|
} else if (aabb_hit_dist < FLT_INF) {
|
|
out_color = ffxLerp(out_color, aabb_color, 0.25f);
|
|
}
|
|
|
|
StoreDebugOutput(tid, out_color);
|
|
}
|
|
|
|
#endif // ifndef FFX_BRIXELIZER_DEBUG_VISUALIZATION_H
|