<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 配置一个导入的映射 -->
<script type="importmap">
{
"imports" : {
"three" : "./threejs/build/three.module.js",
"three/addons/" : "./threejs/examples/jsm/"
}
}
</script>
<script type="module">
/*
光源的基础
=> 实际生活中物体表面的明暗效果是会受到光照的影响,
=> three.js中同样也要模拟光照Light对网格模型Mesh表面的影响。
材质与光源
=> 基础网格材质MeshBasicMaterial(opens new window)不会受到光照影响。
=> 漫反射网格材质MeshLambertMaterial(opens new window)会受到光照影响,
-> 该材质也可以称为Lambert网格材质,音译为兰伯特网格材质
*/
// 1. 首先就是导入我们的three.js
import * as THREE from "three"
// 1.1 导入我们要使用的控件 相机控件
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 2. 场景: 我们需要创建一个用来展示 3d 内容的场景
// 也就是我们的三维场景, 和我们平时的平面的还是不一样的
// 不能正常的展示到网页中 需要单独创建一个场景
// 创建三维场景的语法: const scene = new THREE.Scene()
// 创建三维场景
const scene = new THREE.Scene()
// 3. 相机: 用来代替我们的眼睛去观察物体,通过相机摆放在不同的位置来实现对于3d物体的不同角度的效果的呈现
// 3d 物体有各个面 我们需要使用相机来对各个面进行观察
// 创建一个相机
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
// 4. 渲染器: 我们的场景和相机都是一个虚拟的概念,如果要把内容呈现到网页当中,需要通过渲染器来进行渲染。
// 其实就是把我们要展示的物体在页面中展示出来
// 创建一个渲染器
const renderer = new THREE.WebGLRenderer({
// 因为我们的底色是黑色的 我们看起来依旧是不直观
// 所以我们来设置辅助透射层
// alpha: 英/ˈælfə/ 阿尔法
alpha: true, // 背景是否可以设置透明色
antialias: true // 表示是否开启反锯齿
// 注意: 这里有问题不能起效果
});
// 设置渲染器的大小, 我们设置的大小就是我们的整个窗口
renderer.setSize( window.innerWidth, window.innerHeight ); // 设置渲染器的大小
// 把渲染器要渲染的内容添加到body中
document.body.appendChild( renderer.domElement ); // 把渲染器的内容加载成为一个body的子元素
// 注意: 有了坐标系以后的操作
// 5. 着色器: 一个基础的几何体,并不是最终要展示的内容而是一个等待被描述的几何体(毛坯) 也是一个什么样的物体
// 这就相当于是我们的毛坯房还没有进行装修
// 创建着色器(这里就是创建了一个立方体) 除了立方体还有其他几何体: 圆柱体 球体 .....
// 这里的三个值,指的就是正方体三个方向(x, y, z)的大小
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
// 6. 材质: 用于对着色器(几何体)表面材料的说明
// 创建材质 这会我创建的材质不在是之前的 我们创建一个Lambert网格材质
// material: 英/məˈtɪəriəl/ 布料 原料 素材的意思
// 注意: 因为 Lambert 材料的收到光照影响的
const material = new THREE.MeshLambertMaterial({
// 设置颜色()
color: '0xff0000'
})
// 7. 物体: Mesh 网格模型 , 网格模型就是最终需要展示的3d物体
// 创建最终要展示的物体
const cube = new THREE.Mesh(geometry, material);// 创建的物体是哪个着色器(几何体) 使用那种材质
// 在场景scene当中添加创建好的物体
// 也就是把物体添加到场景中
// 没有添加光源值之前都是以黑色形态存在
scene.add(cube);
// 注意: 这个时候的物体的黑色的 是因为 Lambert 材料的收到光照影响的
// 注意: 我们没有添加光源只会以黑色的形态存在
// 接下来我们添加一个点光源 就像等于我们的灯泡
// 创建点光源
// 第一个参数: 表示的是光的颜色
// 第二个参数: 表示的是光的强度
// 0xffffff: 白色
const pointLight = new THREE.PointLight('0xffffff', 1.0)
// 上面创建出了光源, 接下来我们就要把光源添加到一个位置
// 第一个参数: 表示的是 x 轴的位置
// 第一个参数: 表示的是 y 轴的位置
// 第一个参数: 表示的是 z 轴的位置
// pointLight.position.set(10, 0, 0) // 表示的意思是在 x 轴 10 的位置设置了一个光源
// 上面的设置只能照射到一个面 我们重新调整
pointLight.position.set(10, 10, 10) // 表示的意思是在 x 轴 10 的位置设置了一个光源
// 之后我们在场景中添加我们的点光源
scene.add(pointLight)
// 为的方便我们看到我们的光源的位置 three.js提供了一个helper帮助我们查看光源的位置
// 第一个参数: 那个光源
// 第二个参数: 什么位置
const pointLightHelper = new THREE.PointLightHelper(pointLight, 10)
// 之后在场景中添加
scene.add(pointLightHelper)
// 8. 设置相机的位置
camera.position.z = 5;
// camera.position.x = 2;
// camera.position.y = 5;
// 创建一个辅助线(辅助器)
const axesHelper = new THREE.AxesHelper(3)
// 在我们的场景中使用辅助线
scene.add(axesHelper)
// 上面导入了我们的控件以后我们就可以得到一个控制器
// 9. 我们创建一个控制器
// Orbit: 英/ˈɔːbɪt/ 轨道的意思
// 需要传递参数
// 第一个: 我们的相机
// 第二个: 我们的渲染器中的节点
// 作用: 其实的对像机器的参数做出调整的
const controls = new OrbitControls(camera, renderer.domElement)
// 证明 : 对像机器的参数做出调整的
// 给控制器添加一个事件
controls.addEventListener('change', () => {
// 我们打印出相机的位置
// console.log('camera.position', camera.position);
// 值发生改变以后执行重新的渲染即可
renderer.render(scene, camera)
})
// 这个时候我们直接使用渲染函数进行渲染就好了
// 也就不需要之前的自动旋转了
renderer.render(scene, camera)
</script>
</body>
</html>