You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
* Visualize texture system starts out in an inactive state until a command is issued, avoiding overhead of tracking views and scene textures, saving 1.4% on the render thread. * Visualization overhead eliminated for views besides the one currently being visualized. * Support for visualization of textures from scene captures, via "view=N" option (specifying the unique ID of the view), with "view=?" displaying a list of views for reference. * Improved visualization for cube maps. PIP uses 2:1 aspect for the longitudinal render to match resource viewer display, and pixel perfect option shows tiled flat cube map faces (actual pixels) rather than running a projection. * Padding for scene or screen pass textures is removed in the visualization -- the padding otherwise shows up as garbage or blank space. To remove scene texture padding, it's necessary to add a field to RDG textures to provide an option to track the viewport sizes that were rendered for a given texture. If not set, the assumption is the whole texture was rendered. The field is set for FSceneTextures and FScreenPassTexture, covering the vast majority of cases, plus the denoiser was spot fixed -- worst case if any other cases are missed, you still see the padding. You can tell padding was present when visualizing by contrasting the texture size with the viewport size. Padding was always a potential issue for the visualizer, but is exacerbated by scene captures, as the padded scene textures are set to a size that's a union of the main view and any scene captures. Padding is also exacerbated by dynamic resolution scaling, as the buffers will be padded to the maximum resolution. For example, a cube map rendering at 512x512 will have 93% of the pixel area as padding if the front buffer is at 1440p, or the default dynamic resolution setup will have 70% of the pixels as padding at minimum res. #rb Jason.Nadro [CL 31160232 by jason hoerner in ue5-main branch]
223 lines
7.8 KiB
Plaintext
223 lines
7.8 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
VisualizeTexture.usf: VisualizeTexture shader
|
|
=============================================================================*/
|
|
|
|
#include "../Common.ush"
|
|
|
|
#define INPUT_MAPPING_COLOR 0
|
|
#define INPUT_MAPPING_DEPTH 1
|
|
#define INPUT_MAPPING_SHADOW 2
|
|
|
|
// to visualize the content of a texture to the screen, useful for debugging
|
|
// use "VisualizeTexture" in the console to activate
|
|
Texture2D VisualizeTexture2D;
|
|
SamplerState VisualizeTexture2DSampler;
|
|
Texture3D VisualizeTexture3D;
|
|
SamplerState VisualizeTexture3DSampler;
|
|
TextureCube VisualizeTextureCube;
|
|
SamplerState VisualizeTextureCubeSampler;
|
|
|
|
//default Texture2D type is <float4>, which won't read the X28_G8UINT format properly.
|
|
Texture2D<uint4> VisualizeDepthStencil;
|
|
|
|
Texture2D<uint> VisualizeUINT8Texture2D;
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|
|
Texture2DMS<float4> VisualizeTexture2DMS;
|
|
TextureCubeArray VisualizeTextureCubeArray;
|
|
SamplerState VisualizeTextureCubeArraySampler;
|
|
#endif
|
|
|
|
// [0]: r:RGBAdd, g:SingleChannelMul, b:Add, a:FracScale
|
|
// [1]: r:BlinkState=0/1, g:Frac when 0, saturate when 1, b:array index, a:custom mip
|
|
// [2]: r:0=normal 1=depth, 2=shadow depth, g:unwrapcubemap, b:singlechannel(0-3), a:unused
|
|
float4 VisualizeParam[3];
|
|
// x, y (0 for 2D textures), z(only !=0 if 3d texture), w unused
|
|
float3 TextureExtent;
|
|
|
|
|
|
void VisualizeTexturePS(
|
|
float4 SvPosition : SV_POSITION,
|
|
out float4 OutColor : SV_Target0)
|
|
{
|
|
float2 UV = SvPosition.xy / TextureExtent.xy;
|
|
|
|
// Longitude Latitude unwrapping
|
|
float3 SpherePos;
|
|
{
|
|
float2 Angles = float2(2 * PI * (UV.x + 0.5f), PI * (1 - UV.y));
|
|
float s = sin(Angles.y);
|
|
SpherePos = float3(s * sin(Angles.x), -s * cos(Angles.x), -cos(Angles.y));
|
|
}
|
|
|
|
// Pixel based cube map unwrapping -- assumes 4x3 aspect ratio. Produces a seamless panorama in the middle, connected to adjacent sky / floor faces.
|
|
float3 CubePixelPos;
|
|
{
|
|
float2 LerpCoords = UV * float2(4.0, 3.0);
|
|
float FaceCoords[3] =
|
|
{
|
|
frac(LerpCoords.x) * 2.0 - 1.0,
|
|
frac(LerpCoords.y) * 2.0 - 1.0,
|
|
1.0
|
|
};
|
|
|
|
// Table selecting a UV coordinate or "1" for each of the XYZ axes using a hex digit, preceded by a "0" or "2" to specify whether the axis should be negated.
|
|
uint FaceUVMappingTable[12] =
|
|
{
|
|
0x010002, // Positive Z faces (different rotations to line up with panoramic neighbor below)
|
|
0x200102,
|
|
0x212002,
|
|
0x002102,
|
|
0x020021, // Positive X
|
|
0x200221, // Positive Y
|
|
0x222021, // Negative X
|
|
0x002221, // Negative Y
|
|
0x210022, // Negative Z faces (different rotations to line up with panoramic neighbor above)
|
|
0x202122,
|
|
0x012022,
|
|
0x000122,
|
|
};
|
|
uint FaceUVMapping = FaceUVMappingTable[floor(LerpCoords.x) + floor(LerpCoords.y) * 4.0];
|
|
CubePixelPos = float3(
|
|
FaceCoords[(FaceUVMapping >> 16) & 0xf] * (1.0 - ((float) ((FaceUVMapping >> 20) & 0xf))),
|
|
FaceCoords[(FaceUVMapping >> 8) & 0xf] * (1.0 - ((float) ((FaceUVMapping >> 12) & 0xf))),
|
|
FaceCoords[(FaceUVMapping >> 0) & 0xf] * (1.0 - ((float) ((FaceUVMapping >> 4) & 0xf))));
|
|
}
|
|
|
|
// volume texture unwrapping
|
|
float3 VolumePos;
|
|
{
|
|
uint LayerCount = TextureExtent.z;
|
|
uint LayerUCount = (uint)sqrt(TextureExtent.z);
|
|
uint LayerVCount = LayerCount / LayerUCount;
|
|
|
|
uint LayerUId = (uint)(UV.x * LayerUCount);
|
|
uint LayerVId = (uint)(UV.y * LayerVCount);
|
|
uint LayerId = LayerUId + LayerUCount * LayerVId;
|
|
|
|
VolumePos.z = LayerId / (TextureExtent.z - 1);
|
|
VolumePos.x = frac(UV.x * LayerUCount);
|
|
VolumePos.y = frac(UV.y * LayerVCount);
|
|
}
|
|
|
|
float MipLevel = VisualizeParam[1].a;
|
|
float ArrayIndex = VisualizeParam[1].b;
|
|
|
|
|
|
|
|
#if TEXTURE_TYPE == 0
|
|
// Select pixel accurate map coordinates if the visualization is 4x3 aspect ratio
|
|
float4 TexLookup = TextureCubeSampleLevel(VisualizeTextureCube, VisualizeTextureCubeSampler, TextureExtent.x*0.75 == TextureExtent.y ? CubePixelPos : SpherePos, MipLevel);
|
|
#elif TEXTURE_TYPE == 2 || TEXTURE_TYPE == 6
|
|
float4 TexLookup = Texture2DSampleLevel(VisualizeTexture2D, VisualizeTexture2DSampler, UV, MipLevel);
|
|
#elif TEXTURE_TYPE == 3
|
|
#if FEATURE_LEVEL < FEATURE_LEVEL_SM4
|
|
float4 TexLookup = float4(1.0f, 0.0f, 1.0f, 1.0f);
|
|
#else
|
|
float4 TexLookup = Texture3DSampleLevel(VisualizeTexture3D, VisualizeTexture3DSampler, VolumePos, MipLevel);
|
|
#endif
|
|
#elif TEXTURE_TYPE == 4
|
|
#if FEATURE_LEVEL < FEATURE_LEVEL_SM5
|
|
float4 TexLookup = float4(1.0f, 0.0f, 1.0f, 1.0f);
|
|
#else
|
|
float4 TexLookup = TextureCubeArraySampleLevel(VisualizeTextureCubeArray, VisualizeTextureCubeArraySampler, SpherePos, ArrayIndex, MipLevel);
|
|
#endif
|
|
#elif TEXTURE_TYPE == 5
|
|
float4 TexLookup = float4(1,1,0,0); // yellow, not yet supported
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|
|
TexLookup = VisualizeTexture2DMS.Load(int2(UV * TextureExtent.xy), 0);
|
|
#endif
|
|
#elif TEXTURE_TYPE == 7
|
|
float IntTexLookup = float(VisualizeUINT8Texture2D.Load(int3(UV * TextureExtent.xy, 0)));
|
|
float4 TexLookup = IntTexLookup.xxxx;
|
|
#elif TEXTURE_TYPE == 8
|
|
// 32 bits int, rather arbitrarily visualized as spread over the rgba channels
|
|
int IntTexLookup = VisualizeUINT8Texture2D.Load(int3(UV * TextureExtent.xy, 0));
|
|
float4 TexLookup;
|
|
TexLookup.r = IntTexLookup & 0xFF;
|
|
TexLookup.g = (IntTexLookup >> 8) & 0xFF;
|
|
TexLookup.b = (IntTexLookup >> 16) & 0xFF;
|
|
TexLookup.a = (IntTexLookup >> 24) & 0xFF;
|
|
#endif
|
|
|
|
uint InputValueMapping = (uint)VisualizeParam[2].r;
|
|
if(InputValueMapping != INPUT_MAPPING_COLOR)
|
|
{
|
|
float Depth = TexLookup.r;
|
|
if (InputValueMapping == INPUT_MAPPING_DEPTH)
|
|
{
|
|
// current z buffer is negated (1 is near, 0 is far)
|
|
#if HAS_INVERTED_Z_BUFFER
|
|
Depth = 1 - Depth;
|
|
#endif
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
|
|
// map depth to nice colors
|
|
float Scale = 64.0; // This 64 looks like a hardware limit.
|
|
Depth = (exp2(Depth * Scale) - 1.0) * (1.0 / (exp2(Scale) - 1.0));
|
|
Depth *= Depth;
|
|
Depth *= Depth;
|
|
|
|
float Value = Depth * Depth;
|
|
TexLookup = float4(pow(Value, 0.25f), pow(Value, 1), pow(Value, 4), 0);
|
|
}
|
|
else if (InputValueMapping == INPUT_MAPPING_SHADOW)
|
|
{
|
|
// linearly blend from White (near) to Teal (far).
|
|
float3 TealBlue = float3(54.f/255.f, 117.f/255.f, 136.f/255.f);
|
|
float3 White = float3(1.0f, 1.0f, 1.0f);
|
|
TexLookup.rgb = lerp(White, TealBlue, Depth);
|
|
}
|
|
#if TEXTURE_TYPE == 6
|
|
// inside #ifdef to avoid D3DDebug error:
|
|
// The resource return type for component 0 declared in the shader code (UINT) is not compatible with the Shader Resource View format bound to slot 1 of the Pixel Shader unit (UNORM). This mismatch is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #361: DEVICE_DRAW_RESOURCE_RETURN_TYPE_MISMATCH]
|
|
float fStencil = VisualizeDepthStencil.Load(int3(UV * TextureExtent.xy, 0)).g;
|
|
fStencil /= 255.0f;
|
|
TexLookup.a = fStencil;
|
|
#endif
|
|
|
|
#else
|
|
}
|
|
TexLookup.r = Depth;
|
|
#endif
|
|
}
|
|
|
|
float4 RGBAMask = 0;
|
|
int SingleChannel = (int)VisualizeParam[2].z;
|
|
switch (SingleChannel)
|
|
{
|
|
case 0: RGBAMask = float4(1,0,0,0); break;
|
|
case 1: RGBAMask = float4(0,1,0,0); break;
|
|
case 2: RGBAMask = float4(0,0,1,0); break;
|
|
case 3: RGBAMask = float4(0,0,0,1); break;
|
|
default: RGBAMask = float4(0,0,0,0); break;
|
|
}
|
|
float Add = dot( TexLookup, RGBAMask ) * VisualizeParam[0].y + VisualizeParam[0].z;
|
|
|
|
|
|
OutColor.rgb = TexLookup.rgb * VisualizeParam[0].xxx + Add.xxx;
|
|
|
|
float3 ScaledColor = OutColor.rgb * VisualizeParam[0].w;
|
|
float3 FracOutColor = lerp(ScaledColor, saturate(ScaledColor), VisualizeParam[1].y);
|
|
|
|
float3 AlternateColor = FracOutColor;
|
|
|
|
// blink red if <0
|
|
if(OutColor.r < 0.0f || OutColor.g < 0.0f || OutColor.b < 0.0f)
|
|
{
|
|
AlternateColor = float3(1, 0, 0);
|
|
}
|
|
|
|
// blink blue if not finite
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
|
|
if (isfinite(OutColor.rgb).x == false)
|
|
{
|
|
AlternateColor = float3(0, 0, 1);
|
|
}
|
|
#endif
|
|
OutColor.rgb = lerp(FracOutColor, AlternateColor, VisualizeParam[1].x);
|
|
OutColor.a = 0;
|
|
} |