116 lines
4.6 KiB
HLSL
116 lines
4.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*
|
|
float SampleExplicitTrilinear_{ParameterName}(SamplerState Sampler, float3 UVW, int MipLevel)
|
|
{
|
|
int3 TotalDim = {NumCellsName} * {NumTiles};
|
|
float3 GridPos = float3(TotalDim[0] * UVW[0] - 0.5, TotalDim[1] * UVW[1] - 0.5, TotalDim[2] * UVW[2] - 0.5f);
|
|
int3 GridCell = floor(GridPos);
|
|
|
|
float3 delta = float3( GridPos[0] - GridCell[0], GridPos[1] - GridCell[1], GridPos[2] - GridCell[2]);
|
|
// local values
|
|
float4 F;
|
|
|
|
// bottom face
|
|
F[0] = {GridName}.Load( int4( GridCell[0], GridCell[1], GridCell[2], MipLevel) );
|
|
F[1] = {GridName}.Load( int4( GridCell[0] + 1, GridCell[1], GridCell[2], MipLevel) );
|
|
F[2] = {GridName}.Load( int4( GridCell[0] + 1, GridCell[1] +1 , GridCell[2], MipLevel) );
|
|
F[3] = {GridName}.Load( int4( GridCell[0], GridCell[1] +1 , GridCell[2], MipLevel) );
|
|
// bottom value
|
|
float BV = (1.-delta.y) * (F[0] *(1.-delta.x) + F[1]*(delta.x)) + delta.y * (F[3]*(1.-delta.x) + F[2]*delta.x);
|
|
|
|
// top face
|
|
F[0] = {GridName}.Load( int4( GridCell[0], GridCell[1], GridCell[2] + 1, MipLevel) );
|
|
F[1] = {GridName}.Load( int4( GridCell[0] + 1, GridCell[1], GridCell[2] + 1, MipLevel) );
|
|
F[2] = {GridName}.Load( int4( GridCell[0] + 1, GridCell[1] +1 , GridCell[2] + 1, MipLevel) );
|
|
F[3] = {GridName}.Load( int4( GridCell[0], GridCell[1] +1 , GridCell[2] + 1, MipLevel) );
|
|
// top value
|
|
float TV = (1.-delta.y) * (F[0] *(1.-delta.x) + F[1]*(delta.x)) + delta.y * (F[3]*(1.-delta.x) + F[2]*delta.x);
|
|
|
|
// interp between bottom and top
|
|
return TV * delta.z + BV * (1.-delta.z);
|
|
}
|
|
*/
|
|
|
|
float{NumChannels} SampleTriCubicLagrange_{ParameterName}(SamplerState Sampler, float3 UVW, int MipLevel)
|
|
{
|
|
int3 TotalDim = {NumCellsName} * {NumTiles};
|
|
float3 GridPos = float3(TotalDim[0] * UVW[0] - 0.5, TotalDim[1] * UVW[1] - 0.5, TotalDim[2] * UVW[2] - 0.5f);
|
|
|
|
// identify the lower-left-hand corner of the cell
|
|
int3 GridCell = floor(GridPos);
|
|
|
|
int3 LocalCell = GridCell % {NumCellsName};
|
|
|
|
const int3 MaxCell = {NumCellsName} - int3(2,2,2);
|
|
|
|
if (any((LocalCell <= int3(1,1,1)) || (LocalCell >= MaxCell)))
|
|
{
|
|
// revert to trilinear hardware sampling at the boundary cells.
|
|
return {GridName}.SampleLevel(Sampler, UVW, MipLevel);
|
|
}
|
|
else
|
|
{
|
|
// sample point offset from lower left
|
|
float3 delta = float3( GridPos[0] - GridCell[0], GridPos[1] - GridCell[1], GridPos[2] - GridCell[2]);
|
|
|
|
|
|
float t = 1. + delta.x;
|
|
float u = 1. + delta.y;
|
|
float v = 1. + delta.z;
|
|
|
|
float4x{NumChannels} DataInZ;
|
|
float{NumChannels} minv = 3.402823466e+38;
|
|
float{NumChannels} maxv = -3.402823466e+38;
|
|
for (int zk = 0; zk < 4; zk++)
|
|
{
|
|
int plane = GridCell[2] + zk -1;
|
|
|
|
float4x{NumChannels} DataInY;
|
|
for (int yj = 0; yj < 4; yj++)
|
|
{
|
|
float4x{NumChannels} DataInX;
|
|
|
|
int row = GridCell[1] + yj - 1;
|
|
|
|
for(int xi = 0; xi < 4; xi++)
|
|
{
|
|
int col = GridCell[0] + xi - 1;
|
|
DataInX[xi] = {GridName}.Load(int4(col, row, plane, MipLevel));
|
|
minv = min(DataInX[xi], minv);
|
|
maxv = max(DataInX[xi], maxv);
|
|
}
|
|
|
|
// coefficients
|
|
float{NumChannels} Cx0 = 6.f * DataInX[0];
|
|
float{NumChannels} Cx1 = -11.f * DataInX[0] + 18.f * DataInX[1] - 9.f * DataInX[2] + 2.f * DataInX[3];
|
|
float{NumChannels} Cx2 = 6.f * DataInX[0] - 15.f * DataInX[1] +12.f * DataInX[2] - 3.f * DataInX[3];
|
|
float{NumChannels} Cx3 = -DataInX[0] + 3.f * DataInX[1] - 3.f * DataInX[2] + DataInX[3];
|
|
|
|
DataInY[yj] = (1.f/6.f) * (Cx0 + t * ( Cx1 + t * ( Cx2 + t * Cx3 ) ));
|
|
|
|
}
|
|
|
|
float{NumChannels} Cy0 = 6.f * DataInY[0];
|
|
float{NumChannels} Cy1 = -11.f * DataInY[0] + 18.f * DataInY[1] - 9.f * DataInY[2] + 2.f * DataInY[3];
|
|
float{NumChannels} Cy2 = 6.f * DataInY[0] - 15.f * DataInY[1] +12.f * DataInY[2] - 3.f * DataInY[3];
|
|
float{NumChannels} Cy3 = -DataInY[0] + 3.f * DataInY[1] - 3.f * DataInY[2] + DataInY[3];
|
|
|
|
DataInZ[zk] = (1.f/6.f) * (Cy0 + u * ( Cy1 + u * ( Cy2 + u * Cy3 ) ));
|
|
|
|
}
|
|
|
|
float{NumChannels} Cz0 = 6.f * DataInZ[0];
|
|
float{NumChannels} Cz1 = -11.f * DataInZ[0] + 18.f * DataInZ[1] - 9.f * DataInZ[2] + 2.f * DataInZ[3];
|
|
float{NumChannels} Cz2 = 6.f * DataInZ[0] - 15.f * DataInZ[1] +12.f * DataInZ[2] - 3.f * DataInZ[3];
|
|
float{NumChannels} Cz3 = -DataInZ[0] + 3.f * DataInZ[1] - 3.f * DataInZ[2] + DataInZ[3];
|
|
|
|
float{NumChannels} TriCubicValue = (1.f/6.f) * (Cz0 + v * ( Cz1 + v * ( Cz2 + v * Cz3 ) ));
|
|
|
|
// for the fluid sims, a nice look can be achieved with BlendAmount = 0.25f;
|
|
// float BlendAmount = 0.0f;
|
|
// return lerp(TriCubicValue, TriLinearValue, BlendAmount);
|
|
|
|
return min(max(TriCubicValue, minv), maxv);
|
|
}
|
|
} |