スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

鏡面反射光+拡散反射光

2007-11-28 | 20:29

前回の鏡面反射光に拡散反射光も考慮したデモです。
クリックすると光源が移動します。
クリック位置が下に行くほどハイライト係数が高くなるようになってます。
(ハイライト係数が大きくなると、ハイライト部分はシャープになります)

package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    import org.papervision3d.core.*;    
    [SWF(width="400", height="400", backgroundColor="#ffffff")]
        public class Light2 extends Sprite
        {
            private var bmd:BitmapData;
            private var center:Number3D;
            private var radius:int;
            public function Light2()
            {
                stage.frameRate = 5;
                radius = stage.stageWidth/2*0.6;
                center = new Number3D(stage.stageWidth/2,stage.stageHeight/2,0);

                bmd = new BitmapData( stage.stageWidth,stage.stageHeight,false,0x010101);
                addChild(new Bitmap(bmd));

                render(new Point(stage.stageWidth/2, stage.stageWidth/2));
                stage.addEventListener (MouseEvent.CLICK, function(e:*):void{
                        render(new Point(stage.mouseX, stage.mouseY)); });
            }

            private function render(p:Point):void{
                var h:Number = p.y * 20/stage.stageHeight + 1;
                // Y座標を左下が原点となる座標に変換
                p.y = stage.stageHeight - p.y;
                for(var x:int = 0 ; x < stage.stageWidth ; x++){
                    for(var y:int = 0 ; y < stage.stageHeight ; y++){
                        var n:Number3D;
                        var xx:int = x-center.x;
                        var yy:int = y-center.y;
                        if(Math.sqrt(xx*xx+yy*yy) > radius)
                            continue;

                        // x,yに対応するz
                        var z:Number  = -Math.sqrt(radius*radius - xx*xx + yy*yy);
                        // x,y,zの法線ベクトル
                        n= new Number3D(xx, yy, z);
                        n.normalize();

                        // 逆光線ベクトル
                        var lightDash:Number3D = new Number3D(p.x - x, p.y - y ,-500-z);
                        lightDash.normalize ();
                        var temp:Number = 2*(Number3D.dot(lightDash, n));
                        // 光線の正反射ベクトル
                        var reflection:Number3D =
                            Number3D.sub(new Number3D(temp* n.x, temp*n.y, temp*n.z), lightDash);
                        reflection.normalize();
                        // 視線ベクトル(逆向き)
                        var eye:Number3D = new Number3D(center.x-x,center.y-y,-1000-z);
                        eye.normalize();

                        var dot:Number = Number3D.dot(reflection,eye);
                        dot = Math.max(dot,0);
                        var strength:Number = Math.pow(dot, h);
                        //strength = (strength*128+128) /256;

                        // 光線ベクトル
                        var light:Number3D = new Number3D(x - p.x, y - p.y , z+500);
                        light.normalize();
                        // 拡散反射光
                        var diff:Number = -Number3D.dot(n,light);
                        diff = Math.max(diff,0);

                        // 鏡面反射と拡散反射
                        strength = (strength + diff) / 2;

                        bmd.setPixel(x, stage.stageHeight-y, 0xff*strength);
                    }
                }
            }
        }
}


上記の知識はこの本より
スポンサーサイト

Comment

Post a comment

Secret

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。