e4s-sdk/gamedata/shaders/d3d11/fluid_common_tricubic.hlsli
2026-06-17 23:06:51 +03:00

233 lines
6 KiB
HLSL

/////////////////////////////////
// BEGIN Custom Sampling Functions
Texture1D HHGGTex;
// cubic b-spline
float bsW0(float a)
{
return (1.0 / 6.0 * (-(a * a * a) + (3.0 * a * a) - (3.0 * a) + 1.0));
}
float bsW1(float a)
{
return (1.0 / 6.0 * ((3.0 * a * a * a) - (6.0 * a * a) + 4.0));
}
float bsW2(float a)
{
return (1.0 / 6.0 * (-(3.0 * a * a * a) + (3.0 * a * a) + (3.0 * a) + 1.0));
}
float bsW3(float a)
{
return (1.0 / 6.0 * a * a * a);
}
float g0(float a)
{
return (bsW0(a) + bsW1(a));
}
float g1(float a)
{
return (bsW2(a) + bsW3(a));
}
float h0texels(float a)
{
return (1.0 + a - (bsW1(a) / (bsW0(a) + bsW1(a))));
}
float h1texels(float a)
{
return (1.0 - a + (bsW3(a) / (bsW2(a) + bsW3(a))));
}
/// end cubic-bspline
// first derivative of cubic b-spline
float bsfdW0(float a)
{
return (1.0 / 6.0 * (-(3.0 * a * a) + (6.0 * a) - 3.0));
}
float bsfdW1(float a)
{
return (1.0 / 6.0 * ((9.0 * a * a) - (12.0 * a)));
}
float bsfdW2(float a)
{
return (1.0 / 6.0 * (-(9.0 * a * a) + (6.0 * a) + 3.0));
}
float bsfdW3(float a)
{
return (1.0 / 6.0 * 3.0 * a * a);
}
float gfd0(float a)
{
return (bsfdW0(a) + bsfdW1(a));
}
float gfd1(float a)
{
return (bsfdW2(a) + bsfdW3(a));
}
float hfd0texels(float a)
{
return (1.0 + a - (bsfdW1(a) / (bsfdW0(a) + bsfdW1(a))));
}
float hfd1texels(float a)
{
return (1.0 - a + (bsfdW3(a) / (bsfdW2(a) + bsfdW3(a))));
}
/// end first derivative of cubic b-spline
float4 getHHGG(float xTexels)
{
// float a = frac(xTexels);
// return float4( -h0texels(a), h1texels(a), 1.0-g0(a), g0(a) );
return HHGGTex.SampleLevel(samRepeat, xTexels, 0);
}
float4 getfdHHGG(float xTexels)
{
float a = frac(xTexels);
return float4(-hfd0texels(a), hfd1texels(a), gfd1(a), -gfd1(a));
}
float4 SampleTricubicGeneric(Texture3D tex, float3 tc, float4 hg_x, float4 hg_y, float4 hg_z)
{
float3 tc100, tc000, tc110, tc010,
tc101, tc001, tc111, tc011;
tc100 = tc;
tc000 = tc;
tc100.x += (hg_x.x * recGridDim.x);
tc000.x += (hg_x.y * recGridDim.x);
tc110 = tc100;
tc010 = tc000;
tc110.y += (hg_y.x * recGridDim.y);
tc010.y += (hg_y.x * recGridDim.y);
tc100.y += (hg_y.y * recGridDim.y);
tc000.y += (hg_y.y * recGridDim.y);
tc111 = tc110;
tc011 = tc010;
tc101 = tc100;
tc001 = tc000;
tc111.z += (hg_z.x * recGridDim.z);
tc011.z += (hg_z.x * recGridDim.z);
tc101.z += (hg_z.x * recGridDim.z);
tc001.z += (hg_z.x * recGridDim.z);
float4 v001 = tex.SampleLevel(samLinearClamp, tc001, 0);
float4 v011 = tex.SampleLevel(samLinearClamp, tc011, 0);
float4 v101 = tex.SampleLevel(samLinearClamp, tc101, 0);
float4 v111 = tex.SampleLevel(samLinearClamp, tc111, 0);
float4 v0Y1 = (v001 * hg_y.z) + (v011 * hg_y.w);
float4 v1Y1 = (v101 * hg_y.z) + (v111 * hg_y.w);
float4 vXY1 = (v0Y1 * hg_x.z) + (v1Y1 * hg_x.w);
tc110.z += (hg_z.y * recGridDim.z);
tc010.z += (hg_z.y * recGridDim.z);
tc100.z += (hg_z.y * recGridDim.z);
tc000.z += (hg_z.y * recGridDim.z);
float4 v000 = tex.SampleLevel(samLinearClamp, tc000, 0);
float4 v010 = tex.SampleLevel(samLinearClamp, tc010, 0);
float4 v100 = tex.SampleLevel(samLinearClamp, tc100, 0);
float4 v110 = tex.SampleLevel(samLinearClamp, tc110, 0);
float4 v0Y0 = (v000 * hg_y.z) + (v010 * hg_y.w);
float4 v1Y0 = (v100 * hg_y.z) + (v110 * hg_y.w);
float4 vXY0 = (v0Y0 * hg_x.z) + (v1Y0 * hg_x.w);
float4 vXYZ = (vXY0 * hg_z.z) + (vXY1 * hg_z.w);
return vXYZ;
}
float4 SampleTricubic(Texture3D tex, float3 tc)
{
float3 tcTexels = (tc * gridDim.xyz) - 0.49;
float4 hg_x = getHHGG(tcTexels.x);
float4 hg_y = getHHGG(tcTexels.y);
float4 hg_z = getHHGG(tcTexels.z);
return SampleTricubicGeneric(tex, tc, hg_x, hg_y, hg_z);
}
float4 SampleGradientTricubic(Texture3D tex, float3 tc)
{
float3 tcTexels = (tc * gridDim.xyz) - 0.49;
float4 hg_x = getHHGG(tcTexels.x);
float4 hg_y = getHHGG(tcTexels.y);
float4 hg_z = getHHGG(tcTexels.z);
float4 hgfd_x = getfdHHGG(tcTexels.x);
float4 hgfd_y = getfdHHGG(tcTexels.y);
float4 hgfd_z = getfdHHGG(tcTexels.z);
return float4(SampleTricubicGeneric(tex, tc, hgfd_x, hg_y, hg_z).r,
SampleTricubicGeneric(tex, tc, hg_x, hgfd_y, hg_z).r,
SampleTricubicGeneric(tex, tc, hg_x, hg_y, hgfd_z).r, 1.0);
}
float4 SampleTrilinear(Texture3D tex, float3 tc)
{
return tex.SampleLevel(samLinearClamp, tc, 0);
}
float4 SampleGradientTrilinear(Texture3D tex, float3 tc)
{
#define LEFTCELL float3(tc.x - (1.0 / gridDim.x), tc.y, tc.z)
#define RIGHTCELL float3(tc.x + (1.0 / gridDim.x), tc.y, tc.z)
#define BOTTOMCELL float3(tc.x, (tc.y - (1.0 / gridDim.y)), tc.z)
#define TOPCELL float3(tc.x, (tc.y + (1.0 / gridDim.y)), tc.z)
#define DOWNCELL float3(tc.x, tc.y, tc.z - (1.0 / gridDim.z))
#define UPCELL float3(tc.x, tc.y, tc.z + (1.0 / gridDim.z))
float4 texL = tex.SampleLevel(samLinearClamp, LEFTCELL, 0);
float4 texR = tex.SampleLevel(samLinearClamp, RIGHTCELL, 0);
float4 texB = tex.SampleLevel(samLinearClamp, BOTTOMCELL, 0);
float4 texT = tex.SampleLevel(samLinearClamp, TOPCELL, 0);
float4 texU = tex.SampleLevel(samLinearClamp, UPCELL, 0);
float4 texD = tex.SampleLevel(samLinearClamp, DOWNCELL, 0);
return float4(texR.r - texL.r, texT.r - texB.r, texU.r - texD.r, 1);
}
float4 Sample(Texture3D tex, float3 tc)
{
if (g_bRaycastFilterTricubic)
{
return SampleTricubic(tex, tc);
}
else
{
return SampleTrilinear(tex, tc);
}
}
float4 SampleGradient(Texture3D tex, float3 tc)
{
if (g_bRaycastFilterTricubic)
{
return SampleGradientTricubic(tex, tc);
}
else
{
return SampleGradientTrilinear(tex, tc);
}
}
// END Custom Sampling Functions
/////////////////////////////////