суббота, 28 января 2012 г.
пятница, 27 января 2012 г.
iMac Greyish Smudge
Мой iMac 27' уже где-то полтора года в эксплуатации. А сегодня я заметил на его матрице, в правом верхнем углу, странные серые разводы. Я подумал что на фронтальном стекле скопились пыль и жир и протёр его влажной салфеткой. Но оказалось, что это повреждения IPS матрицы, а не грязь на стекле.
Я прошёл по офису и выяснил, что подобные пятна появились и на других iMac-ах, в основном в правом верхнем углу. Ну и наконец Google подсказал, что это распространённый дефект этих моноблоков: пользователи жалуются.
Думаю, через два-три года там образуется порядочное серое пятно :(
Я прошёл по офису и выяснил, что подобные пятна появились и на других iMac-ах, в основном в правом верхнем углу. Ну и наконец Google подсказал, что это распространённый дефект этих моноблоков: пользователи жалуются.
Думаю, через два-три года там образуется порядочное серое пятно :(
понедельник, 23 января 2012 г.
DirectGL progress
Завершил работу над функциями по загрузке 2D-текстур. Решено реализовать только загрузку BMP, TGA и DDS форматов (без поддержки расширений DX10, т. к. они всё равно не применимы в DX9-рендере). Я написал простой unit test который грузит DDS текстуры разных форматов (как сжатые, так и различных форматов вида RGB8, R5G6B5 и т. д.), а фактически текстуры разделены на два лагеря - несжатые RGBA8 и сжатые DXT, всё остальное практически никогда не используется для хранения в видеопамяти. Для полноты необходимо реализовать ещё загрузку cubemap текстуры из DDS, но это если руки дойдут.
Решено также постепенно подключать к проекту различные unit test-ы, как это практикуется в Wine, чтобы тестировать враппер на соответствие реальному поведению рантайма Direct3D. Из того же Wine эти тесты и думаю заимствовать (как-никак open source).
Также заставил работать через враппер два сэмпла из DirectX 9 SDK - EmptyProject и SimpleSample. Как и другие примеры они интенсивно используют DXUT, так что это хороший тест "на прочность". Но тут обнаружился интересный баг - шрифт рисуется в бэк-буфер перевернутым по оси ординат:
Тут нужно отметить, что при портировании Direct3D кода на OpenGL есть один неприятный момент: начало системы текстурных координат Direct3D находится в левом верхнем углу, тогда как в OpenGL - в левом нижнем. Для обычных текстур это не имеет значения, т. к. похоже драйвер правильно укладывает их в память (или железо вычисляет адрес в памяти) в зависимости от используемого API. Но с render target текстурами при их семплировании в шейдере приходится инвертировать текстурные координаты по оси Y. Это решение имеет по крайней мере два недостатка:
1) Необходимо пересмотреть код всех шейдеров и в тех местах, где семплируется render target, поправить текстурные координаты.
2) Возможны случаи, когда в шейдер на один и тот же текстурный слот попеременно передаётся обычная текстура и render target. Тут приходится заводить дополнительный булевый флажок либо создавать отдельный шейдер для каждого случая. При использовании флажка, если он по какой-то причине не отражает реальное положение дел (упустили где-то, энджин-то большой), изображение нарисуется перевёрнутым.
Оба эти решения являются неприемлемыми.
Как компромисс, мною решено менять матрицу проекции так, чтобы растеризуемая геометрия рисовалась в render target с инвертированием по оси ординат. Позже, при семплировании этого render target в шейдере, произойдёт восстановление правильного изображения. Обычно в коде достаточно мало мест, где устанавливается матрица проекции для вершинного шейдера (или TnL), или мы можем знать номер регистра, по которому лежит первая строка (столбец) матрицы, поэтому внести поправки в этом случае легче, чем в остальных.
Если же использовать этот метод, то любые другие способы записи в render target (например, отображение шрифта силами GDI), не проходят преобразование матрицей, и попадают в render target с исходными координатами - соответственно при семплировании в шейдере изображение перевернётся. Впрочем, это минорный недостаток, в реальных играх вся графика полигональна.
Общий вид GDI текста с инвертированием текстурных координат:
Как видно, теперь перевернулись элементы интерфейса, нарисованные с помощью полигонов. Надеюсь, дилемма понятна.
Из спортивного интереса хочется, чтобы пример всё-таки работал корректно! Я думаю, что наиболее красивым решением будет рисовать строки текста в промежуточную текстуру, которую потом натягивать на полоски геометрии, имеющие положение и размерности рисуемой строки.
Решено также постепенно подключать к проекту различные unit test-ы, как это практикуется в Wine, чтобы тестировать враппер на соответствие реальному поведению рантайма Direct3D. Из того же Wine эти тесты и думаю заимствовать (как-никак open source).
Также заставил работать через враппер два сэмпла из DirectX 9 SDK - EmptyProject и SimpleSample. Как и другие примеры они интенсивно используют DXUT, так что это хороший тест "на прочность". Но тут обнаружился интересный баг - шрифт рисуется в бэк-буфер перевернутым по оси ординат:
Тут нужно отметить, что при портировании Direct3D кода на OpenGL есть один неприятный момент: начало системы текстурных координат Direct3D находится в левом верхнем углу, тогда как в OpenGL - в левом нижнем. Для обычных текстур это не имеет значения, т. к. похоже драйвер правильно укладывает их в память (или железо вычисляет адрес в памяти) в зависимости от используемого API. Но с render target текстурами при их семплировании в шейдере приходится инвертировать текстурные координаты по оси Y. Это решение имеет по крайней мере два недостатка:
1) Необходимо пересмотреть код всех шейдеров и в тех местах, где семплируется render target, поправить текстурные координаты.
2) Возможны случаи, когда в шейдер на один и тот же текстурный слот попеременно передаётся обычная текстура и render target. Тут приходится заводить дополнительный булевый флажок либо создавать отдельный шейдер для каждого случая. При использовании флажка, если он по какой-то причине не отражает реальное положение дел (упустили где-то, энджин-то большой), изображение нарисуется перевёрнутым.
Оба эти решения являются неприемлемыми.
Как компромисс, мною решено менять матрицу проекции так, чтобы растеризуемая геометрия рисовалась в render target с инвертированием по оси ординат. Позже, при семплировании этого render target в шейдере, произойдёт восстановление правильного изображения. Обычно в коде достаточно мало мест, где устанавливается матрица проекции для вершинного шейдера (или TnL), или мы можем знать номер регистра, по которому лежит первая строка (столбец) матрицы, поэтому внести поправки в этом случае легче, чем в остальных.
Если же использовать этот метод, то любые другие способы записи в render target (например, отображение шрифта силами GDI), не проходят преобразование матрицей, и попадают в render target с исходными координатами - соответственно при семплировании в шейдере изображение перевернётся. Впрочем, это минорный недостаток, в реальных играх вся графика полигональна.
Общий вид GDI текста с инвертированием текстурных координат:
Как видно, теперь перевернулись элементы интерфейса, нарисованные с помощью полигонов. Надеюсь, дилемма понятна.
Из спортивного интереса хочется, чтобы пример всё-таки работал корректно! Я думаю, что наиболее красивым решением будет рисовать строки текста в промежуточную текстуру, которую потом натягивать на полоски геометрии, имеющие положение и размерности рисуемой строки.
четверг, 19 января 2012 г.
понедельник, 16 января 2012 г.
четверг, 12 января 2012 г.
30
Вот так вот живёшь, крутишься, чего-то добиваешься...
А тут тебе, хлоп - тридцать лет стукнуло :)
А тут тебе, хлоп - тридцать лет стукнуло :)
пятница, 6 января 2012 г.
Stereo Texture
Пока мы все вынуждены ждать Direct3D 11.1, где появится нэйтивная поддержка стереоскопии, под DirectX 9 для всяких этих ваших ассассинов кридов приходится использовать различные хаки, чтобы улучшить поддержку стерео.
Механизм, через который работает 3D Vision на картах NVidia, довольно прост - драйвер добавляет footer в каждый вершинный шейдер таким образом, чтобы позиция вершины в clip space различалась для правого и левого кадра (см. NVIDIA 3D Vision Automatic Best Practices Guide). Таким образом стерео автоматически работает в большинстве трёхмерных игр и даже тех, которые изначально под него не разрабатывались.
Проблемы начинаются в случаях, если при рендеринге использовались какие-то нечестные техники или в случае различных deferred подходов - картинка обычно выглядит неестественно, если не сказать хуже. 3D Vision работает на уровне геометрического пайплайна, во всех остальных случаях нужно что-то делать руками самостоятельно. Вот недавно по работе мне было поручено исправить некоторые огрехи нашего движка при работе в стерео-режиме. Как выяснилось, одна из техник использовала механизм отложенного рендеринга партиклов, при котором цвет и дополнительная информация сначала рисуются в промежуточный render target, а потом изображение из него "вклеивается" в основной кадр. Понятно, что 3D Vision проплывает в этом случае по левому борту, и необходимы поправки уже в пиксельном шейдере. Но вот загвоздка - стандартными средствами Direct3D выяснить какой из кадров - правый или левый, рисуется в данный момент - в шейдере невозможно, а без возможности их различать нет и возможности что-либо изменить.
Начав искать в Сети методы решения подобных проблем, я обнаружил, что NVidia предоставляет пример StereoIssues в NVIDIA Graphics SDK 11, в котором имеется код по созданию специальной "стереотекстуры" (файл nvstereo.h). Стереотекстура позволяет семплировать в шейдере данные, которые будут различаться для левого и правого кадра, так что, например, можно вычислить смещение для каждого кадра по формуле:
Это очередной хак на уровне D3D9/10 API, и для его включения необходимо разместить fourcc 'NV3D' в последней строке staging текстуры формата RGBA32F, данные из которой впоследствии необходимо скопировать в обычную текстуру посредством UpdateSurface()/CopySubresourceRegion(). При копировании драйвер разместит данные для левого кадра в целевой текстуре, а для правого (как я понимаю) создаст shadow copy и разместит в ней данные для правого кадра, взяв их по определённому адресу (см. раздел 3D Video в GDC09 3DVision The In and Out). Если всё сделать в том порядке, который предлагается в примере, то шейдер действительно будет семплировать различные данные по одним и тем же текстурным координатам. Ну а дальше уже дело техники...
Одним из подводных камней, о который я споткнулся, является то, что недостаточно просто при старте скопировать данные в стереотекстуру и в дальнейшем пользоваться ею. Всё дело в том, что 3D Vision не включается с первым же кадром: драйвер сначала собирает некоторую информацию о первых кадрах, и только потом включается стереорежим. После его включения и нужно создавать стереотекстуру, а лучше всего проверять переключение режимов функцией NvAPI_Stereo_IsActivated() из NvAPI, и обновлять её после изменения результата. А в примере StereoIssues идут ещё дальше: т. к. пользователь может динамически изменять такие параметры 3D Vision как EyeSeparation и Convergence, то необходимо отслеживать изменения этих параметров и своевременно обновлять данные в стереотекстуре.
Механизм, через который работает 3D Vision на картах NVidia, довольно прост - драйвер добавляет footer в каждый вершинный шейдер таким образом, чтобы позиция вершины в clip space различалась для правого и левого кадра (см. NVIDIA 3D Vision Automatic Best Practices Guide). Таким образом стерео автоматически работает в большинстве трёхмерных игр и даже тех, которые изначально под него не разрабатывались.
Проблемы начинаются в случаях, если при рендеринге использовались какие-то нечестные техники или в случае различных deferred подходов - картинка обычно выглядит неестественно, если не сказать хуже. 3D Vision работает на уровне геометрического пайплайна, во всех остальных случаях нужно что-то делать руками самостоятельно. Вот недавно по работе мне было поручено исправить некоторые огрехи нашего движка при работе в стерео-режиме. Как выяснилось, одна из техник использовала механизм отложенного рендеринга партиклов, при котором цвет и дополнительная информация сначала рисуются в промежуточный render target, а потом изображение из него "вклеивается" в основной кадр. Понятно, что 3D Vision проплывает в этом случае по левому борту, и необходимы поправки уже в пиксельном шейдере. Но вот загвоздка - стандартными средствами Direct3D выяснить какой из кадров - правый или левый, рисуется в данный момент - в шейдере невозможно, а без возможности их различать нет и возможности что-либо изменить.
Начав искать в Сети методы решения подобных проблем, я обнаружил, что NVidia предоставляет пример StereoIssues в NVIDIA Graphics SDK 11, в котором имеется код по созданию специальной "стереотекстуры" (файл nvstereo.h). Стереотекстура позволяет семплировать в шейдере данные, которые будут различаться для левого и правого кадра, так что, например, можно вычислить смещение для каждого кадра по формуле:
pos.x += separation * (pos.w - convergence)
Это очередной хак на уровне D3D9/10 API, и для его включения необходимо разместить fourcc 'NV3D' в последней строке staging текстуры формата RGBA32F, данные из которой впоследствии необходимо скопировать в обычную текстуру посредством UpdateSurface()/CopySubresourceRegion(). При копировании драйвер разместит данные для левого кадра в целевой текстуре, а для правого (как я понимаю) создаст shadow copy и разместит в ней данные для правого кадра, взяв их по определённому адресу (см. раздел 3D Video в GDC09 3DVision The In and Out). Если всё сделать в том порядке, который предлагается в примере, то шейдер действительно будет семплировать различные данные по одним и тем же текстурным координатам. Ну а дальше уже дело техники...
Одним из подводных камней, о который я споткнулся, является то, что недостаточно просто при старте скопировать данные в стереотекстуру и в дальнейшем пользоваться ею. Всё дело в том, что 3D Vision не включается с первым же кадром: драйвер сначала собирает некоторую информацию о первых кадрах, и только потом включается стереорежим. После его включения и нужно создавать стереотекстуру, а лучше всего проверять переключение режимов функцией NvAPI_Stereo_IsActivated() из NvAPI, и обновлять её после изменения результата. А в примере StereoIssues идут ещё дальше: т. к. пользователь может динамически изменять такие параметры 3D Vision как EyeSeparation и Convergence, то необходимо отслеживать изменения этих параметров и своевременно обновлять данные в стереотекстуре.
четверг, 5 января 2012 г.
Игры
Я работаю в Ubisoft не потому, что мне нравится играть в игры, а просто потому, что мне нравится их программировать :)
Intel Celeron M
Из-за того, что в моём ноуте стоит сабжевый процессор, IE 8 на нём безбожно тормозит и сёрфинг по Сети лишь раздражает. Ситуация с Opera лишь чуть лучше. По законам копроэкономики я как потреблядь должен был побежать в магазин и прикупить что-нить с намного более мощным CPU (желательно с 4-мя ядрами!). Но вот незадача, Google Chrome на текущей конфигурации летает.
Не пишите говнософт.
Не пишите говнософт.
понедельник, 2 января 2012 г.
ТВ
По случаю Нового года довелось посмотреть телевизор.
Я смотрю, его прямо оккупировали, каждый год одни и те же рожи! Все сытые и довольные, с улыбками поздравляют нас и как всегда желают быть счастливыми! Сколько, интересно, им это стоит и кому на это жаловаться?
P.S. Да ещё этот ваш карлик, карманный президент, выскочит в перерыве на экран и в двух словах расскажет, как у вас там всё пиздато, и что Россия катится полным ходом в светлое будущее.
Я смотрю, его прямо оккупировали, каждый год одни и те же рожи! Все сытые и довольные, с улыбками поздравляют нас и как всегда желают быть счастливыми! Сколько, интересно, им это стоит и кому на это жаловаться?
P.S. Да ещё этот ваш карлик, карманный президент, выскочит в перерыве на экран и в двух словах расскажет, как у вас там всё пиздато, и что Россия катится полным ходом в светлое будущее.
Подписаться на:
Сообщения (Atom)