Повторяющиеся текстуры сильно искажаются / дрожат при вращении камеры - PullRequest
6 голосов
/ 09 января 2012

Первоначально я задавал этот вопрос на gamedev , но ни один из ответов не помог решить проблему, и я до сих пор не понимаю, что является настоящей причиной.Я ничего не видел о повторной публикации вопросов в SE в FAQ, поэтому я могу только надеяться, что это нормально.Более того, в ретроспективе вопрос, вероятно, больше связан с графическим программированием в целом, чем просто с разработкой игр.

Редактирование 1 начинается

Поведение исходного поста относится только к Windows XP и Windows 7, браузерам Firefox и Chrome.В Ubuntu таких искажений нет, но вместо этого текстуры «трясутся» во время вращения камеры.Когда вращение прекращается, встряхивание прекращается, но текстуры могут находиться не в полностью правильном положении.

Правка 1 заканчивается

Правка 3 начинается

Программа была протестирована на 4 разных компьютерах и не работала должным образом ни на одном из них.

Редактировать 3 конца

У меня есть большой воксель в WebGL, который я хочу покрыть мозаичной текстурой, каждая плитка имеет длину стороны 1 в пространстве вершин.В этом тестовом сценарии камера указывает на отрицательное направление z, а стороны вокселя находятся в плоскостях xy, xz, yz.

Меньшие воксели (то есть меньшее количество повторов) работают довольно хорошо, но около 2000x и y повторяются для каждого лица (то есть размер вокселя 2000 *2000* 2000), текстуры начинают выглядеть очень некрасиво.Когда камера направлена ​​перпендикулярно лицу, текстуры выглядят правильно, независимо от размера / количества повторов, но для вокселей упомянутого выше размера любое вращение даже на пару градусов вызывает видимую проблему.Увеличение размера вокселя увеличивает искажение.Обратное также верно: с небольшими вокселями текстуры выглядят корректно независимо от вращения камеры.Мне кажется, что нет жесткого порогового значения для размера, но эффект начинает постепенно увеличиваться с нуля, когда воксел увеличивается в размере от приблизительно 2000 на сторону.

См. http://imgur.com/a/spQIv для визуализации.Первое изображение - это то, как оно должно выглядеть, но когда камера поворачивается, линии начинают искажаться, как на втором изображении.Эффект усиливается при увеличении размера вокселя и при вращении камеры.http://imgur.com/a/wRndy содержит два дополнительных изображения с более серьезным эффектом.

Текстуры (по одному X на текстуру) изначально имеют размер 512 * 512 пикселей.Скриншоты никак не масштабировались.

Моим первым предположением были неточности с плавающей точкой, но в это трудно поверить, поскольку объект имеет только размеры порядка 1000.

Моя втораядумаю, это была какая-то странная ошибка округления int / float, но так как все всегда обрабатывается в float, я не понимаю, как это могло произойти.

Третья возможность, о которой я мог подумать, это то, что это просто невозможнои что текстуры не должны повторяться столько раз.Однако это кажется маловероятным ИМО.Я предполагаю (и надеюсь), что есть какая-то довольно элементарная проблема.

Любые предложения о том, что может вызывать или обычно вызывает такие вещи, высоко ценятся, потому что у меня, кажется, очень трудная задача.Я пытаюсь сузить источник этой проблемы самостоятельно.

Я использую:

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.generateMipmap(gl.TEXTURE_2D);

и в шейдере:

#ifdef GL_ES
precision highp float;
#endif

Я такжевыполнил несколько очень элементарных вычислений: для 32-битных операций с плавающей запятой максимальное значение составляет около 8,4 миллиона.Для длины стороны вокселя 2000 (которую я заметил, был уровень, где эффект стал видимым), можно было наивно ожидать приблизительно 0,00025 от ошибки округления с плавающей точкой в ​​координатах.Предполагая, что каждый повтор занимает около 100 пикселей на экране, ошибка должна быть значительно меньше 1 пикселя, что не так.Если мой расчет выше не был сделан неправильно, я бы поэтому сказал, что Float32 не виноват, и причина должна быть в другом месте.

Текстура линии используется только для визуализации проблемы.Проблема сохраняется и с другими (более естественными) видами текстур.

Редактирование 2 начинается

Включение или отключение сглаживания не делает видимой разницы

Редактировать 2 конца

Ответы [ 2 ]

6 голосов
/ 10 января 2012

Я верю, что то, что вы видите, действительно может быть вызвано прецедентом. Вы правильно рассчитали, что координаты с плавающей точкой должны быть достаточно хорошими, проблема в том, что аппаратное обеспечение не , используя поплавки для поиска текстур. Блоки текстурного интерполятора имеют значительно меньшую точность (не знаю, как сегодня, но на старых картах GeForce он был всего 16 бит).

Итак ... как можно превысить точность интерполятора? Используя большие текстурные координаты (многократные повторения) на большой геометрии, это именно то, что вы делаете. Способ устранения? Разделите вашу геометрию, чтобы использовать меньшие текстурные координаты (вы можете смещать текстурные координаты целыми шагами, чтобы они были ближе к 0).

Вот скриншот того, как экстремально это может выглядеть (я не смог воспроизвести ошибку на моем GeForce 260, но он хорошо виден на моем планшете Tegra 2, как показано на изображение ниже).

2 голосов
/ 03 мая 2013

Я столкнулся с подобной проблемой под iOS. После повторения текстуры 127 раз, плохие вещи начали происходить.

Решение, которое сработало, было следующим:

Я использовал GL_TRIANGLE_STRIP с некоторыми вырожденными треугольниками. Текстура выровнена по вершинам, поэтому на краю текстуры есть невидимый (вырожденный) треугольник, где текстура «отображается» зеркально, когда я устанавливаю координату текстуры в начало координат. Таким образом, следующий видимый треугольник показывает текстуру с координатой (0.0, 0.0), и она никогда не выходит за координату (x, 127.0).

В блоге объясняется это с некоторыми примерами и фотографиями.

...