package {
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.shadematerials.CellMaterial;
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
import org.papervision3d.materials.shadematerials.GouraudMaterial;
import org.papervision3d.materials.shadematerials.PhongMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;
public class Example004 extends BasicView {
private static const ORBITAL_RADIUS:Number = 200;
private var sphere1:Sphere;
private var sphere2:Sphere;
private var sphere3:Sphere;
private var sphere4:Sphere;
private var sphereGroup:DisplayObject3D;
public function Example004() {
super(0, 0, true, false);
// set up the stage
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// Initialise Papervision3D
init3D();
// Create the 3D objects
createScene();
// Start rendering the scene
startRendering();
}
private function init3D():void {
// position the camera
camera.x = -200;
camera.y = 200;
camera.z = -500;
}
private function createScene():void {
// Specify a point light source and its location
var light:PointLight3D = new PointLight3D(true);
light.x = 400;
light.y = 1000;
light.z = -400;
// Create a new material (flat shaded) and apply it to a sphere
var flatShadedMaterial:MaterialObject3D = new FlatShadeMaterial(light, 0x6654FF, 0x060433);
sphere1 = new Sphere(flatShadedMaterial, 50, 10, 10);
sphere1.x = -ORBITAL_RADIUS;
// Create a new material (Gouraud shaded) and apply it to a sphere
var gouraudMaterial:MaterialObject3D = new GouraudMaterial(light, 0x6654FF, 0x060433);
sphere2 = new Sphere(gouraudMaterial, 50, 10, 10);
sphere2.x = ORBITAL_RADIUS;
// Create a new material (Phong shaded) and apply it to a sphere
var phongMaterial:MaterialObject3D = new PhongMaterial(light, 0x6654FF, 0x060433, 150);
sphere3 = new Sphere(phongMaterial, 50, 10, 10);
sphere3.z = -ORBITAL_RADIUS;
// Create a new material (cell shaded) and apply it to a sphere
var cellMaterial:MaterialObject3D = new CellMaterial(light, 0x6654FF, 0x060433, 5);
sphere4 = new Sphere(cellMaterial, 50, 10, 10);
sphere4.z = ORBITAL_RADIUS;
// Create a 3D object to group the spheres
sphereGroup = new DisplayObject3D();
sphereGroup.addChild(sphere1);
sphereGroup.addChild(sphere2);
sphereGroup.addChild(sphere3);
sphereGroup.addChild(sphere4);
// Add the light and spheres to the scene
scene.addChild(sphereGroup);
scene.addChild(light);
}
override protected function onRenderTick(event:Event=null):void {
// rotate the spheres
sphere1.yaw(-8);
sphere2.yaw(-8);
sphere3.yaw(-8);
sphere4.yaw(-8);
// rotate the group of spheres
sphereGroup.yaw(3);
// call the renderer
super.onRenderTick(event);
}
}
}
执行代码后,会看到4个旋转的球体,每个球体都对光有不同阴影效果。
这个例子的代码仍然是前几篇的代码大致相同的,3D场景的初始化过程:viewport 和 camera的设置也是一样的,不同之处在于构建了四个球体,并加入了光源。
加入光源在Papervision3D 中是件很简单的事情:new 一个PointLight3D,再设置一下坐标就好了。
// Specify a point light source and its location
var light:PointLight3D = new PointLight3D(true);
light.x = 400;
light.y = 1000;
light.z = -400;
PointLight3D构造函数中传入true的意思是是否人为的让这个光源点可见,在这个例子里其实不是必需的,但是但是在调式的时候让光源点可见是很有帮助的。
让新加入场景的光产生效果,我们需要可以产生阴影的材质。另外我们在画面上看到球体的颜色是球体的材质提供的,所以你可以这样认为,Papervision3D 中的光源只能产生白色光。
// Create a new material (flat shaded) and apply it to a sphere
var flatShadedMaterial:MaterialObject3D = new FlatShadeMaterial(light, 0x6654FF, 0x060433);
sphere1 = new Sphere(flatShadedMaterial, 50, 10, 10);
sphere1.x = -ORBITAL_RADIUS;
// Create a new material (Gouraud shaded) and apply it to a sphere
var gouraudMaterial:MaterialObject3D = new GouraudMaterial(light, 0x6654FF, 0x060433);
sphere2 = new Sphere(gouraudMaterial, 50, 10, 10);
sphere2.x = ORBITAL_RADIUS;
// Create a new material (Phong shaded) and apply it to a sphere
var phongMaterial:MaterialObject3D = new PhongMaterial(light, 0x6654FF, 0x060433, 150);
sphere3 = new Sphere(phongMaterial, 50, 10, 10);
sphere3.z = -ORBITAL_RADIUS;
// Create a new material (cell shaded) and apply it to a sphere
var cellMaterial:MaterialObject3D = new CellMaterial(light, 0x6654FF, 0x060433, 5);
sphere4 = new Sphere(cellMaterial, 50, 10, 10);
sphere4.z = ORBITAL_RADIUS;
以上的代码作用是构建4个球体,每个球体都指定了一种材质,你可以发现4种材质的第一个参数都是指定光源,后面跟了2种颜色。对于 FlatShadeMaterial 和 GouraudMaterial 这2种颜色分别表示diffuse 和 ambient。对于PhongMaterial 这2种颜色分别表示specular 和 ambient,后面一个参数150表示反射率,这个值可以从0 到255变化。对于CellMaterial 这2种颜色表示光在这2种颜色渐变,后面一个参数5表示渐变分为5段。
然后将这些球体加入一个DisplayObjet3D 组里并加入scene的显示列表。
// Create a 3D object to group the spheres
sphereGroup = new DisplayObject3D();
sphereGroup.addChild(sphere1);
sphereGroup.addChild(sphere2);
sphereGroup.addChild(sphere3);
sphereGroup.addChild(sphere4);
// Add the light and spheres to the scene
scene.addChild(sphereGroup);
scene.addChild(light);
最后给这些球体加入动画效果,让这4个球各自饶着自己的Y轴自转,4个球组成的DisplayObject3D组也饶着自己的Y轴自转。
// rotate the spheres
sphere1.yaw(-8);
sphere2.yaw(-8);
sphere3.yaw(-8);
sphere4.yaw(-8);
// rotate the group of spheres
sphereGroup.yaw(3);
ok,结束。这篇文章只是写了一点很基础的关于光影的应用,当然你可以找网上找到更多的一些较为复杂的效果。不过不管怎么说,从这里开始是个很不错的选择。