Skip to content

Instantly share code, notes, and snippets.

@Fewes
Last active May 7, 2024 07:16
Show Gist options
  • Save Fewes/59d2c831672040452aa77da6eaab2234 to your computer and use it in GitHub Desktop.
Save Fewes/59d2c831672040452aa77da6eaab2234 to your computer and use it in GitHub Desktop.
Tricubic texture sampling using 8 trilinear samples
#ifndef TRICUBIC_INCLUDED
#define TRICUBIC_INCLUDED
float4 Cubic(float v)
{
float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
float4 s = n * n * n;
float x = s.x;
float y = s.y - 4.0 * s.x;
float z = s.z - 4.0 * s.y + 6.0 * s.x;
float w = 6.0 - x - y - z;
return float4(x, y, z, w) * (1.0 / 6.0);
}
float4 tex3DTricubic(sampler3D tex, float3 texCoords, float3 textureSize)
{
float4 texelSize = float4(1.0 / textureSize.xz, textureSize.xz);
texCoords = texCoords * textureSize - 0.5;
float3 f = frac(texCoords);
texCoords -= f;
float4 xcubic = Cubic(f.x);
float4 ycubic = Cubic(f.y);
float4 zcubic = Cubic(f.z);
float2 cx = texCoords.xx + float2(-0.5, 1.5);
float2 cy = texCoords.yy + float2(-0.5, 1.5);
float2 cz = texCoords.zz + float2(-0.5, 1.5);
float2 sx = xcubic.xz + xcubic.yw;
float2 sy = ycubic.xz + ycubic.yw;
float2 sz = zcubic.xz + zcubic.yw;
float2 offsetx = cx + xcubic.yw / sx;
float2 offsety = cy + ycubic.yw / sy;
float2 offsetz = cz + zcubic.yw / sz;
offsetx /= textureSize.xx;
offsety /= textureSize.yy;
offsetz /= textureSize.zz;
float4 sample0 = tex3Dlod(tex, float4(offsetx.x, offsety.x, offsetz.x, 0));
float4 sample1 = tex3Dlod(tex, float4(offsetx.y, offsety.x, offsetz.x, 0));
float4 sample2 = tex3Dlod(tex, float4(offsetx.x, offsety.y, offsetz.x, 0));
float4 sample3 = tex3Dlod(tex, float4(offsetx.y, offsety.y, offsetz.x, 0));
float4 sample4 = tex3Dlod(tex, float4(offsetx.x, offsety.x, offsetz.y, 0));
float4 sample5 = tex3Dlod(tex, float4(offsetx.y, offsety.x, offsetz.y, 0));
float4 sample6 = tex3Dlod(tex, float4(offsetx.x, offsety.y, offsetz.y, 0));
float4 sample7 = tex3Dlod(tex, float4(offsetx.y, offsety.y, offsetz.y, 0));
float gx = sx.x / (sx.x + sx.y);
float gy = sy.x / (sy.x + sy.y);
float gz = sz.x / (sz.x + sz.y);
float4 x0 = lerp(sample1, sample0, gx);
float4 x1 = lerp(sample3, sample2, gx);
float4 x2 = lerp(sample5, sample4, gx);
float4 x3 = lerp(sample7, sample6, gx);
float4 y0 = lerp(x1, x0, gy);
float4 y1 = lerp(x3, x2, gy);
return lerp(y1, y0, gz);
}
#endif // TRICUBIC_INCLUDED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment