计算机图形学 实验报告
班级 计算机工硕班 学号 2011220456 姓名 王泽晶
1
实验五: Phong光照模型
实验目的
通过本次试验,学生可以掌握简单光照明模型的计算,以及真实感绘制中三维场景搭建的初步知识。
实验内容:
对给定的光源、相机状态,对球进行Phong光照明模型绘制。
搭建三维场景:
a) 在三维空间中摆放1个球,半径为R,默认为50 ,摆放位置为(0,0,0) b) 球的材质默认值为Ka = (0.1,0.1,0.1), Kd = (0,0,0.8), Ks = 0.2, n = 10 c) 视点方向初始为(0,0,1), 光源方向初始为(1,1,1) d) 视口设置为x0 = -100, y0 = -75, w = 200, h = 150
使用phong模型绘制场景
试验步骤:
添加成员函数,编写成员数代码为
override public function computeIntersection( viewStart:Vec3, viewDir:Vec3):Boolean {
// See http://paulbourke.net/geometry/sphereline/
var viewEnd:Vec3 = viewStart.add(viewDir);
var A:Number = Math.pow(viewEnd.getVec(0) - viewStart.getVec(0), 2)
Math.pow(viewEnd.getVec(2) - viewStart.getVec(2), 2);
+Math.pow(viewEnd.getVec(1) - viewStart.getVec(1), 2) +
var B:Number =((viewEnd.getVec(0) - viewStart.getVec(0)) * (viewStart.getVec(0)
(viewEnd.getVec(1) - viewStart.getVec(1)) * (viewStart.getVec(1) - (viewEnd.getVec(2) - viewStart.getVec(2)) * (viewStart.getVec(2) -
- _position.getVec(0)) + _position.getVec(1)) + _position.getVec(2))) * 2.0;
2
}
var C:Number = Math.pow(_position.getVec(0) - viewStart.getVec(0), 2) +
Math.pow(_position.getVec(1) - viewStart.getVec(1), 2) +
Math.pow(_position.getVec(2) - viewStart.getVec(2), 2) - _radius*_radius;
// Solve C + Bt + At^2 = 0
var delta:Number = B*B - 4*A*C;
if ( delta<0.0 || A==0.0 ) return false;
// We don't consider whether 0 var t1:Number = (-B + Math.sqrt(delta)) / (2*A); var t2:Number = (-B - Math.sqrt(delta)) / (2*A); if ( t1 point = viewStart.multiplyk(1.0 - t1).add(viewEnd.multiplyk(t1)); point = viewStart.multiplyk(1.0 - t2).add(viewEnd.multiplyk(t2)); else normal = Vec3.normalize(point.minus(_position)); return true; public var _width :Number =0.0; public var _height:Number = 0.0; public var data:Array = new Array(); protected function group1_creationCompleteHandler(event:FlexEvent):void { } public function draw():void{ graphics.clear(); if(txtViewDir.text == \) var ary:Array = txtViewDir.text.split(\); var flag:Boolean = false; for(var i:int= 0;i if(flag) if(ary[i] == \ || isNaN(ary[i])) { } flag = true; break; return; draw(); 3 } { } txtViewDir.setStyle(\,0x000000); var viewDir:Vec3 = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2])); ary = txtLight.text.split(\); flag = false; for(i= 0;i if(flag) { } txtLight.setStyle(\,0x000000); var light:Light = new Light(); light.direction = new Vec3(Number(ary[0]), Number(ary[1]), light.ambient = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2])); light.intensity = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2])); var material:Material = new Material(); material.diffuse =new Vec3(0.0, 0.0, 0.8); material.specular =new Vec3(0.2, 0.2, 0.2); material.ambient =new Vec3(0.1, 0.1, 0.1); data = createSceneImage( 200, 150, viewDir, light, material ); drawImg(); txtLight.setStyle(\,0xff0000); return; if(ary[i] == \ || isNaN(ary[i])) { } flag = true; break; txtViewDir.setStyle(\,0xff0000); return; Number(ary[2])).negative(); public function drawImg():void{ for(var y:int = 0 ;y<150;y++) 4 } { } for(var x:int =0;x<200;x++){ } var index:int = (y*200 + x) * 3; var r:Number = data[index+0]; var g:Number = data[index+1]; var b:Number = data[index+2]; var cl:uint =(r << 16) | (g << 8) | b; this.graphics.beginFill(cl) this.graphics.drawCircle(x,y,1); this.graphics.endFill(); public function allocateBuffer( width:int,height: int ):Array { } public function createSceneImage( width:int,height: int , { var data:Array = new Array(); var sphere:SphereObject = new SphereObject(50.0); sphere.setPosition(new Vec3(0.0, 0.0, 0.0) ); sphere.setMaterial( material ); var halfW:int = width / 2 var halfH:int = height / 2; for ( var y:int=0; y for ( var x:int=0; x var viewStart:Vec3 = new Vec3(Number(x - halfW), Number(y - halfH), 0.0); if ( sphere.computeIntersection(viewStart, viewDir) ) var index:int = (y*width + x) * 3; sphere.color = sphere.computeColor(light, viewDir, sphere.normal); sphere.color = new Vec3(0.1, 0.1, 0.1); else viewDir:Vec3, light:Light, material:Material ):Array var data:Array = new Array(); data.length = width * height * 3; _width = width; _height = height return data; 5 } } } data[index+0] = (sphere.color.getVec(0) * 255.0); data[index+1] = (sphere.color.getVec(1) * 255.0); data[index+2] = (sphere.color.getVec(2) * 255.0); return data; protected function button1_clickHandler(event:MouseEvent):void { // TODO Auto-generated method stub draw(); } 编译运行得到如下结果: 6