139 lines
4.3 KiB
HLSL
139 lines
4.3 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
LumenHairTracing.ush
|
|
=============================================================================*/
|
|
|
|
#include "../Common.ush"
|
|
#include "../HZBTracing.ush"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Screen tracing
|
|
|
|
#ifndef USE_HAIRSTRANDS_SCREEN
|
|
#define USE_HAIRSTRANDS_SCREEN 0
|
|
#endif
|
|
|
|
#if USE_HAIRSTRANDS_SCREEN
|
|
|
|
void TraceHairScreen(
|
|
float3 RayTranslatedWorldOrigin,
|
|
float3 RayWorldDirection,
|
|
float MaxWorldTraceDistance,
|
|
float4 InHZBUvFactorAndInvFactor,
|
|
float MaxIterations,
|
|
float UncertainTraceRelativeDepthThreshold,
|
|
float NumThicknessStepsToDetermineCertainty,
|
|
inout bool bHit,
|
|
inout bool bUncertain,
|
|
inout float3 OutScreenUV,
|
|
inout float3 OutLastVisibleScreenUV,
|
|
inout float OutHitTileZ)
|
|
{
|
|
TraceHZB(
|
|
HairStrands.HairOnlyDepthTexture,
|
|
HairStrands.HairOnlyDepthClosestHZBTexture,
|
|
HZBBaseTexelSize,
|
|
HZBUVToScreenUVScaleBias,
|
|
RayTranslatedWorldOrigin,
|
|
RayWorldDirection,
|
|
MaxWorldTraceDistance,
|
|
InHZBUvFactorAndInvFactor,
|
|
MaxIterations,
|
|
UncertainTraceRelativeDepthThreshold,
|
|
NumThicknessStepsToDetermineCertainty,
|
|
0,
|
|
bHit,
|
|
bUncertain,
|
|
OutScreenUV,
|
|
OutLastVisibleScreenUV,
|
|
OutHitTileZ);
|
|
}
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Voxel tracing
|
|
|
|
#ifndef USE_HAIRSTRANDS_VOXEL
|
|
#define USE_HAIRSTRANDS_VOXEL 0
|
|
#endif
|
|
|
|
#if USE_HAIRSTRANDS_VOXEL
|
|
|
|
#define VOXEL_TRAVERSAL_TYPE VOXEL_TRAVERSAL_LINEAR_MIPMAP
|
|
#define VOXEL_TRAVERSAL_DEBUG 0
|
|
|
|
#include "../HairStrands/HairStrandsVoxelPageTraversal.ush"
|
|
|
|
void TraceHairVoxels(
|
|
const uint2 PixelCoord,
|
|
const float SceneDepth,
|
|
const float3 SampleTranslatedWorldPosition,
|
|
const float3 SampleDirection,
|
|
const float TraceDistance,
|
|
const bool bIsReflectionTracing,
|
|
out bool bHit,
|
|
out float OutTransparency,
|
|
out float OutHitT)
|
|
{
|
|
// Hair strands voxel to apply hair shadow on top of opaque geometry
|
|
float3 RayStart = SampleTranslatedWorldPosition;
|
|
float3 RayEnd = SampleTranslatedWorldPosition + SampleDirection * TraceDistance;
|
|
float4 Random = GetHairVoxelJitter2(PixelCoord.xy, View.StateFrameIndexMod8, VirtualVoxel.JitterMode);
|
|
|
|
// Jitter start position to mask/compensate coarse voxel resolution
|
|
float3 NormalizedDepthBias = 0;
|
|
{
|
|
const float PositionBiasScale = 0.5f;
|
|
NormalizedDepthBias = (VirtualVoxel.DepthBiasScale_Shadow * SampleDirection + PositionBiasScale * (Random.xyz * 2 - 1));
|
|
}
|
|
|
|
FVirtualVoxelCommonDesc CommonDesc;
|
|
CommonDesc.PageCountResolution = VirtualVoxel.PageCountResolution;
|
|
CommonDesc.PageTextureResolution = VirtualVoxel.PageTextureResolution;
|
|
CommonDesc.PageResolution = VirtualVoxel.PageResolution;
|
|
CommonDesc.PageResolutionLog2 = VirtualVoxel.PageResolutionLog2;
|
|
|
|
FHairTraversalSettings TraversalSettings = InitHairTraversalSettings();
|
|
TraversalSettings.DensityScale = bIsReflectionTracing ? VirtualVoxel.DensityScale_Shadow : VirtualVoxel.DensityScale_Environment;
|
|
TraversalSettings.CountThreshold = 1;
|
|
TraversalSettings.DistanceThreshold = TraceDistance;
|
|
TraversalSettings.bDebugEnabled = false;
|
|
TraversalSettings.SteppingScale = bIsReflectionTracing ? VirtualVoxel.SteppingScale_Shadow : VirtualVoxel.SteppingScale_Environment;
|
|
TraversalSettings.Random = Random.xyz;
|
|
TraversalSettings.PixelRadius = ConvertGivenDepthRadiusForProjectionType(VirtualVoxel.HairCoveragePixelRadiusAtDepth1, SceneDepth);
|
|
TraversalSettings.bUseOpaqueVisibility = false;
|
|
|
|
float Transparency = 1;
|
|
float HitT = TraceDistance;
|
|
bool bHasValidHitT = false;
|
|
const uint VoxelDescCount = VirtualVoxel.NodeDescCount;
|
|
for (uint VoxelDescIt = 0; Transparency > 0.01f && VoxelDescIt < VoxelDescCount; ++VoxelDescIt)
|
|
{
|
|
const FVirtualVoxelNodeDesc NodeDesc = UnpackVoxelNode(VirtualVoxel.NodeDescBuffer[VoxelDescIt], VirtualVoxel.PageResolution);
|
|
|
|
FHairTraversalResult Result = InitHairTraversalResult();
|
|
Result = ComputeHairCountVirtualVoxel(
|
|
RayStart + NormalizedDepthBias * NodeDesc.VoxelWorldSize,
|
|
RayEnd,
|
|
CommonDesc,
|
|
NodeDesc,
|
|
VirtualVoxel.PageIndexBuffer,
|
|
VirtualVoxel.PageTexture,
|
|
TraversalSettings);
|
|
|
|
if (Result.HitT >= 0)
|
|
{
|
|
Transparency = min(Transparency, saturate(1 - Result.HairCount));
|
|
HitT = min(HitT, Result.HitT);
|
|
bHasValidHitT = true;
|
|
}
|
|
}
|
|
|
|
bHit = bHasValidHitT;
|
|
OutTransparency = Transparency;
|
|
OutHitT = HitT;
|
|
}
|
|
|
|
#endif // USE_HAIRSTRANDS_VOXEL
|