在对纹理进行采样时在 GLSL 中使用 floor() 函数会留下故障
Using floor() function in GLSL when sampling a texture leaves glitch
这是我遇到的问题的 shadertoy 示例:
https://www.shadertoy.com/view/4dVGzW
我正在通过从 floor-ed 纹理坐标采样来采样纹理:
#define GRID_SIZE 20.0
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
// Sample texture at integral positions
vec2 texUV = floor(uv * GRID_SIZE) / GRID_SIZE;
fragColor = texture2D(iChannel0, texUV).rgba;
}
我看到的错误是 有时 在网格方块之间绘制了 1-2 条像素线。
请注意,我们不仅在 Web 上使用 GLSL ES,而且在 Unity 中使用 HLSL 也看到了这个问题。
floor()
和浮点运算有什么我不懂的吗?!我不仅想知道如何修复它,还想知道 为什么 它会发生?
原来是在为这些网格线使用纹理中的低细节 mipmap。将纹理上的过滤器设置更改为 "nearest" 或 "linear" 过滤而不是 "mipmap" 修复了它。
也可以使用第三个 "bias" 参数调用 texture2D,该参数修改它将使用的 mipmap 级别。
感谢shadertoy的评论者回答问题!
(不确定如何在没有偏差的情况下为自定义着色器实际选择 mipmap 级别,如果有人知道会很感兴趣!)
这是我遇到的问题的 shadertoy 示例:
https://www.shadertoy.com/view/4dVGzW
我正在通过从 floor-ed 纹理坐标采样来采样纹理:
#define GRID_SIZE 20.0
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
// Sample texture at integral positions
vec2 texUV = floor(uv * GRID_SIZE) / GRID_SIZE;
fragColor = texture2D(iChannel0, texUV).rgba;
}
我看到的错误是 有时 在网格方块之间绘制了 1-2 条像素线。
请注意,我们不仅在 Web 上使用 GLSL ES,而且在 Unity 中使用 HLSL 也看到了这个问题。
floor()
和浮点运算有什么我不懂的吗?!我不仅想知道如何修复它,还想知道 为什么 它会发生?
原来是在为这些网格线使用纹理中的低细节 mipmap。将纹理上的过滤器设置更改为 "nearest" 或 "linear" 过滤而不是 "mipmap" 修复了它。
也可以使用第三个 "bias" 参数调用 texture2D,该参数修改它将使用的 mipmap 级别。
感谢shadertoy的评论者回答问题!
(不确定如何在没有偏差的情况下为自定义着色器实际选择 mipmap 级别,如果有人知道会很感兴趣!)