Hello,
I have looked at quite a bit of code and read some of the online API docs and Tutorials as to writing shaders and such. However, I still can’t come up with a solution to creating a custom texture from a simple float buffer and including adding it to an existing shader. Perhaps it has something to do with the RDG system for shader parameters. I am using the 4.24 engine source code and trying to add a custom texture to the RayTracingPrimary shader.
Buffer :
float TableData[12] = {
0.0, 0.0, 0.0 ,
0.0, 0.0, 0.0 ,
0.0, 0.0, 0.0 ,
-0.572215, -0.819053, 0.0415015 };
RayTracingPrimaryRays.cpp
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "RendererPrivate.h"
#include "GlobalShader.h"
#include "DeferredShadingRenderer.h"
#include "SceneTextureParameters.h"
#if RHI_RAYTRACING
#include "ClearQuad.h"
#include "SceneRendering.h"
#include "SceneRenderTargets.h"
#include "RHIResources.h"
#include "PostProcess/PostProcessing.h"
#include "RayTracing/RaytracingOptions.h"
#include "Raytracing/RaytracingLighting.h"
DECLARE_GPU_STAT(RayTracingPrimaryRays);
class FRayTracingPrimaryRaysRGS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FRayTracingPrimaryRaysRGS)
SHADER_USE_ROOT_PARAMETER_STRUCT(FRayTracingPrimaryRaysRGS, FGlobalShader)
class FDenoiserOutput : SHADER_PERMUTATION_BOOL("DIM_DENOISER_OUTPUT");
class FEnableTwoSidedGeometryForShadowDim : SHADER_PERMUTATION_BOOL("ENABLE_TWO_SIDED_GEOMETRY");
using FPermutationDomain = TShaderPermutationDomain<FDenoiserOutput, FEnableTwoSidedGeometryForShadowDim>;
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER(int32, SamplesPerPixel)
SHADER_PARAMETER(int32, MaxRefractionRays)
SHADER_PARAMETER(int32, HeightFog)
SHADER_PARAMETER(int32, ShouldDoDirectLighting)
SHADER_PARAMETER(int32, ReflectedShadowsType)
SHADER_PARAMETER(int32, ShouldDoEmissiveAndIndirectLighting)
SHADER_PARAMETER(int32, UpscaleFactor)
SHADER_PARAMETER(int32, ShouldUsePreExposure)
SHADER_PARAMETER(uint32, PrimaryRayFlags)
SHADER_PARAMETER(float, TranslucencyMinRayDistance)
SHADER_PARAMETER(float, TranslucencyMaxRayDistance)
SHADER_PARAMETER(float, TranslucencyMaxRoughness)
SHADER_PARAMETER(int32, TranslucencyRefraction)
SHADER_PARAMETER(float, MaxNormalBias)
SHADER_PARAMETER_SRV(RaytracingAccelerationStructure, TLAS)
SHADER_PARAMETER_SRV(StructuredBuffer<FRTLightingData>, LightDataBuffer)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SSProfilesTexture)
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, ViewUniformBuffer)
SHADER_PARAMETER_STRUCT_REF(FRaytracingLightDataPacked, LightDataPacked)
SHADER_PARAMETER_STRUCT_REF(FReflectionUniformParameters, ReflectionStruct)
SHADER_PARAMETER_STRUCT_REF(FFogUniformParameters, FogUniformParameters)
SHADER_PARAMETER_STRUCT_INCLUDE(FSceneTextureParameters, SceneTextures)
SHADER_PARAMETER_STRUCT_INCLUDE(FSceneTextureSamplerParameters, SceneTextureSamplers)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SceneColorTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, Table)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, ColorOutput)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float>, RayHitDistanceOutput)
END_SHADER_PARAMETER_STRUCT()
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return ShouldCompileRayTracingShadersForProject(Parameters.Platform);
}
};
IMPLEMENT_GLOBAL_SHADER(FRayTracingPrimaryRaysRGS, "/Engine/Private/RayTracing/RayTracingPrimaryRays.usf", "RayTracingPrimaryRaysRGS", SF_RayGen);
void FDeferredShadingSceneRenderer::PrepareRayTracingTranslucency(const FViewInfo& View, TArray<FRHIRayTracingShader*>& OutRayGenShaders)
{
// Declare all RayGen shaders that require material closest hit shaders to be bound
FRayTracingPrimaryRaysRGS::FPermutationDomain PermutationVector;
PermutationVector.Set<FRayTracingPrimaryRaysRGS::FEnableTwoSidedGeometryForShadowDim>(EnableRayTracingShadowTwoSidedGeometry());
auto RayGenShader = View.ShaderMap->GetShader<FRayTracingPrimaryRaysRGS>(PermutationVector);
OutRayGenShaders.Add(RayGenShader->GetRayTracingShader());
}
void FDeferredShadingSceneRenderer::RenderRayTracingPrimaryRaysView(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
FRDGTextureRef* InOutColorTexture,
FRDGTextureRef* InOutRayHitDistanceTexture,
int32 SamplePerPixel,
int32 HeightFog,
float ResolutionFraction,
ERayTracingPrimaryRaysFlag Flags)
{
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(GraphBuilder.RHICmdList);
FSceneTextureParameters SceneTextures;
SetupSceneTextureParameters(GraphBuilder, &SceneTextures);
FSceneTextureSamplerParameters SceneTextureSamplers;
SetupSceneTextureSamplers(&SceneTextureSamplers);
int32 UpscaleFactor = int32(1.0f / ResolutionFraction);
ensure(ResolutionFraction == 1.0 / UpscaleFactor);
ensureMsgf(FComputeShaderUtils::kGolden2DGroupSize % UpscaleFactor == 0, TEXT("PrimaryRays ray tracing will have uv misalignement."));
FIntPoint RayTracingResolution = FIntPoint::DivideAndRoundUp(View.ViewRect.Size(), UpscaleFactor);
//GEngine->AddOnScreenDebugMessage(1337, 0.0f, FColor::Black, FString::Printf(TEXT("FATAL ERROR: %s"), UpscaleFactor));
//UE_LOG(LogWindows, Log, TEXT("UpscaleFactor %d"), UpscaleFactor);
//UE_LOG(LogWindows, Warning, TEXT("UpscaleFactor %d"), UpscaleFactor);
{
FPooledRenderTargetDesc Desc = SceneContext.GetSceneColor()->GetDesc();
Desc.Format = PF_FloatRGBA;
Desc.Flags &= ~(TexCreate_FastVRAM | TexCreate_Transient);
Desc.Extent /= UpscaleFactor;
Desc.TargetableFlags |= TexCreate_UAV;
if(*InOutColorTexture == nullptr)
{
*InOutColorTexture = GraphBuilder.CreateTexture(Desc, TEXT("RayTracingPrimaryRays"));
}
Desc.Format = PF_R16F;
if(*InOutRayHitDistanceTexture == nullptr)
{
*InOutRayHitDistanceTexture = GraphBuilder.CreateTexture(Desc, TEXT("RayTracingPrimaryRaysHitDistance"));
}
}
FRayTracingPrimaryRaysRGS::FParameters* PassParameters = GraphBuilder.AllocParameters<FRayTracingPrimaryRaysRGS::FParameters>();
FRayTracingPrimaryRaysOptions TranslucencyOptions = GetRayTracingTranslucencyOptions();
PassParameters->SamplesPerPixel = SamplePerPixel;
PassParameters->MaxRefractionRays = TranslucencyOptions.MaxRefractionRays > -1 ? TranslucencyOptions.MaxRefractionRays : View.FinalPostProcessSettings.RayTracingTranslucencyRefractionRays;
PassParameters->HeightFog = HeightFog;
PassParameters->ShouldDoDirectLighting = TranslucencyOptions.EnableDirectLighting;
PassParameters->ReflectedShadowsType = TranslucencyOptions.EnableShadows > -1 ? TranslucencyOptions.EnableShadows : (int32)View.FinalPostProcessSettings.RayTracingTranslucencyShadows;
PassParameters->ShouldDoEmissiveAndIndirectLighting = TranslucencyOptions.EnableEmmissiveAndIndirectLighting;
PassParameters->UpscaleFactor = UpscaleFactor;
PassParameters->TranslucencyMinRayDistance = FMath::Min(TranslucencyOptions.MinRayDistance, TranslucencyOptions.MaxRayDistance);
PassParameters->TranslucencyMaxRayDistance = TranslucencyOptions.MaxRayDistance;
PassParameters->TranslucencyMaxRoughness = FMath::Clamp(TranslucencyOptions.MaxRoughness >= 0 ? TranslucencyOptions.MaxRoughness : View.FinalPostProcessSettings.RayTracingTranslucencyMaxRoughness, 0.01f, 1.0f);
PassParameters->TranslucencyRefraction = TranslucencyOptions.EnableRefraction >= 0 ? TranslucencyOptions.EnableRefraction : View.FinalPostProcessSettings.RayTracingTranslucencyRefraction;
PassParameters->MaxNormalBias = GetRaytracingMaxNormalBias();
PassParameters->ShouldUsePreExposure = View.Family->EngineShowFlags.Tonemapper;
PassParameters->PrimaryRayFlags = (uint32)Flags;
PassParameters->TLAS = View.RayTracingScene.RayTracingSceneRHI->GetShaderResourceView();
PassParameters->ViewUniformBuffer = View.ViewUniformBuffer;
FStructuredBufferRHIRef LightingDataBuffer;
PassParameters->LightDataPacked = CreateLightDataPackedUniformBuffer(Scene->Lights, View, EUniformBufferUsage::UniformBuffer_SingleFrame, LightingDataBuffer);
PassParameters->LightDataBuffer = RHICreateShaderResourceView(LightingDataBuffer);
PassParameters->SceneTextures = SceneTextures;
PassParameters->SceneTextureSamplers = SceneTextureSamplers;
FRDGTextureRef SceneColorTexture = GraphBuilder.RegisterExternalTexture(SceneContext.GetSceneColor(), TEXT("SceneColor"));
PassParameters->SceneColorTexture = SceneColorTexture;
PassParameters->ReflectionStruct = CreateReflectionUniformBuffer(View, EUniformBufferUsage::UniformBuffer_SingleFrame);
PassParameters->FogUniformParameters = CreateFogUniformBuffer(View, EUniformBufferUsage::UniformBuffer_SingleFrame);
PassParameters->ColorOutput = GraphBuilder.CreateUAV(*InOutColorTexture);
PassParameters->RayHitDistanceOutput = GraphBuilder.CreateUAV(*InOutRayHitDistanceTexture);
FUpdateTextureRegion2D* Region = new FUpdateTextureRegion2D(0, 0, 0, 0, 2, 2);
UTexture2D* TableTex = UTexture2D::CreateTransient(2, 2, PF_FloatRGB);
TableTex->UpdateTextureRegions(0, 1, Region, 2 * 3, 96, (uint8*)TableData);
PassParameters->Table = (TAlignedShaderParameterPtr<FRDGTexture*>)TableTex;
// TODO: should be converted to RDG
TRefCountPtr<IPooledRenderTarget> SubsurfaceProfileRT((IPooledRenderTarget*)GetSubsufaceProfileTexture_RT(GraphBuilder.RHICmdList));
if (!SubsurfaceProfileRT)
{
SubsurfaceProfileRT = GSystemTextures.BlackDummy;
}
PassParameters->SSProfilesTexture = GraphBuilder.RegisterExternalTexture(SubsurfaceProfileRT);
FRayTracingPrimaryRaysRGS::FPermutationDomain PermutationVector;
PermutationVector.Set<FRayTracingPrimaryRaysRGS::FEnableTwoSidedGeometryForShadowDim>(EnableRayTracingShadowTwoSidedGeometry());
auto RayGenShader = View.ShaderMap->GetShader<FRayTracingPrimaryRaysRGS>(PermutationVector);
ClearUnusedGraphResources(RayGenShader, PassParameters);
GraphBuilder.AddPass(
RDG_EVENT_NAME("RayTracingPrimaryRays %dx%d", RayTracingResolution.X, RayTracingResolution.Y),
PassParameters,
ERDGPassFlags::Compute,
[PassParameters, this, &View, RayGenShader, RayTracingResolution](FRHICommandList& RHICmdList)
{
SCOPED_GPU_STAT(RHICmdList, RayTracingPrimaryRays);
FRayTracingPipelineState* Pipeline = View.RayTracingMaterialPipeline;
FRayTracingShaderBindingsWriter GlobalResources;
SetShaderParameters(GlobalResources, RayGenShader, *PassParameters);
FRHIRayTracingScene* RayTracingSceneRHI = View.RayTracingScene.RayTracingSceneRHI;
RHICmdList.RayTraceDispatch(Pipeline, RayGenShader->GetRayTracingShader(), RayTracingSceneRHI, GlobalResources, RayTracingResolution.X, RayTracingResolution.Y);
});
}
#endif // RHI_RAYTRACING
Shader/RayTracingPrimaryRays.usf
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#ifndef DIM_DENOISER_OUTPUT
#define DIM_DENOISER_OUTPUT 0
#endif
#include "../Common.ush"
#define SUPPORT_CONTACT_SHADOWS 0
#define USE_SOURCE_TEXTURE 1
#define USE_SOURCE_TEXTURE_ARRAY 1
#define LTCMatTexture RaytracingLightsDataPacked.LTCMatTexture
#define LTCMatSampler RaytracingLightsDataPacked.LTCMatSampler
#define LTCAmpTexture RaytracingLightsDataPacked.LTCAmpTexture
#define LTCAmpSampler RaytracingLightsDataPacked.LTCAmpSampler
#define PreIntegratedGF ReflectionStruct.PreIntegratedGF
#define PreIntegratedGFSampler ReflectionStruct.PreIntegratedGFSampler
#include "../DeferredShadingCommon.ush"
#include "../DeferredLightingCommon.ush"
#include "../ReflectionEnvironmentShared.ush"
#include "../Montecarlo.ush"
#include "../PathTracing/Utilities/PathTracingRandomSequence.ush"
#include "../HeightFogCommon.ush"
#include "../SobolRandom.ush"
#include "../SceneTextureParameters.ush"
#include "RayTracingCommon.ush"
#include "RayTracingDeferredShadingCommon.ush"
#include "RayTracingHitGroupCommon.ush"
#include "RayTracingDirectionalLight.ush"
#include "RayTracingRectLight.ush"
#include "RayTracingSphereLight.ush"
#include "RayTracingSpotLight.ush"
#include "RayTracingPointLight.ush"
#define ERayTracingPrimaryRaysFlag_None 0
#define ERayTracingPrimaryRaysFlag_UseGBufferForMaxDistance (1u << 0)
#define ERayTracingPrimaryRaysFlag_ConsiderSurfaceScatter (1u << 1)
#define ERayTracingPrimaryRaysFlag_AllowSkipSkySample (1u << 2)
int SamplesPerPixel;
int MaxRefractionRays;
int HeightFog;
int ReflectedShadowsType;
int ShouldDoDirectLighting;
int ShouldDoEmissiveAndIndirectLighting;
int UpscaleFactor;
int ShouldUsePreExposure;
uint PrimaryRayFlags;
float TranslucencyMinRayDistance;
float TranslucencyMaxRayDistance;
float TranslucencyMaxRoughness;
int TranslucencyRefraction;
float MaxNormalBias;
Texture2D SceneColorTexture;
Texture2D Table ;
FVector3d ray2 ;
RaytracingAccelerationStructure TLAS;
RWTexture2D<float4> ColorOutput;
RWTexture2D<float> RayHitDistanceOutput;
#include "RayTracingLightingCommon.ush"
float FresnelDielectric(float Eta, float IoH, float ToH)
{
float Rs = Square((Eta * IoH - ToH) / (Eta * IoH + ToH));
float Rp = Square((Eta * ToH - IoH) / (Eta * ToH + IoH));
return (Rs + Rp) / 2;
}
bool RefractRay(float3 V, float3 N, float Ior1, float Ior2, bool bIsEntering, out float3 L, out float EventThroughput)
{
float Eta = Ior1 / Ior2;
if (bIsEntering)
{
Eta = 1.0f / Ior1;
}
V = -V;
const float CosThetaI = dot(V, N);
const float CosThetaT2 = 1.f - Eta * Eta * (1.0f - CosThetaI * CosThetaI);
if (CosThetaT2 < 0.0f)
{
// Total internal reflection
EventThroughput = 1.0f;
L = reflect(-V, N);
return false;
}
const float CosThetaT = -(CosThetaI >= 0.0f ? 1.0f : -1.0f) * sqrt(CosThetaT2);
L = (Eta * CosThetaI + CosThetaT) * N - Eta * V;
float VoH = abs(dot(N, V));
float ToH = abs(dot(N, L));
EventThroughput = 1 - FresnelDielectric(Eta, VoH, ToH);
return true;
}
float3 GetSkyRadiance(float3 Direction, float Roughness)
{
float SkyAverageBrightness = 1.0f;
return GetSkyLightReflection(Direction, Roughness, SkyAverageBrightness);
}
RAY_TRACING_ENTRY_RAYGEN(RayTracingPrimaryRaysRGS)
{
uint2 DispatchThreadId = DispatchRaysIndex().xy + View.ViewRectMin;
uint2 PixelCoord = GetPixelCoord(DispatchThreadId, UpscaleFactor);
uint LinearIndex = PixelCoord.y * View.BufferSizeAndInvSize.x + PixelCoord.x; // TODO(Denoiser): PixelCoord or DispatchThreadId
RandomSequence RandSequence;
RandomSequence_Initialize(RandSequence, LinearIndex, View.StateFrameIndex);
float2 InvBufferSize = View.BufferSizeAndInvSize.zw;
float2 UV = (float2(PixelCoord) + 0.5) * InvBufferSize;
#if 0
FGBufferData GBufferData = GetGBufferDataFromSceneTextures(UV);
#else
//#dxr-todo: workaround for flickering. UE-87281
FGBufferData GBufferData = GetGBufferDataFromSceneTexturesLoad(PixelCoord);
#endif
float Depth = GBufferData.Depth;
float3 WorldPosition = ReconstructWorldPositionFromDepth(UV, Depth);
float WorldSpaceDistance = length(WorldPosition - View.WorldViewOrigin);
// Trace rays from camera origin to (Gbuffer - epsilon) to only intersect translucent objects
RayDesc Ray = CreatePrimaryRay(UV);
Ray.Direction = normalize ( float3 ( Table.SampleLevel(GlobalPointClampedSampler, float2(0,0), 0 ).x, Table.SampleLevel(GlobalPointClampedSampler, float2(0,0), 0 ).y, Table.SampleLevel(GlobalPointClampedSampler, float2(0,0), 0 ).z) ) ;
FRayCone RayCone = (FRayCone)0;
RayCone.SpreadAngle = View.EyeToPixelSpreadAngle;
if((ERayTracingPrimaryRaysFlag_UseGBufferForMaxDistance & PrimaryRayFlags) != 0)
{
Ray.TMax = WorldSpaceDistance - 0.1;
}
bool bAllowSkySampling;
if((ERayTracingPrimaryRaysFlag_AllowSkipSkySample & PrimaryRayFlags) != 0)
{
// Sky is only sampled when infinite reflection rays are used.
bAllowSkySampling = TranslucencyMaxRayDistance < 0;
}
else
{
bAllowSkySampling = true;
}
// Check if the Sky Light should affect reflection rays within translucency.
const bool bSkyLightAffectReflection = ShouldSkyLightAffectReflection();
bool bHasScattered = (ERayTracingPrimaryRaysFlag_ConsiderSurfaceScatter & PrimaryRayFlags) != 0;
// Integrated data by path tracing
float3 PathRadiance = 0.0;
float PathThroughput = 1.0; // A float for now because UE does not support colored translucency as of today.
float LastRoughness = 0.0;
float LastIor = 1.0f;
float HitDistance = 0.0f;
for (uint RefractionRayIndex = 0; RefractionRayIndex < MaxRefractionRays; ++RefractionRayIndex)
{
const uint RefractionRayFlags = 0;
const uint RefractionInstanceInclusionMask = RAY_TRACING_MASK_ALL;
const bool bRefractionEnableSkyLightContribution = true;
float3 PathVertexRadiance = float3(0, 0, 0);
FMaterialClosestHitPayload Payload = TraceRayAndAccumulateResults(
Ray,
TLAS,
RefractionRayFlags,
RefractionInstanceInclusionMask,
RandSequence,
MaxNormalBias,
ReflectedShadowsType,
ShouldDoDirectLighting,
ShouldDoEmissiveAndIndirectLighting,
RayCone,
bRefractionEnableSkyLightContribution,
PathVertexRadiance);
LastRoughness = Payload.Roughness;
//
// Handle no hit condition
//
if (Payload.IsMiss())
{
if (bHasScattered && bAllowSkySampling)
{
// We only sample the sky if the ray has scattered (i.e. been refracted or reflected). Otherwise we are going ot use the regular scene color.
PathRadiance += PathThroughput * GetSkyRadiance(Ray.Direction, LastRoughness);
}
break;
}
float3 HitPoint = Ray.Origin + Ray.Direction * Payload.HitT;
float NextMaxRayDistance = Ray.TMax - Payload.HitT;
//
// Handle surface lighting
//
float vertexRadianceWeight = Payload.Opacity; // Opacity as coverage. This works for RAY_TRACING_BLEND_MODE_OPAQUE and RAY_TRACING_BLEND_MODE_TRANSLUCENT.
// It is also needed for RAY_TRACING_BLEND_MODE_ADDITIVE and RAY_TRACING_BLEND_MODE_ALPHA_COMPOSITE: radiance continbution is alway weighted by coverage.
// #dxr_todo: I have not been able to setup a material using RAY_TRACING_BLEND_MODE_MODULATE.
PathRadiance += PathThroughput * PathVertexRadiance * vertexRadianceWeight;
//
// Handle reflection tracing with a ray per vertex of the refraction path
//
// Shorten the rays on rougher surfaces between user-provided min and max ray lengths.
// When a shortened ray misses the geometry, we fall back to local reflection capture sampling (similar to SSR).
const float LocalMaxRayDistance = bAllowSkySampling ? 1e27f : lerp(TranslucencyMaxRayDistance, TranslucencyMinRayDistance, Payload.Roughness);
if (Payload.Roughness < TranslucencyMaxRoughness)
{
// Trace reflection ray
uint DummyVariable;
float2 RandSample = RandomSequence_GenerateSample2D(RandSequence, DummyVariable);
RayDesc ReflectionRay;
ReflectionRay.TMin = 0.01;
ReflectionRay.TMax = LocalMaxRayDistance;
ReflectionRay.Origin = HitPoint;
ReflectionRay.Direction = GenerateReflectedRayDirection(Ray.Direction, Payload.WorldNormal, Payload.Roughness, RandSample);
ApplyPositionBias(ReflectionRay, Payload.WorldNormal, MaxNormalBias);
const uint ReflectionRayFlags = RAY_FLAG_CULL_BACK_FACING_TRIANGLES;
const uint ReflectionInstanceInclusionMask = RAY_TRACING_MASK_ALL;
const bool bReflectionEnableSkyLightContribution = bSkyLightAffectReflection;
float3 ReflectionRadiance = float3(0, 0, 0);
FMaterialClosestHitPayload ReflectionPayload = TraceRayAndAccumulateResults(
ReflectionRay,
TLAS,
ReflectionRayFlags,
ReflectionInstanceInclusionMask,
RandSequence,
MaxNormalBias,
ReflectedShadowsType,
ShouldDoDirectLighting,
ShouldDoEmissiveAndIndirectLighting,
RayCone,
bReflectionEnableSkyLightContribution,
ReflectionRadiance);
// If we have not hit anything, sample the distance sky radiance.
if (ReflectionPayload.IsMiss())
{
ReflectionRadiance = GetSkyRadiance(ReflectionRay.Direction, LastRoughness);
}
// #dxr_todo: reflection IOR and clear coat also? This only handles default material.
float NoV = saturate(dot(-Ray.Direction, Payload.WorldNormal));
const float3 ReflectionThroughput = EnvBRDF(Payload.SpecularColor, Payload.Roughness, NoV);
PathRadiance += PathThroughput * ReflectionThroughput * ReflectionRadiance * vertexRadianceWeight;
}
//
// Handle refraction through the surface.
//
// Update the refraction path transmittance and check stop condition
float PathVertexTransmittance = Payload.BlendingMode == RAY_TRACING_BLEND_MODE_ADDITIVE ? 1.0 : 1.0 - Payload.Opacity;
PathThroughput *= PathVertexTransmittance;
if (PathThroughput <= 0.0)
{
break;
}
// Set refraction ray for next iteration
float3 RefractedDirection = Ray.Direction;
if (TranslucencyRefraction)
{
float Ior1 = DielectricF0ToIor(DielectricSpecularToF0(Payload.Specular)); // Not using Payload.Ior but parameterisation from specular.
float Ior2 = LastIor;
bHasScattered |= Ior1 != Ior2;
float ReflectionRefractionEventThroughput;
bool bIsEntering = Payload.IsFrontFace();
if (!RefractRay(Ray.Direction, Payload.WorldNormal, Ior1, Ior2, bIsEntering, RefractedDirection, ReflectionRefractionEventThroughput))
{
//#dxr_todo: handle total internal reflection ray event. We could just continue form this path. And not use the new IOR.
// We should combine that step with the one above reflection evaluation. For now we stop tracing.
break;
}
LastIor = Ior1;
PathThroughput *= ReflectionRefractionEventThroughput;
// ray has bent, so it may need to go arbitrarily far
NextMaxRayDistance = LocalMaxRayDistance;
}
//
// Setup refracted ray to be traced
//
Ray.Origin = HitPoint;
Ray.TMin = 0.01;
Ray.TMax = NextMaxRayDistance;
Ray.Direction = RefractedDirection;
float SurfaceCurvature = 0.0f; /* #todo_dxr assume no curvature */
RayCone = PropagateRayCone(RayCone, SurfaceCurvature, Depth);
}
if (!bHasScattered)
{
// Use the scene radiance for ray that has not been scattered/refracted (no surface or IORin=IORout). Still apply the throughtput in case we have traversed surfaces with opacity>0.
PathRadiance += PathThroughput * SceneColorTexture.SampleLevel(GlobalPointClampedSampler, UV, 0).xyz / View.PreExposure;
}
if(ShouldUsePreExposure)
{
PathRadiance.rgb *= View.PreExposure;
}
PathRadiance = ClampToHalfFloatRange(PathRadiance);
ColorOutput[DispatchThreadId] = float4(PathRadiance, 0.0f);
RayHitDistanceOutput[DispatchThreadId] = HitDistance;
}
So this is all I am trying to do. Load a texture into the shader that is a float array and I want to redirect the rays in the shader at line
Ray.Direction = normalize ( float3 ( Table.SampleLevel(GlobalPointClampedSampler, float2(0,0), 0 ).x, Table.SampleLevel(GlobalPointClampedSampler, float2(0,0), 0 ).y, Table.SampleLevel(GlobalPointClampedSampler, float2(0,0), 0 ).z) ) ;
This should be easy but it seems like I am shooting in the dark. Some help would be appreciated. Thanks.