Files
UnrealEngineUWP/Engine/Shaders/Private/VirtualTextureCompress.usf
jeremy moore a8aff04a29 Use RGBA16 alias for BC1/BC4 when rendering runtime virtual textures.
Removes inconsistency for some platforms.
Removes special case uint2/uint4 stuff in the compression shader.
#preflight 61dcd1423c7555edfda4894c

#ROBOMERGE-AUTHOR: jeremy.moore
#ROBOMERGE-SOURCE: CL 18568577 in //UE5/Release-5.0/... via CL 18568581
#ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v899-18417669)

[CL 18568587 by jeremy moore in ue5-release-engine-test branch]
2022-01-10 21:54:23 -05:00

291 lines
10 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
VirtualTextureCompress.usf:
Compression pass for runtime virtual texture
todo[vt]: Lots of possible optimizations to do...
=============================================================================*/
#include "Common.ush"
#include "BlockCompressionCommon.ush"
#include "BCCompressionCommon.ush"
#include "ETCCompressionCommon.ush"
#ifndef ETC_PROFILE
#define ETC_PROFILE 0
#endif
uint4 DestRect;
Texture2D<float4> RenderTexture0;
SamplerState TextureSampler0;
Texture2D<float4> RenderTexture1;
SamplerState TextureSampler1;
Texture2D<float4> RenderTexture2;
SamplerState TextureSampler2;
RWTexture2D<uint4> OutCompressTexture0;
RWTexture2D<uint4> OutCompressTexture1;
RWTexture2D<uint4> OutCompressTexture2;
/** Pack ETC RG32 to RGBA16 for output. */
uint4 PackRG32(in uint2 u2)
{
uint x0 = (u2.x >> 16) & 0x0000ffff;
uint y0 = (u2.y >> 16) & 0x0000ffff;
uint x1 = (u2.x) & 0x0000ffff;
uint y1 = (u2.y) & 0x0000ffff;
return uint4(x1,x0,y1,y0);
}
/** Trivial vertex shader for copy shaders. */
void CopyVS(in uint VertexId : SV_VertexID, out float4 OutPosition : SV_POSITION, out float2 OutTexCoord : TEXCOORD0)
{
OutTexCoord = float2(((VertexId + 1) / 3) & 1, VertexId & 1);
OutPosition.xy = float2(OutTexCoord.x, 1.f - OutTexCoord.y) * 2.f - 1.f;
OutPosition.zw = float2(0, 1);
}
/** Compress base color to a single BC1 target. */
[numthreads(8,8,1)]
void CompressBaseColorCS(
uint3 ThreadId : SV_DispatchThreadID
)
{
uint2 SamplePos = ThreadId.xy * 4;
if (any(ThreadId.xy >= DestRect.zw))
return;
float2 TexelUVSize = 1.f / float2(DestRect.zw);
float2 SampleUV = (float2(SamplePos) + 0.5f) * TexelUVSize;
float3 BlockBaseColor[16];
ReadBlockRGB(RenderTexture0, TextureSampler0, SampleUV, TexelUVSize, BlockBaseColor);
#if ETC_PROFILE
OutCompressTexture0[ThreadId.xy + DestRect.xy] = PackRG32(CompressBlock_ETC2_SRGB(BlockBaseColor));
#else
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBC1Block_SRGB(BlockBaseColor);
#endif
}
/** Simple copy of base color used for thumbnails. */
void CopyBaseColorPS(
in float4 InPosition : SV_POSITION,
in noperspective float2 InTexCoord : TEXCOORD0,
out float4 OutColor0 : SV_Target0)
{
float3 BaseColor = RenderTexture0.SampleLevel(TextureSampler0, InTexCoord, 0).xyz;
OutColor0 = float4(BaseColor, 1.f);
}
/** Compress base color, normal, roughness and specular to BC3 target pair. */
[numthreads(8,8,1)]
void CompressBaseColorNormalSpecularCS(
uint3 ThreadId : SV_DispatchThreadID
)
{
uint2 SamplePos = ThreadId.xy * 4;
if (any(SamplePos >= DestRect.zw))
return;
float2 TexelUVSize = 1.f / float2(DestRect.zw);
float2 SampleUV = (float2(SamplePos) + 0.5f) * TexelUVSize;
float3 BlockBaseColor[16];
ReadBlockRGB(RenderTexture0, TextureSampler0, SampleUV, TexelUVSize, BlockBaseColor);
float BlockNormalX[16];
float BlockNormalY[16];
ReadBlockXY(RenderTexture1, TextureSampler1, SampleUV, TexelUVSize, BlockNormalX, BlockNormalY);
float3 BlockSpecular[16];
ReadBlockRGB(RenderTexture2, TextureSampler2, SampleUV, TexelUVSize, BlockSpecular);
for (int i=0; i<16; i++)
{
BlockSpecular[i].z = round(BlockSpecular[i].z);
}
#if ETC_PROFILE
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_RGBA(BlockBaseColor, BlockNormalX);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_RGBA(BlockSpecular, BlockNormalY);
#else
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBC3Block_SRGB(BlockBaseColor, BlockNormalX);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBC3Block(BlockSpecular, BlockNormalY);
#endif
}
/** Compress base color, normal, roughness to BC1 & BC3. */
[numthreads(8, 8, 1)]
void CompressBaseColorNormalRoughnessCS(
uint3 ThreadId : SV_DispatchThreadID
)
{
uint2 SamplePos = ThreadId.xy * 4;
if (any(SamplePos >= DestRect.zw))
return;
float2 TexelUVSize = 1.f / float2(DestRect.zw);
float2 SampleUV = (float2(SamplePos) + 0.5f) * TexelUVSize;
float3 BlockBaseColor[16];
ReadBlockRGB(RenderTexture0, TextureSampler0, SampleUV, TexelUVSize, BlockBaseColor);
float3 BlockNormalXRougnnessY[16];
const float BlockNormalZ[16]={ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
ReadBlockRGB(RenderTexture1, TextureSampler2, SampleUV, TexelUVSize, BlockNormalXRougnnessY);
#if ETC_PROFILE
OutCompressTexture0[ThreadId.xy + DestRect.xy] = PackRG32(CompressBlock_ETC2_RGB(BlockBaseColor));
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_RGBA(BlockNormalXRougnnessY, BlockNormalZ);
#else
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBC1Block_SRGB(BlockBaseColor);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBC3Block(BlockNormalXRougnnessY, BlockNormalZ);
#endif
}
/** Copy path used when we disable texture compression, because we need to keep the same final channel layout. */
void CopyBaseColorNormalSpecularPS(
in float4 InPosition : SV_POSITION,
in noperspective float2 InTexCoord : TEXCOORD0,
out float4 OutColor0 : SV_Target0,
out float4 OutColor1 : SV_Target1)
{
float3 BaseColor = RenderTexture0.SampleLevel(TextureSampler0, InTexCoord, 0).xyz;
float2 NormalXY = RenderTexture1.SampleLevel(TextureSampler1, InTexCoord, 0).xy;
float3 RoughnessSpecularNormalZ = RenderTexture2.SampleLevel(TextureSampler2, InTexCoord, 0).xyz;
RoughnessSpecularNormalZ.z = round(RoughnessSpecularNormalZ.z);
OutColor0 = float4(BaseColor, NormalXY.x);
OutColor1 = float4(RoughnessSpecularNormalZ, NormalXY.y);
}
/** Compress base color, normal, roughness and specular to BC3, BC5, BC1 target set. */
[numthreads(8,8,1)]
void CompressBaseColorNormalSpecularYCoCgCS(
uint3 ThreadId : SV_DispatchThreadID
)
{
uint2 SamplePos = ThreadId.xy * 4;
if (any(SamplePos >= DestRect.zw))
return;
float2 TexelUVSize = 1.f / float2(DestRect.zw);
float2 SampleUV = (float2(SamplePos) + 0.5f) * TexelUVSize;
float3 BlockBaseColor[16];
ReadBlockRGB(RenderTexture0, TextureSampler0, SampleUV, TexelUVSize, BlockBaseColor);
float BlockNormalX[16];
float BlockNormalY[16];
ReadBlockXY(RenderTexture1, TextureSampler1, SampleUV, TexelUVSize, BlockNormalX, BlockNormalY);
float3 BlockSpecular[16];
ReadBlockRGB(RenderTexture2, TextureSampler2, SampleUV, TexelUVSize, BlockSpecular);
for (int i=0; i<16; i++)
{
BlockSpecular[i].z = round(BlockSpecular[i].z);
}
#if ETC_PROFILE
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_YCoCg(BlockBaseColor);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_RG(BlockNormalX, BlockNormalY);
OutCompressTexture2[ThreadId.xy + DestRect.xy] = PackRG32(CompressBlock_ETC2_RGB(BlockSpecular));
#else
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBC3BlockYCoCg(BlockBaseColor);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBC5Block(BlockNormalX, BlockNormalY);
OutCompressTexture2[ThreadId.xy + DestRect.xy] = CompressBC1Block(BlockSpecular);
#endif
}
/** Copy path used when we disable texture compression, because we need to keep the same final channel layout. */
void CopyBaseColorNormalSpecularYCoCgPS(
in float4 InPosition : SV_POSITION,
in noperspective float2 InTexCoord : TEXCOORD0,
out float4 OutColor0 : SV_Target0,
out float4 OutColor1 : SV_Target1,
out float4 OutColor2 : SV_Target2)
{
float3 YCoCg = RGB2YCoCg(RenderTexture0.SampleLevel(TextureSampler0, InTexCoord, 0).xyz);
float2 NormalXY = RenderTexture1.SampleLevel(TextureSampler1, InTexCoord, 0).xy;
float3 RoughnessSpecularNormalZ = RenderTexture2.SampleLevel(TextureSampler2, InTexCoord, 0).xyz;
RoughnessSpecularNormalZ.z = round(RoughnessSpecularNormalZ.z);
OutColor0 = float4(YCoCg.yz, 0, YCoCg.x);
OutColor1 = float4(NormalXY, 0, 1);
OutColor2 = float4(RoughnessSpecularNormalZ, 1);
}
/** Compress base color, normal, roughness, specular and mask to BC3, BC5, BC3 target set. */
[numthreads(8,8,1)]
void CompressBaseColorNormalSpecularMaskYCoCgCS(
uint3 ThreadId : SV_DispatchThreadID
)
{
uint2 SamplePos = ThreadId.xy * 4;
if (any(SamplePos >= DestRect.zw))
return;
float2 TexelUVSize = 1.f / float2(DestRect.zw);
float2 SampleUV = (float2(SamplePos) + 0.5f) * TexelUVSize;
float3 BlockBaseColor[16];
ReadBlockRGB(RenderTexture0, TextureSampler0, SampleUV, TexelUVSize, BlockBaseColor);
float BlockNormalX[16];
float BlockNormalY[16];
float BlockMask[16];
ReadBlockXYA(RenderTexture1, TextureSampler1, SampleUV, TexelUVSize, BlockNormalX, BlockNormalY, BlockMask);
float3 BlockSpecular[16];
ReadBlockRGB(RenderTexture2, TextureSampler2, SampleUV, TexelUVSize, BlockSpecular);
for (int i=0; i<16; i++)
{
BlockSpecular[i].z = round(BlockSpecular[i].z);
}
#if ETC_PROFILE
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_YCoCg(BlockBaseColor);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_RG(BlockNormalX, BlockNormalY);
OutCompressTexture2[ThreadId.xy + DestRect.xy] = CompressBlock_ETC2_RGBA(BlockSpecular, BlockMask);
#else
OutCompressTexture0[ThreadId.xy + DestRect.xy] = CompressBC3BlockYCoCg(BlockBaseColor);
OutCompressTexture1[ThreadId.xy + DestRect.xy] = CompressBC5Block(BlockNormalX, BlockNormalY);
OutCompressTexture2[ThreadId.xy + DestRect.xy] = CompressBC3Block(BlockSpecular, BlockMask);
#endif
}
/** Copy path used when we disable texture compression, because we need to keep the same final channel layout. */
void CopyBaseColorNormalSpecularMaskYCoCgPS(
in float4 InPosition : SV_POSITION,
in noperspective float2 InTexCoord : TEXCOORD0,
out float4 OutColor0 : SV_Target0,
out float4 OutColor1 : SV_Target1,
out float4 OutColor2 : SV_Target2)
{
float3 YCoCg = RGB2YCoCg(RenderTexture0.SampleLevel(TextureSampler0, InTexCoord, 0).xyz);
float3 NormalXYMask = RenderTexture1.SampleLevel(TextureSampler1, InTexCoord, 0).xyz;
float3 RoughnessSpecularNormalZ = RenderTexture2.SampleLevel(TextureSampler2, InTexCoord, 0).xyz;
RoughnessSpecularNormalZ.z = round(RoughnessSpecularNormalZ.z);
OutColor0 = float4(YCoCg.yz, 0, YCoCg.x);
OutColor1 = float4(NormalXYMask.xy, 0, 1);
OutColor2 = float4(RoughnessSpecularNormalZ, NormalXYMask.z);
}
/** Copy world height (without compression)
* This path is used when want to copy the world height data into a thumbnail. */
void CopyWorldHeightPS(
in float4 InPosition : SV_POSITION,
in noperspective float2 InTexCoord : TEXCOORD0,
out float4 OutColor0 : SV_Target0)
{
float WorldHeight = RenderTexture0.SampleLevel(TextureSampler0, InTexCoord, 0).r;
OutColor0 = float4(WorldHeight.xxx, 1.f);
}