Files
UnrealEngine/Engine/Shaders/Private/LandscapeGrassWeight.usf
2025-05-18 13:04:45 +08:00

233 lines
7.7 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Common.ush"
#include "/Engine/Generated/Material.ush"
#include "/Engine/Generated/VertexFactory.ush"
struct FLandscapeGrassWeightInterpolantsVSToPS
{
float4 Position : SV_POSITION;
FVertexFactoryInterpolantsVSToPS FactoryInterpolants;
float4 PositionPreOffset : TEXCOORD9;
#if VF_USE_PRIMITIVE_SCENE_DATA
float LocalPosZ : TEXCOORD10;
#endif // VF_USE_PRIMITIVE_SCENE_DATA
};
#if VERTEXSHADER
float2 RenderOffset;
/** Vertex Shader */
void VSMain(
FVertexFactoryInput Input,
out FLandscapeGrassWeightInterpolantsVSToPS Output
)
{
ResolvedView = ResolveView();
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
float4 WorldPosition = VertexFactoryGetWorldPosition(Input, VFIntermediates);
half3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPosition.xyz, TangentToLocal);
// We can't deal correctly with horizontal WPO. We can choose to either:
// (i) only take the offset in the direction of the heightfield which means that grass can mismatch on some slopes, or
// (ii) take the full offset which means that grass can be missing or corrupt at edges of each tile.
// We choose (i) here.
float3 WPO = GetMaterialWorldPositionOffset(VertexParameters);
WPO = DFMultiplyVector(WPO, VertexFactoryGetWorldToLocal(VFIntermediates)) * float3(0, 0, 1);
WPO = DFMultiplyVector(WPO, VertexFactoryGetLocalToWorld(VFIntermediates));
WorldPosition.xyz += WPO;
#if VF_USE_PRIMITIVE_SCENE_DATA
FDFVector3 AbsoluteWorldPosition = DFFastSubtract(WorldPosition.xyz, ResolvedView.PreViewTranslation);
Output.LocalPosZ = DFMultiplyDemote(AbsoluteWorldPosition, VertexFactoryGetWorldToLocal(VFIntermediates)).z;
#endif // VF_USE_PRIMITIVE_SCENE_DATA
Output.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters);
float4 RasterizedWorldPosition = VertexFactoryGetRasterizedWorldPosition(Input, VFIntermediates, WorldPosition);
Output.PositionPreOffset = mul(RasterizedWorldPosition, ResolvedView.TranslatedWorldToClip);
Output.Position = Output.PositionPreOffset + float4(RenderOffset, 0, 0);
}
#elif PIXELSHADER
int OutputPass;
// Pixel Shader
void PSMain(
FLandscapeGrassWeightInterpolantsVSToPS Interpolants
OPTIONAL_IsFrontFace,
out HALF4_TYPE OutColor : SV_Target0
)
{
ResolvedView = ResolveView();
// Build the SvPosition without RenderOffset so that we correctly reproject WorldPosition etc.
float4 SvPositionPreOffset = Interpolants.PositionPreOffset / Interpolants.PositionPreOffset.w;
SvPositionPreOffset.xy = (SvPositionPreOffset.xy * float2(0.5f, -0.5f) + 0.5f) * ResolvedView.ViewSizeAndInvSize.xy;
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants.FactoryInterpolants, SvPositionPreOffset);
FPixelMaterialInputs PixelMaterialInputs;
CalcMaterialParameters(MaterialParameters, PixelMaterialInputs, SvPositionPreOffset, bIsFrontFace);
// Calculate and pack landscape height.
#if VF_USE_PRIMITIVE_SCENE_DATA
float Height = clamp(round(Interpolants.LocalPosZ / TERRAIN_ZSCALE) + 32768.0, 0, 65535);
#else // !VF_USE_PRIMITIVE_SCENE_DATA
float3 LocalPos = WSMultiplyDemote(GetWorldPosition(MaterialParameters), GetWorldToInstance(MaterialParameters));
float Height = clamp(round(LocalPos.z / TERRAIN_ZSCALE) + 32768.0, 0, 65535);
#endif // VF_USE_PRIMITIVE_SCENE_DATA
float2 PackedHeight = float2(floor(Height / 256), fmod(Height, 256)) / 255;
// Height = first 2 outputs:
OutColor = float4(PackedHeight, 0.0, 0.0);
switch(OutputPass)
{
case 0:
{
#if HAVE_GetGrassWeight0
OutColor[2] = GetGrassWeight0(MaterialParameters).x;
#endif // HAVE_GetGrassWeight0
#if HAVE_GetGrassWeight1
OutColor[3] = GetGrassWeight1(MaterialParameters).x;
#endif // HAVE_GetGrassWeight1
break;
}
case 1:
{
#if HAVE_GetGrassWeight2
OutColor[0] = GetGrassWeight2(MaterialParameters).x;
#endif // HAVE_GetGrassWeight2
#if HAVE_GetGrassWeight3
OutColor[1] = GetGrassWeight3(MaterialParameters).x;
#endif // HAVE_GetGrassWeight3
#if HAVE_GetGrassWeight4
OutColor[2] = GetGrassWeight4(MaterialParameters).x;
#endif // HAVE_GetGrassWeight4
#if HAVE_GetGrassWeight5
OutColor[3] = GetGrassWeight5(MaterialParameters).x;
#endif // HAVE_GetGrassWeight5
break;
}
case 2:
{
#if HAVE_GetGrassWeight6
OutColor[0] = GetGrassWeight6(MaterialParameters).x;
#endif // HAVE_GetGrassWeight6
#if HAVE_GetGrassWeight7
OutColor[1] = GetGrassWeight7(MaterialParameters).x;
#endif // HAVE_GetGrassWeight7
#if HAVE_GetGrassWeight8
OutColor[2] = GetGrassWeight8(MaterialParameters).x;
#endif // HAVE_GetGrassWeight8
#if HAVE_GetGrassWeight9
OutColor[3] = GetGrassWeight9(MaterialParameters).x;
#endif // HAVE_GetGrassWeight9
break;
}
case 3:
{
#if HAVE_GetGrassWeight10
OutColor[0] = GetGrassWeight10(MaterialParameters).x;
#endif // HAVE_GetGrassWeight10
#if HAVE_GetGrassWeight11
OutColor[1] = GetGrassWeight11(MaterialParameters).x;
#endif // HAVE_GetGrassWeight11
#if HAVE_GetGrassWeight12
OutColor[2] = GetGrassWeight12(MaterialParameters).x;
#endif // HAVE_GetGrassWeight12
#if HAVE_GetGrassWeight13
OutColor[3] = GetGrassWeight13(MaterialParameters).x;
#endif // HAVE_GetGrassWeight13
break;
}
case 4:
{
#if HAVE_GetGrassWeight14
OutColor[0] = GetGrassWeight14(MaterialParameters).x;
#endif // HAVE_GetGrassWeight14
#if HAVE_GetGrassWeight15
OutColor[1] = GetGrassWeight15(MaterialParameters).x;
#endif // HAVE_GetGrassWeight15
#if HAVE_GetGrassWeight16
OutColor[2] = GetGrassWeight16(MaterialParameters).x;
#endif // HAVE_GetGrassWeight16
#if HAVE_GetGrassWeight17
OutColor[3] = GetGrassWeight17(MaterialParameters).x;
#endif // HAVE_GetGrassWeight17
break;
}
case 5:
{
#if HAVE_GetGrassWeight18
OutColor[0] = GetGrassWeight18(MaterialParameters).x;
#endif // HAVE_GetGrassWeight18
#if HAVE_GetGrassWeight19
OutColor[1] = GetGrassWeight19(MaterialParameters).x;
#endif // HAVE_GetGrassWeight19
#if HAVE_GetGrassWeight20
OutColor[2] = GetGrassWeight20(MaterialParameters).x;
#endif // HAVE_GetGrassWeight20
#if HAVE_GetGrassWeight21
OutColor[3] = GetGrassWeight21(MaterialParameters).x;
#endif // HAVE_GetGrassWeight21
break;
}
case 6:
{
#if HAVE_GetGrassWeight22
OutColor[0] = GetGrassWeight22(MaterialParameters).x;
#endif // HAVE_GetGrassWeight22
#if HAVE_GetGrassWeight23
OutColor[1] = GetGrassWeight23(MaterialParameters).x;
#endif // HAVE_GetGrassWeight23
#if HAVE_GetGrassWeight24
OutColor[2] = GetGrassWeight24(MaterialParameters).x;
#endif // HAVE_GetGrassWeight24
#if HAVE_GetGrassWeight25
OutColor[3] = GetGrassWeight25(MaterialParameters).x;
#endif // HAVE_GetGrassWeight25
break;
}
case 7:
{
#if HAVE_GetGrassWeight26
OutColor[0] = GetGrassWeight26(MaterialParameters).x;
#endif // HAVE_GetGrassWeight26
#if HAVE_GetGrassWeight27
OutColor[1] = GetGrassWeight27(MaterialParameters).x;
#endif // HAVE_GetGrassWeight27
#if HAVE_GetGrassWeight28
OutColor[2] = GetGrassWeight28(MaterialParameters).x;
#endif // HAVE_GetGrassWeight28
#if HAVE_GetGrassWeight29
OutColor[3] = GetGrassWeight29(MaterialParameters).x;
#endif // HAVE_GetGrassWeight29
break;
}
case 8:
{
#if HAVE_GetGrassWeight30
OutColor[0] = GetGrassWeight30(MaterialParameters).x;
#endif // HAVE_GetGrassWeight30
#if HAVE_GetGrassWeight31
OutColor[1] = GetGrassWeight31(MaterialParameters).x;
#endif // HAVE_GetGrassWeight31
break;
// UMaterialExpressionLandscapeGrassOutput::MaxGrassTypes == 32. Uncomment this if it ever gets increased :
//#if HAVE_GetGrassWeight32
// OutColor[2] = GetGrassWeight32(MaterialParameters);
//#endif // HAVE_GetGrassWeight32
//#if HAVE_GetGrassWeight33
// OutColor[3] = GetGrassWeight33(MaterialParameters);
//#endif // HAVE_GetGrassWeight33
}
default:
break;
}
}
#endif