Copy problematic files from Main due to issues with 5337699

Note: RayTracingRectLight.cpp is revision 3 from Main.
Note: RayTracingRectLightRGS.usf is revision 3 from Main.

#rb none

[CL 5408796 by Peter Engstrom in Dev-Networking branch]
This commit is contained in:
Peter Engstrom
2019-03-15 04:30:26 -04:00
parent d2af84e417
commit d504b972ff
4 changed files with 825 additions and 0 deletions

View File

@@ -0,0 +1,314 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "../Common.ush"
#include "../DeferredShadingCommon.ush"
#include "../PathTracing/Utilities/PathTracingRandomSequence.ush"
#include "../RectLight.ush"
#include "../ShadingModels.ush"
#include "RayTracingCommon.ush"
#include "RayTracingRectLight.ush"
#include "MipTreeCommon.ush"
RaytracingAccelerationStructure TLAS;
RWTexture2D<float4> RWLuminanceUAV;
RWTexture2D<float> RWRayDistanceUAV;
uint CalcLinearIndex(uint2 PixelCoord)
{
return PixelCoord.y * View.BufferSizeAndInvSize.x + PixelCoord.x;
}
// #patrick todo: move to RayTracingCommon.ush
float3 ReconstructWorldPositionFromDepth(float2 UV, float Depth)
{
float2 ScreenPosition = (UV - View.ScreenPositionScaleBias.wz) / View.ScreenPositionScaleBias.xy;
float4 HomogeneousWorldPosition = mul(float4(ScreenPosition * Depth, Depth, 1), View.ScreenToWorld);
float3 WorldPosition = HomogeneousWorldPosition.xyz / HomogeneousWorldPosition.w;
return WorldPosition;
}
bool GenerateRectLightImportanceSampledRay(
float3 WorldPosition,
float3 WorldNormal,
float3 LightPosition,
float3 LightNormal,
float3 LightdPdu,
float3 LightdPdv,
float LightWidth,
float LightHeight,
inout RandomSequence RandSequence,
out float3 RayOrigin,
out float3 RayDirection,
out float RayTMin,
out float RayTMax,
out float RayPdf
)
{
uint MipCount = log2(RectLight.MipTreeDimensions.x);
uint2 MipPixel = 0;
float MipPdf = 1.0;
uint StopLevel = 0;
for (uint Index = 0; Index < MipCount - StopLevel; ++Index)
{
uint MipIndex = MipCount - Index - 1;
uint BufferOffset = BufferOffsetAtPixel(MipPixel, MipIndex, RectLight.MipTreeDimensions.xy);
uint4 BufferOffsets = BufferOffset + uint4(0, 1, 2, 3);
float4 PowerTerm = float4(RectLight.MipTree[BufferOffsets.x], RectLight.MipTree[BufferOffsets.y], RectLight.MipTree[BufferOffsets.z], RectLight.MipTree[BufferOffsets.w]);
PowerTerm = max(PowerTerm, 0.0);
// Determine sample positions
uint DummyVariable;
float2 Jitter = RandomSequence_GenerateSample2D(RandSequence, DummyVariable);
float2 DimInv = 1.0 / DimensionsAtLevel(RectLight.MipTreeDimensions.xy, MipIndex);
float2 UV00 = (MipPixel + Jitter) * DimInv - 0.5;
float2 UV10 = (MipPixel + Jitter + uint2(1, 0)) * DimInv - 0.5;
float2 UV01 = (MipPixel + Jitter + uint2(0, 1)) * DimInv - 0.5;
float2 UV11 = (MipPixel + Jitter + uint2(1, 1)) * DimInv - 0.5;
float3 Position00 = LightPosition + LightdPdu * LightWidth * UV00.x + LightdPdv * LightHeight * UV00.y;
float3 Position10 = LightPosition + LightdPdu * LightWidth * UV10.x + LightdPdv * LightHeight * UV10.y;
float3 Position01 = LightPosition + LightdPdu * LightWidth * UV01.x + LightdPdv * LightHeight * UV01.y;
float3 Position11 = LightPosition + LightdPdu * LightWidth * UV11.x + LightdPdv * LightHeight * UV11.y;
// Evaluate irradiance coefficients
float3 LightDirection00 = WorldPosition - Position00;
float3 LightDirection10 = WorldPosition - Position10;
float3 LightDirection01 = WorldPosition - Position01;
float3 LightDirection11 = WorldPosition - Position11;
float4 DistanceSquaredTerm = float4(
dot(LightDirection00, LightDirection00),
dot(LightDirection10, LightDirection10),
dot(LightDirection01, LightDirection01),
dot(LightDirection11, LightDirection11)
);
float4 CosineTerm = float4(
saturate(dot(normalize(LightDirection00), LightNormal)),
saturate(dot(normalize(LightDirection10), LightNormal)),
saturate(dot(normalize(LightDirection01), LightNormal)),
saturate(dot(normalize(LightDirection11), LightNormal))
);
// Build CDF on approximate irradiance
float4 Cdf = PowerTerm * CosineTerm / DistanceSquaredTerm;
Cdf.y += Cdf.x;
Cdf.z += Cdf.y;
Cdf.w += Cdf.z;
Cdf /= Cdf.w;
// Sample CDF
float RandSample = RandomSequence_GenerateSample1D(RandSequence, DummyVariable);
if (RandSample < Cdf.x)
{
MipPdf *= Cdf.x;
}
else if (RandSample < Cdf.y)
{
MipPdf *= Cdf.y - Cdf.x;
MipPixel.x += 1;
}
else if (RandSample < Cdf.z)
{
MipPdf *= Cdf.z - Cdf.y;
MipPixel.y += 1;
}
else // if (RandSample < Cdf.w)
{
MipPdf *= Cdf.w - Cdf.z;
MipPixel += 1;
}
MipPixel = uint2(MipPixel.x << 1, MipPixel.y << 1);
}
MipPixel = uint2(MipPixel.x >> 1, MipPixel.y >> 1);
// Sample within stop-level texel
uint DummyVariable;
float2 PixelOffset = RandomSequence_GenerateSample2D(RandSequence, DummyVariable);
float2 DimensionsAtStopLevel = DimensionsAtLevel(RectLight.MipTreeDimensions.xy, StopLevel);
float2 MipPixelUV = (MipPixel + PixelOffset) / DimensionsAtStopLevel;
// Map sample point to quad
MipPixelUV -= 0.5;
float2 RectLightOffset = MipPixel / DimensionsAtStopLevel;
float3 LightOrigin = LightPosition + LightdPdu * LightWidth * RectLightOffset.x + LightdPdv * LightHeight * RectLightOffset.y;
LightPosition += LightdPdu * LightWidth * MipPixelUV.x + LightdPdv * LightHeight * MipPixelUV.y;
float3 LightDirection = normalize(LightPosition - WorldPosition);
// Light-normal culling
if (dot(-LightDirection, LightNormal) <= 0.0)
{
RayPdf = 0.0;
return false;
}
// #dxr_todo: Performing direct lighting here could save some recalculation
// Define ray
RayOrigin = WorldPosition;
RayDirection = LightDirection;
RayTMin = 0.0;
RayTMax = length(LightPosition - WorldPosition);
// Construct solid angle pdf
FRect Rect;
Rect.Origin = LightOrigin - WorldPosition;
Rect.Axis[0] = LightdPdu;
Rect.Axis[1] = LightdPdv;
Rect.Axis[2] = cross(LightdPdu, LightdPdv);
Rect.Extent = float2(LightWidth, LightHeight) / DimensionsAtStopLevel;
FSphericalRect SphericalRect = BuildSphericalRect(Rect);
float SolidAnglePdf = 1.0 / SphericalRect.SolidAngle;
RayPdf = MipPdf * SolidAnglePdf;
return RayTMax > RayTMin;
}
[shader("raygeneration")]
void RectLightRGS()
{
uint2 PixelCoord = DispatchRaysIndex().xy;
RandomSequence RandSequence;
uint LinearIndex = CalcLinearIndex(PixelCoord);
RandomSequence_Initialize(RandSequence, LinearIndex, View.FrameNumber);
// Get G-Buffer surface data
float2 InvBufferSize = View.BufferSizeAndInvSize.zw;
float2 UV = (float2(PixelCoord) + 0.5) * InvBufferSize;
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV);
FGBufferData GBuffer = ScreenSpaceData.GBuffer;
float Depth = ScreenSpaceData.GBuffer.Depth;
float3 WorldPosition = ReconstructWorldPositionFromDepth(UV, Depth);
float3 CameraOrigin = ReconstructWorldPositionFromDepth(UV, 0.0f);
float3 CameraDirection = normalize(WorldPosition - CameraOrigin);
float3 WorldNormal = ScreenSpaceData.GBuffer.WorldNormal;
float3 BaseColor = ScreenSpaceData.GBuffer.BaseColor;
float3 DiffuseColor = ScreenSpaceData.GBuffer.DiffuseColor;
float3 SpecularColor = ScreenSpaceData.GBuffer.SpecularColor;
float Roughness = ScreenSpaceData.GBuffer.Roughness;
float RayDistance = 0.0;
float HitCount = 0.0;
uint SamplesPerPixel = RectLight.SamplesPerPixel;
// Mask out depth values that are infinitely far away
float DeviceZ = SceneTexturesStruct.SceneDepthTexture.Load(int3(PixelCoord, 0)).r;
bool IsFiniteDepth = DeviceZ > 0.0;
bool bTraceRay = (
IsFiniteDepth &&
GBuffer.ShadingModelID != SHADINGMODELID_UNLIT);
if (!bTraceRay)
{
SamplesPerPixel = 0.0;
}
float3 LightPosition = RectLight.Position;
float3 LightNormal = RectLight.Normal;
float3 LightdPdu = RectLight.dPdu;
float3 LightdPdv = RectLight.dPdv;
float LightWidth = RectLight.Width;
float LightHeight = RectLight.Height;
// Encode the rect light parameter into the light parameters struct
// todo: send direction the light shader parameter data instead of the custon RectLight data.
FLightShaderParameters LightParameters;
LightParameters.Position = RectLight.Position;
LightParameters.Direction = -RectLight.Normal;
LightParameters.Tangent = RectLight.dPdu;
LightParameters.SourceRadius = 0.5f * RectLight.Width;
LightParameters.SourceLength = 0.5f * RectLight.Height;
float3 ExitantRadiance = 0.0;
float3 DiffuseExitantRadiance = 0.0;
for (uint SampleIndex = 0; SampleIndex < SamplesPerPixel; ++SampleIndex)
{
RayDesc Ray;
uint DummyVariable;
float2 RandSample = RandomSequence_GenerateSample2D(RandSequence, DummyVariable);
float RayPdf = 0.0;
bool bIsValid = false;
#if TEXTURE_IMPORTANCE_SAMPLING
if (RectLight.bIsTextureImportanceSampling)
{
bIsValid = GenerateRectLightImportanceSampledRay(WorldPosition, WorldNormal, LightPosition, LightNormal, LightdPdu, LightdPdv, LightWidth, LightHeight, RandSequence, Ray.Origin, Ray.Direction, Ray.TMin, Ray.TMax, RayPdf);
}
else
#endif
{
bIsValid = GenerateRectLightOcclusionRay(LightParameters, WorldPosition, WorldNormal, RandSample, Ray.Origin, Ray.Direction, Ray.TMin, Ray.TMax, RayPdf);
}
if (!bIsValid)
{
continue;
}
ApplyPositionBias(Ray, WorldNormal, RectLight.MaxNormalBias);
float NoL = dot(WorldNormal, Ray.Direction);
if (NoL <= 0.0)
{
continue;
}
uint RayFlags = 0
| RAY_FLAG_CULL_BACK_FACING_TRIANGLES
| RAY_FLAG_FORCE_OPAQUE; // #dxr_todo: generate a special shader permutation for occlusion ray tracing that includes any-hit shaders for masked geometry
FDefaultPayload Payload = (FDefaultPayload)0;
TraceRay(
TLAS, // AccelerationStructure
RayFlags,
RAY_TRACING_MASK_OPAQUE, // InstanceInclusionMask
RAY_TRACING_SHADER_SLOT_MATERIAL, // RayContributionToHitGroupIndex
RAY_TRACING_NUM_SHADER_SLOTS, // MultiplierForGeometryContributionToShaderIndex
0, // MissShaderIndex
Ray, // RayDesc
Payload // Payload
);
if (Payload.HitT >= 0.0)
{
RayDistance += Payload.HitT;
HitCount += 1.0;
}
else
{
// Sample light texture
float3 LightPosition = Ray.Origin + Ray.Direction * Ray.TMax;
float3 RectLightCorner = RectLight.Position - 0.5 * (RectLight.dPdu * RectLight.Width + RectLight.dPdv * RectLight.Height);
float3 DeltaPosition = LightPosition - RectLightCorner;
float2 SampleUV = float2(dot(DeltaPosition, RectLight.dPdu) / RectLight.Width, dot(DeltaPosition, RectLight.dPdv) / RectLight.Height);
SampleUV = 1.0 - SampleUV;
float3 TextureColor = Texture2DSample(RectLight.Texture, RectLight.TextureSampler, SampleUV).xyz;
float3 IncomingRadiance = RectLight.Color * TextureColor;
// Evaluate material
half3 N = WorldNormal;
half3 V = -CameraDirection;
half3 L = Ray.Direction;
FShadowTerms ShadowTerms = { 0.0, 0.0, 0.0 };
FDirectLighting LightingSample = EvaluateBxDF(ScreenSpaceData.GBuffer, N, V, L, NoL, ShadowTerms);
float3 Brdf = LightingSample.Diffuse + LightingSample.Transmission + LightingSample.Specular;
// #dxr_todo: Determine best way to incorporate integrals:
// 1) Return combined contribution (current method)
// 2) Split the integral (defer specular contribution to another pass)
// 3) Store diffuse and specular contribution separately
float3 Irradiance = IncomingRadiance * NoL / RayPdf;
ExitantRadiance += Irradiance * Brdf;
DiffuseExitantRadiance += Irradiance * (LightingSample.Diffuse + LightingSample.Transmission);
}
}
float3 Result = (SamplesPerPixel > 0) ? ExitantRadiance / SamplesPerPixel : ExitantRadiance;
RWLuminanceUAV[PixelCoord].rgb = Result;
RWLuminanceUAV[PixelCoord].a = 1.0;
RWRayDistanceUAV[PixelCoord] = (HitCount > 0.0) ? RayDistance / HitCount : 1.0e27;
}

View File

@@ -0,0 +1,53 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
SceneViewFamilyBlackboard.ush:
=============================================================================*/
#pragma once
#include "SceneTexturesCommon.ush"
#include "DeferredShadingCommon.ush"
uint bIsSceneLightingChannelsValid;
// Matches FSceneViewFamilyBlackboard
Texture2D SceneDepthBuffer;
Texture2D SceneVelocityBuffer;
Texture2D SceneGBufferA;
Texture2D SceneGBufferB;
Texture2D SceneGBufferC;
Texture2D SceneGBufferD;
Texture2D SceneGBufferE;
Texture2D<uint> SceneLightingChannels;
// @param UV - UV space in the GBuffer textures (BufferSize resolution)
FGBufferData GetGBufferDataFromSceneBlackboard(float2 UV, bool bGetNormalizedNormal = true)
{
float4 GBufferA = SceneGBufferA.SampleLevel(GlobalPointClampedSampler, UV, 0);
float4 GBufferB = SceneGBufferB.SampleLevel(GlobalPointClampedSampler, UV, 0);
float4 GBufferC = SceneGBufferC.SampleLevel(GlobalPointClampedSampler, UV, 0);
float4 GBufferD = SceneGBufferD.SampleLevel(GlobalPointClampedSampler, UV, 0);
float4 GBufferE = SceneGBufferE.SampleLevel(GlobalPointClampedSampler, UV, 0);
float4 GBufferVelocity = SceneVelocityBuffer.SampleLevel(GlobalPointClampedSampler, UV, 0);
uint CustomStencil = 0;
float CustomNativeDepth = 0;
float DeviceZ = SceneDepthBuffer.SampleLevel(GlobalPointClampedSampler, UV, 0).r;
float SceneDepth = ConvertFromDeviceZ(DeviceZ);
return DecodeGBufferData(GBufferA, GBufferB, GBufferC, GBufferD, GBufferE, GBufferVelocity, CustomNativeDepth, CustomStencil, SceneDepth, bGetNormalizedNormal, CheckerFromSceneColorUV(UV));
}
/** Returns the light channel mask that should be executed for this pixel. */
uint GetSceneLightingChannel(uint2 PixelCoord)
{
BRANCH
if (bIsSceneLightingChannelsValid)
{
return SceneLightingChannels.Load(uint3(PixelCoord, 0)).x;
}
return ~0;
}

View File

@@ -0,0 +1,438 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "DeferredShadingRenderer.h"
#if RHI_RAYTRACING
#include "ClearQuad.h"
#include "SceneRendering.h"
#include "SceneRenderTargets.h"
#include "RenderTargetPool.h"
#include "RHIResources.h"
#include "UniformBuffer.h"
#include "VisualizeTexture.h"
#include "PostProcess/PostProcessing.h"
#include "PostProcess/SceneFilterRendering.h"
#include "RectLightSceneProxy.h"
#include "RaytracingOptions.h"
#include "RHI/Public/PipelineStateCache.h"
static int32 GRayTracingStochasticRectLight = 0;
static FAutoConsoleVariableRef CVarRayTracingStochasticRectLight(
TEXT("r.RayTracing.StochasticRectLight"),
GRayTracingStochasticRectLight,
TEXT("0: use analytical evaluation (default)\n")
TEXT("1: use stochastic evaluation\n")
);
static int32 GRayTracingStochasticRectLightSamplesPerPixel = 1;
static FAutoConsoleVariableRef CVarRayTracingRecLightStochasticSamplesPerPixel(
TEXT("r.RayTracing.StochasticRectLight.SamplesPerPixel"),
GRayTracingStochasticRectLightSamplesPerPixel,
TEXT("Sets the samples-per-pixel for rect light evaluation (default = 1)")
);
static int32 GRayTracingStochasticRectLightIsTextureImportanceSampling = 1;
static FAutoConsoleVariableRef CVarRayTracingStochasticRecLightIsTextureImportanceSampling(
TEXT("r.RayTracing.StochasticRectLight.IsTextureImportanceSampling"),
GRayTracingStochasticRectLightIsTextureImportanceSampling,
TEXT("Enable importance sampling for rect light evaluation (default = 1)")
);
bool ShouldRenderRayTracingStochasticRectLight(const FLightSceneInfo& LightSceneInfo)
{
return IsRayTracingEnabled() && GRayTracingStochasticRectLight == 1
&& LightSceneInfo.Proxy->CastsRaytracedShadow()
&& LightSceneInfo.Proxy->GetLightType() == LightType_Rect;
}
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FRectLightData, )
// Pass settings
SHADER_PARAMETER(int, SamplesPerPixel)
SHADER_PARAMETER(int, bIsTextureImportanceSampling)
// Light data
SHADER_PARAMETER(FVector, Position)
SHADER_PARAMETER(FVector, Normal)
SHADER_PARAMETER(FVector, dPdu)
SHADER_PARAMETER(FVector, dPdv)
SHADER_PARAMETER(FVector, Color)
SHADER_PARAMETER(float, Width)
SHADER_PARAMETER(float, Height)
SHADER_PARAMETER(FIntVector, MipTreeDimensions)
SHADER_PARAMETER(float, MaxNormalBias)
SHADER_PARAMETER(float, BarnCosAngle)
SHADER_PARAMETER(float, BarnLength)
SHADER_PARAMETER_TEXTURE(Texture2D, Texture)
SHADER_PARAMETER_SAMPLER(SamplerState, TextureSampler)
// Sampling data
SHADER_PARAMETER_SRV(Buffer<float>, MipTree)
END_GLOBAL_SHADER_PARAMETER_STRUCT()
DECLARE_GPU_STAT_NAMED(RayTracingRectLight, TEXT("Ray Tracing RectLight"));
IMPLEMENT_GLOBAL_SHADER_PARAMETER_STRUCT(FRectLightData, "RectLight");
template <int TextureImportanceSampling>
class FRectLightRGS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FRectLightRGS, Global)
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
OutEnvironment.SetDefine(TEXT("TEXTURE_IMPORTANCE_SAMPLING"), TextureImportanceSampling);
}
public:
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return ShouldCompileRayTracingShadersForProject(Parameters.Platform);
}
FRectLightRGS() {}
virtual ~FRectLightRGS() {}
FRectLightRGS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FGlobalShader(Initializer)
{
ViewParameter.Bind(Initializer.ParameterMap, TEXT("View"));
SceneTexturesParameter.Bind(Initializer.ParameterMap, TEXT("SceneTexturesStruct"));
RectLightParameter.Bind(Initializer.ParameterMap, TEXT("RectLight"));
TLASParameter.Bind(Initializer.ParameterMap, TEXT("TLAS"));
TransmissionProfilesTextureParameter.Bind(Initializer.ParameterMap, TEXT("SSProfilesTexture"));
TransmissionProfilesLinearSamplerParameter.Bind(Initializer.ParameterMap, TEXT("TransmissionProfilesLinearSampler"));
LuminanceUAVParameter.Bind(Initializer.ParameterMap, TEXT("RWLuminanceUAV"));
RayDistanceUAVParameter.Bind(Initializer.ParameterMap, TEXT("RWRayDistanceUAV"));
}
bool Serialize(FArchive& Ar)
{
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
Ar << ViewParameter;
Ar << SceneTexturesParameter;
Ar << RectLightParameter;
Ar << TLASParameter;
Ar << TransmissionProfilesTextureParameter;
Ar << TransmissionProfilesLinearSamplerParameter;
Ar << LuminanceUAVParameter;
Ar << RayDistanceUAVParameter;
return bShaderHasOutdatedParameters;
}
void Dispatch(
FRHICommandListImmediate& RHICmdList,
const FRayTracingScene& RayTracingScene,
FUniformBufferRHIParamRef ViewUniformBuffer,
FUniformBufferRHIParamRef SceneTexturesUniformBuffer,
FUniformBufferRHIParamRef RectLightUniformBuffer,
FUnorderedAccessViewRHIParamRef LuminanceUAV,
FUnorderedAccessViewRHIParamRef RayDistanceUAV,
uint32 Width, uint32 Height
)
{
FRayTracingPipelineStateInitializer Initializer;
FRayTracingShaderRHIParamRef RayGenShaderTable[] = { GetRayTracingShader() };
Initializer.SetRayGenShaderTable(RayGenShaderTable);
FRHIRayTracingPipelineState* Pipeline = PipelineStateCache::GetAndOrCreateRayTracingPipelineState(Initializer); // #dxr_todo: this should be done once at load-time and cached
FRayTracingShaderBindingsWriter GlobalResources;
GlobalResources.Set(TLASParameter, RayTracingScene.RayTracingSceneRHI->GetShaderResourceView());
GlobalResources.Set(ViewParameter, ViewUniformBuffer);
GlobalResources.Set(SceneTexturesParameter, SceneTexturesUniformBuffer);
GlobalResources.Set(RectLightParameter, RectLightUniformBuffer);
GlobalResources.Set(LuminanceUAVParameter, LuminanceUAV);
GlobalResources.Set(RayDistanceUAVParameter, RayDistanceUAV);
if (TransmissionProfilesTextureParameter.IsBound())
{
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
const IPooledRenderTarget* PooledRT = GetSubsufaceProfileTexture_RT((FRHICommandListImmediate&)RHICmdList);
if (!PooledRT)
{
// no subsurface profile was used yet
PooledRT = GSystemTextures.BlackDummy;
}
const FSceneRenderTargetItem& Item = PooledRT->GetRenderTargetItem();
GlobalResources.SetTexture(TransmissionProfilesTextureParameter.GetBaseIndex(), Item.ShaderResourceTexture);
GlobalResources.SetSampler(TransmissionProfilesLinearSamplerParameter.GetBaseIndex(), TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI());
}
RHICmdList.RayTraceDispatch(Pipeline, GetRayTracingShader(), RayTracingScene.RayTracingSceneRHI, GlobalResources, Width, Height);
}
private:
// Input
FShaderResourceParameter TLASParameter;
FShaderUniformBufferParameter ViewParameter;
FShaderUniformBufferParameter SceneTexturesParameter;
FShaderUniformBufferParameter RectLightParameter;
// SSS Profile
FShaderResourceParameter TransmissionProfilesTextureParameter;
FShaderResourceParameter TransmissionProfilesLinearSamplerParameter;
// Output
FShaderResourceParameter LuminanceUAVParameter;
FShaderResourceParameter RayDistanceUAVParameter;
};
#define IMPLEMENT_RECT_LIGHT_TYPE(TextureImportanceSampling) \
typedef FRectLightRGS<TextureImportanceSampling> FRectLightRGS##TextureImportanceSampling; \
IMPLEMENT_SHADER_TYPE(template<>, FRectLightRGS##TextureImportanceSampling, TEXT("/Engine/Private/RayTracing/RayTracingRectLightRGS.usf"), TEXT("RectLightRGS"), SF_RayGen);
IMPLEMENT_RECT_LIGHT_TYPE(0);
IMPLEMENT_RECT_LIGHT_TYPE(1);
class FVisualizeRectLightMipTreePS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FVisualizeRectLightMipTreePS, Global);
public:
static bool ShouldCache(EShaderPlatform Platform)
{
return ShouldCompileRayTracingShadersForProject(Platform);
}
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return ShouldCompileRayTracingShadersForProject(Parameters.Platform);
}
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
FVisualizeRectLightMipTreePS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FGlobalShader(Initializer)
{
DimensionsParameter.Bind(Initializer.ParameterMap, TEXT("Dimensions"));
MipTreeParameter.Bind(Initializer.ParameterMap, TEXT("MipTree"));
}
FVisualizeRectLightMipTreePS() {}
template<typename TRHICommandList>
void SetParameters(
TRHICommandList& RHICmdList,
const FViewInfo& View,
const FRWBuffer& MipTree,
const FIntVector Dimensions)
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();
FGlobalShader::SetParameters<FViewUniformShaderParameters>(RHICmdList, ShaderRHI, View.ViewUniformBuffer);
SetShaderValue(RHICmdList, ShaderRHI, DimensionsParameter, Dimensions);
SetSRVParameter(RHICmdList, ShaderRHI, MipTreeParameter, MipTree.SRV);
}
virtual bool Serialize(FArchive& Ar) override
{
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
Ar << DimensionsParameter;
Ar << MipTreeParameter;
return bShaderHasOutdatedParameters;
}
private:
FShaderParameter DimensionsParameter;
FShaderResourceParameter MipTreeParameter;
};
IMPLEMENT_SHADER_TYPE(, FVisualizeRectLightMipTreePS, TEXT("/Engine/Private/PathTracing/VisualizeMipTreePixelShader.usf"), TEXT("VisualizeMipTreePS"), SF_Pixel)
void FDeferredShadingSceneRenderer::VisualizeRectLightMipTree(
FRHICommandListImmediate& RHICmdList,
const FViewInfo& View,
const FRWBuffer& RectLightMipTree,
const FIntVector& RectLightMipTreeDimensions
)
{
// Allocate render target
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
FPooledRenderTargetDesc Desc = SceneContext.GetSceneColor()->GetDesc();
Desc.Flags &= ~(TexCreate_FastVRAM | TexCreate_Transient);
TRefCountPtr<IPooledRenderTarget> RectLightMipTreeRT;
GRenderTargetPool.FindFreeElement(RHICmdList, Desc, RectLightMipTreeRT, TEXT("RectLightMipTreeRT"));
// Define shaders
const auto ShaderMap = GetGlobalShaderMap(View.FeatureLevel);
TShaderMapRef<FPostProcessVS> VertexShader(ShaderMap);
TShaderMapRef<FVisualizeRectLightMipTreePS> PixelShader(ShaderMap);
FTextureRHIParamRef RenderTargets[2] =
{
SceneContext.GetSceneColor()->GetRenderTargetItem().TargetableTexture,
RectLightMipTreeRT->GetRenderTargetItem().TargetableTexture
};
SetRenderTargets(RHICmdList, 2, RenderTargets, SceneContext.GetSceneDepthSurface(), ESimpleRenderTargetMode::EExistingColorAndDepth, FExclusiveDepthStencil::DepthRead_StencilNop);
// PSO definition
FGraphicsPipelineStateInitializer GraphicsPSOInit;
SceneContext.BeginRenderingSceneColor(RHICmdList, ESimpleRenderTargetMode::EExistingColorAndDepth, FExclusiveDepthStencil::DepthRead_StencilWrite, true);
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
GraphicsPSOInit.BlendState = TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI();
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<FM_Solid, CM_None>::GetRHI();
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI;
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader);
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader);
GraphicsPSOInit.PrimitiveType = PT_TriangleList;
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
// Transition to graphics
RHICmdList.TransitionResource(EResourceTransitionAccess::EReadable, EResourceTransitionPipeline::EComputeToGfx, RectLightMipTree.UAV);
// Draw
RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f);
PixelShader->SetParameters(RHICmdList, View, RectLightMipTree, RectLightMipTreeDimensions);
DrawRectangle(
RHICmdList,
0, 0,
View.ViewRect.Width(), View.ViewRect.Height(),
View.ViewRect.Min.X, View.ViewRect.Min.Y,
View.ViewRect.Width(), View.ViewRect.Height(),
FIntPoint(View.ViewRect.Width(), View.ViewRect.Height()),
SceneContext.GetBufferSizeXY(),
*VertexShader);
ResolveSceneColor(RHICmdList);
GVisualizeTexture.SetCheckPoint(RHICmdList, RectLightMipTreeRT);
// Transition to compute
RHICmdList.TransitionResource(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EGfxToCompute, RectLightMipTree.UAV);
ResolveSceneColor(RHICmdList);
SceneContext.FinishRenderingSceneColor(RHICmdList);
}
void FDeferredShadingSceneRenderer::PrepareRayTracingRectLight(const FViewInfo& View, TArray<FRayTracingShaderRHIParamRef>& OutRayGenShaders)
{
// Declare all RayGen shaders that require material closest hit shaders to be bound
TShaderMapRef<FRectLightRGS<0>> Shader0(GetGlobalShaderMap(View.FeatureLevel));
TShaderMapRef<FRectLightRGS<1>> Shader1(GetGlobalShaderMap(View.FeatureLevel));
OutRayGenShaders.Add(Shader0->GetRayTracingShader());
OutRayGenShaders.Add(Shader1->GetRayTracingShader());
}
template <int TextureImportanceSampling>
void RenderRayTracingRectLightInternal(
FRHICommandListImmediate& RHICmdList,
const TArray<FViewInfo>& Views,
const FLightSceneInfo& RectLightSceneInfo,
TRefCountPtr<IPooledRenderTarget>& ScreenShadowMaskTexture,
TRefCountPtr<IPooledRenderTarget>& RayDistanceTexture
)
{
check(RectLightSceneInfo.Proxy);
check(RectLightSceneInfo.Proxy->IsRectLight());
FRectLightSceneProxy* RectLightSceneProxy = (FRectLightSceneProxy*)RectLightSceneInfo.Proxy;
FLightShaderParameters LightShaderParameters;
RectLightSceneProxy->GetLightShaderParameters(LightShaderParameters);
FRectLightData RectLightData;
RectLightData.SamplesPerPixel = GRayTracingStochasticRectLightSamplesPerPixel;
RectLightData.bIsTextureImportanceSampling = GRayTracingStochasticRectLightIsTextureImportanceSampling;
RectLightData.Position = RectLightSceneInfo.Proxy->GetOrigin();
RectLightData.Normal = RectLightSceneInfo.Proxy->GetDirection();
const FMatrix& WorldToLight = RectLightSceneInfo.Proxy->GetWorldToLight();
RectLightData.dPdu = FVector(WorldToLight.M[0][1], WorldToLight.M[1][1], WorldToLight.M[2][1]);
RectLightData.dPdv = FVector(WorldToLight.M[0][2], WorldToLight.M[1][2], WorldToLight.M[2][2]);
RectLightData.Color = LightShaderParameters.Color / 2.0;
// #dxr_todo: Ray traced textured area lights are 1.5X brighter than those in lit mode.
if (RectLightSceneProxy->HasSourceTexture())
{
RectLightData.Color *= 2.0 / 3.0;
}
RectLightData.Width = 2.0f * LightShaderParameters.SourceRadius;
RectLightData.Height = 2.0f * LightShaderParameters.SourceLength;
RectLightData.Texture = LightShaderParameters.SourceTexture;
RectLightData.TextureSampler = RHICreateSamplerState(FSamplerStateInitializerRHI(SF_Bilinear, AM_Border, AM_Border, AM_Border));
RectLightData.MipTree = RectLightSceneProxy->RectLightMipTree.SRV;
RectLightData.MipTreeDimensions = RectLightSceneProxy->RectLightMipTreeDimensions;
RectLightData.MaxNormalBias = GetRaytracingOcclusionMaxNormalBias();
RectLightData.BarnCosAngle = FMath::Cos(FMath::DegreesToRadians(RectLightSceneProxy->BarnDoorAngle));
RectLightData.BarnLength = RectLightSceneProxy->BarnDoorLength;
FUniformBufferRHIRef RectLightUniformBuffer = RHICreateUniformBuffer(&RectLightData, FRectLightData::StaticStructMetadata.GetLayout(), EUniformBufferUsage::UniformBuffer_SingleDraw);
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex)
{
const FViewInfo& View = Views[ViewIndex];
const FIntPoint ViewSize = View.ViewRect.Size();
TShaderMapRef<FRectLightRGS<TextureImportanceSampling>> RectLightRayGenerationShader(GetGlobalShaderMap(View.FeatureLevel));
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
FSceneTexturesUniformParameters SceneTextures;
SetupSceneTextureUniformParameters(SceneContext, View.FeatureLevel, ESceneTextureSetupMode::All, SceneTextures);
FUniformBufferRHIRef SceneTexturesUniformBuffer = RHICreateUniformBuffer(&SceneTextures, FSceneTexturesUniformParameters::StaticStructMetadata.GetLayout(), EUniformBufferUsage::UniformBuffer_SingleDraw);
// Dispatch
RectLightRayGenerationShader->Dispatch(
RHICmdList,
View.RayTracingScene,
View.ViewUniformBuffer,
SceneTexturesUniformBuffer,
RectLightUniformBuffer,
ScreenShadowMaskTexture->GetRenderTargetItem().UAV,
RayDistanceTexture->GetRenderTargetItem().UAV,
ViewSize.X, ViewSize.Y
);
}
// Transition out to graphics pipeline
FComputeFenceRHIRef Fence = RHICmdList.CreateComputeFence(TEXT("RayTracingRectLight"));
RHICmdList.TransitionResource(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EComputeToGfx, ScreenShadowMaskTexture->GetRenderTargetItem().UAV, Fence);
GVisualizeTexture.SetCheckPoint(RHICmdList, ScreenShadowMaskTexture);
RHICmdList.TransitionResource(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EComputeToGfx, RayDistanceTexture->GetRenderTargetItem().UAV);
GVisualizeTexture.SetCheckPoint(RHICmdList, RayDistanceTexture);
}
#endif // RHI_RAYTRACING
void FDeferredShadingSceneRenderer::RenderRayTracingStochasticRectLight(
FRHICommandListImmediate& RHICmdList,
const FLightSceneInfo& RectLightSceneInfo,
TRefCountPtr<IPooledRenderTarget>& RectLightRT,
TRefCountPtr<IPooledRenderTarget>& HitDistanceRT
)
#if RHI_RAYTRACING
{
SCOPED_DRAW_EVENT(RHICmdList, RayTracingRectLight);
SCOPED_GPU_STAT(RHICmdList, RayTracingRectLight);
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
FPooledRenderTargetDesc Desc = SceneContext.GetSceneColor()->GetDesc();
Desc.Format = PF_FloatRGBA;
Desc.Flags &= ~(TexCreate_FastVRAM | TexCreate_Transient);
GRenderTargetPool.FindFreeElement(RHICmdList, Desc, RectLightRT, TEXT("RayTracingRectLight"));
//ClearUAV(RHICmdList, RectLightRT->GetRenderTargetItem(), FLinearColor::Black);
Desc.Format = PF_R16F;
GRenderTargetPool.FindFreeElement(RHICmdList, Desc, HitDistanceRT, TEXT("RayTracingRectLightDistance"));
//ClearUAV(RHICmdList, HitDistanceRT->GetRenderTargetItem(), FLinearColor::Black);
if (RectLightSceneInfo.Proxy->HasSourceTexture())
{
RenderRayTracingRectLightInternal<1>(RHICmdList, Views, RectLightSceneInfo, RectLightRT, HitDistanceRT);
}
else
{
RenderRayTracingRectLightInternal<0>(RHICmdList, Views, RectLightSceneInfo, RectLightRT, HitDistanceRT);
}
}
#else
{
unimplemented();
}
#endif

View File

@@ -0,0 +1,20 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#if RHI_RAYTRACING
class RENDERER_API FRayTracingDynamicGeometryCollection
{
public:
FRayTracingDynamicGeometryCollection();
void AddDynamicMeshBatchForGeometryUpdate(const FScene* Scene, const FSceneView* View, const FPrimitiveSceneProxy* PrimitiveSceneProxy, const FMeshBatch& MeshBatch, FRayTracingGeometry& Geometry, uint32 NumMaxVertices, FRWBuffer& Buffer);
void DispatchUpdates(FRHICommandListImmediate& RHICmdList);
void Clear();
private:
TUniquePtr<TArray<struct FMeshComputeDispatchCommand>> DispatchCommands;
};
#endif // RHI_RAYTRACING