#ifndef MINECRAFT_TEXTURE_SAMPLING_GLSL #define MINECRAFT_TEXTURE_SAMPLING_GLSL vec4 sampleNearest(sampler2D source, vec2 uv, vec2 pixelSize, vec2 du, vec2 dv, vec2 texelScreenSize) { // Convert our UV back up to texel coordinates and find out how far over we are from the center of each pixel vec2 uvTexelCoords = uv / pixelSize; vec2 texelCenter = round(uvTexelCoords) - 0.5f; vec2 texelOffset = uvTexelCoords - texelCenter; // Move our offset closer to the texel center based on texel size on screen texelOffset = (texelOffset - 0.5f) * pixelSize / texelScreenSize + 0.5f; texelOffset = clamp(texelOffset, 0.0f, 1.0f); uv = (texelCenter + texelOffset) * pixelSize; return textureGrad(source, uv, du, dv); } vec4 sampleNearest(sampler2D source, vec2 uv, vec2 pixelSize) { vec2 du = dFdx(uv); vec2 dv = dFdy(uv); vec2 texelScreenSize = sqrt(du * du + dv * dv); return sampleNearest(source, uv, pixelSize, du, dv, texelScreenSize); } // Rotated Grid Super-Sampling vec4 sampleRGSS(sampler2D source, vec2 uv, vec2 pixelSize) { vec2 du = dFdx(uv); vec2 dv = dFdy(uv); vec2 texelScreenSize = sqrt(du * du + dv * dv); float maxTexelSize = max(texelScreenSize.x, texelScreenSize.y); float minPixelSize = min(pixelSize.x, pixelSize.y); float transitionStart = minPixelSize * 1.0; float transitionEnd = minPixelSize * 2.0; float blendFactor = smoothstep(transitionStart, transitionEnd, maxTexelSize); float duLength = length(du); float dvLength = length(dv); float minDerivative = min(duLength, dvLength); float maxDerivative = max(duLength, dvLength); float effectiveDerivative = sqrt(minDerivative * maxDerivative); float mipLevelExact = max(0.0, log2(effectiveDerivative / minPixelSize)); float mipLevelLow = floor(mipLevelExact); float mipLevelHigh = mipLevelLow + 1.0; float mipBlend = fract(mipLevelExact); const vec2 offsets[4] = vec2[]( vec2(0.125, 0.375), vec2(-0.125, -0.375), vec2(0.375, -0.125), vec2(-0.375, 0.125) ); vec4 rgssColorLow = vec4(0.0); vec4 rgssColorHigh = vec4(0.0); for (int i = 0; i < 4; ++i) { vec2 sampleUV = uv + offsets[i] * pixelSize; rgssColorLow += textureLod(source, sampleUV, mipLevelLow); rgssColorHigh += textureLod(source, sampleUV, mipLevelHigh); } rgssColorLow *= 0.25; rgssColorHigh *= 0.25; vec4 rgssColor = mix(rgssColorLow, rgssColorHigh, mipBlend); vec4 nearestColor = sampleNearest(source, uv, pixelSize, du, dv, texelScreenSize); return mix(nearestColor, rgssColor, blendFactor); } #endif