如何在3D模型上实现太阳光照模拟?

如何在3D模型上实现太阳光照模拟?

    • 示例描述与操作指南
    • 示例效果展示
    • 实现步骤

示例描述与操作指南

当前示例用于模拟太阳光照效果。

示例效果展示

实现步骤

第一步 添加屏幕炫光

/**
 * @description:  添加一个屏幕炫光到场景,因为屏幕炫光不是实际的光源,只是一个效果,因此一般配合其他光源使用。
 *                一般用此屏幕炫光来模拟太阳光源,因此配合一个平行光源使用。
 *                一般使平行光产生阴影效果分为以下几步:
 *                1. 将渲染器的阴影设置打开,即 renderer.shadowMap.enabled = true;
 *                2. 将此光源的产生阴影的属性打开,即 spotLdirectionalLightight.castShadow = true;
 *                3. 调整此光源的光源阴影范围,一般要使产生阴影的物体的位置大于阴影相机的最小值,小于最大值;
 *                4. 将需要产生阴影的物体的产生阴影的属性打开,即obj.castShadow = true;
 *                5. 将要接收阴影的属性打开,即obj.receiveShadow = true;

 */
const addLensflareLight = () => {
  vizbim.renderer.shadowMap.enabled = true;  // 将渲染器的阴影设置打开,这样渲染器就可以渲染场景内物体的阴影了

  const textureLoader = new THREE.TextureLoader(); // threejs里面的加载器,用于加载图片

  // 用于模仿太阳光的图片图片,地址可以换成本地路径
  const textureFlare0 = textureLoader.load('http://renyuan.bos.xyz/lensflare0.png');
  const textureFlare3 = textureLoader.load('http://renyuan.bos.xyz/lensflare3.png');

  directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 新建一个平行光源,颜色未白色,强度为1
  directionalLight.position.set(0, 0, 200); // 将此平行光源调整到一个合适的位置
  directionalLight.castShadow = true; // 将此平行光源产生阴影的属性打开
  vizbim.components[componentid].castShadow = true;  // 将正方体产生阴影的设置属性打开
  vizbim.components[componentid].receiveShadow = false;  // 将正方体接收阴影的属性关闭

  directionalLight.target = vizbim.components[componentid]; // 将平行光源的目标设置为正方体构件

  // 设置平行光的的阴影属性,即一个长方体的长宽高,在设定值的范围内的物体才会产生阴影
  const d = 140;
  directionalLight.shadow.camera.left = -d;
  directionalLight.shadow.camera.right = d;
  directionalLight.shadow.camera.top = d;
  directionalLight.shadow.camera.bottom = -d;
  directionalLight.shadow.camera.near = 2;
  directionalLight.shadow.camera.far = 8000;

  directionalLight.shadow.mapSize.x = 1024;  // 定义阴影贴图的宽度和高度,必须为2的整数此幂
  directionalLight.shadow.mapSize.y = 1024;  // 较高的值会以计算时间为代价提供更好的阴影质量

  vizbim.scene.add(directionalLight);  // 将此平行光源加入场景中,我们才可以看到这个光源

  directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 300);  // 创建一个平行光源帮助器,帮助我们看到该光源的位置以及辐射范围
  vizbim.scene.add(directionalLightHelper);  // 将此帮助器添加进场景

  const lensflare = new THREE.Lensflare();  // 实例化一个屏幕炫光对象
  // 加载屏幕炫光所用的图片,并且设置它的大小,距离光源的距离,和颜色。
  // 距离光源的距离的范围值为0到1之间,0为光源位置,1为屏幕位置。
  lensflare.addElement(new THREE.LensflareElement(textureFlare0, 700, 0, directionalLight.color));
  lensflare.addElement(new THREE.LensflareElement(textureFlare3, 60, 0.6));
  lensflare.addElement(new THREE.LensflareElement(textureFlare3, 70, 0.7));
  lensflare.addElement(new THREE.LensflareElement(textureFlare3, 120, 0.9));
  lensflare.addElement(new THREE.LensflareElement(textureFlare3, 70, 1));

  directionalLight.add(lensflare); // 将屏幕炫光添加进平行光里,这样屏幕炫光的位置就是平行光源的位置,并且也加到了场景中
  addGround(); // 创建一个底面,用来接收正方体的阴影
}

第二步 创建阴影平面

// 创建一个地面,用来接收正方体的阴影
// 需要将地面接收阴影的属性打开,以接收阴影
const addGround = () => {
  const material = new THREE.MeshLambertMaterial({
    side: THREE.DoubleSide,  // 将材质设置为双面,如果设置为单面,则只有一面能看见材质,另一面看着就是透明
    color: 0x808080,  // 将材质设置为双面,如果设置为单面,则只有一面能看见材质,另一面看着就是透明
  });
  const geometry = new THREE.PlaneGeometry(50000, 50000, 32);  // 一个长方形几何体,长宽都为100
  const cube = new THREE.Mesh(geometry, material);  // 创建这个mesh对象
  cube.position.copy(vizbim.components[componentid].position);  // 将这个矩形的位置设置为正方体物体的位置
  cube.position.z -= 100;  // 将这个正方体的位置向z轴负方向调整100
  cube.receiveShadow = true;    // 将地面接收阴影的属性打开

  vizbim.scene.add(cube);  // 将地面添加到场景中
  moveTheBox();
  animate();
  render();
}

第三步 构件旋转

// 令构件旋转
const moveTheBox = () => {
  vizbim.components[componentid].rotation.z += 0.01;
  requestAnimationFrame(moveTheBox);
}

下载完整代码

你可能感兴趣的:(#,三维示例代码)