233 lines
7.7 KiB
HLSL
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 |