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

Вниз

Как правильно нарисовать дым?   Найти похожие ветки 

 
Sour Smile   (2006-02-22 20:16) [0]

Задний план (фон) представляет собой весьма тёмное (подвальное) помещение в виде кирпичной кладки, с еле различимыми стыками между кирпичами.

Вот на этом фоне, время от времени, должен появляться клуб дыма и медленно двигаясь, постепенно растворяться.

Клуб дыма - это квадратный, 32-битный bmp-спрайт. Спрайт дыма полностью белый (все цветовые компоненты R,G,B всех пикселей=255), а альфа-компонент в форме овала (в средине спрайта альфа=255, постепенно уменьшаясь к краям на ноль).

Спрайт дыма накладываю на фон с альфа смешением, а чтобы добиться эффекта растворения, прежде уменьшаю значение альфа-компоненты каждого пикселя спрайта дыма, на некоторое значение, увеличивающееся после каждого вывода спрайта.

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

Выходит, что я неправильно накладываю дым на фон...
А как это сделать правильно?


 
antonn ©   (2006-02-22 21:16) [1]

я так понял, что на кирпичную кладку "наносится белая текстура".
какая формула вычисления цвета пикселя?
должна быть такая, примерно (для одного канала из RGB):
кирпич:=кирпич+trunc((дым-кирпич)*(альфаканал_дыма/255));
и основной цвет дыма можно сделать не белым, а серым, а альфаканал немного высветлить.


 
Sour Smile   (2006-02-23 17:23) [2]

Привет antonn :)

Спрайт дыма я вывожу с помощью твоей же, слегка модифицированной процедуры:

procedure CopyBitmapAlfa(_B_in, _B_out: TBitmap; _x ,_y: Integer; Alfa2: Integer = 255);
const
 MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
 MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
 PRGBArray = ^TRGBArray;
 TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
 PRGBAArray = ^TRGBAArray;
 TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var
 x, y: Integer;
 _r, _b, _g, _Alfa: Integer;
 w_in, h_in, w_out, h_out, tmp, x_cor, y_cor, x_corS, y_corS: Integer;
 RowOut: PRGBArray;
 RowIn: PRGBAArray;
 _d, _dd: double;

begin
 case _B_in.PixelFormat of
   pf24bit:
   begin
     _B_out.Canvas.CopyRect(Rect(_x, _y, _B_in.Width+_x, _B_in.Height+_y), _B_in.Canvas, _B_in.Canvas.ClipRect);
   end;
   pf32bit:
   begin
     w_in:=_B_in.Width;
     h_in:=_B_in.Height;
     w_out:=_B_out.Width;
     h_out:=_B_out.Height;
     if (_x)>w_out-1 then exit; if (_x+w_out)<0 then exit;
     if (_y)>h_out-1 then exit; if (_y+h_out)<0 then exit;

     if _x<0 then x_corS:=abs(_x) else x_corS:=0;
     if _y<0 then y_corS:=abs(_y) else y_corS:=0;
     if (_x+w_in)>w_out then x_cor:=_x+w_in-w_out else x_cor:=0;
     if (_y+h_in)>h_out then y_cor:=_y+h_in-h_out else y_cor:=0;

     y_cor:=h_in-1-y_cor;
     tmp:=w_in-1-x_cor; _dd:=100/(255*100);
     for y:=y_corS to y_cor do
     begin
       RowOut:= _B_out.ScanLine[y+_y];
       RowIn:= _B_in.ScanLine[y];
       for x:=x_corS to tmp do
       begin
         _Alfa:=RowIn[x].rgbReserved+Alfa2-255;
         if _Alfa>=255 then
         begin
           RowOut[x+_x].rgbtRed   := RowIn[x].rgbRed;
           RowOut[x+_x].rgbtGreen := RowIn[x].rgbGreen;
           RowOut[x+_x].rgbtBlue  := RowIn[x].rgbBlue;
         end else
         if _Alfa>0 then
         begin
           _d:=_Alfa*_dd;

           _r:= trunc(RowOut[x+_x].rgbtRed+(RowIn[x].rgbRed-RowOut[x+_x].rgbtRed)*_d);
           if _r>255 then _r:=255 else if _r<0 then _r:=0;

           _g:= trunc(RowOut[x+_x].rgbtGreen+(RowIn[x].rgbGreen-RowOut[x+_x].rgbtGreen)*_d);
           if _g>255 then _g:=255 else if _g<0 then _g:=0;

           _b:= trunc(RowOut[x+_x].rgbtBlue+(RowIn[x].rgbBlue-RowOut[x+_x].rgbtBlue)*_d);
           if _b>255 then _b:=255 else if _b<0 then _b:=0;

           RowOut[x+_x].rgbtRed:=_r;
           RowOut[x+_x].rgbtGreen:=_g;
           RowOut[x+_x].rgbtBlue:=_b;
         end;
       end;
     end;
   end;
 end;
end;


Аргумент Alfa2 я как раз и ввёл для эффекта растворения.


> antonn ©   (22.02.06 21:16) [1]
>
> и основной цвет дыма можно сделать не белым, а серым, а
> альфаканал немного высветлить.

Высветлять больше некуда, в центре спрайта дыма (в месте наибольшего скопления) альфа=255


 
antonn ©   (2006-02-23 17:53) [3]

Sour Smile   (23.02.06 17:23) [2]
Аргумент Alfa2 я как раз и ввёл для эффекта растворения.

хы-хы, _dd:=100/(255*100); не просто так, у меня через такое чудо общая прозрачность наложения высчитывалась. жирным отмечено процентная видимость, т.е. при 0 ничего не увидишь. Думаю, это было нужно? :)


 
Gorger ©   (2006-02-28 04:29) [4]

Юзайте либу LibPNG. Антон, простите, но Ваша либа уступает LibPNG.


 
antonn ©   (2006-02-28 07:09) [5]

Gorger ©   (28.02.06 4:29) [4]
Антон, простите, но Ваша либа уступает LibPNG.

определенно. Хотя бы тем, что не поддерживает png, имеет код, насыщеный проверками, и, соотвественно, хромающей производительностью:)
но одно но, мой код не тащит за собой библиотеку, и для рисования 32х битных битмапов его хватает:)



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

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

Наверх




Память: 0.49 MB
Время: 0.029 c
15-1155989075
Мичман Панин
2006-08-19 16:04
2006.09.10
Вопрос для знатоков: чем критерии выбора одежды отличаются от


3-1151559877
yaral
2006-06-29 09:44
2006.09.10
Подключиться к базе MSDE


1-1153992363
oleg___
2006-07-27 13:26
2006.09.10
Реализация интерфейса


15-1155804379
memo
2006-08-17 12:46
2006.09.10
O... Задача.....


15-1150837157
Strate
2006-06-21 00:59
2006.09.10
Opera 9 Final!!!