![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Алгоритм вычисления карты освещения [Delphi, OpenGL]
Ricks © (2005-10-21 01:55:00)Как вычислить карту освещения (lightmap) если известна карта высот (heightmap)??? Дополнительно можно внести любые данные об источнике света (угол поворота, наклон к горизонту итд итп).
Люди, подскажите, как это лучше сделать (пример реализации - Warcraft), а то мой алгоритм какой-то кривой...
Ricks (2005-10-23 02:13:00) [1]Сетки, в смысле 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;
На здоровье! :)
Я думаю, разобраться в типах будет не сложно...
Signate (2005-10-22 10:47:00) [2]
> Ricks © (22.10.05 02:02) [11]
А можешь подксказать как ты сделал? и еще если не сложно сделай скрин сетки карты :-) Спасиб
Ricks (2005-10-22 02:02:00) [3]Да, raytrace - прекрасный метод:
http://www.ricks.pisem.net/ray.jpg
Ricks (2005-10-22 01:05:00) [4]От освещения в смысле GL_LIGHTING (и тем самым нормалей) и еще от цветовой раскраски я отказался - сильно тормозит.....
> рейтрейс- хорошая идея, попробую!
_111_ (2005-10-22 00:53:00) [5]смотрел скрин Ricks`a. Вроде симпатично выглядит. Чем не нравится?
_111_ (2005-10-22 00:45:00) [6]а почему бы не свалить все на железо
http://opengl.gamedev.ru/articles/?id=119&page=3
здесь показано как это сделать
а сам я делал так :
расчитывал smooth нормали и сдвигал их по карте в направлении, противоположном источнику света. И включал обычный GL_LIGHT0.
Пускай нечестно, но результат меня удовлетворил- и освещение гладкое и какие никакие тени. (хорошо смотрится для рельефа с небольшими высотами до 20% от размера карты)
Ricks (2005-10-22 00:28:00) [7]Под условной высотой имеется ввиду то, что если использовать настоящую высоту из карты, то для самой высокой точки (255) представь себе длинну проекции, а соответственно и длинну тени.....
TButton (2005-10-21 13:37:00) [8]
> ля каждой точки на карте получал условную высоту, из которой
> потом расчитывалась проекция на карту освещения и потом
> эту проекцию (полоску) заполнял:
по описанию больше похоже на карту высот
A22 (2005-10-21 13:19:00) [9]попробуй сделать рейтрейс: для каждого пикселя лайтмапа двигайся по прямой, соединяющей ее с позицией источника света, если на пути будет найдено препятствие (какая-то точка хейтмапа, лежащая выше точки прямой) - значит исходный пиксель в тени. Для точек же освещенных подойдет обычная формула N dot L
P.S. сам не пробовал, руки не дошли пока, но делал бы, наверное, так :)
Ricks (2005-10-21 12:11:00) [10]
> т.е. освещения только рельефа(карты)?
Я делаю пока только 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 и проходя по всей карте высот, определять тень, используя разницу высот?
TButton (2005-10-21 10:08:00) [11]по идее там рассчитывается нормаль для центра каждой клетки карты
и направление на источник света
потом по косинусу угла разницы рассчитывается
относительная освещенность клетки
а дальше можно интерполяцию сделать от центра к центру.
но вот выразить это красивой формулой
(или набором формул)
у меня не очень получается.
TButton (2005-10-21 10:05:00) [12]
> т.е. освещения только рельефа(карты)?
да. мне бы тоже было интересно узнать.
_111_ (2005-10-21 02:28:00) [13]А как связаны lightmap и heightmap? т.е. освещения только рельефа(карты)?
тем более, если мне не изменяет память, в warcraft`е динамическое освещение