Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2006.09.10;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "Media";
Текущий архив: 2006.09.10;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.048 c
2-1156332390
GeLLeR
2006-08-23 15:26
2006.09.10
Добавление вложенных папок в плейлист


2-1155884743
her
2006-08-18 11:05
2006.09.10
TBytes и TIdSocketHandle


1-1153814890
312Kbps
2006-07-25 12:08
2006.09.10
Crystal Reports 9 + Delphi 7 !!!!


2-1156161877
Delphi basic
2006-08-21 16:04
2006.09.10
Как добавить в набор данных номера записей?


1-1153906243
SDA
2006-07-26 13:30
2006.09.10
по VirtualTreeView





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский