# threejs基础示例

<figure><img src="/files/O3P6rMZha0NTgZiLxnCx" alt=""><figcaption></figcaption></figure>

基本的使用代码，threejs的初始化以及快速开始参考three官网

```javascript

import * as THREE from "three";
import OctreeCSG from "./OctreeCSG/OctreeCSG";
import { OrbitControls } from "./node_modules/three/examples/jsm/controls/OrbitControls.js";
import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils";

const getOctreeCSG = (cube, cube1) => {
  const octree1 = OctreeCSG.fromMesh(cube);
  const octree2 = OctreeCSG.fromMesh(cube1);

  const resultOctree = OctreeCSG["subtract"](
    octree1.clone(),
    octree2.clone(),
    false
  );
  return OctreeCSG.toGeometry(resultOctree);
};

const mergeGeo = (geos, mat, x, y, z, xPos, yPos, zPos) => {
  const box = new THREE.Mesh(new THREE.BoxGeometry(x, y, z), mat);
  box.position.set(xPos, yPos, zPos);
  box.updateMatrix();
  geos.push(box.geometry.applyMatrix4(box.matrix));
  return geos;
};

const boardHeight = 5;
const depth = 2;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.set(0, -200, 300);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x313538, 1);
// 开启阴影渲染
renderer.shadowMap.enabled = true;

//domElement canvas对象
document.body.appendChild(renderer.domElement);

// const axesHelper = new THREE.AxesHelper(500);
// // axesHelper.rotateX(1);
// scene.add(axesHelper);

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(500, 250, depth),
  new THREE.MeshLambertMaterial({
    color: 0xccdbdd,
  })
);
cube.position.z = depth / 2;
const cube_ = new THREE.Mesh(
  new THREE.BoxGeometry(500, 250, boardHeight - depth),
  new THREE.MeshLambertMaterial({
    color: 0xccdbdd,
  })
);
// cube_.rotateX(1);
cube_.position.z = -(boardHeight - depth) / 2;
scene.add(cube_);
// 动态插入物体
const mat = new THREE.MeshLambertMaterial({
  color: 0x333333,
});
let geos = [];
const list = [
  [-200, 80],
  [-200, 0],
  [-200, -80],
  [-120, 80],
  [-120, 0],
  [-120, -80],
  [-40, 80],
  [-40, 0],
  [-40, -80],
  [40, 80],
  [40, 0],
  [40, -80],
  [120, 80],
  [120, 0],
  [120, -80],
  [200, 80],
  [200, 0],
  [200, -80],
];
list.map((e) => {
  geos = mergeGeo(geos, mat, 50, 50, depth, e[0], e[1], depth / 2);
});

// 合并模型
let merged = mergeGeometries(geos);
let mergeMesh = new THREE.Mesh(merged, mat);

// scene.add(mergeMesh);
const resultGeom1 = getOctreeCSG(cube, mergeMesh);

const subtract = new THREE.Mesh(
  resultGeom1,
  new THREE.MeshStandardMaterial({
    color: 0xc3d6d3,
    roughness: 0.3, // 设置粗糙度为0.3，使其表面具有一些纹理
  })
);

scene.add(subtract);

const light1 = new THREE.DirectionalLight(0xeeeeee, 1);
// 设置光源位置
light1.position.set(300, 300, 400);
scene.add(light1);

const light2 = new THREE.DirectionalLight(0xeeeeee, 1);
// 设置光源位置
light2.position.set(-300, 300, 400);
scene.add(light2);

// 设置计算阴影的区域，最好刚好紧密包围在对象周围
// 计算阴影的区域过大：模糊  过小：看不到或显示不完整
// light.shadow.camera.near = 0.5;
// light.shadow.camera.far = 300;
// light.shadow.camera.left = -50;
// light.shadow.camera.right = 50;
// light.shadow.camera.top = 200;
// light.shadow.camera.bottom = -100;
// 光源辅助线
// const helper = new THREE.DirectionalLightHelper(light);
// scene.add(helper);
// 设置mapSize属性可以使阴影更清晰，不那么模糊
// light.shadow.mapSize.set(1024, 1024);
const ambientLight = new THREE.AmbientLight(0xaaaaaa, 2);
scene.add(ambientLight);

// 渲染工件
const job = new THREE.Mesh(
  new THREE.BoxGeometry(10, 25, 60),
  new THREE.MeshLambertMaterial({
    color: 0x97b2c8,
  })
);
job.position.set(-220, 92.5, 30);
scene.add(job);

function animate() {
  requestAnimationFrame(animate); //向浏览器发起一个执行某函数的请求， 什么时候会执行由浏览器决定，一般默认保持60FPS的频率
  renderer.render(scene, camera); //每次渲染出一幅图像
}
animate();
//创建鼠标控制器
const controls = new OrbitControls(camera, renderer.domElement);
// controls.target = new THREE.Vector3(250, 0, 0);
// controls.addEventListener('change',render); //当使用requestAnimationFrame时，没必要在通过controls.addEventListener('change', render)监听鼠标事件调用渲染函数

// 纹理
// const loader = new THREE.TextureLoader();
// let mesh = null;
// loader.load(
//   "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.16pic.com%2F00%2F07%2F46%2F16pic_746871_b.jpg",
//   (texture) => {
//     // 基础材质
//     const material = new THREE.MeshBasicMaterial({
//       map: texture,
//     });
//     // 网格
//     mesh = new THREE.Mesh(geometry, material);
//     mesh.position.x = 5;
//     scene.add(mesh);
//   }
// );

// 引用blender 模型
// const loader = new OBJLoader();
// const mtlLoader = new MTLLoader();
// mtlLoader.load("./1.mtl", (mtl) => {
//   mtl.preload();
//   console.log(mtl);
//   loader.load("./1.obj", (root) => {
//     console.log(root);
//     scene.add(root);
//   });
// });

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://408550179s-organization.gitbook.io/blog/threejs-ji-chu-shi-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
