Three.js学习二: 将小案例继续加强

1、三维空间的认识

辅助观察坐标系

THREE.AxesHelper()的参数表示坐标系坐标轴线段尺寸大小,你可以根据需要改变尺寸。

// AxesHelper:辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);

材质半透明设置

设置材质半透明,这样可以看到坐标系的坐标原点。

const material = new THREE.MeshBasicMaterial({
    color: 0x0000ff, //设置材质颜色
    transparent:true,//开启透明
    opacity:0.5,//设置透明度
});

AxesHelper的xyz轴

three.js坐标轴颜色红R、绿G、蓝B分别对应坐标系的xyz轴,对于three.js的3D坐标系默认y轴朝上

设置模型在坐标系中的位置或尺寸

通过模型的位置、尺寸设置,加深3D坐标系的概念。

测试:设置长方体xyz不同方向尺寸

// 设置几何体长宽高,也就是x、y、z三个方向的尺寸
//对比三个参数分别对应xyz轴哪个方向
new THREE.BoxGeometry(100, 60, 20);

测试:改变位置

// 设置模型mesh的xyz坐标
mesh.position.set(100,0,0);

改变相机参数——预览新的渲染效果

你可以尝试源码中改变相机的参数,看看场景中的物体渲染效果怎么变化。

相机放在x轴负半轴,目标观察点是坐标原点,这样相当于相机的视线是沿着x轴正方向,只能看到长方体的一个矩形平面。

camera.position.set(-1000, 0, 0);
camera.lookAt(0, 0, 0);
// 相机视线沿着x轴负半轴,mesh位于相机后面,自然看不到
camera.position.set(-1000, 0, 0);
camera.lookAt(-2000, 0, 0);

相机far偏小,mesh位于far之外,物体不会显示在画布上。

// const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
// 你可以进行下面测试,改变相机参数,把mesh放在视锥体之外,看看是否显示
// 3000改为300,使mesh位于far之外,mesh不在视锥体内,被剪裁掉
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 300);

​ 

2.光源对物体表面影响 

实际生活中物体表面的明暗效果是会受到光照的影响,比如晚上不开灯,你就看不到物体,灯光比较暗,物体也比较暗。在threejs中,咱们用网格模型Mesh模拟生活中物体,所以threejs中模拟光照Light对物体表面的影响,就是模拟光照Light对网格模型Mesh表面的影响。

你可以打开课件中案例源码,对比有光照和无光照两种情况,网格模型Mesh表面的差异。

#受光照影响材质

threejs提供的网格材质,有的受光照影响,有的不受光照影响。

基础网格材质MeshBasicMaterial (opens new window)不会受到光照影响。

//MeshBasicMaterial不受光照影响
const material = new THREE.MeshBasicMaterial(); 

漫反射网格材质MeshLambertMaterial (opens new window)会受到光照影响,该材质也可以称为Lambert网格材质,音译为兰伯特网格材质。

一个立方体长方体使用MeshLambertMaterial材质,不同面和光线夹角不同,立方体不同面就会呈现出来不同的明暗效果。

//MeshLambertMaterial受光照影响
const material = new THREE.MeshLambertMaterial(); 

光源简介

Three.js提供了多种模拟生活中光源的API,文档搜索关键词light就可以看到。

 

点光源PointLight (opens new window)可以类比为一个发光点,就像生活中一个灯泡以灯泡为中心向四周发射光线。

//点光源:两个参数分别表示光源颜色和光照强度
// 参数1:0xffffff是纯白光,表示光源颜色
// 参数2:1.0,表示光照强度,可以根据需要调整
const pointLight = new THREE.PointLight(0xffffff, 1.0);

 除了通过THREE.PointLight的参数2设置光照强度,你可以可以直接访问光照强度属性.intensity设置。

pointLight.intensity = 1.0;//光照强度

光源衰减

实际生活中点光源,比如比如一个灯泡,随机距离的改变,光线会衰减,越来越弱,光源衰减属性.decay默认值是2.0,如果你不希望衰减可以设置为0.0

pointLight.decay = 0.0;//设置光源不随距离衰减

【扩展提醒】:如果使用默认衰减2.0,不同版本可能有差异,对于部分threejs新版本,有时候你可能看不到光源效果,这时候可以把光照强度加强试试看,如果你的版本不影响,就不用加强光照强度(根据版本情况灵活对应)。

// 你可以对比不同光照强度明暗差异(传播同样距离)
pointLight.intensity = 10000.0;//光照强度
pointLight.intensity = 50000.0;//光照强度

光源位置

你把点光源想象为一个电灯泡,你在3D空间中,放的位置不同,模型的渲染效果就不一样。

注意光源位置尺寸大小:如果你希望光源照在模型的外表面,那你就需要把光源放在模型的外面。

//点光源位置
pointLight.position.set(400, 0, 0);//点光源放在x轴上

光源添加到场景

光源和网格模型Mesh对应一样是三维场景的一部分,自然需要添加到三维场景中才能起作用。

scene.add(pointLight); //点光源添加到场景中

设置好上面所有代码,你现在可以执行代码,用浏览器查看渲染效果。

#改变光源位置,观察网格模型表面的明暗变化。

pointLight.position.set(400, 200, 300); 

视频讲解(opens new window)

平时开发调试代码,或者展示模型的时候,可以通过相机控件OrbitControls实现旋转缩放预览效果。

#OrbitControls使用

你可以打开课件案例源码测试下效果。

  • 旋转:拖动鼠标左键
  • 缩放:滚动鼠标中键
  • 平移:拖动鼠标右键

#引入扩展库OrbitControls.js

// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

注意:如果你在原生.html文件中,使用上面引入方式import { OrbitControls } from 'three/addons/controls/OrbitControls.js';,注意通过<script type="importmap">配置。

<script type="importmap">
    {
		"imports": {
			"three": "../../../three.js/build/three.module.js",
      "three/addons/": "../../../three.js/examples/jsm/"
		}
	}
</script>

#使用OrbitControls

// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
    renderer.render(scene, camera); //执行渲染操作
});//监听鼠标、键盘事件

#OrbitControls本质

OrbitControls本质上就是改变相机的参数,比如相机的位置属性,改变相机位置也可以改变相机拍照场景中模型的角度,实现模型的360度旋转预览效果,改变透视投影相机距离模型的距离,就可以改变相机能看到的视野范围。

controls.addEventListener('change', function () {
    // 浏览器控制台查看相机位置变化
    console.log('camera.position',camera.position);
});

平行光与环境光

视频讲解(opens new window)

本节课通过平行光DirectionalLight (opens new window)和环境光AmbientLight (opens new window)进一步了解光照对应模型Mesh表面的影响。

#点光源辅助观察PointLightHelper

通过点光源辅助观察对象PointLightHelper (opens new window)可视化点光源。

预览观察:可以借助相机控件OrbitControls旋转缩放三维场景便于预览点光源位置

// 光源辅助观察
const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
scene.add(pointLightHelper);

改变点光源位置,观察光照效果变化。

pointLight.position.set(100, 60, 50);
// 改变点光源位置,使用OrbitControls辅助观察
pointLight.position.set(-400, -200, -300);

#环境光设置

环境光AmbientLight (opens new window)没有特定方向,只是整体改变场景的光照明暗。

//环境光:没有特定方向,整体改变场景的光照明暗
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);

#平行光

平行光DirectionalLight (opens new window)就是沿着特定方向发射。

// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh;
scene.add(directionalLight);

#平行光辅助观察DirectionalLightHelper

通过点光源辅助观察对象DirectionalLightHelper (opens new window)可视化点光源。

// DirectionalLightHelper:可视化平行光
const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5,0xff0000);
scene.add(dirLightHelper);

#平行光与Mesh表面光线反射规律

平行光照射到网格模型Mesh表面,光线和模型表面构成一个入射角度,入射角度不同,对光照的反射能力不同。

光线照射到漫反射网格材质MeshLambertMaterial (opens new window)对应Mesh表面,Mesh表面对光线反射程度与入射角大小有关。

// 对比不同入射角,mesh表面对光照的反射效果
directionalLight.position.set(100, 0, 0);
directionalLight.position.set(0, 100, 0);
directionalLight.position.set(100, 100, 100);
directionalLight.position.set(100, 60, 50);
//directionalLight.target默认指向坐标原点

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值