Files
UnrealEngine/Engine/Shaders/Private/HairStrands/HairStrandsScreenTracing.ush
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

74 lines
2.5 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "../Common.ush"
#include "../BlueNoise.ush"
#include "../SSRT/SSRTRayCast.ush"
#include "../HZB.ush"
float ScreenTraceLength;
float GetRayVisibility(float3 TranslatedWorldPosition,float SceneDepth, float3 RayDirection, uint2 PixelCoord, uint PixelRayIndex, uint NumPixelSamples, bool bJitter)
{
const float SlopeCompareToleranceScale = 0.5f;
const float MaxScreenTraceFraction = ScreenTraceLength * 2.0f / (float)View.ViewSizeAndInvSize.x;
float TraceDistance = MaxScreenTraceFraction * 2.0 * GetScreenRayLengthMultiplierForProjectionType(SceneDepth).x;
float DepthThresholdScale = View.ProjectionDepthThicknessScale;
const float PositionBias = 0.1f;
const float3 TranslatedWorldStartPosition = TranslatedWorldPosition + RayDirection * PositionBias;
FSSRTCastingSettings CastSettings = CreateDefaultCastSettings();
CastSettings.bStopWhenUncertain = true;
bool bHit = false;
float Level;
float3 HitUVz;
bool bRayWasClipped;
uint NumSteps = 4;
float StartMipLevel = 0;
float RayRoughness = .2f;
uint2 NoiseCoord = PixelCoord * uint2(NumPixelSamples, 1) + uint2(PixelRayIndex, 0);
float StepOffset = bJitter > 0 ? BlueNoiseScalar(PixelCoord, View.StateFrameIndex) : 0;
FSSRTRay Ray = InitScreenSpaceRayFromWorldSpace(
TranslatedWorldStartPosition, RayDirection,
/* WorldTMax = */ TraceDistance,
/* SceneDepth = */ SceneDepth,
/* SlopeCompareToleranceScale */ SlopeCompareToleranceScale * DepthThresholdScale * (float)NumSteps,
/* bExtendRayToScreenBorder = */ false,
/* out */ bRayWasClipped);
bool bUncertain;
float3 DebugOutput;
CastScreenSpaceRay(
ClosestHZBTexture, ClosestHZBTextureSampler,
StartMipLevel,
CastSettings,
Ray, RayRoughness, NumSteps, StepOffset - .9f,
HZBUvFactorAndInvFactor, false,
/* out */ DebugOutput,
/* out */ HitUVz,
/* out */ Level,
/* out */ bHit,
/* out */ bUncertain);
bHit = bHit && !bUncertain;
return bHit ? 0.0f : 1.0f;
}
float ComputeScreenTraceHairCount(
const uint2 PixelCoord,
const float PixelRadius,
const float SceneDepth,
float3 TranslatedWorldPosition,
float3 SampleDirection,
uint SampleIt=0,
uint SampleCount=1,
bool bJitter = true)
{
const float HairCountPerScreenSpaceIntersection = 1.5f; // Arbitrary value, visually tweaked
const float ScreenTraceVis = GetRayVisibility(TranslatedWorldPosition, SceneDepth, SampleDirection, PixelCoord, SampleIt, SampleCount, bJitter);
return saturate(1.f-ScreenTraceVis) * HairCountPerScreenSpaceIntersection;
}