Three.js入门①

  最近学习Three.js,此贴供学习记录之用。
  学习视频:Three.js教程。讲解很详细,也有配套的笔记,但不包含前端基础知识的讲解,如果是纯小白的朋友,可以找这位up之前的教程学习一下。

附:此贴记录时间在前期工作(包括环境配置、软件和插件下载等)都准备好之后,在macOS系统,使用VScode编写。

三维场景显示在我们的屏幕中总共分三步:

三维场景渲染步骤

在写.js文件之前

  • 使用importmaps配置路径
    关于importmaps具体的讲解请看这里
<!-- importmap导入映射 -->
<script type="importmap">
	{
		"imports": {
			"three": "./three.js/build/three.module.js"
		}
	}
</script>

⚠️注:若不使用importmap配置,而是在.js文件中直接引入,在使用其他控件时可能会遇到浏览器控制台报错"TypeError: Module name, ‘three’ does not resolve to a valid URL.
",博主尚未想明白是什么原因🥲。

  • .html文件
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Three.js入门①</title>
    </head>

    <body>
        <div id="webgl" style="margin: 100px; background-color: blueviolet;"></div>
        
        <!-- importmap导入映射 -->
        <script type="importmap">
            {
                "imports": {
                    "three": "./three.js/build/three.module.js"
                }
            }
        </script>

        <!-- 引入.js文件 -->
        <script src="./0503_1.js" type="module"></script>
    </body>
</html>

一、创建一个三维场景

  • 引入js
// 引入three.js
import * as THREE from 'three';
  • 创建一个三维场景
// 创建一个三维场景
const scene = new THREE.Scene();
  • 加入辅助观察坐标系
// 添加辅助观察坐标系
const axesHelper = new THREE.axesHelper(100);	// x,y,z,长度均为100,也可以写成(100, 100, 100)
// 将坐标系加入场景
scene.add(axesHelper);

三维场景中的物体

  • 创建物体(形状)
// 添加物体 几何体,长方体,定义长宽高
const geometry = new THREE.BoxGeometry(50, 50, 50);
  • 创建材质对象(外观)
    这里将材质设置为半透明以便更好观察辅助坐标系
// 创建材质对象
const material = new THREE.MeshBasicMaterial({
	color: 0xff0000,	// 颜色
	transparent: true,	// 设置透明
	opacity: 0.5	// 透明度
});
  • 创建网格模型(实体)
// 创建网格模型 参数:形状,材质
const mesh = new THREE.Mesh(geometry, material);
  • 设置物体位置
// 设置模型在三维空间位置
mesh.position.set(0, 0, 0);
  • 添加物体到场景中
// 添加物体
scene.add(mesh);

二、加入摄影机

  • 设置在屏幕中显示的尺寸,即画布尺寸
// 设置画布尺寸
const width = 800;
const height = 500;
  • 创建相机对象并设置参数

透视投影摄像机参数:
    fov: 视场角度 模拟观察范围,在此范围内的物体予以显示
    aspect: 视锥水平和竖直方向长度比 常与画布大小相同
    near: 视锥近截面距相机距离
    far: 视锥远截面距相机距离

// 创建相机对象 设置参数
const camera = new THREE.PerspectiveCamera(30, width/height, 0.1, 3000);
  • 设置相机的位置
// 相机位置设置
camera.position.set(200, 200, 200);
  • 设置观察目标
// 设置观察目标
camera.lookAt(0, 0, 0);	// 观察原点
camera.lookAt(mesh.position);	// 观察物体mesh位置

三、对场景进行渲染

  • 创建WebGL渲染器对象
// 创建WebGL渲染器对象
const renderer = new THREE.WebGLRenderer();
  • 设置Canvas画布
// 设置画布
renderer.setSize(width, height);
  • 渲染器执行渲染方法
// 执行渲染方法 对哪个场景使用哪个相机进行拍照
renderer.render(scene, camera);
  • 将元素插入
// 插入body
document.body.appendChild(renderer.domElement);
// 插入指定位置
document.getElementById("webgl").appendChild(renderer.domElement);	// renderer.domElement为一个HTML元素

完整.js文件

// 引入three.js
import * as THREE from 'three';

// 创建一个三维场景
const scene = new THREE.Scene();

// 添加辅助观察坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);

// 添加物体 几何体,长方体,定义长宽高
const geometry = new THREE.BoxGeometry(50, 50, 50);
// 创建材质对象
const material = new THREE.MeshBasicMaterial({
    color:0xff0000,
    transparent: true,  // 设置透明
    opacity: 0.5    // 透明度
});
// 创建网格模型 给出物体及材质
const mesh = new THREE.Mesh(geometry, material);
// 设置模型在三维空间中的位置
mesh.position.set(0, 10, 0);
// 将物体添加到场景中
scene.add(mesh);

// 控制台打印
console.log("mesh", mesh);

// 设置画布尺寸(单位:px)
const width = 800;
const height = 500;

// 创建相机对象 设置相机参数
/* 
    fov: 视场角度   模拟观察范围,物体需在视场范围内才可显示
    aspect: 视锥水平和竖直方向长度比    通常与画布大小相同
    near: 视锥近裁截面对相机距离
    far: 视锥远裁截面对相机距离
 */
const camera = new THREE.PerspectiveCamera(30, width/height, 0.1, 3000);
// 设置相机位置
camera.position.set(200, 200, 200);
// 相机观察目标
camera.lookAt(mesh.position);   // 指向某个物体 网格模型mesh

// 创建WebGL渲染器对象
const renderer = new THREE.WebGLRenderer();
// 设置Canvas画布尺寸
renderer.setSize(width, height);
// 渲染器执行渲染方法 使用哪个相机对哪个场景进行拍照
renderer.render(scene, camera);
// 获得渲染方法.render()生成的Canvas画布

// 将Canvas画布插入特定元素位置
document.getElementById("webgl").appendChild(renderer.domElement);	// renderer.domElement为一个HTML元素
  • 效果(辣眼睛配色hhhhhh)
    辣眼睛的效果

画布Canvas的全屏显示

画布也是一种html元素,故three.js渲染输出的Canvas画布的布局方法与普通web前端相同。

const width = window.innerWidth;	//窗口文档显示区的宽度作为画布宽度
const height = window.innerHeight;	//窗口文档显示区的高度作为画布高度
  • 此时Canvas的显示:
    未改css

可以看到上图的Canvas左侧和上侧均有白边,若要实现完全的全屏显示,还需要修改一下body元素的css设置。

<style>
	body{
		overflow: hidden;
		margin: 0;
	}
</style>
  • 修改后:
    无白边

Canvas画布宽高度动态变化

Canvas画布宽高度动态变化,需要更新相机和渲染的参数,才能正常渲染。

// onresize 事件会在窗口被调整大小时发生
window.onresize = function () {
    // 重置渲染器输出画布canvas尺寸
    renderer.setSize(window.innerWidth, window.innerHeight);
    // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
    // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
    // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
    camera.updateProjectionMatrix();
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值