初步学习和简单的示例
首先 中文官网
1. 创建纹理贴图 | Three.js中文网 (webgl3d.cn)
git地址 Releases · mrdoob/three.js · GitHub
到代码部分下载zip 就可以了 我们使用npm 就可以 但是 git的例子上有很多可以学习的场景
2 使用的结构总结
三要素 场景 相机 渲染器
场景 物体+材料=模型 灯光
//创建一个三维场景
const scene = new THREE.Scene();
const jinGeometry = new THREE.SphereGeometry(12, 16, 16);
const jinMaterial = new THREE.MeshPhongMaterial({ color: "yellow" });
const jinMesh = new THREE.Mesh(jinGeometry, jinMaterial);
jinMesh.position.set(170, 0, 0);
scene.add(jinMesh);
// 光 环境光 点光 点光才能看出阴影和分界的效果
const ambient = new THREE.AmbientLight("#fff", 0.4);
const light = new THREE.PointLight("#fff", 1); //点光源,color:灯光颜色,intensity:光照强度
scene.add(ambient);
light.position.set(200, 300, 400);
scene.add(light);
相机 暂时有两个相机 一个是透视的一个是正常的 需要注意设置相机的画面尺寸 这个是有很大的额影响的 我就设置的一下不对的 结果找了半天错误
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set(300, 300, 600);
camera.lookAt(0, 0, 0);
渲染器
const renderer = new THREE.WebGLRenderer();
// 设置像素比 和宽高
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth - 50, window.innerHeight - 50);
//渲染器工作
setTimeout(() => {
renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数
animate();
}, 50);
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
onMounted(() => {
const dom = document.getElementById("my-three");
dom?.appendChild(renderer.domElement);
});
全部的示例代码
<template>
<div id="my-three"></div>
</template>
<script lang="ts" setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { onMounted } from "vue";
//创建一个三维场景
const scene = new THREE.Scene();
//纹理贴图
const textureLoader = new THREE.TextureLoader();
// 创建物体和材料
const sunGeometry = new THREE.SphereGeometry(100, 16, 16);
const sunMaterial = new THREE.MeshPhongMaterial({
// 加载有个时间 是异步的
map: textureLoader.load("./sun.jpeg"),
});
const sunMesh = new THREE.Mesh(sunGeometry, sunMaterial);
//水星
const shuiGeometry = new THREE.SphereGeometry(10, 16, 16);
const shhuiMaterial = new THREE.MeshPhongMaterial({
color: "blue",
});
const shuiesh = new THREE.Mesh(shuiGeometry, shhuiMaterial);
scene.add(shuiesh);
shuiesh.position.set(130, 0, 0);
//金星
const jinGeometry = new THREE.SphereGeometry(12, 16, 16);
const jinMaterial = new THREE.MeshPhongMaterial({ color: "yellow" });
const jinMesh = new THREE.Mesh(jinGeometry, jinMaterial);
jinMesh.position.set(170, 0, 0);
scene.add(jinMesh);
//地球
const earthGeometry = new THREE.SphereGeometry(13, 32, 16);
const earthMaterial = new THREE.MeshPhongMaterial({ color: "#ccc" });
const earthMesh = new THREE.Mesh(earthGeometry, earthMaterial);
earthMesh.position.set(220, 0, 0);
scene.add(earthMesh);
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const elapsed = clock.getElapsedTime();
jinMesh.position.set(Math.sin(elapsed) * 170, 0, Math.cos(elapsed) * 170);
renderer.render(scene, camera);
}
// 加一个 辅助线吧
const lineHelper = new THREE.AxesHelper(500);
sunMesh.position.set(0, 0, 0);
scene.add(lineHelper);
scene.add(sunMesh);
// 光 环境光 点光 点光才能看出阴影和分界的效果
const ambient = new THREE.AmbientLight("#fff", 0.4);
const light = new THREE.PointLight("#fff", 1); //点光源,color:灯光颜色,intensity:光照强度
scene.add(ambient);
light.position.set(200, 300, 400);
scene.add(light);
// 相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set(300, 300, 600);
camera.lookAt(0, 0, 0);
//渲染器
const renderer = new THREE.WebGLRenderer();
// 设置像素比 和宽高
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth - 50, window.innerHeight - 50);
//渲染器工作
setTimeout(() => {
renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数
animate();
}, 50);
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
onMounted(() => {
const dom = document.getElementById("my-three");
dom?.appendChild(renderer.domElement);
});
</script>
<style scoped></style>
如果是导入的外部模型需要注意的事 调用一下 计算最小的盒子大小哦
Load 一个文件
Const a= res.scene.children[0].children[1]
a.geometry.compoutedBoundingBox()