indices 顶点
PBR 基于物理的渲染
贴图库 poliigon
资源:Threejs/examples/js
Float32Array 32位浮点数数组
BufferGeometry 几何体,每三个点组成一个三角形面
attributes.position.count 顶点数量,多个三角形面之间重合的顶点分别算
attributes.position.array 顶点坐标数组,一个顶点占三个轴坐标
attributes.position.uv 几何体展开图,用于确定贴图位置
attributes.position.normal 确定姿态
BoxGeometry 立方体 attributes.position.count 是24,估计是顶点复用
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Titletitle>
- <script src="three.min.js">script>
-
- <script src="../examples/js/controls/OrbitControls.js">script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js">script>
- head>
- <body>
- <script>
- // 场景
- const scene = new THREE.Scene();
-
- // 物体
- const geometry = new THREE.BoxGeometry(100, 150, 200); // 几何体
- const material = new THREE.MeshLambertMaterial({ // 材质
- color: 0x00ff00,
- transparent: true,
- opacity: 0.6
- });
- const mesh = new THREE.Mesh(geometry, material); // 物体(由几何体和材质确定)
- mesh.position.set(0, 0, 100); // 物体质心的位置
- mesh.scale.set(2, 1, 3); // 缩放
- mesh.rotateX(Math.PI / 4); // 旋转弧度,绕着穿过质心的轴线旋转
- scene.add(mesh); // 往场景里添加物体
-
- // 光源
- const light = new THREE.PointLight(0xffffff, 1, 10000); // 点光源
- light.position.set(300, 400, 500); // 光源位置
- scene.add(light);
-
- // 坐标轴
- const axesHelper = new THREE.AxesHelper(500); // x红 y绿 z蓝
- scene.add(axesHelper);
-
- // 可视化点光源
- const pointLightHelper = new THREE.PointLightHelper(light, 1);
- scene.add(pointLightHelper);
-
- // 透视相机(fov水平视场角,fov和aspect间接确定了垂直视场角,near和far确定了相机观察的距离区间)
- const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
- camera.position.set(600, 600, 600); // 相机位置
- camera.lookAt(0, 0, 0); // 拍摄目标,即朝向
-
- // 渲染器,即canvas画布
- const renderer = new THREE.WebGLRenderer();
- renderer.setSize(window.innerWidth, window.innerHeight); // canvas 尺寸,单位为像素,与场景里的尺寸无关
- renderer.setClearColor(0xffffff); // 画布颜色
- renderer.render(scene, camera);
- document.body.appendChild(renderer.domElement); // 将canvas加入到 dom
-
- // 相机控制器,改变的是相机的位置
- // 滚轮,改变位置-朝向保持不变(即相机在朝向上移动,始终朝向拍摄目标)
- // 鼠标左键拖动,改变位置-与拍摄目标距离保持不变(即相机在球面上移动,始终朝向拍摄目标)
- // 鼠标左键平移,改变朝向
- const controls = new THREE.OrbitControls(camera, renderer.domElement);
- controls.target.set(0, 0, 0); // 拍摄目标,即朝向
- controls.update(); // 会覆盖 camera.lookAt
- controls.addEventListener("change", () => {
- renderer.render(scene, camera); // 移动相机后,重新渲染画布
- });
-
- // 动画
- const clock = new THREE.Clock();
-
- function animate() {
- // console.log(clock.getDelta()); // 间隔时间,用于获取渲染耗时
- renderer.render(scene, camera);
- mesh.rotateY(0.01);
- window.requestAnimationFrame(animate)
- }
-
- animate();
-
- // GSAP 动画库
- let animate1 = gsap.to(mesh.position, {
- x: 300,
- duration: 5,
- ease: "bounce.inOut", // 速度曲线
- delay: 2,
- repeat: 2,
- yoyo: true, // 往返
- onStart: ()=>{
- console.log('动画开始');
- },
- onComplete: () => {
- console.log('动画结束');
- }
- });
- window.addEventListener('click', (event) => {
- if(animate1.isActive){
- animate1.pause(); // 暂停动画
- }
- else{
- animate1.resume(); // 恢复动画
- }
- });
-
- // 画布点投射,即画布上的一点沿着视锥线画一条射线;用于寻找与射线交汇的物体,即鼠标拾取,进而实现交互
- window.addEventListener('click', (event) => {
- const pointer = new THREE.Vector2(); // 画布点
- pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
- pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
-
- const raycaster = new THREE.Raycaster(); // 射线
- raycaster.setFromCamera(pointer, camera);
-
- const intersects = raycaster.intersectObjects(scene.children); // 找出与射线交汇的物体
- for (let i = 0; i < intersects.length; i++) {
- console.log(intersects[i]);
- }
- });
- script>
- body>
- html>