Как равномерно применить яркость к частям волос с помощью OpenGL с помощью шейдеров GLSL?

Я создал прическу в Blender 2.66, используя систему частиц волос. Это выглядит так:

введите описание изображения здесь

Как видите, яркость была применена к фрагментам линий. После преобразования я экспортировал свою сетку прически в формат файла OBJ. Я проанализировал это в своей программе, и рендер выглядит так:

введите описание изображения здесь

Частицы были нарисованы как GL_LINES (в моем файле OBJ у меня есть 2 вершины на грань).

В другой тестовой программе я хотел проверить светимость с помощью простого фрагмента линии. Вот мои буферы вершин:

static GLfloat vertices[6] =
{
    0.000000f, 0.000000f, -2.000000f,
    0.000000f, 0.000000f, 2.000000f
};

static GLfloat normals[6] =
{
    0.000000f, 1.000000f, 0.000000f,
    0.000000f, 1.000000f, 0.000000f
};

static GLfloat colors[6] =
{
    0.000000f, 0.000000f, 1.000000f,
    0.000000f, 0.000000f, 1.000000f
};

И результат (линия вращается в начале координат перпендикулярно оси X -> я назвал glLineWidth (5.0f), чтобы получить лучший видимый результат):

введите описание изображения здесь

С помощью анимации в реальном времени я мог видеть, что яркость правильная, но только на определенной стороне линии. Это нормально, потому что линейный сегмент должен иметь бесконечное количество нормалей, а у меня всего две нормали (по одной на вершину). Я хочу уточнить, что эти две нормали являются нормалью к плоскости уравнения Y = 0 -> n (0.0, 1.0, 0.0). Поэтому мне интересно, можно ли добавить несколько нормалей на вершину? Я считаю, что OpengL не может этого сделать. Но, может быть, возможен и другой способ. Вот рисунок, который объясняет, что я хочу сделать, чтобы вычислить правильную яркость для каждой части отрезка линии:

введите описание изображения здесь

Как вы можете видеть выше на первом изображении, Blender может вычислять яркость в реальном времени на отрезке линии. Кроме того, на этом изображении присутствует рендер OpenGL. Так что я уверен, что это возможно. Я пробовал повторить те же координаты сегмента линии два раза, но для второй строки я применяю противоположный нормальный n2 (0,0, -1,0, 0,0), но это не работает. «Другая сторона» - «темная». То же самое и с двумя полигонами. В настоящее время я использую шейдер GLSL. Я думаю, что это возможно с использованием специальных шейдеров, таких как шейдер геометрии или шейдер тесселяции. Возможно, потребуется язык CUDA. Но я не уверен.

Кто-нибудь может мне помочь?


person user1364743    schedule 10.04.2013    source источник


Ответы (2)


ananthonline уже дал вам несколько ссылок, но это полный перебор для простой модели освещения линейных прядей.

Если ваши требования не столь высоки, вы можете применить модель освещения Фонга к прядям. Вы можете спросить, подождите что, пряди не имеют нормалей, но они вам нужны для Фонга? Ну и да, и нет. Линейный сегмент имеет бесконечное количество нормалей, также называемых плоскостью. Или, другими словами, прямая линия сама по себе перпендикулярна плоскости.

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

I(phi) = I_max * cos( phi )

или, заменив phi вектором и cos( angle(↑a,↑b) ) = ↑a · ↑b где ||↑a|| = ||↑b|| = 1

I(↑a, ↑b) = I_max * ↑a · ↑b

Теперь пусть ↑c · ↑b = 0, где ||↑c|| = 1, затем ↑a · ↑b = 1 - ↑a · ↑c. Но ↑c · ↑b = 0 - это определение нормального. Это означает, что для линейного сегмента направления ↑b и направления на источник света ↑c вы можете записать интенсивность как

I(↑b, ↑c) = I_max * (1 - ↑b · ↑c)

И это модель освещения Фонга для линий. И, как оказалось, это именно то, что делает Blender.

Обновление: зеркальное отражение

Положение глаз нужно только для расчета зеркального рефлекса. Вы также можете сделать это, предположив, что нормаль к пряди линии - это вектор направления света, перпендикулярный к этой нити. Пусть ↑b снова будет направлением линейного сегмента, а ↑c направлением к свету. Затем, применяя метод ортонормировки Грама-Шмидта, вы можете получить нормаль на месте ↑n с помощью

↑n = normalize(↑c - ↑b·↑c)

Используя это, вы можете построить обычный набор

- vertex position
- vertex "normal"
- light direction
- light half direction

в вершинном шейдере линейных прядей, передать его в обычный шейдер фрагментов Фонга и выполнить вычисления как обычно.

person datenwolf    schedule 10.04.2013
comment
Спасибо за полный ответ. Но я не понимаю, почему в уравнении нет положения глаз? Чтобы вычислить окончательный цвет, мне нужно положение глаз и положение света, верно? Являются ли они вектором b и вектором c в вашем примере? А I_max - это максимальное значение цвета? У вас есть рисунок, на котором можно это показать? Я не понял, к чему именно относятся эти векторы. Еще раз спасибо. - person user1364743; 11.04.2013
comment
Извините, я неправильно прочитал. Хорошо для векторов b и c. Но когда я меняю положение глаза, этот не мешает уравнению? - person user1364743; 11.04.2013
comment
Хорошо, спасибо вам большое за всех. Теперь я лучше понимаю. Пока. - person user1364743; 11.04.2013
comment
Это плохой ответ на плохой вопрос. На такую ​​сложную вещь, как рендеринг волос, нельзя ответить вступлением в затенение ?! Для меня это похоже на ТАК спам или SEO. - person starmole; 11.04.2013
comment
@starmole: Мы не говорим здесь о рендеринге волос. Это приближение к освещению перегибов линии, которое очень хорошо работает описанным мною методом. Кстати, я (все еще) лучший пользователь тега OpenGL на StackOverflow (т.е. люди считают мои ответы одними из лучших об OpenGL). Также нигде в моем ответе нет шейдерного кода. Это только математика. Вы действительно читали мой ответ? - person datenwolf; 11.04.2013
comment
@starmole Что за ...? Это шутка? Вопрос не касался самого сложного или лучшего способа обработки волос. Он спрашивал о конкретной проблеме, возникшей при попытке осветить линии, и этот ответ представляет собой легкое, простое и общее решение (даже если, возможно, не самое специализированное, красивое или сложное). И ни в коем случае не упоминаются шейдеры или что-то еще, а просто общее математическое решение конкретной проблемы недостаточной нормальной информации, с которой столкнулся OP. Ваш комментарий выглядит как ТАК спам или как будто вы, по крайней мере, не читали вопрос и ответ. - person Christian Rau; 11.04.2013
comment
@starmole Да, независимо от того, с какой довольно простой проблемой сталкивается ОП, пока он говорит о волосах, наиболее полезным и лучшим решением, вероятно, будет просто отослать его к некоторым сложным статьям о высококачественном рендеринге волос и оставить его самому себе , определенно (чтобы не дискредитировать ответ ananthonline, это также полезно)! И, кстати, что такое SEO (подождите, может я не хочу знать)? - person Christian Rau; 11.04.2013
comment
Да, я сделал. Это здравый ответ. Я сам стараюсь отвечать на вопросы по gl. И я ценю, что вы помогаете. Часто ответ - просто изучить основы линейной алгебры. Я просто не могу понять, как вопрос соответствует твоему ответу. Проведу аналогию: как построить машину? - Так работает ньютоновская физика. Да, это нужно знать, чтобы построить машину. Но это бесполезно. - person starmole; 11.04.2013
comment
@starmole ... С помощью анимации в реальном времени я мог видеть, что яркость правильная, но только на определенной «стороне» линии. Это нормально, потому что линейный сегмент должен иметь бесконечное количество нормалей, а у меня всего две нормали (по одной на вершину) ... Так что мне интересно, можно ли добавить несколько нормалей на вершину? ... Но, может быть, другой способ - возможно ... - Как объяснения datenwolf не подходят в точности к этой проблеме? - person Christian Rau; 11.04.2013
comment
@starmole - я понятия не имею, в чем, черт возьми, была ваша проблема с этим ответом, но этот первый комментарий был совершенно неуместным ответом. Это хорошо объясненный ответ того, кто заслужил здесь большое уважение. Пожалуйста, будьте более конструктивны в своих комментариях в будущем. - person Brad Larson; 12.04.2013

Это сложная тема. Вам следует начать с чтения статьи Маршнера 2003 г. о волосах. освещение. Если вы достаточно запутались, посмотрите объяснение nvidia этой модели (раздел 23.3). , Hair Shading), который включает красивые диаграммы и код шейдера.

Надеюсь это поможет!

person Ani    schedule 10.04.2013