67 lines
2.2 KiB
HLSL
67 lines
2.2 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "../Common.ush"
|
|
#include "PathTracingCommon.ush"
|
|
|
|
RaytracingAccelerationStructure TLAS;
|
|
RWBuffer<float> RWStartingExtinctionCoefficient;
|
|
|
|
RAY_TRACING_ENTRY_RAYGEN(PathTracingInitExtinctionCoefficientRG)
|
|
{
|
|
const uint RayFlags = 0;
|
|
const uint MissShaderIndex = 0;
|
|
const uint InstanceInclusionMask = PATHTRACER_MASK_CAMERA; // Ignore hair strands, only trace what camera rays can see
|
|
|
|
FRayDesc UpRay;
|
|
UpRay.Origin = PrimaryView.TranslatedWorldCameraOrigin;
|
|
UpRay.Direction = float3(0, 0, 1);
|
|
UpRay.TMin = 0.0;
|
|
UpRay.TMax = RAY_DEFAULT_T_MAX;
|
|
|
|
float3 StartingSigmaT = 0.0;
|
|
for (;;)
|
|
{
|
|
FPackedPathTracingPayload PackedPayload = InitPathTracingPayload(PATHTRACER_SCATTER_CAMERA, 0.0);
|
|
// SUBSTRATE_TODO: Set the stochastic slab random value? Add special flag to only return extinction of solid glass?
|
|
// The current behavior will only work correctly for single-slab materials
|
|
TraceRay(
|
|
TLAS,
|
|
RayFlags,
|
|
InstanceInclusionMask,
|
|
RAY_TRACING_SHADER_SLOT_MATERIAL,
|
|
RAY_TRACING_NUM_SHADER_SLOTS,
|
|
MissShaderIndex,
|
|
UpRay.GetNativeDesc(),
|
|
PackedPayload);
|
|
#if NEED_TMIN_WORKAROUND // extra safety - discard hit if not conforming
|
|
if (PackedPayload.HitT <= UpRay.TMin)
|
|
{
|
|
PackedPayload.HitT = -1.0;
|
|
}
|
|
#endif
|
|
if (PackedPayload.IsMiss())
|
|
{
|
|
// we didn't hit anything
|
|
break;
|
|
}
|
|
FPathTracingPayload HitPayload = UnpackPathTracingPayload(PackedPayload, UpRay);
|
|
if (HitPayload.IsMaterialSolidGlass())
|
|
{
|
|
// Found a solid transmissive medium -- pickup the extinction
|
|
float3 LocalSigmaT = HitPayload.GetExtinction();
|
|
|
|
// increase when we leave a medium (that means we must have been inside before)
|
|
// decrease when we enter a medium (will be cancelled out when we leave)
|
|
StartingSigmaT += HitPayload.IsFrontFace() ? -LocalSigmaT : +LocalSigmaT;
|
|
}
|
|
// keep tracing
|
|
UpRay.TMin = ComputeNewTMin(UpRay.Origin, UpRay.Direction, PackedPayload.HitT);
|
|
}
|
|
// clamp against 0 in the unlikely case that we only hit front faces of glass on our way up
|
|
StartingSigmaT = max(StartingSigmaT, 0.0);
|
|
|
|
RWStartingExtinctionCoefficient[0] = StartingSigmaT.x;
|
|
RWStartingExtinctionCoefficient[1] = StartingSigmaT.y;
|
|
RWStartingExtinctionCoefficient[2] = StartingSigmaT.z;
|
|
}
|