Files
UnrealEngine/Engine/Plugins/TextureGraph/Shaders/Utils/MinMaxDownsample_comp.usf
2025-05-18 13:04:45 +08:00

89 lines
2.4 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "/Engine/Public/Platform.ush"
// Permutations
#ifndef SOURCE_TO_MIN_MAX_PASS
#define SOURCE_TO_MIN_MAX_PASS 0
#endif
int4 TilingDimensions; /// The width and height of each dst tiles (xy) and the number of tiles in the source (zw)
Texture2D SourceTiles_0;
Texture2D SourceTiles_1;
Texture2D SourceTiles_2;
Texture2D SourceTiles_3;
RWTexture2D<float2> Result;
#define Fetch4(tex) float4( \
tex.Load(uint3(tile_pos, 0)).x, \
tex.Load(uint3(tile_pos.x + 1, tile_pos.y, 0)).x, \
tex.Load(uint3(tile_pos.x, tile_pos.y + 1, 0)).x, \
tex.Load(uint3(tile_pos.x + 1, tile_pos.y + 1, 0)).x)
float4 fetch4At(int2 tile_pos)
{
uint2 halfTileSize = TilingDimensions.xy >> 1;
uint2 tile = min(tile_pos / halfTileSize, TilingDimensions.zw - 1);
tile_pos -= tile * halfTileSize;
tile_pos *= 2;
int tileIdx = tile.x * 2 + tile.y;
if (tileIdx == 1) return Fetch4(SourceTiles_1);
if (tileIdx == 2) return Fetch4(SourceTiles_2);
if (tileIdx == 3) return Fetch4(SourceTiles_3);
return Fetch4(SourceTiles_0);
}
#define Fetch4XY(tex) float4x2( \
tex.Load(uint3(tile_pos, 0)).xy, \
tex.Load(uint3(tile_pos.x + 1, tile_pos.y, 0)).xy, \
tex.Load(uint3(tile_pos.x, tile_pos.y + 1, 0)).xy, \
tex.Load(uint3(tile_pos.x + 1, tile_pos.y + 1, 0)).xy )
float4x2 fetch4XYAt(int2 tile_pos)
{
uint2 halfTileSize = TilingDimensions.xy >> 1;
uint2 tile = min(tile_pos / halfTileSize, TilingDimensions.zw - 1);
tile_pos -= tile * halfTileSize;
tile_pos *= 2;
int tileIdx = tile.x * 2 + tile.y;
if (tileIdx == 1) return Fetch4XY(SourceTiles_1);
if (tileIdx == 2) return Fetch4XY(SourceTiles_2);
if (tileIdx == 3) return Fetch4XY(SourceTiles_3);
return Fetch4XY(SourceTiles_0);
}
#ifndef THREADGROUPSIZE_X
#define THREADGROUPSIZE_X 4
#define THREADGROUPSIZE_Y 4
#define THREADGROUPSIZE_Z 1
#endif
[numthreads(THREADGROUPSIZE_X, THREADGROUPSIZE_Y, THREADGROUPSIZE_Z)]
void CSH_MinMaxDownsample(uint3 ThreadId : SV_DispatchThreadID)
{
#if SOURCE_TO_MIN_MAX_PASS
float4 values = fetch4At(ThreadId.xy);
float vmin = min(min(values.x, values.y), min(values.z, values.w));
float vmax = max(max(values.x, values.y), max(values.z, values.w));
#else
float4x2 values = fetch4XYAt(ThreadId.xy);
float vmin = min(min(values[0].x, values[1].x), min(values[2].x, values[3].x));
float vmax = max(max(values[0].y, values[1].y), max(values[2].y, values[3].y));
#endif
Result[ThreadId.xy] = float2(vmin, vmax);
}