HLFX.Ru Forum Страницы (2): [1] 2 »
Показать все 30 сообщений этой темы на одной странице

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=10)


Отправлено XaeroX 17-10-2005 в 09:57:

Совершенствуем "эффект хромирования"

В Half-Life, как вы наверное знаете, определенные текстуры на моделях выглядят как бы хромированными - их текстурные координаты искажаются определенным образом. Фактически для искажения нужны: вектора, задающие направления (вправо и вверх) и нормаль к вершине. Нормаль вычисляется для каждой вершины при подготовке модели, и полученные значения хрома умножаются на текущие координаты текстуры.

Смоделируем этот процесс. Для этого мы напишем вершинную программу, производящую нужные вычисления, а нормаль передаем средствами OpenGL (для боксов в примере нормали генерируются автоматически).

Cg Vertex Shader:
1
struct VertIn
2
{
3
  float4 pos : POSITION;
4
  float3 normal : NORMAL;
5
  float3 tex0 : TEXCOORD0;
6
  float4 col : COLOR;
7
};
8
 
9
struct VertOut
10
{
11
  float4 pos : POSITION;
12
  float4 tex0 : TEXCOORD0;
13
  float4 col : COLOR;
14
};
15
 
16
VertOut main(VertIn vin)
17
{
18
  VertOut vout;
19
  float4 g_vecRight = float4( 1.0f, 0.0f, 0.0f, 0.0f );
20
  float4 g_vecUp = float4( 0.0f, 1.0f, 0.0f, 0.0f );
21
 
22
  vout.pos = mul(glstate.matrix.mvp, vin.pos);
23
  g_vecRight = mul(glstate.matrix.inverse.mvp, g_vecRight);
24
  g_vecUp = mul(glstate.matrix.inverse.mvp, g_vecUp);
25
 
26
  vout.tex0.x = vin.tex0.x * (dot(vin.normal, g_vecRight.xyz) + 1.0);
27
  vout.tex0.y = vin.tex0.y * (dot(vin.normal, g_vecUp.xyz) + 1.0);
28
  vout.col = vin.col;
29
  return vout;
30
}


Выглядит не очень красиво. Для более реалистичного эффекта нужно учесть микрорельеф поверхности попиксельно. Основные вычисления мы производим в пиксельной программе, а вершинная передает ей вектора направления (учтите: в вашей собственной игре нужно передавать вектора вручную, а не задавать как константы в шейдере!).
Вершинная программа выглядит просто:
Cg Vertex Shader:
1
struct VertIn
2
{
3
  float4 pos : POSITION;
4
  float3 normal : NORMAL;
5
  float2 tex0 : TEXCOORD0;
6
  float4 color : COLOR;
7
};
8
 
9
struct VertOut
10
{
11
  float4 pos : POSITION;
12
  float2 tex0 : TEXCOORD0;
13
  float3 tex1 : TEXCOORD1;
14
  float3 tex2 : TEXCOORD2;
15
  float4 color : COLOR;
16
};
17
 
18
VertOut main(VertIn vin)
19
{
20
  VertOut vout;
21
  float4 g_vecRight = float4( 1.0f, 0.0f, 0.0f, 0.0f );
22
  float4 g_vecUp = float4( 0.0f, 1.0f, 0.0f, 0.0f );
23
 
24
  vout.pos = mul(glstate.matrix.mvp, vin.pos);
25
  vout.tex1 = mul(glstate.matrix.inverse.mvp, g_vecRight).xyz;
26
  vout.tex2 = mul(glstate.matrix.inverse.mvp, g_vecUp).xyz;
27
  vout.tex0 = vin.tex0;
28
  vout.color = vin.color;
29
  return vout;
30
}


Пиксельный шейдер чуть сложнее - нам вначале нужно прочитать нормаль из тектуры - карты нормалей (мы привязали ее к юниту 1).
Cg Pixel Shader:
1
struct VertOut
2
{
3
  float4 pos : POSITION;
4
  float2 tex0 : TEXCOORD0;
5
  float3 tex1 : TEXCOORD1;
6
  float3 tex2 : TEXCOORD2;
7
  float4 color : COLOR;
8
};
9
 
10
struct FragOut
11
{
12
  float4 col : COLOR;
13
};
14
 
15
FragOut main(VertOut fin,
16
uniform sampler2D diffuseMap :TEXUNIT0,
17
uniform sampler2D normalMap :TEXUNIT1)
18
{
19
  FragOut fout;
20
 
21
  float2 tc;
22
  float4 normal = tex2D(normalMap, fin.tex0);
23
 
24
  //expand normal [0,1] -> [-1,1]
25
  normal.xyz = normal.xyz*2 - 1;
26
 
27
  tc.x = fin.tex0.x * (dot(normal.xyz, fin.tex1.xyz) + 1.0);
28
  tc.y = fin.tex0.y * (dot(normal.xyz, fin.tex2.xyz) + 1.0);
29
 
30
  fout.col = fin.color * tex2D(diffuseMap, tc);
31
  return fout;
32
}


Сравните два бокса в примере (справа - тот, что использует попиксельные нормали) и почувствуйте, так сказать, разницу! Нажатием кнопки мыши можно изменить используемый нормалмап. По умолчанию используется "пустой" нормалмап - фактически простая нормаль, поэтому картинка справа идентична левой.

Пример требует наличия поддержки вершинных и пиксельных шейдеров 2.0

__________________

xaerox on Vivino


Отправлено Format.com 17-10-2005 в 12:04:

Вложение - unexpected end of archive.


Отправлено XaeroX 17-10-2005 в 19:24:

Так, с аттачами вроде все исправил. Вот вложение. Кстати, я там изменил кое-что в шейдерах, теперь все правильнее.

__________________

xaerox on Vivino


Отправлено Дядя Миша 17-10-2005 в 19:33:

Хороший хром
особенно 3 и 4 варианты.
Кстати тебе совет - сделай так, чтобы окошко нельзя было растягивать на весь экран, а то кубик пропадает.


Отправлено XaeroX 17-10-2005 в 19:36:

Окошко растягивать можно, но так, чтобы пропорции соблюдались. Так что больше можно сделать при желании.

Вот я когда-то про такой хром и говорил на Half-Life.ru. Его можно без проблем сделать на world brush'ах в хл. Чем я вскоре и займусь

__________________

xaerox on Vivino


Отправлено Дядя Миша 17-10-2005 в 19:38:

XaeroX а нафига нужны хромированные браши? :confused:


Отправлено XaeroX 17-10-2005 в 19:43:

Ну как нафига. Металлические конструкции. И потом, хром ведь можно накладывать как вторую текстуру. Красиво смотрится - сам же сказал

__________________

xaerox on Vivino


Отправлено BUzer 18-10-2005 в 10:47:

Красиво. А что исходник не приложил?

Вот тоже че-нить подобное заиметь.. Кстати, а если не юзать cg, то под какое расширение лучше шейдер писать? arb_vertex_program? Или nv_ какой-нибудь?..


Отправлено XaeroX 18-10-2005 в 10:54:

Я сг для примера написал (кстати, это и есть исходник. дело в шейдере, остальное любой сам допишет). Я арб юзаю, и тебе советую, если хочешь, чтобы на радеонах работало.

__________________

xaerox on Vivino


Отправлено Дядя Миша 18-10-2005 в 11:14:

XaeroXвроде как бампом?
ну разве что так
просто я лично считаю, что важны не сами эффекты, а их гармонирование с окружающей средой.
как пример - мощнейщая детализация на ящике с убогой текстуркой 32х32 дает прямо противоположные впечатления.


Отправлено XaeroX 18-10-2005 в 11:36:

g-cont согласен. но в примере текстурки 64 х 64, и вроде ничего так смотрятся. А бамп здесь не при чем, разве что карта нормалей тоже используется, а по сути все разное.

__________________

xaerox on Vivino


Отправлено Jumpdaphuckup! 12-11-2005 в 09:49:

XaeroX а ты бы сделал вариант только с вертексными шейдерами


Отправлено XaeroX 12-11-2005 в 09:54:

Цитата:
Jumpdaphuckup! писал:
а ты бы сделал вариант только с вертексными шейдерами

как ты себе это представляешь?

__________________

xaerox on Vivino


Отправлено Jumpdaphuckup! 12-11-2005 в 14:49:

XaeroX если б представлял, то не просил бы


Отправлено XaeroX 12-11-2005 в 15:00:

Jumpdaphuckup! вся идея основана именно на пиксельных шейдерах А вариант только на вертексных я там привел - смотри пример.

__________________

xaerox on Vivino


Временная зона GMT. Текущее время 20:18. Страницы (2): [1] 2 »
Показать все 30 сообщений этой темы на одной странице

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