threejs 笔记 05 —— 光源

1,052 阅读3分钟

环境光

光源的基类为Light

AmbientLight

环境光会均匀的照亮场景中的所有物体。

环境光不能用来投射阴影,因为它没有方向,也不会体现物体的棱角

/**
 * 创建网格模型
 */
var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
var material = new THREE.MeshLambertMaterial({
  color: 0xffffff
}); //材质对象Material
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中

var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );

可接受参数

color, intensity

颜色和光照强度

color
var light = new THREE.AmbientLight( 0xff0000 ); // soft white light
scene.add( light );

模型本身的颜色设置为白色,受平行光照射颜色影响比较明显

var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
var material = new THREE.MeshLambertMaterial({
  color: 0xffffff
}); //材质对象Material
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中

intensity
var ambient = new THREE.AmbientLight(0xff0000, 0.6);

intensity默认值为1;

光照效果设置为0.6,明显比上一个效果暗许多

点光源

从一个点向各个方向发射的光源。一个常见的例子是模拟一个灯泡发出的光。

/**
 * 光源设置
 */
//点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
// 通过add方法插入场景中,不插入的话,渲染的时候不会获取光源的信息进行光照计算
scene.add(point); //点光源添加到场景中

位置

点光源位置可以调整,调整光照角度

  let btn = document.getElementById("btn");
  if (btn) {
    btn.onclick = function () {
      setInterval(() => {
        let y = point.position.y;
        point.position.setY(y - 10);
      }, 100);
    };
  }

下面可以看一下光源运动后对模型产生的影响; 为了方便观看,添加一个点光源的辅助对象

var sphereSize = 10; // 辅助对象尺寸
var pointLightHelper = new THREE.PointLightHelper(point, sphereSize);
scene.add(pointLightHelper);

颜色

和环境光一样,点光源也可以通过调整颜色,改变场景中物体的颜色

point.color = new THREE.Color(0xff0000)

强度

point.intensity = 5

point.intensity = 0.5

平行光

平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。

var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
scene.add( directionalLight );

关于平行光对象,位置、颜色、光照强度,与其他光源api基本相同, 主要看一下光源跟踪

光源跟踪 target

平行光的方向是从它的位置到目标位置。默认的目标位置为原点 (0,0,0)。

  /**
   * 光源设置
   */
  // 平行光
  var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  let v3 = new THREE.Vector3(120, 120, -100);
  directionalLight.position.copy(v3);
  scene.add(directionalLight);

  var helper = new THREE.DirectionalLightHelper(directionalLight, 5);
  scene.add(helper);

  let btn = document.getElementById("btn");
  if (btn) {
    btn.onclick = function () {
      setInterval(() => {
        let y = directionalLight.position.y;
        directionalLight.position.setY(y - 5);
        helper.update ()
      }, 100);
    };
  }

设置target之后,光源可以从light.position照射到light.target.position

light.target必须要添加到scene中

  /**
   * 光源设置
   */
  // 平行光
  var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  let v3 = new THREE.Vector3(120, 120, -100);
  directionalLight.position.copy(v3);
  scene.add(directionalLight);

  var helper = new THREE.DirectionalLightHelper(directionalLight, 5);
  scene.add(helper);

  var geometry = new THREE.BoxGeometry(10, 10, 10); //创建一个立方体几何对象Geometry
  var material = new THREE.MeshLambertMaterial({
    color: 0xff0000,
  }); //材质对象Material
  var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

  // directionalLight.position.set(120, 120, -100);
  let v3n = v3.negate();
  mesh.position.copy(v3n);
  directionalLight.target = mesh;
  scene.add( directionalLight.target );

  let btn = document.getElementById("btn");
  if (btn) {
    btn.onclick = function () {
      setInterval(() => {
        let y = directionalLight.target.position.y;
        directionalLight.target.position.setY(y - 5);
        helper.update ()
      }, 100);
    };
  }

这样设置,灯光就可以一直跟踪directionalLight.target进行照射,而不是一个只有旋转分量的'自由平行光'

通过这样的调整,我们可以做很多效果,比如日出日落等

其他光源可以在以后学习中继续探索

有一起学习的小伙伴,可以留言、关注一起探讨threejs