Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.14;
Скачать: CL | DM;

Вниз

Алгоритм вычисления карты освещения   Найти похожие ветки 

 
Ricks ©   (2005-10-21 01:55) [0]

Как вычислить карту освещения (lightmap) если известна карта высот (heightmap)??? Дополнительно можно внести любые данные об источнике света (угол поворота, наклон к горизонту итд итп).
Люди, подскажите, как это лучше сделать (пример реализации - Warcraft), а то мой алгоритм какой-то кривой...


 
_111_   (2005-10-21 02:28) [1]

А как связаны lightmap и heightmap? т.е. освещения только рельефа(карты)?

тем более, если мне не изменяет память, в warcraft`е динамическое освещение


 
TButton ©   (2005-10-21 10:05) [2]


> т.е. освещения только рельефа(карты)?

да. мне бы тоже было интересно узнать.


 
TButton ©   (2005-10-21 10:08) [3]

по идее там рассчитывается нормаль для центра каждой клетки карты
и направление на источник света
потом по косинусу угла разницы рассчитывается
относительная освещенность клетки
а дальше можно интерполяцию сделать от центра к центру.

но вот выразить это красивой формулой
(или набором формул)
у меня не очень получается.


 
Ricks ©   (2005-10-21 12:11) [4]


> т.е. освещения только рельефа(карты)?

Я делаю пока только lightmap для ландшафта

Делал так:
для каждой точки на карте получал условную высоту, из которой потом расчитывалась проекция на карту освещения и потом эту проекцию (полоску) заполнял:

procedure BuildLightmap( HM : TByteMatrix; w, l : integer;
                        LAngle : single; LHorAngle : single;
                        HDiv : single; basicL : integer; var LM : TByteMatrix);
var x, z   : integer;
   ha     : single;
   ax, az : single;
   h, pj  : single;
   r      : integer;
   nx, nz : single;
begin
for z:=0 to pred(l) do
 for x:=0 to pred(w) do
  LM[z, x]:=255;

ha:=roundto( cos(   LHorAngle * pi / 180 ), -5);
ax:=roundto( cos( pi - LAngle * pi / 180 ), -5);
az:=roundto( sin( pi - LAngle * pi / 180 ), -5);

for z:=0 to pred(l) do
 for x:=0 to pred(w) do begin
  h:=HM[z, x] / HDiv;
  if (h = 0) then continue;

  pj:=h * ha;
  if (pj = 0) then Continue;

  for r:=1 to round(pj) do begin
   nx:=r * ax;
   nz:=r * az;
   if (x + nx < 0) or (x + nx > pred(l)) then Continue;
   if (z + nz < 0) or (z + nz > pred(w)) then Continue;
   if HM[ z + round(nz), x + round(nx) ] < HM[ z, x ]
    then LM[ z + round(nz), x + round(nx) ]:=basicL;
  end;

 end;

end;

Но выглядит оно почти не реалистично, и совсем не впечатляюще... :(

Может быть, следовало бы использовать матрицу скажем 3*3 и проходя по всей карте высот, определять тень, используя разницу высот?


 
A22 ©   (2005-10-21 13:19) [5]

попробуй сделать рейтрейс: для каждого пикселя лайтмапа двигайся по прямой, соединяющей ее с позицией источника света, если на пути будет найдено препятствие (какая-то точка хейтмапа, лежащая выше точки прямой) - значит исходный пиксель в тени. Для точек же освещенных подойдет обычная формула N dot L

P.S. сам не пробовал, руки не дошли пока, но делал бы, наверное, так :)


 
TButton ©   (2005-10-21 13:37) [6]


> ля каждой точки на карте получал условную высоту, из которой
> потом расчитывалась проекция на карту освещения и потом
> эту проекцию (полоску) заполнял:

по описанию больше похоже на карту высот


 
Ricks ©   (2005-10-22 00:28) [7]

Под условной высотой имеется ввиду то, что если использовать настоящую высоту из карты, то для самой высокой точки (255) представь себе длинну проекции, а соответственно и длинну тени.....


 
_111_   (2005-10-22 00:45) [8]

а почему бы не свалить все на железо
http://opengl.gamedev.ru/articles/?id=119&page=3
здесь показано как это сделать

а сам я делал так :
расчитывал smooth нормали и сдвигал их по карте в направлении, противоположном источнику света. И включал обычный GL_LIGHT0.
Пускай нечестно, но результат меня удовлетворил- и освещение гладкое и какие никакие тени. (хорошо смотрится для рельефа с небольшими высотами до 20% от размера карты)


 
_111_   (2005-10-22 00:53) [9]

смотрел скрин Ricks`a. Вроде симпатично выглядит. Чем не нравится?


 
Ricks ©   (2005-10-22 01:05) [10]

От освещения в смысле GL_LIGHTING (и тем самым нормалей) и еще от цветовой раскраски я отказался - сильно тормозит.....

> рейтрейс
- хорошая идея, попробую!


 
Ricks ©   (2005-10-22 02:02) [11]

Да, raytrace - прекрасный метод:
http://www.ricks.pisem.net/ray.jpg


 
Signate ©   (2005-10-22 10:47) [12]


> Ricks ©   (22.10.05 02:02) [11]

А можешь подксказать как ты сделал? и еще если не сложно сделай скрин сетки карты :-) Спасиб


 
Ricks ©   (2005-10-23 02:13) [13]

Сетки, в смысле wireframe? Если да, то:
http://www.ricks.pisem.net/wire.jpg

Насчет как сделал:

procedure BuildLightmap2( HM : TByteMatrix; w, l : integer; a: single; var LM : TByteMatrix);
var x, z   : integer;
   dx, dz : single;
   px, pz : single;
   mx, mz : integer;
   cx, cz : integer;
   u      : integer;
begin
for z:=0 to pred(l) do
 for x:=0 to pred(w) do
  LM[z, x]:=255;

dx:=cosex(a);
dz:=sinex(a - 90);

for z:=0 to pred(l) do
 for x:=0 to pred(w) do begin
  px:=x;
  pz:=z;
  while (px >= 0) and (pz >= 0) and (px <= pred(w)) and (pz <= pred(l)) do begin
   cx:=round(px);
   cz:=round(pz);
   mx:=round(px + dx);
   mz:=round(pz + dz);

   if (mx < 0) or (mz < 0) or (mx >= w) or (mz >= w) then Break;

   if (mx <> cx) or (mz <> cz) then
    if HM[mz, mx] >= HM[cz, cx] then begin
     u:=236 - round( (HM[mz, mx] - HM[cz, cx]) * 3 );
     if u < 0 then u:=0;
     if u > 255 then u:=255;
     LM[cz, cx]:=u;
    end;
   
   px:=px + dx;
   pz:=pz + dz;
  end;
 end;
end;


На здоровье! :)
Я думаю, разобраться в типах будет не сложно...



Страницы: 1 вся ветка

Текущий архив: 2006.05.14;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.045 c
2-1146129870
Golik
2006-04-27 13:24
2006.05.14
из DBGrid в Exel ???


15-1145362719
worldmen
2006-04-18 16:18
2006.05.14
Что такое URL


9-1129754635
Ricks
2005-10-20 00:43
2006.05.14
Элементарный поиск пути


15-1145456846
geserx
2006-04-19 18:27
2006.05.14
Снесла курочка...


2-1146143540
mfender
2006-04-27 17:12
2006.05.14
События в компоненте