Использование функции floor() в GLSL при выборке текстуры оставляет сбой

Вот шейдерный пример проблемы, которую я вижу:

https://www.shadertoy.com/view/4dVGzW

Я сэмплирую текстуру, сэмплируя координаты текстуры на полу:

#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 пикселя.

Сетка цветов

Обратите внимание, что мы видели эту проблему не только при использовании GLSL ES в Интернете, но и при использовании HLSL в Unity.

Есть ли что-то связанное с floor() и арифметикой с плавающей запятой, чего я не понимаю?! Я хотел бы знать не только, как это исправить, но и почему именно это происходит?


person Joseph Humfrey    schedule 22.01.2016    source источник


Ответы (1)


Оказалось, что для этих линий сетки используется MIP-карта с низкой детализацией из текстуры. Исправлено изменение настроек фильтра текстуры на «ближайшую» или «линейную» фильтрацию, а не на «mipmap».

Также можно вызвать texture2D с третьим параметром «bias», который изменяет, какой уровень mipmap он будет использовать.

Спасибо комментатору на shapertoy за ответ на вопрос!

(Не уверен, как на самом деле уровень MIP-карты выбирается для пользовательских шейдеров без предвзятости, было бы интересно, если бы кто-нибудь знал!)

person Joseph Humfrey    schedule 25.01.2016