Текущий архив: 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