Reply
 
Thread Tools Display Modes   
 
procedural fire (beta)
 
Old 06/12/2009, 22:17 Reply With Quote   #1
kornwaretm
Member
 
kornwaretm's Avatar
 
Join Date: Sep 2008
Location: jogja
Posts: 245
kornwaretm is on a distinguished road
kornwaretm is offline
procedural fire (beta)

procedural fire

PENGANTAR

pada jaman dahulu kala hingga sekarang orang menggunakan file image untuk membuat animasi api(texture animation). biasanya texture tersebut didapatkan dari software-software animasi dalam bentuk image file(.jpg, .bmp, .png, dsb).

MANFAAT

karena saya terlalu malas untuk melakukan hal diatas. ups... alasan yang jahat, bagai mana kalo kita bisa membuat api tersebut on the fly, dengan image yang lebih sedikit dan kecil ukurannya.

fungsi dari class ini adalah menggenerate array of bitmapData yang menggambarkan pergerakan api. class ini turunan dari Sprite sehingga bisa langsung di-attach kan pada Sprite lain.


LANDASAN TEORI

algoritma :
step 1.
membuat warna api yang berupa grandient dengan tipe radial

step 2.
menggenerate alpha channel untuk croping. alpha channel dihasilkan dari image fireShape dan image Cloud. dengan melakukan blending antar cloud-cloud. dengan detail level tertentu.

step 3
gradient color tadi ditulis ke bitmap data, kemudian di clone ke sejumlah frame buffer(array of bitmapData), pada setiap buffer apply alpha yang telah digenerate. mainkan texture coordinate tiap cloud, generate lagi alpha chanell untuk buffer yang lain.

step 4
tampilkan hasil berdasarkan posisi frame.


IMPLEMENTASI
dibutuhkan 2 texture yang pertama adalah texture fireShape yang mewakili bentuk api, dan yang kedua adalah texture cloud yang merupakan hasil dari ....eemmmm filter->render->cloud. texture cloud harus tile.
Code:
//preparing textures var rt:Bitmap = new tx(); var fs:Bitmap = new sht();
set resolusi dari api yang akan dibuat
Code:
//set fire's resolution var reshx:Number = 256; var reshy:Number = 256;
buat color template yang isinya akan digunakan untuk menggenerate base color dari api yang akan dibuat. silakan lihat dokumentasi tentang gradientfill untuk as3(sama dengan gradientFill di as2)
Code:
//setup colors of the fire var colors:Array = new Array(0xfffc00, 0xff0000) var ratios:Array = new Array(0, 256 / 4); var template:fireColorTemplate = new fireColorTemplate(); template.setColors(colors, ratios);
panggil constructor. masukkan parameter colorTemplate, 2texture texture diatas, resolusi api, detail dan frame. detail terisi 5 cloud yang igunakan akan di-blending 5 kali untuk menghasilkan feature-feature yang lebih detail. detail tinggi menggambarkan api yang besar. dan detail yang rendah menggambarkan api yang kecil. frame diisi 30 artinya saya akan memainkan texture animation untuk FPS 30.
Code:
//create our fire var rfire:proceduralFire = new proceduralFire(template, rt.bitmapData, fs.bitmapData, reshx, reshy, 5, 30) addChild(rfire);
atur posisi api
Code:
// set position rfire.x = 400; rfire.y = 300;
selamat mencoba
1.demo
2.fd sample project
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.

- my works -
   
 
 
Old 06/12/2009, 23:16 Reply With Quote   #2
ewaru
Senior Member
 
ewaru's Avatar
 
Join Date: Jan 2007
Location: Earth? Place that can ping IRIS maybe...
Posts: 541
ewaru is on a distinguished road
Send a message via Yahoo to ewaru ewaru is offline
Hmm... Kalo di dunia 3D cg kayaknya dah umum tuh..

Aku beberapa bulan lalu abis baca paper tentang generate cloud on the fly.

Tekniknya, dengan "sebar" density particles, generate "sprite" dengan kepadatan yang sesuai dengan density n sudut pantang kamera, billboard spritenya, combine, addition, (kalo perlu) atur pencahayaan...

Detilnya tapi lupa

keuntungan dari generate partikel sudah pasti bisa dikasih physics semau designer, tapi dibayar ama processing time

Kalo dari sudut pandang aku, I'd prefer sprite based particle karena lebih artistic ^^
__________________
東方Rule!

current project:[kebanyakan, masuk gudang dulu]
-my portfolio-blag-
   
 
 
Old 07/12/2009, 20:57 Reply With Quote   #3
kornwaretm
Member
 
kornwaretm's Avatar
 
Join Date: Sep 2008
Location: jogja
Posts: 245
kornwaretm is on a distinguished road
kornwaretm is offline
@ewaru
thanks replynya
waduh .. perlu gogling lage neeh. hehe. punya link na gak buat generate cloud on the fly-na.

tentang sprite based particle, kalo sprite yang kita perlukan banyak kan bakan mengurangi FPS. ya kan? kalo di procedural fire saya ada fungsi getBuffer so kita bisa mbikin api satu saja lalu ambil buffernya dan bikin sprite laen pake buffer tsb

btw saya sudah update classnya
Code:
/* * 2D procedural fire (proceduralFire beta) * Part of Cornicle Game Development Kit * * Copyright (c) 2009 Kornelius Heru C.M, All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package cornicleProceduralFire { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.MovieClip; import flash.display.Sprite; import flash.events.Event; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; /** * ... * @author cornicle */ public class proceduralFire extends Sprite { private var drawSurface:BitmapData; private var cloudTexture:BitmapData; private var fireShapeTexture:BitmapData; private var speed:Number; private var frameCount:Number; private var framePos:Number; private var frameBuffer:Array; private var detail:Number; private var time:Number public function proceduralFire(template:fireColorTemplate, cloudTexture:BitmapData, fireShapeTexture:BitmapData, width:Number, height:Number, detail:Number, frames:Number) { //base attributes this.detail = Math.min(Math.max(detail, 1), 10); this.frameCount = frames; this.cloudTexture = cloudTexture; this.fireShapeTexture = fireShapeTexture; this.framePos = 0; this.time = 0; //setup fire setupFire(width, height); //init fire into frame buffer initFire(template); //adding listener initEvent(); } private function setupFire(width:Number, height:Number):void { //primary drawing surface drawSurface = new BitmapData(width, height, true, 0x00000000); var bmp:Bitmap = new Bitmap(drawSurface); addChild(bmp) bmp.x = -width / 2; bmp.y = -height / 4 * 3; //alpha generator via movie clip blending; frameBuffer = new Array(); } private function initFire(template:fireColorTemplate):void { var W:Number = drawSurface.width; var H:Number = drawSurface.height; //fixed texture scaling factor var tsX:Number = W / cloudTexture.width; var tsY:Number = H / cloudTexture.height; var colorTexture:BitmapData = new BitmapData(W, H, true, 0x00000000); var cmc:MovieClip = new MovieClip(); //init alpha buffers var point1:Point = new Point(0, 0); var point2:Point = new Point(W, 0); var point3:Point = new Point(W, H); var point4:Point = new Point(0, H); //drawing base color var colors:Array = template.getColors(); var alphas:Array = template.getAlphas(); var ratios:Array = template.getRatios(); var grMat:Matrix = new Matrix(); grMat.translate(W / 2, H / 4 * 3); cmc.graphics.beginGradientFill("radial", colors, alphas, ratios, grMat); cmc.graphics.moveTo(point1.x, point1.y); cmc.graphics.lineTo(point2.x, point2.y); cmc.graphics.lineTo(point3.x, point3.y); cmc.graphics.lineTo(point4.x, point4.y); cmc.graphics.endFill(); colorTexture.draw(cmc); cmc.graphics.clear(); //logaritmic division var devidingFactor:Number = 0; for (var t:Number = 0 ; t <= detail ; t ++) { devidingFactor += t; } //drawwing alpha buffer for (var i:Number = 0 ; i < frameCount ; i++) { var xTrans:Number; //new bitmap for frame buffer var bmp:BitmapData = new BitmapData(W, H, true, 0x00000000); for (var s:Number = 1 ; s < detail + 2 ; s++) { //texture matrix var mat:Matrix = new Matrix(); //draw our alpha layer cmc.graphics.clear(); if (s == detail + 1) { //using the fire shape mat.scale(tsX, tsY); cmc.graphics.beginBitmapFill(fireShapeTexture, mat); }else { //using cloud texture if (isNaN(xTrans)) { xTrans = W * Math.random(); } mat.translate(xTrans, -(i / frameCount)*cloudTexture.width); mat.scale(tsX * 1 / s * 4, tsY * 1 / s * 4); cmc.graphics.beginBitmapFill(cloudTexture, mat); } //draw the square cmc.graphics.moveTo(point1.x, point1.y); cmc.graphics.lineTo(point2.x, point2.y); cmc.graphics.lineTo(point3.x, point3.y); cmc.graphics.lineTo(point4.x, point4.y); cmc.graphics.endFill(); //draw to frameBuffer surface if (s == detail + 1) { var ct:ColorTransform = new ColorTransform( 1, 1, 1, 1, -52, -52, -52, 0); //over burn bmp.draw(cmc, null, ct, "add"); //crop everything with fire shape bmp.draw(cmc, null, null, "multiply"); }else { var alpha:Number = s / devidingFactor * 2; var ct2:ColorTransform = new ColorTransform( alpha, alpha, alpha, alpha); bmp.draw(cmc, null, ct2, "add"); } } //fill our buffer var bufferContent:BitmapData = colorTexture.clone(); //apply our generated alpha to base color. bufferContent.copyChannel(bmp, new Rectangle(0, 0, drawSurface.width, drawSurface.height), new Point(0, 0), 1, 8); frameBuffer.push(bufferContent); } } private function update(e:Event):void { drawSurface.copyPixels(frameBuffer[framePos], new Rectangle(0, 0, drawSurface.width, drawSurface.height), new Point(0, 0)); if (framePos < frameCount-1) { framePos++; }else { framePos = 0; } } private function initEvent():void { addEventListener(Event.ENTER_FRAME, update); } public function getBuffer():Array { var result:Array = new Array(); for (var i:Number = 0 ; i < frameBuffer.length ; i++) { result.push(frameBuffer[i].clone()); } return result; } } }
color template
Code:
/* * fireColorTemplate * Part of Cornicle Game Development Kit * * Copyright (c) 2009 Kornelius Heru C.M, All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package cornicleProceduralFire { /** * ... * @author cornicle */ public class fireColorTemplate { private var colors:Array; private var ratios:Array; private var alphas:Array; public function fireColorTemplate() { alphas = new Array(); } public function setColors(colors:Array, ratios:Array):void { //number of colors and ratios if (colors.length != ratios.length) return; this.colors = copyArray(colors); this.ratios = copyArray(ratios); alphas.splice(0, alphas.length); for (var i:Number = 0 ; i < colors.length ; i++) { alphas.push(255); } } private function copyArray(target:Array):Array { var result:Array = new Array(); for (var i:Number = 0 ; i < target.length ; i++) { result.push(target[i]); } return result; } public function getColors():Array { return copyArray(colors); } public function getAlphas():Array { return copyArray(alphas); } public function getRatios():Array { return copyArray(ratios); } } }
mohon saran-sarannya lagi
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.

- my works -
   
 
 
Old 07/12/2009, 21:32 Reply With Quote   #4
alijaya
GDI Power Users
 
alijaya's Avatar
 
Join Date: Dec 2007
Location: Pangkalpinang
Posts: 3,279
alijaya is on a distinguished road
Send a message via Yahoo to alijaya alijaya is offline
Hmmm... Aku rasa perlin noise di bitmap data hampir mirip ma efek cloud di sotosop, coba di cek
__________________
tobat ngejunk. tobat nyepam. tobat bikin yang gak bener. tobat kasih komen gak jelas. tobat buang-buang ikon. tobat jadi orang jelek. tobat maen komputer sambil belajar. tobat banget kalo ngomong gak bertanggung jawab. tobat banget untuk kesalahan laennya.
"siapa yang mau ikut2an tobat??"
blog : http://alijaya.wordpress.com/, http://bothaxe.wordpress.com/
   
 
 
Old 07/12/2009, 22:18 Reply With Quote   #5
kornwaretm
Member
 
kornwaretm's Avatar
 
Join Date: Sep 2008
Location: jogja
Posts: 245
kornwaretm is on a distinguished road
kornwaretm is offline
wanderful........
jadi tambah dong perlin noise
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.

- my works -
   
   Reply   


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT +7. The time now is 01:30.


skin developed by: uray
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.