You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
When we do this we only need a single quad to render each landscape component subsection. This reduces vertex shader cost which can sometimes dominate RVT rendering. And it can remove the need to set difficult to understand landscape RVT LOD settings. One downside is that bilinear texture map interpolation is different to triangle barycentric interpolation, so there is a subtle difference in extreme cases, but nothing visually bad. The difference will matter for VHM rendering though. [CL 22968373 by jeremy moore in ue5-main branch]
148 lines
5.5 KiB
Plaintext
148 lines
5.5 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
// Material shader for runtime virtual texture
|
|
|
|
#include "Common.ush"
|
|
#include "GammaCorrectionCommon.ush"
|
|
#include "/Engine/Generated/Material.ush"
|
|
#include "/Engine/Generated/VertexFactory.ush"
|
|
|
|
struct FVirtualTextureVSOutput
|
|
{
|
|
FVertexFactoryInterpolantsVSToPS FactoryInterpolants;
|
|
float4 Position : SV_POSITION;
|
|
};
|
|
|
|
#if VERTEXSHADER
|
|
|
|
void MainVS(
|
|
FVertexFactoryInput Input,
|
|
out FVirtualTextureVSOutput Output
|
|
)
|
|
{
|
|
ResolvedView = ResolveView();
|
|
|
|
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
|
|
|
|
#if VF_PER_PIXEL_HEIGHTMAP
|
|
if (HasVertexFactoryPerPixelHeight())
|
|
{
|
|
// Special case PerPixel Height for Landscape.
|
|
// Remove PerVertex Height and apply in Pixel Shader.
|
|
VFIntermediates.LocalPosition.z = 0;
|
|
}
|
|
#endif
|
|
|
|
float4 WorldPosition = VertexFactoryGetWorldPosition(Input, VFIntermediates);
|
|
float3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
|
|
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPosition.xyz, TangentToLocal);
|
|
|
|
{
|
|
float4 RasterizedWorldPosition = VertexFactoryGetRasterizedWorldPosition(Input, VFIntermediates, WorldPosition);
|
|
float4 ClipSpacePosition = mul(RasterizedWorldPosition, ResolvedView.TranslatedWorldToClip);
|
|
Output.Position = ClipSpacePosition;
|
|
}
|
|
|
|
Output.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters);
|
|
}
|
|
|
|
#endif // VERTEXSHADER
|
|
|
|
// Prepare for VirtualTextureUnpackNormal() in VirtualTextureCommon.h
|
|
float3 PackNormal( in float3 N )
|
|
{
|
|
return normalize(N) * (127.f / 255.f) + (127.f / 255.f);
|
|
}
|
|
|
|
// Prepare for VirtualTextureUnpackHeight() in VirtualTextureCommon.ush
|
|
// LWC_TODO: LWC scale/bias?
|
|
float PackWorldHeight( in FLWCScalar Height, in float2 PackHeightScaleBias )
|
|
{
|
|
return LWCSaturate(LWCAdd(LWCMultiply(Height, PackHeightScaleBias.x), PackHeightScaleBias.y));
|
|
}
|
|
|
|
void FPixelShaderInOut_MainPS(
|
|
in FVertexFactoryInterpolantsVSToPS Interpolants,
|
|
inout FPixelShaderIn In,
|
|
inout FPixelShaderOut Out )
|
|
{
|
|
ResolvedView = ResolveView();
|
|
|
|
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants, In.SvPosition);
|
|
|
|
FPixelMaterialInputs PixelMaterialInputs;
|
|
CalcPixelMaterialInputs(MaterialParameters, PixelMaterialInputs);
|
|
|
|
float4 ScreenPosition = SvPositionToResolvedScreenPosition(In.SvPosition);
|
|
float3 TranslatedWorldPosition = SvPositionToResolvedTranslatedWorld(In.SvPosition);
|
|
|
|
#if VF_PER_PIXEL_HEIGHTMAP
|
|
if (HasVertexFactoryPerPixelHeight())
|
|
{
|
|
// Special case PerPixel Height for Landscape.
|
|
// Assumes Heightmap is camera aligned.
|
|
float3 LocalPositionDelta = float3(0, 0, GetVertexFactoryPerPixelHeight(Interpolants));
|
|
TranslatedWorldPosition += TransformLocalVectorToWorld(MaterialParameters, LocalPositionDelta);
|
|
}
|
|
#endif
|
|
|
|
CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, In.SvPosition, ScreenPosition, In.bIsFrontFace, TranslatedWorldPosition, TranslatedWorldPosition);
|
|
|
|
#if VIRTUAL_TEXTURE_OUTPUT
|
|
// Output is from a UMaterialExpressionRuntimeVirtualTextureOutput node
|
|
half3 BaseColor = GetVirtualTextureOutput0(MaterialParameters);
|
|
half Specular = GetVirtualTextureOutput1(MaterialParameters);
|
|
half Roughness = GetVirtualTextureOutput2(MaterialParameters);
|
|
half3 Normal = GetVirtualTextureOutput3(MaterialParameters);
|
|
FLWCScalar WorldHeight = GetVirtualTextureOutput4_LWC(MaterialParameters);
|
|
float Opacity = GetVirtualTextureOutput5(MaterialParameters);
|
|
float Mask = GetVirtualTextureOutput6(MaterialParameters);
|
|
#else
|
|
// Output is from standard material output attribute node
|
|
half3 BaseColor = GetMaterialBaseColor(PixelMaterialInputs);
|
|
half Specular = GetMaterialSpecular(PixelMaterialInputs);
|
|
half Roughness = GetMaterialRoughness(PixelMaterialInputs);
|
|
half3 Normal = MaterialParameters.WorldNormal;
|
|
FLWCScalar WorldHeight = LWCGetZ(MaterialParameters.AbsoluteWorldPosition);
|
|
float Opacity = GetMaterialOpacity(PixelMaterialInputs);
|
|
float Mask = 0.f;
|
|
#endif
|
|
|
|
// Apply debug shading
|
|
BaseColor = lerp(BaseColor, half3(In.SvPosition.xy * ResolvedView.ViewSizeAndInvSize.zw, 0), ResolvedView.RuntimeVirtualTextureDebugParams.x * 0.25);
|
|
|
|
#if defined(OUT_BASECOLOR)
|
|
Out.MRT[0] = float4(BaseColor, 1.f) * Opacity;
|
|
#elif defined(OUT_BASECOLOR_NORMAL_ROUGHNESS)
|
|
float3 PackedNormal = PackNormal(Normal);
|
|
//store basecolor in srgb space to improve image quality
|
|
Out.MRT[0] = float4(LinearToSrgb(BaseColor), 1.0) * Opacity;
|
|
//not enough channels for sign of normal z
|
|
Out.MRT[1] = float4(PackedNormal.x, Roughness, PackedNormal.y, 1.0) * Opacity;
|
|
#elif defined(OUT_BASECOLOR_NORMAL_SPECULAR)
|
|
float3 PackedNormal = PackNormal(Normal);
|
|
Out.MRT[0] = float4(BaseColor, 1.f) * Opacity;
|
|
Out.MRT[1] = float4(PackedNormal.xy, Mask, 1.f) * Opacity;
|
|
Out.MRT[2] = float4(Specular, Roughness, PackedNormal.z, 1.f) * Opacity;
|
|
#elif defined(OUT_WORLDHEIGHT)
|
|
float PackedHeight = PackWorldHeight(WorldHeight, ResolvedView.RuntimeVirtualTexturePackHeight);
|
|
Out.MRT[0] = float4(PackedHeight, 0, 0, 1);
|
|
#endif
|
|
}
|
|
|
|
#define PIXELSHADEROUTPUT_INTERPOLANTS 1
|
|
|
|
//#if defined(OUT_BASECOLOR)
|
|
//#define PIXELSHADEROUTPUT_MRT0 1
|
|
//#elif defined(OUT_BASECOLOR_NORMAL_SPECULAR)
|
|
//#define PIXELSHADEROUTPUT_MRT0 1
|
|
//#define PIXELSHADEROUTPUT_MRT1 1
|
|
//#define PIXELSHADEROUTPUT_MRT2 1
|
|
//#elif defined(OUT_WORLDHEIGHT)
|
|
//#define PIXELSHADEROUTPUT_MRT0 1
|
|
//#endif
|
|
|
|
// all PIXELSHADEROUTPUT_ and "void FPixelShaderInOut_MainPS()" need to be setup before this include
|
|
// this include generates the wrapper code to call MainPS(inout FPixelShaderOutput PixelShaderOutput)
|
|
#include "PixelShaderOutputCommon.ush"
|