Papervision3D光影

这篇要介绍一下另一个构成3D世界基本元素:光。光的加入会让我们渲染出来的场景看上去更加真实。在Papervision3D的世界里,光要产生效果,必须要配合照在特殊的材质上才能看到。这篇文章的例子会介绍它们是如何工作的。

在开始之前,有必要介绍几个在3D世界中描述光的术语。
Ambient - 阴影色
Diffuse - 过渡色
Specular - 高光色

然后还要介绍4种基本的材质,光照在上面会产生阴影,表现为向光面更亮,背光面更暗,不同的材质表现出来的效果都不一样。他们是:Flat shaded、Gouraud shaded、Phong shaded 和 Cell shaded,这四种材质可以在orgpapervision3dmaterialsshadematerials 中找到。


下面看看Example004中代码如何写。

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,结束。这篇文章只是写了一点很基础的关于光影的应用,当然你可以找网上找到更多的一些较为复杂的效果。不过不管怎么说,从这里开始是个很不错的选择。

原文地址:https://www.cnblogs.com/eden/p/2019869.html