记录下three.js的学习历程。
three.js基本概念包括画布Canvas、渲染器Renderer、场景Scene、相机Camera、光源Light、几何体Geometry、材质Material、颜色纹理、点模型、线模型、网格模型、阴影、外部三维模型、动画等基础
<canvas id="basic"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/jsm/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
{
//渲染器
const domId = document.getElementById("basic");
const width = 300;
const height = 200;
const renderer = new THREE.WebGLRenderer({
canvas: document.getElementById("basic"),
antialias: true, //抗锯齿,平滑
});
renderer.setSize(width, height); //设置渲染区域的尺寸(像素px)
renderer.setClearColor(0x000000, 1); //设置背景颜色
renderer.setPixelRatio(window.devicePixelRatio); //设置设备像素比,以免渲染模糊问题
//场景
const scene = new THREE.Scene();
//几何体
const geometry = new THREE.BufferGeometry(); //空的几何体
//顶点数据
const vertices = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 30, 0]);
// 设置几何体的顶点位置,3个数据为1组,表示定点的xyz坐标
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
// 点材质
const pointMaterial = new THREE.PointsMaterial({
color: 0xffff00,
size: 10.0, //点对象像素尺寸
});
//点模型对象
const points = new THREE.Points(geometry, pointMaterial);
points.position.set(10, 10, 0);
scene.add(points);
// 线材质对象
const lineMaterial = new THREE.LineBasicMaterial({
color: 0xff0000, //线条颜色
});
// 创建线模型对象
const line = new THREE.LineLoop(geometry, lineMaterial);
line.position.set(50, 10, 0);
scene.add(line);
//网格材质:默认正面可见,反面不可见。
const meshMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff,
// side: THREE.FrontSide, //默认只有正面可见
side: THREE.DoubleSide, //两面可见
// side: THREE.BackSide, //设置只有反面可见
});
const geometry1 = new THREE.BufferGeometry();
const vertices1 = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
geometry1.attributes.position = new THREE.BufferAttribute(vertices1, 3);
//网格模型:由多个三角形的面拼接构成。正反面区分:依相机观察方向的三个点顺序逆时针为正面,顺时针为反面
const mesh = new THREE.Mesh(geometry1, meshMaterial);
mesh.position.set(90, 10, 0);
mesh.rotateX(Math.PI); // 网格模型绕着x轴旋转
mesh.translateY(30); //网格模型沿着y轴正方向平移
mesh.scale.set(2, 2, 2); //网格模型缩放
console.log("模型位置", mesh.position);
scene.add(mesh);
//网格材质:默认正面可见,反面不可见。
const meshMaterial2 = new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
wireframe: true, //线条模式渲染
});
const geometry2 = new THREE.BufferGeometry();
const vertices2 = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
geometry2.attributes.position = new THREE.BufferAttribute(vertices2, 3);
geometry2.scale(1, 2, 2); // 几何体缩放
geometry2.translate(30, 30, 0); // 几何体平移
geometry2.rotateX(Math.PI); // 几何体绕着x轴旋转
console.log("顶点位置数据", geometry2.attributes.position);
const mesh2 = new THREE.Mesh(geometry2, meshMaterial2);
mesh2.position.set(140, 10, 0);
scene.add(mesh2);
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000); //透视投影相机参数设置
camera.position.set(300, 300, 500); //设置相机位置
camera.lookAt(0, 0, 0);
scene.add(camera);
//坐标轴辅助
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
console.log("scene的子对象", scene.children);
renderer.render(scene, camera);
window.onresize = function () {
const width = 400; //若需全屏使用window.innerWidth
const height = 300; //若需全屏使用window.innerHeight
// 重置渲染器输出画布canvas尺寸
renderer.setSize(width, height);
//画布宽高比变化后更新透视投影相机PerspectiveCamera的aspect属性
camera.aspect = width / height;
camera.updateProjectionMatrix();
};
}
</script>
Group
<canvas id="group"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/jsm/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
{
const domId = document.getElementById("group");
const width = 300;
const height = 200;
const renderer = new THREE.WebGLRenderer({
canvas: document.getElementById("group"),
antialias: true, //抗锯齿,平滑
});
renderer.setSize(width, height);
renderer.setClearColor(0x000000, 1);
renderer.setPixelRatio(window.devicePixelRatio);
const scene = new THREE.Scene();
const material = new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide, //两面可见
});
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(10, 10, 0);
const axis = new THREE.Vector3(1, 0, 0); //向量axis
mesh.translateOnAxis(axis, 20); //沿着axis轴表示方向平移
mesh.rotateOnAxis(axis, Math.PI / 2); //绕axis轴旋转
mesh.scale.set(0.5, 0.5, 0.5);
scene.add(mesh);
//对象clone
const mesh1 = mesh.clone();
//材质clone
mesh1.material = mesh.material.clone();
mesh1.material.color.set(0x00ff00);
mesh1.position.set(0, 50, 0);
// 模型命名
mesh1.name = "test";
const mesh2 = mesh.clone();
mesh2.material = mesh.material.clone();
mesh2.material.color.set(0x00ffff);
mesh2.position.set(50, 50, 0);
//组
const group = new THREE.Group();
group.add(mesh1, mesh2);
group.position.set(0, 90, 0);
group.rotateX(Math.PI / 2);
// 递归遍历group包含所有的对象
group.traverse(function (obj) {
// obj.isMesh:判断模型对象obj是不是网格模型'Mesh',等同于obj.type === 'Mesh'
if (obj.isMesh) {
obj.material.color.set(0xffff00);
obj.material.visible = true;
obj.visible = true;
}
});
console.log("group的子对象", group.children);
scene.add(group);
// 对象移除
// group.remove(mesh1);
// scene.remove(mesh);
// 根据name查找对象节点
const nameNode = scene.getObjectByName("test");
nameNode.material.color.set(0xff0000);
const worldPosition = new THREE.Vector3();
nameNode.getWorldPosition(worldPosition);
//世界坐标-子对象的坐标叠加所有父对象的坐标
console.log("世界坐标", worldPosition);
//本地坐标-子对象相对于父对象的坐标
console.log("本地坐标", nameNode.position);
//可视化mesh的局部坐标系
const meshAxesHelper = new THREE.AxesHelper(50);
nameNode.add(meshAxesHelper);
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000); //透视投影相机参数设置
camera.position.set(300, 300, 300); //设置相机位置
camera.lookAt(0, 0, 0);
scene.add(camera);
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
renderer.render(scene, camera);
}
</script>
标签:scene,const,30,基础,THREE,three,mesh,new,js
From: https://www.cnblogs.com/caroline2016/p/18115739