Three.js开发入门

237 阅读2分钟

场景(Scene)

场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方。

// 场景
const scene = new THREE.Scene();

摄像机(Camera)

正交相机和透视相机

透视相机

这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。

const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); scene.add( camera );

正交相机

在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。
这对于渲染2D场景或者UI元素是非常有用的。

const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); scene.add( camera );

WebGLRenderer

WebGL Render 用WebGL渲染出你精心制作的场景。

// 渲染器
const render = new THREE.WebGLRenderer();

一个例子

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// 场景
const scene = new THREE.Scene();

// 相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight
);

// 设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera);

// 添加物体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterail = new THREE.MeshBasicMaterial();
const cube = new THREE.Mesh(cubeGeometry, cubeMaterail);
// cube.position.set(5, 0, 0);
cube.position.x = 5; // 设置物体位置
// cube.scale.set(2, 1, 1); // 设置缩放
cube.scale.x = 2; // 设置缩放
cube.rotation.set(Math.PI / 4, 0, 0); // 绕x轴旋转45度
scene.add(cube);


// 坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 渲染器
const render = new THREE.WebGLRenderer();
render.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(render.domElement);
render.render(scene, camera);

// 控制器
const controls = new OrbitControls(camera, render.domElement);

// function animate(time) {
//   let t = (time / 1000) % 5;
//   cube.position.x = t * 1;
//   if (cube.position.x > 5) {
//     cube.position.x = 0;
//   }
//   render.render(scene, camera);
//   // requestAnimationFrame 会传递一个时间参数 time
//   requestAnimationFrame(animate);
// }

// 设置时钟
const clock = new THREE.Clock();
function animate() {
  let delta = clock.getDelta();
  console.log(`两次之间的时间间隔是${delta * 1000}毫秒`);
  // let t = delta % 5;
  cube.position.x += delta * 1;
  if (cube.position.x > 5) {
    cube.position.x = 0;
  }
  render.render(scene, camera);
  // requestAnimationFrame 会传递一个时间参数 time
  requestAnimationFrame(animate);
}
animate();

image.png

BufferGeometry

面片、线或点几何体的有效表述。包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// 场景
const scene = new THREE.Scene();

// 相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight
);

// 设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera);

for (let i = 0; i < 50; i++) {
  // 添加物体
  const geometry = new THREE.BufferGeometry();
  // 9 开辟缓冲区大小
  const positionArray = new Float32Array(9);
  // 三角形三个顶点 每个顶点三个点
  for (let j = 0; j < 9; j++) {
    // -5, 5
    positionArray[j] = Math.random() * 10 - 5;
  }
  // 设置属性position 3个点为一组
  geometry.setAttribute(
    "position",
    new THREE.BufferAttribute(positionArray, 3)
  );
  let color = new THREE.Color(Math.random(), Math.random(), Math.random());
  const materail = new THREE.MeshBasicMaterial({
    color: color,
    transparent: true,
    opacity: 0.5,
  });
  // 根据几何体和材质创建物体
  const mesh = new THREE.Mesh(geometry, materail);
  scene.add(mesh);
}

// 坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 渲染器
const render = new THREE.WebGLRenderer();
render.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(render.domElement);
render.render(scene, camera);

// 控制器
const controls = new OrbitControls(camera, render.domElement);
// 设置控制器阻尼,让控制器更具有真实效果
controls.enableDamping = true;

function animate() {
  render.render(scene, camera);
  controls.update();
  requestAnimationFrame(animate);
}

animate();

// 监听画面变化
window.addEventListener("resize", function () {
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新投影矩阵
  camera.updateProjectionMatrix();

  // 更新渲染器
  render.setSize(window.innerWidth, window.innerHeight);

  // 设置渲染器像素比   电脑上的iphone是2
  render.setPixelRatio(window.devicePixelRatio);
});

文件名称.png