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

84 lines
2.8 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "/Engine/Public/Platform.ush"
#include "/Plugin/TextureGraph/SamplerStates.ush"
#include "/Plugin/TextureGraph/ShaderUtil.ush"
// Permutations
#ifndef CHECK_UVMASK
#define CHECK_UVMASK 0
#endif
#ifndef FIRST_PASS
#define FIRST_PASS 0
#endif
Texture2D SourceTexture;
Texture2D WorldUVMask;
float DX;
float DY;
float2 tex2Dlod_UVMask(Texture2D tex, Texture2D uvMask, float2 uv)
{
#if CHECK_UVMASK
const float inf = 3.402823466e+38F;
float4 s = Texture2DSample(tex, SamplerStates_Linear_Clamp, uv);
float mask = Texture2DSample(uvMask, SamplerStates_Linear_Clamp, uv).r;
/// If the mask is anything other than 0, then we return the pixel value as the min
/// and the max. If it is then our (min, max) = (+inf, -inf) so that they fail every
/// subsequent min and max test
return mask > 0 ? s.rr : float2(+inf, -inf);
#else
/// Both min and max are the same
return Texture2DSampleLevel(tex, SamplerStates_NoBorder, uv, 0).rr;
#endif
}
float2 CalcMinMaxWithUVMask(Texture2D tex, float2 uv, float2 pixelSize)
{
float2 s1 = tex2Dlod_UVMask(tex, WorldUVMask, uv + float2(-1.0, 1.0) * pixelSize).r;
float2 s2 = tex2Dlod_UVMask(tex, WorldUVMask, uv + float2(1.0, 1.0) * pixelSize).r;
float2 s3 = tex2Dlod_UVMask(tex, WorldUVMask, uv + float2(-1.0, -1.0) * pixelSize).r;
float2 s4 = tex2Dlod_UVMask(tex, WorldUVMask, uv + float2(1.0, -1.0) * pixelSize).r;
float r = min(min(s1.r, s2.r), min(s3.r, s4.r));
float g = max(max(s1.g, s2.g), max(s3.g, s4.g));
return float2(r, g);
}
float2 CalcMinMax(Texture2D tex, float2 uv, float2 pixelSize)
{
float2 s1 = Texture2DSampleLevel(tex, SamplerStates_NoBorder, uv + float2(-1.0, 1.0) * pixelSize, 0).rg;
float2 s2 = Texture2DSampleLevel(tex, SamplerStates_NoBorder, uv + float2(1.0, 1.0) * pixelSize, 0).rg;
float2 s3 = Texture2DSampleLevel(tex, SamplerStates_NoBorder, uv + float2(-1.0, -1.0) * pixelSize, 0).rg;
float2 s4 = Texture2DSampleLevel(tex, SamplerStates_NoBorder, uv + float2(1.0, -1.0) * pixelSize, 0).rg;
float r = min(min(s1.r, s2.r), min(s3.r, s4.r));
float g = max(max(s1.g, s2.g), max(s3.g, s4.g));
return float2(r, g);
}
float4 FSH_MinMaxDownsampleFirstPass(float2 uv : TEXCOORD0) : SV_Target0
{
return float4(CalcMinMaxWithUVMask(SourceTexture, uv, float2(DX, DY)), 0.0, 0.0);
}
float4 FSH_MinMaxDownsampleSecondPass(float2 uv : TEXCOORD0) : SV_Target0
{
return float4(CalcMinMax(SourceTexture, uv, float2(DX, DY)), 0.0, 0.0);
}
float4 FSH_MinMaxDownsample(float2 uv : TEXCOORD0) : SV_Target0
{
#if FIRST_PASS
return FSH_MinMaxDownsampleFirstPass(uv);
#else
return FSH_MinMaxDownsampleSecondPass(uv);
#endif
}