Форум: "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