three.js基础之小案例
静态场景
<canvas id="mainCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane, addBox, addSphere } from "./init.js";
function init() {
const gui = new GUI();
const renderer = initRenderer("mainCanvas");
const scene = new THREE.Scene();
const camera = initPerspectiveCamera();
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
gui.add(ambientLight, "intensity", 0, 100).name("AmbientLight光源强度");
const spotLight = initSpotLight();
scene.add(spotLight);
// spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
// spotLight.shadow.camera.far = 130;
// spotLight.shadow.camera.near = 40;
gui.add(spotLight.position, "x", -50, 100).name("SpotLight光源位置x");
gui.add(spotLight.position, "y", 0, 100).name("SpotLight光源位置y");
gui.add(spotLight.position, "z", -50, 100).name("SpotLight光源位置z");
gui.add(spotLight, "intensity", 0, 100).name("SpotLight光源强度");
gui.add(spotLight, "angle", 0, 2 * Math.PI).name("SpotLight光源照射范围的角度");
gui.add(spotLight, "distance", 0, 5000).name("SpotLight光源照射的最大距离");
gui.add(spotLight, "decay", 0, 10).name("SpotLight光源沿着光照距离的衰退量");
createTree(scene);
createHouse(scene);
createGroundPlane(scene);
createBoundingWall(scene);
const plane = addPlane();
plane.position.set(15, 0, 0);
scene.add(plane);
const cube = addBox({ color: 0xff0000 });
cube.position.set(-4, 2, 0);
scene.add(cube);
const sphere = addSphere({ color: 0x7777ff });
sphere.position.set(20, 5, 0);
scene.add(sphere);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
}
function createBoundingWall(scene) {
const wallLeft = new THREE.BoxGeometry(70, 2, 2);
const wallRight = new THREE.BoxGeometry(70, 2, 2);
const wallTop = new THREE.BoxGeometry(2, 2, 50);
const wallBottom = new THREE.BoxGeometry(2, 2, 50);
const wallMaterial = new THREE.MeshLambertMaterial({
color: 0xa0522d,
});
const wallLeftMesh = new THREE.Mesh(wallLeft, wallMaterial);
const wallRightMesh = new THREE.Mesh(wallRight, wallMaterial);
const wallTopMesh = new THREE.Mesh(wallTop, wallMaterial);
const wallBottomMesh = new THREE.Mesh(wallBottom, wallMaterial);
wallLeftMesh.position.set(15, 1, -25);
wallRightMesh.position.set(15, 1, 25);
wallTopMesh.position.set(-19, 1, 0);
wallBottomMesh.position.set(49, 1, 0);
scene.add(wallLeftMesh);
scene.add(wallRightMesh);
scene.add(wallBottomMesh);
scene.add(wallTopMesh);
}
function createGroundPlane(scene) {
const planeGeometry = new THREE.PlaneGeometry(70, 50);
const planeMaterial = new THREE.MeshLambertMaterial({
color: 0x9acd32,
});
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15, 0, 0);
scene.add(plane);
}
function createHouse(scene) {
const roof = new THREE.ConeGeometry(5, 4);
const base = new THREE.CylinderGeometry(5, 5, 6);
const roofMesh = new THREE.Mesh(
roof,
new THREE.MeshLambertMaterial({
color: 0x8b7213,
})
);
const baseMesh = new THREE.Mesh(
base,
new THREE.MeshLambertMaterial({
color: 0xffe4c4,
})
);
roofMesh.position.set(25, 8, 0);
baseMesh.position.set(25, 3, 0);
roofMesh.receiveShadow = true;
baseMesh.receiveShadow = true;
roofMesh.castShadow = true;
baseMesh.castShadow = true;
scene.add(roofMesh);
scene.add(baseMesh);
}
function createTree(scene) {
const trunk = new THREE.BoxGeometry(1, 8, 1);
const leaves = new THREE.SphereGeometry(4);
const trunkMesh = new THREE.Mesh(
trunk,
new THREE.MeshLambertMaterial({
color: 0x8b4513,
})
);
const leavesMesh = new THREE.Mesh(
leaves,
new THREE.MeshLambertMaterial({
color: 0x00ff00,
})
);
trunkMesh.position.set(-10, 4, 0);
leavesMesh.position.set(-10, 12, 0);
trunkMesh.castShadow = true;
trunkMesh.receiveShadow = true;
leavesMesh.castShadow = true;
leavesMesh.receiveShadow = true;
scene.add(trunkMesh);
scene.add(leavesMesh);
}
init();
</script>
管道动画
<canvas id="mainCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";
const renderer = initRenderer("mainCanvas");
const scene = new THREE.Scene();
const camera = initPerspectiveCamera();
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
const spotLight = initSpotLight();
scene.add(spotLight);
const path = new THREE.CatmullRomCurve3([
new THREE.Vector3(-5, 2, 9),
new THREE.Vector3(-1, 4, 4),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(6, -6, 0),
new THREE.Vector3(9, -4, 6),
new THREE.Vector3(12, 3, 3),
]);
// 三维样条曲线作为TubeGeometry参数生成管道
const geometry = new THREE.TubeGeometry(path, 100, 5, 30);
const texLoader = new THREE.TextureLoader();
//纹理贴图
texLoader.load("../images/square.jpg", (texture) => {
//UV坐标U方向阵列模式
texture.wrapS = THREE.RepeatWrapping;
// 纹理沿着管道方向阵列(UV坐标U方向)
texture.repeat.x = 100;
const material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
let i = 0;
render();
function render() {
const pointsArr = path.getSpacedPoints(500);
if (i < pointsArr.length - 1) {
camera.position.copy(pointsArr[i]);
camera.lookAt(pointsArr[i + 1]);
i += 1;
} else {
i = 0;
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
</script>
合集:
three.js基础
分类:
javascript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!