You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Implement the core slab BSDF in the path tracer. When Strata is enabled, enlarge the payload slightly to be able to encode a slab without needing to rely on Substrate's packing routines. This allows the path tracer to be more independent of the project settings. Multiple slabs are handled by stochastically returning a single slab from the hit shader. This approaches greatly simplifies the handling of SSS slabs and refractive/translucent cases in the future. Also added a cvar that lets you toggle (at runtime) to the fully simplified form of the material. This doesn't appear that much faster, but it could be interesting to validate the appearance of the simplification procedure. It is gated by an extra cvar to avoid compiling extra permutations by default. #rb Sebastien.Hillaire, Charles.deRousiers #jira UE-173840 #preflight 642709ca91589478cd1575ed [CL 24874059 by chris kulla in ue5-main branch]
70 lines
2.7 KiB
Plaintext
70 lines
2.7 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================================
|
|
PathTracingMedium.usf: Volumetric phase function
|
|
To support atmosphere, we represent a blend of two components: rayleigh scattering and an HG lobe
|
|
In the future, we may add additional HG lobe for cases like cloud rendering
|
|
===============================================================================================*/
|
|
#pragma once
|
|
|
|
#include "../../ParticipatingMediaCommon.ush"
|
|
|
|
#define USE_UNIFORM_PHASE_FUNCTION 0
|
|
|
|
FMaterialSample Medium_SampleMaterial(
|
|
float3 V_World,
|
|
FPathTracingPayload Payload,
|
|
float3 RandSample)
|
|
{
|
|
const float3 RayleighWeight = Payload.GetBaseColor();
|
|
const float3 HGWeight = Payload.GetHGWeight();
|
|
const float G = Payload.GetHGPhaseG();
|
|
|
|
#if USE_UNIFORM_PHASE_FUNCTION
|
|
const float4 Result = UniformSampleSphere(RandSample.xy);
|
|
// uniform scattering
|
|
return CreateMaterialSample(Result.xyz, RayleighWeight + HGWeight, Result.w, 1.0, 1.0, PATHTRACER_SCATTER_VOLUME);
|
|
#else
|
|
const float LobeProb = LobeSelectionProb(RayleighWeight, HGWeight);
|
|
|
|
const float CosTheta = RandSample.x < LobeProb ?
|
|
RayleighPhaseInvertCdf(RescaleRandomNumber(RandSample.x, 0.0, LobeProb)) :
|
|
HenyeyGreensteinPhaseInvertCDF(RescaleRandomNumber(RandSample.x, LobeProb, 1.0), G);
|
|
const float SinTheta = sqrt(saturate(1.0 - CosTheta * CosTheta));
|
|
const float Phi = RandSample.y * (2.0 * PI);
|
|
|
|
const float3 L_World = TangentToWorld(float3(cos(Phi) * SinTheta, sin(Phi) * SinTheta, CosTheta), -V_World);
|
|
|
|
FMaterialSample Result = CreateMaterialSample(L_World, 0.0, 0.0, 1.0, 1.0, PATHTRACER_SCATTER_VOLUME);
|
|
Result.AddLobeWithMIS(RayleighWeight, RayleighPhase(CosTheta), LobeProb);
|
|
Result.AddLobeWithMIS(HGWeight , HenyeyGreensteinPhase(G, CosTheta ) , 1.0 - LobeProb);
|
|
return Result;
|
|
#endif
|
|
}
|
|
|
|
FMaterialEval Medium_EvalMaterial(
|
|
float3 V_World,
|
|
float3 L_World,
|
|
FPathTracingPayload Payload,
|
|
float2 DiffuseSpecularScale
|
|
)
|
|
{
|
|
const float3 RayleighWeight = Payload.GetBaseColor();
|
|
const float3 HGWeight = Payload.GetHGWeight();
|
|
const float G = Payload.GetHGPhaseG();
|
|
|
|
#if USE_UNIFORM_PHASE_FUNCTION
|
|
// simple omni-directional evaluation
|
|
return CreateMaterialEval((RayleighWeight + HGWeight) * DiffuseSpecularScale.x, 1.0 / (4 * PI));
|
|
#else
|
|
const float LobeProb = LobeSelectionProb(RayleighWeight, HGWeight);
|
|
|
|
const float CosTheta = dot(V_World, L_World);
|
|
FMaterialEval Result = NullMaterialEval();
|
|
Result.AddLobeWithMIS(RayleighWeight, RayleighPhase(CosTheta), LobeProb);
|
|
Result.AddLobeWithMIS(HGWeight , HenyeyGreensteinPhase(G, CosTheta), 1.0 - LobeProb);
|
|
Result.Weight *= DiffuseSpecularScale.x;
|
|
return Result;
|
|
#endif
|
|
}
|