基本使用
初始化场景
const scene = new THREE.Scene();
初始化相机
相当于人眼
const camera = new THREE.PerspectiveCamera();
camera.position.set( 0, 20, 100 );
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面
设置相机位置
camera.position.z = 0.1;
设置渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
时刻渲染
const renderFn = () => {
renderer.render(scene, camera);
requestAnimationFrame(renderFn);
};
放入dom
const container = ref(null);
container.value.appendChild(renderer.domElement);
控制器
// 添加控制器 const controls = new OrbitControls(camera, container.value); controls.enableDamping = true;
通常在元素挂载时,放入控制器,时刻渲染,放入dom
坐标轴
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
物体
一个物体由几何体和材质(可以设置金属度,粗糙度等等一系列)构成
//设置几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
//基本材质不受光影响 常用
const material = new THREE.MeshBasicMaterial();
//受光影响 常用
const material = new THREE.MeshStandardMaterial();
//融合构造物体
const cube = new THREE.Mesh(sphereGeometry, material);
运动动画
// 导入动画库
import gsap from "gsap";
var animate1 = gsap.to(cube.position, {
x: 5,
duration: 5,
ease: "power1.inOut",
// 设置重复的次数,无限次循环-1
repeat: -1,
// 往返运动
yoyo: true,
// delay,延迟2秒运动
delay: 2,
onComplete: () => {
console.log("动画完成");
},
onStart: () => {
console.log("动画开始");
},
});
gsap.to(cube.rotation, { x: 2 * Math.PI, duration: 5, ease: "power1.inOut" });
双击全屏,双击退出
window.addEventListener("dblclick", () => {
const fullScreenElement = document.fullscreenElement;
if (!fullScreenElement) {
// 双击控制屏幕进入全屏,退出全屏
// 让画布对象全屏
renderer.domElement.requestFullscreen();
} else {
// 退出全屏,使用document对象
document.exitFullscreen();
}
// console.log(fullScreenElement);
});
添加gui(ui调节器)
import { gui } from "dat.gui";
const gui = new dat.GUI();
gui.add(pointLight.position, "x").min(-5).max(5).step(0.1);
gui.add(pointLight, "distance").min(0).max(5).step(0.001);
gui.add(pointLight, "decay").min(0).max(5).step(0.01);
贴图的使用
//导入置换贴图
const doorHeightTexture = textureLoader.load("./textures/door/height.jpg");
// 导入粗糙度贴图
const roughnessTexture = textureLoader.load("./textures/door/roughness.jpg");
// 导入金属贴图
const metalnessTexture = textureLoader.load("./textures/door/metalness.jpg");
// 导入法线贴图
const normalTexture = textureLoader.load("./textures/door/normal.jpg");
// 材质
const material = new THREE.MeshStandardMaterial({
color: "#ffff00",
map: doorColorTexture,
alphaMap: doorAplhaTexture,
transparent: true,
aoMap: doorAoTexture,
aoMapIntensity: 1,
displacementMap: doorHeightTexture,
displacementScale: 0.1,
roughness: 1,
roughnessMap: roughnessTexture,
metalness: 1,
metalnessMap: metalnessTexture,
normalMap: normalTexture,
// opacity: 0.3,
// side: THREE.DoubleSide,
});
纹理加载的进度
// 单张纹理图的加载
event.onLoad = function () {
console.log("图片加载完成");
};
event.onProgress = function (url, num, total) {
console.log("图片加载完成:", url);
console.log("图片加载进度:", num);
console.log("图片总数:", total);
let value = ((num / total) * 100).toFixed(2) + "%";
console.log("加载进度的百分比:", value);
div.innerHTML = value;
};
event.onError = function (e) {
console.log("图片加载出现错误");
console.log(e);
};
// 设置加载管理器
const loadingManager = new THREE.LoadingManager(
event.onLoad,
event.onProgress,
event.onError
);
// 导入纹理
const textureLoader = new THREE.TextureLoader(loadingManager);
const doorColorTexture = textureLoader.load(
"./textures/door/color.jpg"
// event.onLoad,
// event.onProgress,
// event.onError
);
加载 hdr 环境纹理
要有 import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
// 目标:设置环境纹理
// 加载hdr环境图
const rgbeLoader = new RGBELoader();
rgbeLoader.loadAsync("textures/hdr/002.hdr").then((texture) => {
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = texture;
scene.environment = texture;
});
或者用六张图片构成环境
// 设置cube纹理加载器
const cubeTextureLoader = new THREE.CubeTextureLoader();
const envMapTexture = cubeTextureLoader.load([
"textures/environmentMaps/1/px.jpg",
"textures/environmentMaps/1/nx.jpg",
"textures/environmentMaps/1/py.jpg",
"textures/environmentMaps/1/ny.jpg",
"textures/environmentMaps/1/pz.jpg",
"textures/environmentMaps/1/nz.jpg",
]);
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20);
const material = new THREE.MeshStandardMaterial({
metalness: 0.7,
roughness: 0.1,
envMap: envMapTexture,
});
光和阴影
光有各种光,当物体必须是MeshStandardMaterial 标准材质才会影响。
// 灯光阴影
// 1、材质要满足能够对光照有反应
// 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;
// 3、设置光照投射阴影 directionalLight.castShadow = true;
// 4、设置物体投射阴影 sphere.castShadow = true;
// 5、设置物体接收阴影 plane.receiveShadow = true;
// 投射阴影
sphere.castShadow = true;
scene.add(sphere);
// // 创建平面
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 接收阴影
plane.receiveShadow = true;
scene.add(plane);
// 灯光
// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white light
scene.add(light);
//直线光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(10, 10, 10);
directionalLight.castShadow = true;
scene.add(directionalLight);
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true;
其中光有各种类型并且有各种属性可以设置
初步概念理解
顶点:把物体划分点,更好的控制物体,越多点越精细
法向:控制光照反射的位置
纹理:贴在物体上改变物体看起来的样子,各种图片贴上去
透明:利用贴图处理
粗糙:利用贴图处理
金属度:利用贴图处理
光照:利用贴图处理
贴图网站 (3dtextures.me)
看房的制作
两种方法:1、正方形六面加上六张图 cube.geometry.scale(1, 1, -1); 2、一个圆然后直接rgb sphere.geometry.scale(1, 1, -1);
关键点,图片在表面然后翻转
<template>
<div class="container" ref="container"></div>
</template>
<script setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
import { ref, onMounted } from "vue";
// 初始化场景
const scene = new THREE.Scene();
// 初始化相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 设置相机位置
camera.position.z = 0.1;
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const container = ref(null);
const render = () => {
renderer.render(scene, camera);
requestAnimationFrame(render);
};
// 添加立方体
// const geometry = new THREE.BoxGeometry(10, 10, 10);
// // const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// // const cube = new THREE.Mesh(geometry, material);
// // scene.add(cube);
// // 4_b,
// var arr = ["4_l", "4_r", "4_u", "4_d", "4_b", "4_f"];
// var boxMaterials = [];
// arr.forEach((item) => {
// // 纹理加载
// let texture = new THREE.TextureLoader().load(`./imgs/living/${item}.jpg`);
// // 创建材质
// if (item === "4_u" || item === "4_d") {
// texture.rotation = Math.PI;
// texture.center = new THREE.Vector2(0.5, 0.5);
// boxMaterials.push(new THREE.MeshBasicMaterial({ map: texture }));
// } else {
// boxMaterials.push(new THREE.MeshBasicMaterial({ map: texture }));
// }
// });
// const cube = new THREE.Mesh(geometry, boxMaterials);
// cube.geometry.scale(1, 1, -1);
// scene.add(cube);
// 添加球
const geometry = new THREE.SphereGeometry(5, 32, 32);
const loader = new RGBELoader();
loader.load("./imgs/hdr/Living.hdr", (texture) => {
const material = new THREE.MeshBasicMaterial({ map: texture });
const sphere = new THREE.Mesh(geometry, material);
sphere.geometry.scale(1, 1, -1);
scene.add(sphere);
});
// 挂载完毕之后获取dom
onMounted(() => {
// 添加控制器
const controls = new OrbitControls(camera, container.value);
controls.enableDamping = true;
container.value.appendChild(renderer.domElement);
render();
});
</script>
<style>
</style>