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

  • 相关阅读:
    随笔
    转:windows 下 netsh 实现 端口映射(端口转发)
    2015年01月01日:新年第一天:happy new year to myself
    谨记一次问题排查经历
    新机器,分区为NTFS, 安装 Windows XP、Windows Server 2003 时蓝屏问题,修改为 FAT32 即可
    Oracle 11g 的bug?: aix 上,expdp 11.2.0.1 导出,impdp 11.2.0.3 导入,Interval 分区的 【Interval】 分区属性成了【N】
    Cursor for loop in Oracle
    Oracle date 详解
    oracle中to_timestamp和to_date什么区别
    Oracle FM FM09999999 确保8位数字 即使全是0
  • 原文地址:https://www.cnblogs.com/eden/p/2019869.html
Copyright © 2011-2022 走看看