2007-11-25 | 22:37
バンプマッピングとは、面の方向(法線ベクトル)と照明の方向から面の明るさを決める事により凹凸を表現する方法。
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20050826
下のデモでは波の面の傾きから各面の明るさを求めている。
(時間が経つと波は静まりますが、クリッくするとまた開始されます。
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20050826
下のデモでは波の面の傾きから各面の明るさを求めている。
(時間が経つと波は静まりますが、クリッくするとまた開始されます。
package { import flash.display.*; import flash.events.*; import org.papervision3d.core.*; [SWF(width="100", height="100", backgroundColor="#ffffff")] public class bump extends Sprite { private var fluid:Fluid; private var bmd:BitmapData; private var range:int; public function bump() { stage.frameRate = 5; range = 100; this.fluid = new Fluid(range); //var bitmap:Bitmap = new myImage(); bmd = new BitmapData(range,range,false,0xffffff); addChild(new Bitmap(bmd)); bomb(); stage.addEventListener(MouseEvent.CLICK, function(e:*):void{ bomb(); }); this.addEventListener(Event.ENTER_FRAME, function(e:*):void{ fluid.evaluate(); for(var x:int = 0 ; x < range-1 ; x++){ for(var z:int = 0 ; z < range-1 ; z++){ // (x+1,y,z) - (x,y,z) var v1:Number3D = new Number3D(1, fluid.Buffer[x+1][z] - fluid.Buffer[x][z], 0); // (x,y,z+1) - (x,y,z) var v2:Number3D = new Number3D(0, fluid.Buffer[x][z+1] - fluid.Buffer[x][z], 1); // v1,v2から法線ベクトルを求める var normal:Number3D = Number3D.cross(v1,v2); normal.normalize(); var light:Number3D = new Number3D(range/2-x, 30, range/2); light.normalize(); var shadow:Number = Number3D.dot(normal,light); //trace(shadow); bmd.setPixel(x,z, (0xf0*shadow << 16) + (0xf0*shadow <<8) + 0xff*shadow); } } }); } private function bomb():void{ fluid.clearBuffer(); var xx:int = range/2+8; var yy:int = range/2+8; for(var i:int=xx; i < xx+8; i++){ for(var j:int=yy; j < xx+8 ; j++){ fluid.Buffer[j][i] += 0.3; } } } } } internal class Fluid { private var w:int; private var h:int; private var buffer:Array = new Array(); private var renderBuffer:int = 0; private var k1:Number; private var k2:Number; private var k3:Number; private var range:int; public function Fluid(range:int):void { this.range = range; w = h = range; clearBuffer(); var d:Number = 1; var t:Number = 0.1; var c:Number = 3.2; var mu:Number = 0.0001; var f1:Number = c*c*t*t/(d*d); var f2:Number = 1/(mu*t+2); k1 = (4 - 8*f1)*f2; k2 = (mu*t-2)*f2; k3 = 2*f1*f2; } public function get Buffer():Array{ return buffer[this.renderBuffer]; } public function clearBuffer():void{ buffer = []; // 変位が格納される3次元配列(2*w*h) for(var i:int = 0 ; i < 2; i++){ var a:Array = new Array(); for(var j:int = 0 ; j < h+1; j++){ var aa:Array = new Array(); for(var k:int = 0 ; k < w+1; k++) aa.push(0); a.push(aa); } buffer.push(a); } } public function evaluate():void{ for(var j:int = 0 ; j < h+1; j++){ var crnt:Array = buffer[renderBuffer][j]; var prev:Array = buffer[1-renderBuffer][j]; for(var i:int = 0 ; i < w+1; i++){ var ii:int = i; var jj:int = j; if(i == 0) ii = 1 else if (i == w) ii = i - 1; if(j == 0) jj = 1 else if (j == h) jj = j - 1; var currentN:Number = buffer[renderBuffer][jj + 1][ii]; var currentP:Number = buffer[renderBuffer][jj - 1][ii]; prev[i] = k1*(crnt[ii]) + k2*prev[ii] + k3*(crnt[ii+1] + crnt[ii-1] + currentN + currentP); } } renderBuffer = 1-renderBuffer; } }
毎回全ピクセル再描画しているので遅い。
面の法線ベクトルを求めるには、面を構成する二つのベクトルの外積を求めればよい
スポンサーサイト