HLFX.Ru Forum
Показать все 7 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- OpenGL (https://hlfx.ru/forum/forumdisplay.php?forumid=7)
-- Развевающийся флаг (https://hlfx.ru/forum/showthread.php?threadid=405)


Отправлено XaeroX 03-10-2006 в 05:43:

Развевающийся флаг

Рассмотрим, как сделать развевающийся по ветру флаг с реалистичным освещением. Похожая статься есть на gamedev.ru, идею колыхания флага я взял оттуда, но освещение там оставляет желать лучшего. Посмотрим, что тут можно улучшить.

Для начала замечание: я написал две программы.
flag_sw_vp.exe - software vertex processing (на CPU, будет работать даже на RivaTNT)
flag_hw_vp.exe - hardware vertex processing (требует поддержки вершинных шейдеров)
Сам флаг - это полигональная сетка из 12288 полигонов (конечно, можно меньше, но чтобы увидеть, какой выигрыш в скорости дают вершинные шейдеры, я взял так много).

Итак, что нам нужно сделать:
1. Колебания флага, причем чем ближе к флагштоку, тем они должны быть слабее.
2. Изменение нормали для реалистичного освещения.
3. Собственно освещение - диффузное и бликовое.

Структуры шейдера выглядят так (передаем минимум данных)

Cg Vertex Shader:
1
struct VertIn
2
{
3
  float4 Position			: POSITION;
4
  float2 TexCoord			: TEXCOORD0;
5
};
6
 
7
struct VertOut
8
{
9
  float4 Position			: POSITION;
10
  float2 TexCoord			: TEXCOORD0;
11
  float4 Color			: COLOR0;
12
};


Напишем небольшую вспомогательную функцию для расчета колыхания по уравнению колебаний:
Cg Vertex Shader:
float computeDeform(float factor, float time)
{
  return sin(factor * 15 + time * 8) * factor;
}

factor - расстояние от флагштока (фактически это текстурная координата s)
time - время, передается в шейдер как локальный параметр

А вот сам код шейдера:
Cg Vertex Shader:
1
VertOut main(VertIn vin,
2
uniform float	Amplitude:		C0,
3
uniform float	TimeFactor:		C1,
4
uniform float4	LightPos:		C2,
5
uniform float3	EyePos:			C3,
6
uniform float3	LightColor:		C4)
7
{
8
  VertOut vout;
9
  float deform;
10
  float3 normal;
11
 
12
  //transformation
13
  deform = computeDeform(vin.TexCoord.x, TimeFactor);
14
  vin.Position.z = deform * Amplitude;
15
  normal.x = 1.0f - abs(deform);
16
  normal.y = 0.0f;
17
  normal.z = -1.0f;
18
  normal = normalize(normal);
19
 
20
  //lighting
21
  float3 L2V, E2V, HAV;
22
  float dist, attn, diffuse, specular;
23
 
24
  L2V = LightPos.xyz - vin.Position.xyz;
25
  dist = length(L2V);
26
  L2V = normalize(L2V);
27
  E2V = normalize(EyePos.xyz - vin.Position.xyz);
28
  HAV = normalize((E2V + L2V) * 0.5f);
29
 
30
  attn = 1.0f - dist / LightPos.w;
31
  diffuse = dot(L2V, normal);
32
  specular = pow(saturate(dot(HAV, normal)),20);
33
 
34
  vout.Position = mul(glstate.matrix.mvp, vin.Position);
35
  vout.TexCoord = vin.TexCoord;
36
  vout.Color.rgb = (diffuse + specular) * attn * LightColor.rgb;
37
  vout.Color.a = 1;
38
 
39
  return vout;
40
}


Пару слов о том, как мы искажаем нормаль. Функция синуса периодическая с диапазоном значений от -1 до 1. Очевидно, что при значении 1 и -1, где точка флага на экстремуме, нормаль должна быть не искажена (это значение (0,0,-1)). Там, где синус равен 0, нормаль фактически смотрит в сторону. Поэтому мы и использовали такое выражение: 1.0f - abs(deform). Оно не совсем правильное, как вы можете видеть. Но по-другому, похоже, не сделаешь - для более правильного вычисления нормали нужна информация о соседних вершинах, а она недоступна в шейдере.

Вот как это выглядит:


В архиве - демка. Для запуска flag_hw_vp.exe вам понадобятся библиотеки cg.dll и cgGL.dll. Я их выкладывать не стал, т.к. весят они около мегабайта.

Спасибо за внимание, и приятных вам шейдеров

__________________

xaerox on Vivino


Отправлено BUzer 03-10-2006 в 10:51:

Ты в жизни видел чтобы флаг так развевался? Какие-то ровные вертикальные полосы.. жуть.. Простой анимацией можно сделать гораздо красивее.

У меня заработала только sw-версия. В hw-версии просто есть флагшток и свет, флага нет. Если подставить другие cg.dll и cgGL.dll (у меня их несколько, я уже и не помню, какие откуда качал), то при запуске появляется "failed to load vertex program" (ну или что-то в этом роде). fps везде 62.5.


Отправлено XaeroX 03-10-2006 в 11:05:

Цитата:
BUzer писал:
Ты в жизни видел чтобы флаг так развевался?

Шейдер тебе в руки Делай реализмъ. Правда, на вторых шейдерах не сделаешь, только на третьих - нужнен доступ к текстуре из вершинной программы.
Цитата:
BUzer писал:
Если подставить другие cg.dll и cgGL.dll (у меня их несколько, я уже и не помню, какие откуда качал), то при запуске появляется "failed to load vertex program" (ну или что-то в этом роде).

Странно. Не находит файл flag.cg видимо.
Версия Cg, что я использовал - 1.5b
Цитата:
BUzer писал:
fps везде 62.5.

Тоже странно. У меня в св-версии фпс 43 (в хв - 500).

Добавлено 03-10-2006 в 18:05:

Кстати, одну идею по "рандомизации" предложить могу - плавно менять параметр амплитуды по какой-нибудь функции.

__________________

xaerox on Vivino


Отправлено BUzer 03-10-2006 в 12:49:

XaeroX

Цитата:
Шейдер тебе в руки Делай реализмъ.

Алгоритм-бы придумать.. У меня было желание сделать скринсейвер с развевающимся флагом, но я так и не продумал физическую модель
Цитата:
Правда, на вторых шейдерах не сделаешь, только на третьих - нужнен доступ к текстуре из вершинной программы.

А это зачем?


Отправлено XaeroX 03-10-2006 в 13:31:

Цитата:
BUzer писал:
А это зачем?

Шумовую текстуру юзать
А как еще неравномерность задавать?
В GLSL есть правда ф-я noise, но в Cg ее нет

__________________

xaerox on Vivino


Отправлено exelents 05-02-2007 в 08:38:

Люди, скиньте пожалуйста cg.dll
Или где его взять? В НВидия СДК его не нашел. И в OpenGLSDK тоже нет


Отправлено XaeroX 05-02-2007 в 08:56:

exelents тебе нужен Cg Toolkit. Смотри вот тут:
http://developer.nvidia.com/object/...it-15#downloads

__________________

xaerox on Vivino


Временная зона GMT. Текущее время 15:46.
Показать все 7 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024