Как стать автором
Обновить

Укрощаем числа с плавающей точкой. Возможна ли отладка шейдеров для мобильных устройств на ПК?

Время на прочтение4 мин
Количество просмотров5.6K
Всего голосов 21: ↑19 и ↓2+17
Комментарии11

Комментарии 11

Да, сталкивался с таким. Но решал через '%'. И тут забавная штука. Два шейдера в одном проекте. В одном процент работает, в другом — ругается. Не помню деталей, но помню что так и не допер, в чем была разница.
Нужно обмануть компилятор, который автоматически сократит операции. Для этого мы вносим незначительную погрешность в число после увеличения.


Пример кода не помешал бы, пожалуй. Ибо очень долго думал над тем, что вы имеете в виду, прежде чем понял.
Пример кода сильно зависит от текущей платформы движка и компилятора. Но общий подход такой:
например, пусть Х — наше число, а Y — достаточно большое число для перегрузки.

Если написать: X = (X+Y)-Y, то компилятор сократит Y и получится X=X.
А если сделать: X = (X+Y)*0.00001 — Y, то все будет хорошо, но мы добавили погрешность.
Пример кода приведен в ответе выше.
Пусть Х — наше число, а Y — достаточно большое число для перегрузки.

Если написать: X = (X+Y)-Y, то компилятор сократит Y и получится X=X.
А если сделать: X = (X+Y)*0.00001 — Y, то все будет хорошо, но мы добавили погрешность.
Я так понял что проблема была в том что текстурные координаты «уползали» до больших порядков и больше не влазили в разрядность?

Тогда править нужно на стороне хоста, особенно если вы так жестко лимитируете бюджет. Чем делать frac в шейдере уж лучше «обрезать» оффсет на хосте и засылать в шейдер нормализованное смещение.

В таком случае вы, в принципе, не ограничены точностью и в основном коде хоть double используйте.
Именно так мы и делаем. Мы и обрезаем время на хосте и также имеем возможность проверить, помещаются ли наши числа после операций в самом шейдере в разрядность 16 бит.
Лучше «обрезать» не время, а уже конечный параметр материала.
К примеру у вас есть некий «float2 uvOffset» — вот он и должен «обрезаться» на хосте, заодно и ALU сбережете.

Но мне осталось непонятно одно — вы в заголовке поставили вопрос «Возможна ли отладка шейдеров для мобильных устройств на ПК?» и так на него и не ответили.
Если время начнет «сбоить» то и uvOffset «поплывет», так что проблему нужно на корню решать.
Вспомним, как в двоичной системе выглядят числа с плавающей точкой.

Небольшая опечатка на картинке. «7 цифр. Значение. 32 бита». Должно быть 23 бита.
Извиняюсь за занудство)

А вообще статья полезная, спасибо.
Спасибо.

Картинку уже заменили.

И спасибо за отзыв о статье.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий