You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
7.0 KiB
Plaintext
255 lines
7.0 KiB
Plaintext
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
// The heatmap will change color as the light count increases up to TileCountMax
|
|
static const int TileCountMax = 75;
|
|
static const int OverflowDisplayNumber = 999;
|
|
|
|
|
|
static const float3 BarelyUsedColor = float3(0.05, 0.05, 0.20); // Deep dark blue
|
|
static const float3 LightlyUsedColor = float3(0.05, 0.05, 0.60); // Deep blue
|
|
static const float3 ModeratelyUsedColor = float3(0.05, 0.60, 0.05); // Green
|
|
static const float3 HeavilyUsedColor = float3(1.00, 1.00, 0.05); // Yellow
|
|
static const float3 OverUsedColor = float3(1.00, 0.05, 0.05); // Red
|
|
static const float3 OverflowColor = float3(1.0, 1.0, 1.0); // White
|
|
|
|
|
|
#include <Atom/Features/SrgSemantics.azsli>
|
|
|
|
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
|
|
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
|
|
#include <Atom/Features/PostProcessing/PostProcessUtil.azsli>
|
|
#include <Atom/Features/LightCulling/LightCullingShared.azsli>
|
|
|
|
|
|
#define X 1
|
|
#define _ 0
|
|
|
|
#define PACK_GLYPH_UINT(a, b, c, d) ((d << 3) | (c << 2) | (b << 1) | a)
|
|
|
|
#define CHAR_W 4
|
|
#define GLYPH_HEIGHT 6
|
|
|
|
|
|
#define MAX_CHARS 10
|
|
|
|
|
|
static const uint NumberGlyphs[GLYPH_HEIGHT * MAX_CHARS] =
|
|
{
|
|
// Glpyh for the number 0
|
|
PACK_GLYPH_UINT(_, X, X, _),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(_, X, X, _),
|
|
|
|
// Glpyh for the number 1
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
|
|
// Glpyh for the number 2
|
|
PACK_GLYPH_UINT(X, X, X, _),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(X, _, _, _),
|
|
PACK_GLYPH_UINT(X, _, _, _),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
|
|
// Glpyh for the number 3
|
|
PACK_GLYPH_UINT(X, X, X, _),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, X, X, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, _),
|
|
|
|
// Glpyh for the number 4
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
|
|
// Glpyh for the number 5
|
|
PACK_GLYPH_UINT(X, X, X, _),
|
|
PACK_GLYPH_UINT(X, _, _, _),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
|
|
// Glpyh for the number 6
|
|
PACK_GLYPH_UINT(_, X, X, X),
|
|
PACK_GLYPH_UINT(X, _, _, _),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, _),
|
|
|
|
// Glpyh for the number 7
|
|
PACK_GLYPH_UINT(_, X, X, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
|
|
// Glpyh for the number 8
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
|
|
// Glpyh for the number 9
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(X, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(_, _, _, X),
|
|
PACK_GLYPH_UINT(X, X, X, _),
|
|
};
|
|
|
|
#define IS_UNINITIALIZED 0x0
|
|
#define IS_BACKGROUND 0x1
|
|
#define IS_FOREGROUND 0x2
|
|
|
|
#define PRINT_ITERATION(ch) \
|
|
{ \
|
|
r.x += r.z; \
|
|
if( r.x < r.z ) \
|
|
{ \
|
|
r.xy /= scale; \
|
|
mask = (NumberGlyphs[r.y + ch * GLYPH_HEIGHT] & (1 << r.x)) != 0 ? IS_FOREGROUND : IS_BACKGROUND; \
|
|
} \
|
|
}
|
|
|
|
uint4 InitPrintCoords(uint2 uv, uint2 origin, uint scale)
|
|
{
|
|
uint4 r;
|
|
|
|
r.xy = uv - origin;
|
|
r.zw = uint2(CHAR_W + 1, GLYPH_HEIGHT) * scale;
|
|
|
|
return r;
|
|
}
|
|
|
|
uint PrintNumbersInsideTileImpl(inout uint4 r, uint x, uint scale)
|
|
{
|
|
uint mask = IS_UNINITIALIZED;
|
|
|
|
while( x > 0 && mask == IS_UNINITIALIZED )
|
|
{
|
|
uint n = x % 10;
|
|
x /= 10;
|
|
|
|
PRINT_ITERATION(n);
|
|
}
|
|
|
|
return mask;
|
|
}
|
|
|
|
uint PrintNumbersInsideTile(uint x, uint2 origin, uint2 uv, uint scale)
|
|
{
|
|
uint4 r = InitPrintCoords(uv, origin, scale);
|
|
uint mask = IS_UNINITIALIZED;
|
|
|
|
if( r.y < r.w )
|
|
{
|
|
mask = PrintNumbersInsideTileImpl(r, x, scale);
|
|
}
|
|
|
|
return mask;
|
|
}
|
|
|
|
|
|
float3 ComputeTileColor(const uint2 uv, const uint print_me, const bool overflow)
|
|
{
|
|
int2 local_uv = int2( uv % uint2(TILE_DIM_X, TILE_DIM_Y) );
|
|
|
|
float x = float(print_me) / float(TileCountMax);
|
|
x = sqrt(x);
|
|
x = saturate(x);
|
|
|
|
float3 color;
|
|
|
|
if (overflow)
|
|
{
|
|
color = OverflowColor;
|
|
}
|
|
else if( x <= 0.0 )
|
|
{
|
|
color = float3(0.0, 0.0, 0.0);
|
|
}
|
|
else if( x >= 1.0 )
|
|
{
|
|
color = OverUsedColor;
|
|
}
|
|
else
|
|
{
|
|
color = lerp(BarelyUsedColor, LightlyUsedColor, saturate((x - 0.00) * 4.0));
|
|
color = lerp(color, ModeratelyUsedColor, saturate((x - 0.33) * 4.0));
|
|
color = lerp(color, HeavilyUsedColor, saturate((x - 0.66) * 4.0));
|
|
}
|
|
|
|
float border = (local_uv.x == TILE_DIM_X - 1 || local_uv.y == TILE_DIM_Y - 1) ? 1.0 : 0.0;
|
|
color *= lerp(1.0, 0.75, border);
|
|
|
|
// NOTE: numbers
|
|
|
|
uint mask = PrintNumbersInsideTile(print_me, uint2(TILE_DIM_X - 1, 1), local_uv, 1);
|
|
|
|
if( (mask & IS_FOREGROUND) != 0 )
|
|
{
|
|
color = float3(0.0, 0.0, 0.0);
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
|
|
ShaderResourceGroup PassSrg : SRG_PerPass
|
|
{
|
|
Texture2D<uint> m_lightCount;
|
|
Texture2D<float4> m_framebuffer;
|
|
Texture2D<uint4> m_tileLightData;
|
|
float m_heatmapOpacity;
|
|
}
|
|
|
|
PSOutput MainPS(VSOutput IN)
|
|
{
|
|
const uint2 tileId = ComputeTileId(IN.m_position.xy);
|
|
|
|
const uint tileLightDataW = PassSrg::m_tileLightData[tileId].w;
|
|
|
|
// check to see if we are overflowing the number of lights per tile
|
|
// expect the lighting to flicker if this happens
|
|
const bool overflow = (tileLightDataW >> 31);
|
|
|
|
// We subtract NUM_LIGHT_TYPES because it includes termination markers
|
|
const uint lightCount = overflow ? OverflowDisplayNumber : tileLightDataW - NUM_LIGHT_TYPES;
|
|
|
|
const float3 tileColor = ComputeTileColor(IN.m_position.xy, lightCount, overflow);
|
|
|
|
PSOutput OUT;
|
|
OUT.m_color.rgb = tileColor;
|
|
|
|
// Set this value to > 0 to actually see this pass. It is currently always active.
|
|
OUT.m_color.w = PassSrg::m_heatmapOpacity;
|
|
// ATOM-3682 (improve heatmap integration with the pass system)
|
|
|
|
return OUT;
|
|
}
|