Download

Custom Texture2d in an existing shader

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.