воскресенье, 26 июля 2009 г.

Портрет Дориана Грея

Однажды талантливый художник Бэзил Холлуорд написал портрет молодого и красивого человека по имени Дориан Грей. Дориан был так юн и прекрасен, а портрет так хорош, что в него влюбился сам Дориан. Под влиянием лорда Уоттона, который считал, что жить стоит только ради красоты, Дориан понимает, что его портрет будет всегда обладать тем, чего он неизбежно лишится - молодости. Вот если бы портрет старел, а я - оставался вечно молодым... Я бы душу дьяволу продал за это! - думал Дориан. Желание Дориана исполнилось, и это привело его к аморальному образу жизни. При этом он остался всё тем же прекрасным юношей, а все его грязные поступки запечатлелись на портрете, который он прятал в отдельной комнате, подальше от чужих глаз...

Но сегодня мне хотелось бы написать не о Дориане Грее, а (странное совпадение) его однофамильце, британском геронтологе Обри ди Грее. Как и литературный персонаж, ди Грей не приемлет старение, не считает его "естественным ходом вещей" и является активным борцом за как можно большее продление жизни отдельно взятого индивидуума. Этот странный человек с очень умным взглядом, длинной рыжей бородой и любовью к неформальной одежде (больше похож на обкуренного хиппи :) уже N-ный год пытается убедить научное сообщество, что мы на пороге Конца Старения (End of Ageing).

Геронтология как бы и не совсем новая наука (возникла около столетия назад), но вопросам старения не уделялось большого внимания, видимо считая "так было и будет всегда, что же тут можно поделать?". Но в данном случае ди Грей разработал широкомасштабный план борьбы со старостью - SENS (Стратегия достижения пренебрежимого старения инженерными методами) и стал первым, кто явно перечислил вероятные причины старения и возможные способы их устранения. По классификации ди Грея, существует 7 основных причин, приводящих к старению организма:

1) Исчезновение клеток без появления новых (Cell loss and atrophy).
2) Накопление внеклеточных шлаков (Accumulated extracellular chemical 'junk').
3) Внеклеточные перекрёстные связи белков (Glycation cross-links in extracellular proteins).
4) Устойчивые к разрушению клетки (Death-resistance cells). Т. е. жировые клетки, клетки в хрящах и т. п.
5) Мутации в митохондриях и повреждение окислами (Mitochondrial mutation and oxidative damage).
6) Накопление внутриклеточных шлаков (Accumulated intracellular chemical 'junk').
7) Хромосомные мутации (Nuclear (epi)mutations (cancer)).

Цель программы SENS – создание доступной для каждого человека технологии, при помощи которой можно восстанавливать организм до любой степени омоложения и поддерживать его в таком состоянии в течение любого времени. По мнению ди Грея, большая часть фундаментальных исследований, необходимых для создания эффективной «медицины антистарения» (anti-aging medicine), уже проведены. В настоящий момент главная проблема — недостаток финансирования работ в этой области. Для старта ди Грей просит 1 млрд долларов, и где-то проскальзывала цифра, что для эффективного решения проблемы необходимо финансирование в размере 25 млрд долларов.

Ди Грей стал одним из основателей Фонда Мафусаила, главной целью которого является увеличение продолжительности жизни мыши (для примера - продолжительность жизни обычной домовой мыши составляет 2-3 года). По его мнению, если удастся лабораторными методами продлить её жизнь в два-три раза, то тогда финансирование подобных исследований увеличится, что ускорит решение проблемы.

Вот некоторые ссылки по теме:
Обри ди Грей
Инженерные стратегии пренебрежимого старения (SENS)
Обри ди Грей: Как отменить старение

Вообще эта тема меня серьёзно заинтересовала, думаю, на страницах этого блога она всплывёт ещё не раз :)

вторник, 21 июля 2009 г.

Быстрые лифты

Позавчера вечером, стоя и ожидая лифта, в голову пришла забавная мысль.

Вечером все обычно расползаются по своим квартирам (на N-ых этажах), т. е. вниз спускаются редко, поэтому обычно лифт торчит где-то наверху и приходится ждать, пока он, сволочь, изволит доползти до первого этажа. Если делать лифт для людей, было бы рациональнее вечером, после того как он поднялся наверх, автоматически спускать его вниз, а для экономии энергии - не на первый, а хотя бы на третий этаж. Аналогично и утром, когда все ждут, пока он поднимется с первого этажа, для уменьшения ожидания - поднимать его на на 6-7 этаж (в 9-ти этажном здании). Затраты энергии? Ну лифт же пустой, расходуется минимум по сравнению со случаем, когда в нём едут 2-3 человека весом 50-80 кг каждый.

Вообще идея стара как мир, и умные системы лифтов с заоптимайзенным соотношением время_ожидания/расход_электроэнергии существуют (например AI Supervisory Control 2200), но т. к. мы живём сами понимаете в какой стране, то такого чуда нам никогда не видать как своих ушей.

How to protect your Intellectual Property

Tamir Khason – Just code
Небольшая заметка о Microsoft Software Licensing and Protection Services для .NET.

Предоставляется некий SLP сервис, при котором ваша функция может выполняться на удалённом сервере, а не на машине клиента. Подобная идея пришла и ко мне в голову в прошлом году, только применительно к играм.

Широкополосный интернет породил проблему, он же её и убъёт.

воскресенье, 19 июля 2009 г.

Real-time reflection/refraction

Нашёл способ редактировать блог при блокировке https, по этому поводу надо что-то написать :).

Решил провести некоторый research c отражениями и преломлениями. Как известно, для растеризатора это большая проблема, и если отражения ещё можно как-то делать (на машинах там, или на всяких рюмках), то с преломлениями всё очень непросто. Дело в том, что для сложных прозрачных тел луч может преломляться по крайней мере несколько раз, и в случае растеризации найти, с какой геометрией соприкоснулся преломлённый луч, с кондачка не получится. Эта задача элементарно решается в случае рэйтрейсинга, но на сегодняшний день осуществить его на commodity hardware с нормальной скоростью не представляется возможным. Ждать появления рэйтрейсинга долго и не интересно, а красивых преломлений в real-time хочется уже сейчас, благо железо позволяет извращаться :)

Простейший способ учесть back-face refraction - это отрисовать back-face нормали с тестом глубины GREATER, и смешать front-face и back-face нормали с каким-нить весом, скажем, 0.77. Понятно, что это дедовский способ, но выглядит лучше, чем one-sided вариант. Есть подходы с различными аппроксимациями (Chris Wyman). Тоже в топку. Наиболее правильное решение - это делать рэйтрейсинг преломлённого луча прямо в image-space z-буфера.

Основная идея такая: имеем точку, где выпущенный из камеры луч соприкосается с front-face геометрией преломляющего тела. Находим преломлённый луч, и вытягиваем его до far plane. После этого идём по лучу, отсчитывая на нём позиции с заданным количеством шагов, проецируем их в image space и сравниваем с позицией в z-буфере. Позицию с ближайшим z-значением используем для выборки back-face нормали, которую используем для повторного преломления луча. Затем делаем выборку из кубической карты.
Interactive Image-Space
Refraction of Nearby Geometry

Это работает, но ограниченное кол-во выборок на луче приводит к тому, что мы находим только приблизительно место пересечения луча и геометрии, а это приводит к артефактам изображения. Можно увеличить кол-во выборок (> 8), но производительность начинает падать, а артефакты лечатся плохо. Более правильный подход - binary search на луче.
Interactively Rendering Dynamic Caustics on GPU
(Работа по каустикам, но это не суть важно).
Если тело более-менее выпуклое (а не вогнутое или другой сложной формы), можно за ограниченное кол-во выборок точно найти, где луч соприкасается со второй поверхностью, и использовать эти данные для повторного преломления луча.


Как правильно заметили Oliveira и Brauwers, прямой binary search может давать сбои, в случае если луч сильно отклоняется за пределы преломляющей среды и мы можем сделать выборку в невалидной области image space. Чтобы забороть это, необходимо использовать conservative binary search, т. е. прежде чем разделить луч надвое, нужно проверить, валидна ли область выборки. Если нет, то вторая половина луча отбрасывается, а первая снова делится надвое с проверкой на валидность деления.
Real-Time Refraction Through Deformable Objects
В общем, данная методика позволяет правильно учитывать преломление луча двумя поверхностями, чего обычно бывает достаточно. В принципе можно попробовать и для сложных моделей, с многократным преломлением луча, используя depth peeling или k-buffer для сохранения и сортировки преломляющих поверхностей, но это уже в некоторой степени изврат :(

Зачем нужны все эти сложности с точным поиском пересечения? Дело в том, что у меня есть идея получения преломлённого изображения тела, помещённого внутрь другого (жидкого) тела. Более конкретно - нужно засунуть некоего монстра в контейнер с биожидкостью, где он спокойно плавает и красиво так искажается по Френелю :-))). Стоит задача поиска пересечения луча не только со второй поверхностью, но и с поверхностью другого тела внутри преломляющего тела. Если делать это лишь приблизительно, то конечный результат будет неудовлетворительным.

Другая проблема, связанная с артефактами, заключается в том, что преломлённое изображение внутреннего тела получается больше, чем то, что отрисовывалось в буфер для последующей выборки, вследствие того, что преломляющее тело выступает в роли линзы. При этом часть пикселей растягивается, что неэстетично. Можно как-то фильтровать, но отдача от этого небольшая, изображение больше замыливается, а края всё равно рваные. Тут просто недостаток precomputed данных, поэтому нужно попробовать рисовать в двое большее, чем номинальное, разрешение, там же искать преломление, а уже потом делать downsampling полученного изображения и вклеивать его в кадр. +При поиске преломления делать несколько выборок вокруг найденных uv координат и усреднять цвет.

И последнее, кубические карты. Для повышения реализма хочется, чтобы не всё тело было жидким, а только 2/3 от него, но оставшаяся треть продолжала производить незначительные преломления из-за свойств стекла. Вот ссылка на видео, как это приблизительно должно выглядеть:
Glass in 3d max
(если кто знает, как напрямую вставлять видео с ютюба в блоггер, буду рад совету).

Если делать не по-пацански, то нужно два cubemap-а. Первый - рендерится из камеры, используется для преломлений только от стекла (луч, выпущенный из камеры, испытывает незначительное преломление, поэтому погрешности неважны). Второй cubemap рендерится из центра преломляющего объекта. Зачем? Потому что луч уже после первого (заметного) преломления жидкостью "видит" сцену уже другой, нежели она видна из камеры, и если расстояние между камерой и преломляющим телом более-менее значительно, преломлённое изображение из первого cubemap будет неправильным. Это легко представить, если вообразить, что рядом с преломляющим телом есть какой-то предмет. Преломлённый луч видит его "вблизи", а не так как он виден из камеры. Если не использовать второй корректирующий cubemap, то мы будем видеть просто искажённое изображение из первого. И наоборот, со вторым cubemap-ом должен возникать true эффект линзы. Кроме того, второй cubemap нужен для правильных отражений.

Пока это всё только спекуляции, большая часть этого ещё не реализована. Главное сейчас - понять, как сделать :)