Open fishcu opened 1 month ago
I can at least confirm that lods interpolation is only working with external texture sampling.
I have found that even simple texture()
calls will attempt to use mip-maps if present.
However, they also show the nearest neighbor mip-map level behavior that I have demonstrated above.
It would be better if shader passes as textures behaved the same way as sampling from other "external" textures.
Here's one more example with the accompanying code. A strong deformation is appended to a scanline shader to produce strong aliasing during minimization sampling.
Here's the code for all three images:
// 1. Bilinear interpolation (worst)
// FragColor = vec4(textureLod(Source, uv, 0).rgb, 1.0);
// 2. Bilinear with nearest neighbor mip-mapping (less aliasing, but visible seams)
// FragColor = vec4(texture(Source, uv).rgb, 1.0);
// 3. Anisotropic trilinear filtering (best)
const vec2 d_uv_dx = dFdx(uv) * param.SourceSize.xy;
const vec2 d_uv_dy = dFdy(uv) * param.SourceSize.xy;
const float lambda_base =
max(0.0, 0.5 * log2(max(dot(d_uv_dx, d_uv_dx), dot(d_uv_dy, d_uv_dy))));
float lambda_i;
const float lambda_f = modf(lambda_base, lambda_i);
const vec3 rgb = mix(textureLod(Source, uv, lambda_i).rgb,
textureLod(Source, uv, lambda_i + 1.0).rgb, lambda_f);
FragColor = vec4(rgb, 1.0);
Here are the three images in order:
Description
When using
textureLod
ortextureGrad()
texture sampling with custom screen-space derivatives, the result appears to use nearest-neighbor (NN) mip-map sampling. This results in harsh transitions between mip-map levels.Here's a screenshot showing the actual behavior for![image](https://github.com/libretro/RetroArch/assets/25356186/dd4bb98c-9e1a-42e5-8088-2335d7a76352)
textureGrad()
. This screenshot uses thevulkan
graphics driver.This was tested on different graphics drivers with Slang shaders. The behavior is as follows:
vulkan
: NN mip-map sampling as seen above.glcore
: Same asvulkan
.d3d11
: Mip-map sampling is wholly ignored both fortextureGrad()
andtextureLod()
.d3d12
Same asd3d11
.Here's a screenshot that uses the![image](https://github.com/libretro/RetroArch/assets/25356186/b349ba00-bd9c-4653-b279-ceaee7aef6c2)
d3d12
driver:Expected behavior
I would expect that
textureGrad()
uses proper tri-linear interpolation for smooth anti-aliasing / anisotropy behavior.Here's a simulation of the expected behavior using two texture taps and manual interpolation in the shader code:![image](https://github.com/libretro/RetroArch/assets/25356186/f86a0fc0-a71c-459f-9c56-faa642aaa404)
Actual behavior
See description.
Steps to reproduce the bug
Here's a minimal fragment shader that shows the issue with
textureLod()
:Here's a minimal fragment shader that shows the issue with
textureGrad()
:Make sure to use these minimal examples with a preset that computes mip-map levels properly. Currently, this necessitates a primary "stock" pass to produce the mip-mapping in the first place. Example:
The code for the manual interpolation using 2 taps is as follows:
Bisect Results
Did not do a bisect.
Version/Commit
RA version 1.18.0 Commit hash
72a10eda9a
Environment information