Threejs入门学习笔记

0、前言

three.js全网最全最新入门课程(2024年6月更新)https://www.bilibili.com/video/BV1Gg411X7FY?spm_id_from=333.788.player.switch&vd_source=c8d0fc52fcdbfdaf62f07ee5e37217f9&p=2


1、Threejs的旋转方块

css

css 复制代码
*{
  margin:0;
  padding: 0;
}

canvas{
  display: block;
  position: fixed;
  left: 0;
  top: 0 ;
  width: 100vw;
  height: 100vh;
}

js

javascript 复制代码
import * as THREE from "three";

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.lookAt(0,0,0);
scene.add(camera);

// 创建添加几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 将几何体添加到场景中
scene.add(cube);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 使用渲染器,通过相机将场景渲染进来
//renderer.render(scene, camera);

//渲染函数
function animate() {
    requestAnimationFrame(animate);//下一帧继续调用
    //旋转
    cube.rotation.x+=0.01;
    cube.rotation.y+=0.01;
    //渲染
    renderer.render(scene, camera);
}
animate();

2、轨道控制器查看物体

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

// 创建添加几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 将几何体添加到场景中
scene.add(cube);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;
//设置自动旋转速度
controls.autoRotate=true;
controls.rotateSpeed=2.0;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();

3、物体的位移旋转与父子元素

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

// 创建添加几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const parentMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
const parentCube = new THREE.Mesh(cubeGeometry, parentMaterial);
//父级方块
parentCube.add(cube);
parentCube.position.set(-3,0,0);//世界坐标
parentCube.rotation.x=Math.PI/4;

cube.position.set(3,0,0);//相对父级方块局部坐标
cube.scale.set(2,2,2);//相对父级方块局部缩放
cube.rotation.x=Math.PI/4;//相对父级方块局部旋转,以弧度来表示,绕着x轴旋转45度
// 将父级方块添加到场景中
scene.add(parentCube);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, document.body);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;



//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();

4、自适应屏幕大小

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

// 创建添加几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const parentMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
const parentCube = new THREE.Mesh(cubeGeometry, parentMaterial);
//父级方块
parentCube.add(cube);
parentCube.position.set(-3,0,0);//世界坐标
parentCube.rotation.x=Math.PI/4;

cube.position.set(3,0,0);//相对父级方块局部坐标
cube.scale.set(2,2,2);//相对父级方块局部缩放
cube.rotation.x=Math.PI/4;//相对父级方块局部旋转,以弧度来表示,绕着x轴旋转45度
// 将父级方块添加到场景中
scene.add(parentCube);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


window.addEventListener("dblclick",()=>{    //   双击控制屏幕进入全屏,退出全屏
  const fullScreenElement = document.fullscreenElement;
  if (!fullScreenElement) {
    // 让画布对象全屏
    renderer.domElement.requestFullscreen();
  } else {
    //退出全屏,使用document对象
    document.exitFullscreen();
  }
});

//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();

// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

5、GUI调试开发

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

// 创建添加几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const parentMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
const parentCube = new THREE.Mesh(cubeGeometry, parentMaterial);
//父级方块
parentMaterial.wireframe=true;//线框模式
parentCube.add(cube);
parentCube.position.set(-3,0,0);//世界坐标
parentCube.rotation.x=Math.PI/4;

cube.position.set(3,0,0);//相对父级方块局部坐标
cube.scale.set(2,2,2);//相对父级方块局部缩放
cube.rotation.x=Math.PI/4;//相对父级方块局部旋转,以弧度来表示,绕着x轴旋转45度
// 将父级方块添加到场景中
scene.add(parentCube);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

//控制立方体的位置
// gui.add(cube.position,"x",-5,5).name("立方体x轴的位置");
let folder=gui.addFolder("立方体位置");
folder.add(cube.position,"x").min(-10).max(10).step(1).name("立方体x轴的位置").onChange((val)=>{
    console.log("立方体x轴位置",val);
});
folder.add(cube.position,"y").min(-10).max(10).step(1).name("立方体y轴的位置").onFinishChange((val)=>{
    console.log("立方体y轴位置",val);
});
folder.add(cube.position,"z").min(-10).max(10).step(1).name("立方体z轴的位置");


gui.add(parentMaterial,"wireframe").name("父元素线框模式");
gui.addColor(cube.material,"color").name("立方体颜色");

6、创建平面片

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

// 创建几何体
const geometry = new THREE.BufferGeometry();
const material0 = new THREE.MeshBasicMaterial({ 
    color: 0x00ff00, 
    //side:THREE.DoubleSide,
    wireframe:true,
});
const material1 = new THREE.MeshBasicMaterial({ 
    color: 0xff0000, 
    //side:THREE.DoubleSide,
    //wireframe:true,
});

// //创建顶点数据,顶点是有序的,每三个为一个顶点,逆时针为正面
// const vertices = new Float32Array( [
//  -1.0, -1.0,  0.0, // v0
//   1.0, -1.0,  0.0, // v1
//   1.0,  1.0,  0.0, // v2

//   1.0,  1.0,  0.0, // v3
//  -1.0,  1.0,  0.0, // v4
//  -1.0, -1.0,  0.0  // v5
// ] );
// //创建顶点属性,每三个为一个组position
// geometry.setAttribute("position",new THREE.BufferAttribute(vertices,3));


//使用索引绘制
const vertices = new Float32Array( [
    -1.0, -1.0,  0.0, // v0
     1.0, -1.0,  0.0, // v1
     1.0,  1.0,  0.0, // v2
    -1.0,  1.0,  0.0, // v3
] );
//创建顶点属性,每三个为一个组position
geometry.setAttribute("position",new THREE.BufferAttribute(vertices,3));

//创建索引
const indices=new Uint16Array([0,1,2,2,3,0]);
//创建索引属性
geometry.setIndex(new THREE.BufferAttribute(indices,1));
//设置2个顶点组,形成2个材质
geometry.addGroup(0,3,0);
geometry.addGroup(3,3,1);


console.log(geometry);

// 根据几何体和材质创建物体
const plane = new THREE.Mesh(geometry, [material0,material1]);
scene.add(plane);



//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

7、加载贴图

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

//创建纹理加载器
const textureLoader=new THREE.TextureLoader();
//加载纹理
let texture=textureLoader.load("./texture/a.png");

const planeGeometry=new THREE.PlaneGeometry(1,1);
const planeMaterial=new THREE.MeshBasicMaterial({
    color:0xffffff,
    map:texture,
    transparent:true,//允许透明
});
let plane=new THREE.Mesh(planeGeometry,planeMaterial);
scene.add(plane);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

8、全景图与贴图

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader.js';//导入hdr加载器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

const rebeLoader=new RGBELoader();
rebeLoader.load("./texture/university_workshop_4k.hdr",(envMap)=>{
    //设置球形映射
    envMap.mapping=THREE.EquirectangularReflectionMapping;
    //设置环境贴图
    scene.background=envMap;
    //设置场景环境贴图
    scene.environment=envMap;
    //设置plane的环境贴图
    planeMaterial.envMap=envMap;
});


//创建纹理加载器
const textureLoader=new THREE.TextureLoader();
//加载纹理
let texture=textureLoader.load("./texture/a.png");
//纹理颜色空间
texture.colorSpace=THREE.SRGBColorSpace;
// texture.colorSpace=THREE.LinearSRGBColorSpace;
//texture.colorSpace=THREE.NoColorSpace;

const planeGeometry=new THREE.PlaneGeometry(1,1);
const planeMaterial=new THREE.MeshBasicMaterial({
    color:0xffffff,
    map:texture,
    transparent:true,//允许透明
    reflectivity:0.87,
});
let plane=new THREE.Mesh(planeGeometry,planeMaterial);
scene.add(plane);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");
gui.add(texture,"colorSpace",{
    sRGB:THREE.SRGBColorSpace,
    Liner:THREE.LinearSRGBColorSpace,
    Note:THREE.NoColorSpace,
}).onChange(()=>{
    texture.needsUpdate=true
});

9、线性雾与指数雾

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

const boxGaemetry=new THREE.BoxGeometry(1,1,100);
const boxMaterial=new THREE.MeshBasicMaterial({color:0x00ff00});
const box=new THREE.Mesh(boxGaemetry,boxMaterial);
scene.add(box);

//创建场景fog
scene.fog=new THREE.Fog(0x999999,0.1,50);
//scene.fog=new THREE.FogExp2(0x999999,0.1,50);
scene.background=new THREE.Color(0x999999);

//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

10、加载gltf模型与解释器

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader.js';//导入hdr加载器
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';//导入gltf加载器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=5;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

//实例化加载器gltf
const gltfLoader = new GLTFLoader();
//实现化加载器draco
const dracoLoader=new DRACOLoader();
//设置draco的路径
dracoLoader.setDecoderPath("./draco");
//设置gltf加载器为draco解码器
gltfLoader.setDRACOLoader(dracoLoader);


//加载模型
gltfLoader.load(
    "./texture/adamHead/adamHead.gltf",//模型路径
    function ( gltf ) {//完成加载回调
        console.log(gltf);
        scene.add( gltf.scene );
    },
);




//加载环境贴图
const rebeLoader=new RGBELoader();
rebeLoader.load("./texture/university_workshop_4k.hdr",(envMap)=>{
    //设置球形映射
    envMap.mapping=THREE.EquirectangularReflectionMapping;
    //设置环境贴图
    scene.background=envMap;
    //设置场景环境贴图
    scene.environment=envMap;
});


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

11、射线操作

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader.js';//导入hdr加载器
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';//导入gltf加载器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=25;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

//创建三个球
const sphere1=new THREE.Mesh(
    new THREE.SphereGeometry(1,32,32),
    new THREE.MeshBasicMaterial({color:0x00FF00})
);
sphere1.position.x=-5;
scene.add(sphere1);


const sphere2=new THREE.Mesh(
    new THREE.SphereGeometry(1,32,32),
    new THREE.MeshBasicMaterial({color:0x0000FF})
);
scene.add(sphere2);

const sphere3=new THREE.Mesh(
    new THREE.SphereGeometry(1,32,32),
    new THREE.MeshBasicMaterial({color:0xFF00FF})
);
sphere3.position.x=5;
scene.add(sphere3);


//创建射线
const raycaster=new THREE.Raycaster();
//创建鼠标向量
const mousePointer =new THREE.Vector2();
function onPointerMove( event ) {
    console.log(event.clientX,event.clientY);
    //设置鼠标向量的x,y值
    mousePointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mousePointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    
    //通过摄像机与鼠标更新射线
    raycaster.setFromCamera(mousePointer,camera);
    //计算物体和射线的焦点
    const intersects = raycaster.intersectObjects([sphere1,sphere2,sphere3]);
    if(intersects.length>0){
        intersects[0].object.material.color.set(0xff0000);
        //console.log(intersects);
    }
}
window.addEventListener( 'click', onPointerMove );



//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

12、补间动画tween

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader.js';//导入hdr加载器
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';//导入gltf加载器
import * as TWEEN from 'three/examples/jsm/libs/tween.module.js'//导入tween动画

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=25;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

//创建1个球
const sphere1=new THREE.Mesh(
    new THREE.SphereGeometry(1,32,32),
    new THREE.MeshBasicMaterial({color:0x00FF00})
);
sphere1.position.x=-5;
scene.add(sphere1);

const tween=new TWEEN.Tween(sphere1.position);
tween.to({x:5},2000);//2000ms后到达
// tween.onUpdate(()=>{
//     console.log(sphere1.position.x);
// });
tween.repeat(Infinity);//循环无数次
tween.yoyo(true);//循环往复
tween.delay(1000);
tween.easing(TWEEN.Easing.Quadratic.InOut);//设置缓动函数
//启动补间动画
tween.start();





//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    TWEEN.update();//更新tween
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

13、法向量辅助器

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//导入轨道控制器
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';//导入ili-gui
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader.js';//导入hdr加载器
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';//导入gltf加载器
import * as TWEEN from 'three/examples/jsm/libs/tween.module.js'//导入tween动画
import { VertexNormalsHelper } from 'three/addons/helpers/VertexNormalsHelper.js';//导入法向量辅助器

// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 设置相机位置
camera.position.z=25;
camera.position.y=2;
camera.position.x=2;
camera.lookAt(0,0,0);
scene.add(camera);

//创建平面
const planeGeometry=new THREE.PlaneGeometry();
const planeMaterial=new THREE.MeshBasicMaterial({color:0x00ff00});
const plane=new THREE.Mesh(planeGeometry,planeMaterial);
scene.add(plane);

//创建法向量辅助器
const helper=new VertexNormalsHelper(plane,0.2,0xff0000);
scene.add(helper);


//添加世界坐标辅助器
const axesHelper=new THREE.AxesHelper(5);
scene.add(axesHelper);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
//console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
//设置带阻尼的惯性
controls.enableDamping=true;
controls.dampingFactor=0.05;


//渲染函数
function animate() {
    controls.update();
    renderer.render(scene, camera); // 使用渲染器,通过相机将场景渲染进来
    TWEEN.update();//更新tween
    requestAnimationFrame(animate);//下一帧继续调用
}
animate();


// 监听窗口变化
window.addEventListener("resize",()=>{
    //更新摄像头宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机的投影矩阵
    camera.updateProjectionMatrix();

    //更新渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight);
    //设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});

let eventObj={
    Fullscreen:function(){
        document.body.requestFullscreen();
    },
    ExitFullscreen:function(){
        document.exitFullscreen();
    },
}
//创建GUI
const gui=new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");

相关推荐
hour_go3 小时前
TCP/IP协议相关知识点
网络·笔记·网络协议·tcp/ip
浪裡遊3 小时前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
課代表3 小时前
JavaScript 二维数组的三种定义与初始化方法
javascript·初始化·二维数组·多维数组·动态数组·循环遍历·数组合并
潘达斯奈基~4 小时前
在使用spark的applyInPandas方法过程中,遇到类型冲突问题如何解决
大数据·笔记
鸡吃丸子4 小时前
Next.js 入门指南
开发语言·javascript·next.js
菜鸟‍4 小时前
【论文学习】大语言模型(LLM)论文
论文阅读·人工智能·学习
罚时大师月色4 小时前
Vue+ts 如何实现父组件和子组件通信
javascript·vue.js·ecmascript
漂流瓶jz5 小时前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
我先去打把游戏先5 小时前
ESP32学习笔记(基于IDF):IOT应用——WIFI连接
笔记·单片机·嵌入式硬件·mcu·物联网·学习·esp32