Files
2026-03-08 15:34:38 -05:00

81 lines
2.6 KiB
HLSL

float4 texture2D_AA(in Texture2D tex, in sampler texSampler, in float2 uv)
{
// Texture antialiasing
//
// The texture coordinates are modified so that the bilinear filter will be one pixel width wide instead of one texel width.
if (tex.CalculateLevelOfDetailUnclamped(TextureSampler0, uv) < -0.5f)
{
// Get the UV deltas
float2 dUVdx = ddx(uv) * TEXTURE_DIMENSIONS.xy;
float2 dUVdy = ddy(uv) * TEXTURE_DIMENSIONS.xy;
float2 dU = float2(dUVdx.x, dUVdy.x);
float2 dV = float2(dUVdx.y, dUVdy.y);
float duUV = sqrt(dot(dU, dU));
float dvUV = sqrt(dot(dV, dV));
// First scale the uv so that each texel has a uv range of [0,1]
float2 texelUV = frac(uv * TEXTURE_DIMENSIONS.xy);
// Initially set uvModified to the floor of the texel position
float2 uvModified = (uv * TEXTURE_DIMENSIONS.xy) - texelUV;
// Modify the texelUV to push the uvs toward the edges.
// | | | |
// | _/ | | / |
// Change | U _/ | to | U ___/ |
// | _/ | | / |
// | / | | / |
// | X | | X |
float scalerU = 1.0f / (duUV);
float scalerV = 1.0f / (dvUV);
float2 scaler = max(float2(scalerU, scalerV), 1.0f);
texelUV = clamp(texelUV * scaler, 0.0f, .5f) + clamp(texelUV*scaler - (scaler - .5f), 0.0f, .5f);
uvModified += texelUV;
uvModified /= TEXTURE_DIMENSIONS.xy;
// Update uv
uv = uvModified;
}
return tex.Sample(TextureSampler0, uv);
}
float MakeDepthLinear(float z, float n, float f, bool scaleZ)
{
//Remaps z from [0, 1] to [-1, 1].
if (scaleZ) {
z = 2.f * z - 1.f;
}
return (2.f * n) / (f + n - z * (f - n));
}
float2 computeScreenOffsets(in float3 pos, in float4 data, in float4x4 worldViewProj)
{
float3 normal = data.xyz;
float width = length(normal);
float pixelScale = abs(data.w);
float dir = (data.w < 0) ? -1.f : 1.f;
float4 pos0 = float4(pos, 1.f);
float4 pos1 = float4(pos + normal, 1.f);
pos0 = mul(worldViewProj, pos0);
pos1 = mul(worldViewProj, pos1);
float2 screenNormal = (pos1.xy / pos1.w) - (pos0.xy / pos0.w);
screenNormal = normalize(float2(-screenNormal.y, screenNormal.x));
float w = dot(worldViewProj[3], float4(pos, 1.f));
float pixelRadius = w * pixelScale;
return screenNormal * (dir * width * pixelRadius);
}
// modulo that behaves like glsl (aka: like we actually expect)
float mod(float x, float y)
{
return x - y * floor(x / y);
}