496 lines
19 KiB
HLSL
496 lines
19 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "SSDCommon.ush"
|
|
|
|
|
|
#ifndef COMPILE_SIGNAL_COLOR
|
|
#define COMPILE_SIGNAL_COLOR 0
|
|
#endif
|
|
|
|
#ifndef COMPILE_SIGNAL_COLOR_SH
|
|
#define COMPILE_SIGNAL_COLOR_SH 0
|
|
#endif
|
|
|
|
#ifndef COMPILE_SIGNAL_COLOR_ARRAY
|
|
#define COMPILE_SIGNAL_COLOR_ARRAY 0
|
|
#endif
|
|
|
|
// Maximum number of indepedendent signal domain that can be denoised at same time.
|
|
#ifndef MAX_SIGNAL_BATCH_SIZE
|
|
#error Need to specify the number of signal domain being denoised.
|
|
#endif
|
|
|
|
// Number of sample that can be multiplexed into FSSDSignalSample.
|
|
#ifndef SIGNAL_ARRAY_SIZE
|
|
#error Need to specify the size of the signal array.
|
|
#endif
|
|
|
|
|
|
//------------------------------------------------------- STRUCTURE
|
|
|
|
/** Generic linearily filterable data structure to manipulate any kind of signal. */
|
|
struct FSSDSignalSample
|
|
{
|
|
// Number of sample accumulated.
|
|
float SampleCount;
|
|
|
|
// Scene color and alpha.
|
|
#if COMPILE_SIGNAL_COLOR
|
|
float4 SceneColor;
|
|
#endif
|
|
|
|
// Array of colors.
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
float3 ColorArray[COMPILE_SIGNAL_COLOR_ARRAY];
|
|
#endif
|
|
|
|
// Spherical harmonic of the color.
|
|
#if COMPILE_SIGNAL_COLOR_SH
|
|
FSSDSphericalHarmonicRGB ColorSH;
|
|
#endif
|
|
|
|
// Number of ray that did not find any intersections.
|
|
float MissCount;
|
|
|
|
float TransmissionDistance;
|
|
};
|
|
|
|
/** Generic data structure about the frequency of a FSSDSignalSample. */
|
|
struct FSSDSignalFrequency
|
|
{
|
|
// Hit distance of a this sample.
|
|
float ClosestHitDistance;
|
|
|
|
// Blur radius allowed for this sample.
|
|
float WorldBluringRadius;
|
|
|
|
// Circle confusion multiplier.
|
|
float ConfusionFactor;
|
|
};
|
|
|
|
/** Array of signal samples. Technically should be a typedef, but there is a bug in HLSL with the out operator of an array. */
|
|
struct FSSDSignalArray
|
|
{
|
|
FSSDSignalSample Array[SIGNAL_ARRAY_SIZE];
|
|
};
|
|
|
|
/** Array of signal frequencies. Technically should be a typedef, but there is a bug in HLSL with the out operator of an array. */
|
|
struct FSSDSignalFrequencyArray
|
|
{
|
|
FSSDSignalFrequency Array[SIGNAL_ARRAY_SIZE];
|
|
};
|
|
|
|
|
|
FSSDSignalSample CreateSignalSampleFromScalarValue(float Scalar)
|
|
{
|
|
FSSDSignalSample OutSample;
|
|
#if COMPILE_SIGNAL_COLOR
|
|
OutSample.SceneColor = Scalar;
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
OutSample.ColorArray[ColorId] = Scalar;
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
OutSample.ColorSH.R.V = Scalar;
|
|
OutSample.ColorSH.G.V = Scalar;
|
|
OutSample.ColorSH.B.V = Scalar;
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
OutSample.ColorSH.R.V0 = Scalar;
|
|
OutSample.ColorSH.R.V1 = Scalar;
|
|
OutSample.ColorSH.R.V2 = Scalar;
|
|
OutSample.ColorSH.G.V0 = Scalar;
|
|
OutSample.ColorSH.G.V1 = Scalar;
|
|
OutSample.ColorSH.G.V2 = Scalar;
|
|
OutSample.ColorSH.B.V0 = Scalar;
|
|
OutSample.ColorSH.B.V1 = Scalar;
|
|
OutSample.ColorSH.B.V2 = Scalar;
|
|
#endif
|
|
OutSample.SampleCount = Scalar;
|
|
OutSample.MissCount = Scalar;
|
|
OutSample.TransmissionDistance = Scalar;
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalFrequency CreateInvalidSignalFrequency()
|
|
{
|
|
FSSDSignalFrequency Frequency;
|
|
Frequency.ClosestHitDistance = DENOISER_INVALID_HIT_DISTANCE;
|
|
Frequency.WorldBluringRadius = WORLD_RADIUS_INVALID;
|
|
Frequency.ConfusionFactor = CONFUSION_FACTOR_INVALID;
|
|
return Frequency;
|
|
}
|
|
|
|
FSSDSignalSample CreateSignalSample()
|
|
{
|
|
return CreateSignalSampleFromScalarValue(0.0);
|
|
}
|
|
|
|
FSSDSignalArray CreateSignalArrayFromScalarValue(float Scalar)
|
|
{
|
|
FSSDSignalArray OutSamples;
|
|
UNROLL_N(SIGNAL_ARRAY_SIZE)
|
|
for (uint BatchedSignalId = 0; BatchedSignalId < SIGNAL_ARRAY_SIZE; BatchedSignalId++)
|
|
{
|
|
OutSamples.Array[BatchedSignalId] = CreateSignalSampleFromScalarValue(Scalar);
|
|
}
|
|
return OutSamples;
|
|
}
|
|
|
|
FSSDSignalFrequencyArray CreateInvalidSignalFrequencyArray()
|
|
{
|
|
FSSDSignalFrequencyArray OutFrequencies;
|
|
UNROLL_N(SIGNAL_ARRAY_SIZE)
|
|
for (uint BatchedSignalId = 0; BatchedSignalId < SIGNAL_ARRAY_SIZE; BatchedSignalId++)
|
|
{
|
|
OutFrequencies.Array[BatchedSignalId] = CreateInvalidSignalFrequency();
|
|
}
|
|
return OutFrequencies;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------- SIGNAL OPERATORS
|
|
|
|
FSSDSignalSample MulSignal(FSSDSignalSample Sample, float Scalar)
|
|
{
|
|
FSSDSignalSample OutSample;
|
|
#if COMPILE_SIGNAL_COLOR
|
|
OutSample.SceneColor = Sample.SceneColor * Scalar;
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
OutSample.ColorArray[ColorId] = Sample.ColorArray[ColorId] * Scalar;
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH
|
|
OutSample.ColorSH = MulSH(Sample.ColorSH, Scalar);
|
|
#endif
|
|
OutSample.SampleCount = Sample.SampleCount * Scalar;
|
|
OutSample.MissCount = Sample.MissCount * Scalar;
|
|
OutSample.TransmissionDistance = Sample.TransmissionDistance * Scalar;
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalSample AddSignal(FSSDSignalSample SampleA, FSSDSignalSample SampleB)
|
|
{
|
|
#if COMPILE_SIGNAL_COLOR
|
|
SampleA.SceneColor += SampleB.SceneColor;
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
SampleA.ColorArray[ColorId] += SampleB.ColorArray[ColorId];
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH
|
|
SampleA.ColorSH = AddSH(SampleA.ColorSH, SampleB.ColorSH);
|
|
#endif
|
|
SampleA.SampleCount += SampleB.SampleCount;
|
|
SampleA.MissCount += SampleB.MissCount;
|
|
SampleA.TransmissionDistance += SampleB.TransmissionDistance;
|
|
return SampleA;
|
|
}
|
|
|
|
FSSDSignalSample MinusSignal(FSSDSignalSample Sample)
|
|
{
|
|
#if COMPILE_SIGNAL_COLOR
|
|
Sample.SceneColor = -Sample.SceneColor;
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
Sample.ColorArray[ColorId] = -Sample.ColorArray[ColorId];
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH
|
|
Sample.ColorSH = MulSH(Sample.ColorSH, -1.0);
|
|
#endif
|
|
Sample.SampleCount = -Sample.SampleCount;
|
|
Sample.MissCount = -Sample.MissCount;
|
|
Sample.TransmissionDistance = -Sample.TransmissionDistance;
|
|
return Sample;
|
|
}
|
|
|
|
FSSDSignalSample SubtractSignal(FSSDSignalSample SampleA, FSSDSignalSample SampleB)
|
|
{
|
|
return AddSignal(SampleA, MinusSignal(SampleB));
|
|
}
|
|
|
|
FSSDSignalSample AbsSignal(FSSDSignalSample Sample)
|
|
{
|
|
#if COMPILE_SIGNAL_COLOR
|
|
Sample.SceneColor = abs(Sample.SceneColor);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
Sample.ColorArray[ColorId] = abs(Sample.ColorArray[ColorId]);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
Sample.ColorSH.R.V = abs(Sample.ColorSH.R.V);
|
|
Sample.ColorSH.G.V = abs(Sample.ColorSH.G.V);
|
|
Sample.ColorSH.B.V = abs(Sample.ColorSH.B.V);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
Sample.ColorSH.R.V0 = abs(Sample.ColorSH.R.V0);
|
|
Sample.ColorSH.R.V1 = abs(Sample.ColorSH.R.V1);
|
|
Sample.ColorSH.R.V2 = abs(Sample.ColorSH.R.V2);
|
|
Sample.ColorSH.G.V0 = abs(Sample.ColorSH.G.V0);
|
|
Sample.ColorSH.G.V1 = abs(Sample.ColorSH.G.V1);
|
|
Sample.ColorSH.G.V2 = abs(Sample.ColorSH.G.V2);
|
|
Sample.ColorSH.B.V0 = abs(Sample.ColorSH.B.V0);
|
|
Sample.ColorSH.B.V1 = abs(Sample.ColorSH.B.V1);
|
|
Sample.ColorSH.B.V2 = abs(Sample.ColorSH.B.V2);
|
|
#endif
|
|
Sample.SampleCount = abs(Sample.SampleCount);
|
|
Sample.MissCount = abs(Sample.MissCount);
|
|
Sample.TransmissionDistance = abs(Sample.TransmissionDistance);
|
|
return Sample;
|
|
}
|
|
|
|
FSSDSignalSample SqrtSignal(FSSDSignalSample Sample)
|
|
{
|
|
#if COMPILE_SIGNAL_COLOR
|
|
Sample.SceneColor = sqrt(Sample.SceneColor);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
Sample.ColorArray[ColorId] = sqrt(Sample.ColorArray[ColorId]);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
Sample.ColorSH.R.V = sqrt(Sample.ColorSH.R.V);
|
|
Sample.ColorSH.G.V = sqrt(Sample.ColorSH.G.V);
|
|
Sample.ColorSH.B.V = sqrt(Sample.ColorSH.B.V);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
Sample.ColorSH.R.V0 = sqrt(Sample.ColorSH.R.V0);
|
|
Sample.ColorSH.R.V1 = sqrt(Sample.ColorSH.R.V1);
|
|
Sample.ColorSH.R.V2 = sqrt(Sample.ColorSH.R.V2);
|
|
Sample.ColorSH.G.V0 = sqrt(Sample.ColorSH.G.V0);
|
|
Sample.ColorSH.G.V1 = sqrt(Sample.ColorSH.G.V1);
|
|
Sample.ColorSH.G.V2 = sqrt(Sample.ColorSH.G.V2);
|
|
Sample.ColorSH.B.V0 = sqrt(Sample.ColorSH.B.V0);
|
|
Sample.ColorSH.B.V1 = sqrt(Sample.ColorSH.B.V1);
|
|
Sample.ColorSH.B.V2 = sqrt(Sample.ColorSH.B.V2);
|
|
#endif
|
|
Sample.SampleCount = sqrt(Sample.SampleCount);
|
|
Sample.MissCount = sqrt(Sample.MissCount);
|
|
Sample.TransmissionDistance = sqrt(Sample.TransmissionDistance);
|
|
return Sample;
|
|
}
|
|
|
|
FSSDSignalSample PowerSignal(FSSDSignalSample Sample, float Exponent)
|
|
{
|
|
#if COMPILE_SIGNAL_COLOR
|
|
Sample.SceneColor.r = pow(Sample.SceneColor.r, Exponent);
|
|
Sample.SceneColor.g = pow(Sample.SceneColor.g, Exponent);
|
|
Sample.SceneColor.b = pow(Sample.SceneColor.b, Exponent);
|
|
Sample.SceneColor.a = pow(Sample.SceneColor.a, Exponent);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
Sample.ColorArray[ColorId] = pow(Sample.ColorArray[ColorId], Exponent);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
Sample.ColorSH.R.V = pow(Sample.ColorSH.R.V, Exponent);
|
|
Sample.ColorSH.G.V = pow(Sample.ColorSH.G.V, Exponent);
|
|
Sample.ColorSH.B.V = pow(Sample.ColorSH.B.V, Exponent);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
Sample.ColorSH.R.V0 = pow(Sample.ColorSH.R.V0, Exponent);
|
|
Sample.ColorSH.R.V1 = pow(Sample.ColorSH.R.V1, Exponent);
|
|
Sample.ColorSH.R.V2 = pow(Sample.ColorSH.R.V2, Exponent);
|
|
Sample.ColorSH.G.V0 = pow(Sample.ColorSH.G.V0, Exponent);
|
|
Sample.ColorSH.G.V1 = pow(Sample.ColorSH.G.V1, Exponent);
|
|
Sample.ColorSH.G.V2 = pow(Sample.ColorSH.G.V2, Exponent);
|
|
Sample.ColorSH.B.V0 = pow(Sample.ColorSH.B.V0, Exponent);
|
|
Sample.ColorSH.B.V1 = pow(Sample.ColorSH.B.V1, Exponent);
|
|
Sample.ColorSH.B.V2 = pow(Sample.ColorSH.B.V2, Exponent);
|
|
#endif
|
|
Sample.SampleCount = pow(Sample.SampleCount, Exponent);
|
|
Sample.MissCount = pow(Sample.MissCount, Exponent);
|
|
Sample.TransmissionDistance = pow(Sample.TransmissionDistance, Exponent);
|
|
return Sample;
|
|
}
|
|
|
|
FSSDSignalSample MinSignal(FSSDSignalSample SampleA, FSSDSignalSample SampleB)
|
|
{
|
|
FSSDSignalSample OutSample;
|
|
#if COMPILE_SIGNAL_COLOR
|
|
OutSample.SceneColor = min(SampleA.SceneColor, SampleB.SceneColor);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
OutSample.ColorArray[ColorId] = min(SampleA.ColorArray[ColorId], SampleB.ColorArray[ColorId]);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
OutSample.ColorSH.R.V = min(SampleA.ColorSH.R.V, SampleB.ColorSH.R.V);
|
|
OutSample.ColorSH.G.V = min(SampleA.ColorSH.G.V, SampleB.ColorSH.G.V);
|
|
OutSample.ColorSH.B.V = min(SampleA.ColorSH.B.V, SampleB.ColorSH.B.V);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
OutSample.ColorSH.R.V0 = min(SampleA.ColorSH.R.V0, SampleB.ColorSH.R.V0);
|
|
OutSample.ColorSH.R.V1 = min(SampleA.ColorSH.R.V1, SampleB.ColorSH.R.V1);
|
|
OutSample.ColorSH.R.V2 = min(SampleA.ColorSH.R.V2, SampleB.ColorSH.R.V2);
|
|
OutSample.ColorSH.G.V0 = min(SampleA.ColorSH.G.V0, SampleB.ColorSH.G.V0);
|
|
OutSample.ColorSH.G.V1 = min(SampleA.ColorSH.G.V1, SampleB.ColorSH.G.V1);
|
|
OutSample.ColorSH.G.V2 = min(SampleA.ColorSH.G.V2, SampleB.ColorSH.G.V2);
|
|
OutSample.ColorSH.B.V0 = min(SampleA.ColorSH.B.V0, SampleB.ColorSH.B.V0);
|
|
OutSample.ColorSH.B.V1 = min(SampleA.ColorSH.B.V1, SampleB.ColorSH.B.V1);
|
|
OutSample.ColorSH.B.V2 = min(SampleA.ColorSH.B.V2, SampleB.ColorSH.B.V2);
|
|
#endif
|
|
OutSample.SampleCount = min(SampleA.SampleCount, SampleB.SampleCount);
|
|
OutSample.MissCount = min(SampleA.MissCount, SampleB.MissCount);
|
|
OutSample.TransmissionDistance = min(SampleA.TransmissionDistance, SampleB.TransmissionDistance);
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalSample MaxSignal(FSSDSignalSample SampleA, FSSDSignalSample SampleB)
|
|
{
|
|
FSSDSignalSample OutSample;
|
|
#if COMPILE_SIGNAL_COLOR
|
|
OutSample.SceneColor = max(SampleA.SceneColor, SampleB.SceneColor);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
OutSample.ColorArray[ColorId] = max(SampleA.ColorArray[ColorId], SampleB.ColorArray[ColorId]);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
OutSample.ColorSH.R.V = max(SampleA.ColorSH.R.V, SampleB.ColorSH.R.V);
|
|
OutSample.ColorSH.G.V = max(SampleA.ColorSH.G.V, SampleB.ColorSH.G.V);
|
|
OutSample.ColorSH.B.V = max(SampleA.ColorSH.B.V, SampleB.ColorSH.B.V);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
OutSample.ColorSH.R.V0 = max(SampleA.ColorSH.R.V0, SampleB.ColorSH.R.V0);
|
|
OutSample.ColorSH.R.V1 = max(SampleA.ColorSH.R.V1, SampleB.ColorSH.R.V1);
|
|
OutSample.ColorSH.R.V2 = max(SampleA.ColorSH.R.V2, SampleB.ColorSH.R.V2);
|
|
OutSample.ColorSH.G.V0 = max(SampleA.ColorSH.G.V0, SampleB.ColorSH.G.V0);
|
|
OutSample.ColorSH.G.V1 = max(SampleA.ColorSH.G.V1, SampleB.ColorSH.G.V1);
|
|
OutSample.ColorSH.G.V2 = max(SampleA.ColorSH.G.V2, SampleB.ColorSH.G.V2);
|
|
OutSample.ColorSH.B.V0 = max(SampleA.ColorSH.B.V0, SampleB.ColorSH.B.V0);
|
|
OutSample.ColorSH.B.V1 = max(SampleA.ColorSH.B.V1, SampleB.ColorSH.B.V1);
|
|
OutSample.ColorSH.B.V2 = max(SampleA.ColorSH.B.V2, SampleB.ColorSH.B.V2);
|
|
#endif
|
|
OutSample.SampleCount = max(SampleA.SampleCount, SampleB.SampleCount);
|
|
OutSample.MissCount = max(SampleA.MissCount, SampleB.MissCount);
|
|
OutSample.TransmissionDistance = max(SampleA.TransmissionDistance, SampleB.TransmissionDistance);
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalSample ClampSignal(FSSDSignalSample Sample, FSSDSignalSample SampleMin, FSSDSignalSample SampleMax)
|
|
{
|
|
FSSDSignalSample OutSample;
|
|
#if COMPILE_SIGNAL_COLOR
|
|
OutSample.SceneColor = clamp(Sample.SceneColor, SampleMin.SceneColor, SampleMax.SceneColor);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
OutSample.ColorArray[ColorId] = clamp(Sample.ColorArray[ColorId], SampleMin.ColorArray[ColorId], SampleMax.ColorArray[ColorId]);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
OutSample.ColorSH.R.V = clamp(Sample.ColorSH.R.V, SampleMin.ColorSH.R.V, SampleMax.ColorSH.R.V);
|
|
OutSample.ColorSH.G.V = clamp(Sample.ColorSH.G.V, SampleMin.ColorSH.G.V, SampleMax.ColorSH.G.V);
|
|
OutSample.ColorSH.B.V = clamp(Sample.ColorSH.B.V, SampleMin.ColorSH.B.V, SampleMax.ColorSH.B.V);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
OutSample.ColorSH.R.V0 = clamp(Sample.ColorSH.R.V0, SampleMin.ColorSH.R.V0, SampleMax.ColorSH.R.V0);
|
|
OutSample.ColorSH.R.V1 = clamp(Sample.ColorSH.R.V1, SampleMin.ColorSH.R.V1, SampleMax.ColorSH.R.V1);
|
|
OutSample.ColorSH.R.V2 = clamp(Sample.ColorSH.R.V2, SampleMin.ColorSH.R.V2, SampleMax.ColorSH.R.V2);
|
|
OutSample.ColorSH.G.V0 = clamp(Sample.ColorSH.G.V0, SampleMin.ColorSH.G.V0, SampleMax.ColorSH.G.V0);
|
|
OutSample.ColorSH.G.V1 = clamp(Sample.ColorSH.G.V1, SampleMin.ColorSH.G.V1, SampleMax.ColorSH.G.V1);
|
|
OutSample.ColorSH.G.V2 = clamp(Sample.ColorSH.G.V2, SampleMin.ColorSH.G.V2, SampleMax.ColorSH.G.V2);
|
|
OutSample.ColorSH.B.V0 = clamp(Sample.ColorSH.B.V0, SampleMin.ColorSH.B.V0, SampleMax.ColorSH.B.V0);
|
|
OutSample.ColorSH.B.V1 = clamp(Sample.ColorSH.B.V1, SampleMin.ColorSH.B.V1, SampleMax.ColorSH.B.V1);
|
|
OutSample.ColorSH.B.V2 = clamp(Sample.ColorSH.B.V2, SampleMin.ColorSH.B.V2, SampleMax.ColorSH.B.V2);
|
|
#endif
|
|
OutSample.SampleCount = clamp(Sample.SampleCount, SampleMin.SampleCount, SampleMax.SampleCount);
|
|
OutSample.MissCount = clamp(Sample.MissCount, SampleMin.MissCount, SampleMax.MissCount);
|
|
OutSample.TransmissionDistance = clamp(Sample.TransmissionDistance, SampleMin.TransmissionDistance, SampleMax.TransmissionDistance);
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalSample LerpSignal(FSSDSignalSample Sample0, FSSDSignalSample Sample1, float Interp)
|
|
{
|
|
return AddSignal(Sample0, MulSignal(SubtractSignal(Sample1, Sample0), Interp));
|
|
}
|
|
|
|
/** Normalize the signal sample to one. */
|
|
FSSDSignalSample NormalizeToOneSample(FSSDSignalSample Sample)
|
|
{
|
|
FSSDSignalSample OutSample = MulSignal(Sample, Sample.SampleCount > 0 ? rcp(Sample.SampleCount) : 0);
|
|
OutSample.SampleCount = Sample.SampleCount > 0 ? 1 : 0;
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalSample WaveBroadcastSignal(const FWaveBroadcastSettings BroadcastSettings, FSSDSignalSample Sample)
|
|
{
|
|
FSSDSignalSample OutSample;
|
|
#if COMPILE_SIGNAL_COLOR
|
|
OutSample.SceneColor = WaveBroadcast(BroadcastSettings, Sample.SceneColor);
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_ARRAY
|
|
{
|
|
UNROLL_N(COMPILE_SIGNAL_COLOR_ARRAY)
|
|
for (uint ColorId = 0; ColorId < COMPILE_SIGNAL_COLOR_ARRAY; ColorId++)
|
|
OutSample.ColorArray[ColorId] = WaveBroadcast(BroadcastSettings, Sample.ColorArray[ColorId]);
|
|
}
|
|
#endif
|
|
#if COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 2
|
|
OutSample.ColorSH.R.V = WaveBroadcast(BroadcastSettings, Sample.ColorSH.R.V);
|
|
OutSample.ColorSH.G.V = WaveBroadcast(BroadcastSettings, Sample.ColorSH.G.V);
|
|
OutSample.ColorSH.B.V = WaveBroadcast(BroadcastSettings, Sample.ColorSH.B.V);
|
|
#elif COMPILE_SIGNAL_COLOR_SH && SPHERICAL_HARMONIC_ORDER == 3
|
|
OutSample.ColorSH.R.V0 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.R.V0);
|
|
OutSample.ColorSH.R.V1 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.R.V1);
|
|
OutSample.ColorSH.R.V2 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.R.V2);
|
|
OutSample.ColorSH.G.V0 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.G.V0);
|
|
OutSample.ColorSH.G.V1 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.G.V1);
|
|
OutSample.ColorSH.G.V2 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.G.V2);
|
|
OutSample.ColorSH.B.V0 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.B.V0);
|
|
OutSample.ColorSH.B.V1 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.B.V1);
|
|
OutSample.ColorSH.B.V2 = WaveBroadcast(BroadcastSettings, Sample.ColorSH.B.V2);
|
|
#endif
|
|
OutSample.SampleCount = WaveBroadcast(BroadcastSettings, Sample.SampleCount);
|
|
OutSample.MissCount = WaveBroadcast(BroadcastSettings, Sample.MissCount);
|
|
OutSample.TransmissionDistance = WaveBroadcast(BroadcastSettings, Sample.TransmissionDistance);
|
|
return OutSample;
|
|
}
|
|
|
|
FSSDSignalFrequency MinSignalFrequency(FSSDSignalFrequency FrequencyA, FSSDSignalFrequency FrequencyB)
|
|
{
|
|
FSSDSignalFrequency OutFrequency;
|
|
OutFrequency.ClosestHitDistance = min(FrequencyA.ClosestHitDistance, FrequencyB.ClosestHitDistance);
|
|
OutFrequency.WorldBluringRadius = min(FrequencyA.WorldBluringRadius, FrequencyB.WorldBluringRadius);
|
|
OutFrequency.ConfusionFactor = min(FrequencyA.ConfusionFactor, FrequencyB.ConfusionFactor);
|
|
return OutFrequency;
|
|
}
|
|
|
|
FSSDSignalFrequency WaveBroadcastSignalFrequency(const FWaveBroadcastSettings BroadcastSettings, FSSDSignalFrequency Frequency)
|
|
{
|
|
FSSDSignalFrequency OutFrequency;
|
|
OutFrequency.ClosestHitDistance = WaveBroadcast(BroadcastSettings, Frequency.ClosestHitDistance);
|
|
OutFrequency.WorldBluringRadius = WaveBroadcast(BroadcastSettings, Frequency.WorldBluringRadius);
|
|
OutFrequency.ConfusionFactor = WaveBroadcast(BroadcastSettings, Frequency.ConfusionFactor);
|
|
return OutFrequency;
|
|
}
|