Files
UnrealEngineUWP/Engine/Shaders/Private/LightFunctionCommon.ush
guillaume abadie d16f7e2c89 Fixes PixelDepth material expression on light functions
#rb none
#preflight 62fe3e8f0601ad050483ef84

[CL 21468255 by guillaume abadie in ue5-main branch]
2022-08-19 19:38:51 -04:00

77 lines
3.2 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
LightFunctionCommon.usf: Utility functions for light functions.
=============================================================================*/
#include "/Engine/Private/Strata/Strata.ush"
// This ifdef is to allow shaders(notably the ratracing miss shader implementing light functions) to override where these parameters come from.
#ifndef LightFunctionParameters
/** Tan of spotlight cone outer angle in x, ShadowFadeFraction in y, IsSpotLight in z, IsPointLight in w. */
float4 LightFunctionParameters;
float4x4 LightFunctionTranslatedWorldToLight;
#endif
/**
* Calculates the light function color with the given light vector.
* LightVector is the vector from the light to the position being shaded, in the light's coordinate space.
*/
float3 GetLightFunctionColor(float3 LightVector, float3 TranslatedWorldSpace)
{
// Swizzle so that LightVector.xy are perpendicular to the light direction and LightVector.z is distance along the light direction
LightVector.xyz = LightVector.zyx;
// By default, map textures using the vectors perpendicular to the light direction
float2 LightFunctionUVs = LightVector.xy;
if (LightFunctionParameters.z > 0)
{
// For spotlights, setup UVs that go from 1 at one side of the spotlight cone to 0 at the other side, at any distance from the light
// This minimizes artist setup when they just want to use the spotlight like a projector
LightFunctionUVs = LightVector.xy / (LightVector.z * LightFunctionParameters.x) * .5f + .5f;
}
else if (LightFunctionParameters.w > 0)
{
float3 UnitLightVector = normalize(LightVector);
// Setup 2d UVs for a pointlight that map the texture using spherical coordinates, which is how max handles a 2d texture projector on a point light
// Artists should use a cubemap indexed by a light vector to get better quality
LightFunctionUVs = float2((atan2(UnitLightVector.y, UnitLightVector.x) + PI) / (2 * PI), acos(UnitLightVector.z) / PI);
}
FMaterialPixelParameters MaterialParameters = MakeInitializedMaterialPixelParameters();
#if NUM_MATERIAL_TEXCOORDS
for(int CoordinateIndex = 0;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;CoordinateIndex++)
{
MaterialParameters.TexCoords[CoordinateIndex] = LightFunctionUVs;
}
#endif
MaterialParameters.VertexColor = 1;
MaterialParameters.CameraVector = LightVector.xyz;
MaterialParameters.ReflectionVector = LightVector.xyz;
MaterialParameters.LightVector = LightVector.xyz;
MaterialParameters.AbsoluteWorldPosition = LWCSubtract(TranslatedWorldSpace, PrimaryView.PreViewTranslation);
MaterialParameters.ScreenPosition = mul(float4(TranslatedWorldSpace, 1.0f), PrimaryView.TranslatedWorldToClip);
FPixelMaterialInputs PixelMaterialInputs;
CalcPixelMaterialInputs(MaterialParameters, PixelMaterialInputs);
#if STRATA_ENABLED
#if COMPUTESHADER
return StrataGetBSDFEmissive(MaterialParameters.StrataTree.BSDFs[0]); // Unused code path?
#else
return StrataGetBSDFEmissive(PixelMaterialInputs.FrontMaterial.InlinedBSDF);
#endif
#else // STRATA_ENABLED
#if COMPUTESHADER
return GetMaterialEmissiveForCS(MaterialParameters);
#else
return GetMaterialEmissive(PixelMaterialInputs);
#endif
#endif // STRATA_ENABLED
}