ThreeJS快速入门
ThreeJS开发
该教程由本人学习记录下来的笔记供大家学习
- 初识ThreeJS它是一个web端3D开发的好帮手
- 本人对3D的热爱探索便前往学习了解了一番
- 特此整理以下笔记供大家参阅
学习准备
这里我使用vue脚手架去创建的项目
目录结构:
安装
这里可以单独安装依赖,我这里安装好了,大家只需要在package.json中放入以下代码块
"dependencies": {
"dat.gui": "^0.7.9",
"gsap": "^3.11.0",
"three": "^0.143.0",
"vue": "^3.0.4"
},
- three肯定是必不可少的
- 其次dat.gui是three提供的一款gui界面调试的工具
- gsap是一款动画库,用于实现动画
- vue则是脚手架创建项目时自动安装好的
放入以上代码后则使用以下命令进行安装依赖
npm i
基本使用
这里简单使用three实现一个平面图形
在index.html中编写代码并且下方js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three开发---碰磕</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./src/3D/threeBasic.js"></script>
</body>
</html>
threeBasic.js
1.引入three.js
import * as $Three from 'three'
2.创建一个场景
const scene= new $Three.Scene();
3.创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
设置相机位置x,y,z并放入场景中
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
4.添加物体
这里创建一个平面图形
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
5.初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
6.将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
7、使用渲染器,通过相机将场景渲染进来
renderer.render(scene,camera);
以上代码即可实现简单的效果
npm run dev
运行看看效果图吧!!!
效果图
现在开始一步一步系统学习吧!
控制器
使用控制器查看3d物体
这里我就直接贴代码了,代码中都给了注释,index.html中别忘了引入该js
/**
* 使用控制器查看3d物体
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//编写渲染函数
function render(){
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
以上代码即可实现3D效果了,可拉近拉远,可旋转
物体移动
实现3d物体移动
/**
* 实现3d物体移动
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
cube.position.x+=0.01;
if(cube.position.x>5){
cube.position.x=0
}
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
- 通过new $Three.AxesHelper(5)创建了坐标轴,使得物体移动看着更清晰
- 再通过控制position去修改它的位置
效果图
效果图如下:它是一直在动的哈
物体缩放与旋转
实现3d物体缩放
/**
* 实现3d物体缩放
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//6、使用渲染器,通过相机将场景渲染进来
// renderer.render(scene,camera);
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
cube.position.x+=0.01;
cube.scale.x+=0.01;//缩放scale
cube.rotation.x+=0.01//旋转rotation
if(cube.position.x>5){
cube.position.x=0
cube.scale.x=1
cube.rotation.x=0
}
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
- 旋转通过控制rotation属性
- 缩放通过控制scale属性
以上代码即可看到该图形边变长边旋转…
Clock跟踪时间
/**
* Clock跟踪时间
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//设置时钟
const clock=new $Three.Clock();
//编写渲染函数
function render(){
//获取时钟运行的总时长
let time=clock.getElapsedTime();
let deltaTime=clock.getDelta();
// console.log("时钟运行总时长:",time);
// console.log("两次获取时间的间隔::",deltaTime);
let t=time%5;
cube.position.x =t*1;
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
- 以上代码主要是运用一下Three中的Clock()时钟
Gsap动画
gsap设置各种动画效果
如果没安装该依赖则手动安装一下,跟着教程的话一开始即安装好了,没有安装请安装
npm install gsap
开始使用:
/**
* gsap设置各种动画效果
* npm install gsap
* 官网:https://github.com/greensock/GSAP
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//导入动画库
import gsap from 'gsap'
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
//修改几何体的位置
// cube.position.set(5,0,0)
// cube.position.x=3;
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//6、使用渲染器,通过相机将场景渲染进来
// renderer.render(scene,camera);
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//设置时钟
// const clock=new $Three.Clock();
//设置动画to(物体的属性,{需要执行的操作..},ease执行方式,repeat:重复的次数(死循环设置-1),yoyo:往返移动,delay:延迟移动,onComplete:()=>完成执行的回调函数,onStart:()=>动画开始执行)
var maveposition=gsap.to(cube.position,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut",
onComplete:()=>{
console.log("移动完成")
},
onStart:()=>{
console.log("动画开始")
}
});
window.addEventListener('click',()=>{
//isActive()表示是否在运行移动
if(maveposition.isActive()){
maveposition.pause();//动画暂停
}else{
maveposition.resume();//动画继续
}
})
gsap.to(cube.rotation,{x:2*Math.PI,duration:6,ease: "power1.inOut"})
//编写渲染函数
function render(){
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
- 如何使用代码中都进行了注释,自行看看咯
自适应
以上代码均没有做一个自适应处理
- 当你放大缩小页面时,页面内容还是保持不变,所以我们要解决这个问题!!!
- 通过监听画面变化,更新画面
/**
* 页面自适应
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//导入动画库
import gsap from 'gsap'
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
//修改几何体的位置
// cube.position.set(5,0,0)
// cube.position.x=3;
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//设置动画to(物体的属性,{需要执行的操作..},ease执行方式,repeat:重复的次数(死循环设置-1),yoyo:往返移动,delay:延迟移动,onComplete:()=>完成执行的回调函数,onStart:()=>动画开始执行)
var maveposition=gsap.to(cube.position,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut",
onComplete:()=>{
console.log("移动完成")
},
onStart:()=>{
console.log("动画开始")
}
});
window.addEventListener('click',()=>{
//isActive()表示是否在运行移动
if(maveposition.isActive()){
maveposition.pause();//动画暂停
}else{
maveposition.resume();//动画继续
}
})
gsap.to(cube.rotation,{x:2*Math.PI,duration:6,ease: "power1.inOut"})
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
})
- resize表示页面大小被改变时触发的事件
Gui
通过gui界面更改参数
没安装的话请安装
npm install --save dat.gui
使用:
/**
* gui界面更改参数
* npm install --save dat.gui
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//导入动画库
import gsap from 'gsap'
//导入gui
import * as dat from 'dat.gui'
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将几何体添加到场景中
const gui=new dat.GUI()
gui.add(cube.position,"x").min(0).max(5).step(0.02).name("正方体x坐标").onChange((val)=>{
console.log("你修改了x=",val)
}).onFinishChange((val)=>{
console.log("完全停下来..",val)
})
//修改物体颜色
let params={
color:'#ffff00',
fn:()=>{
gsap.to(cube.rotation,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut"})
},
}
gui.addColor(params,'color').onChange((val)=>cube.material.color.set(val));
//设置选项卡
gui.add(cube,'visible').name("是否显示");
var folder=gui.addFolder("设置立方体");
folder.add(cube.material,"wireframe");
//设置按钮点击触发某个事件
gui.add(params,"fn").name("立方体运动")
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//6、使用渲染器,通过相机将场景渲染进来
// renderer.render(scene,camera);
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//设置时钟
// const clock=new $Three.Clock();
//设置动画to(物体的属性,{需要执行的操作..},ease执行方式,repeat:重复的次数(死循环设置-1),yoyo:往返移动,delay:延迟移动,onComplete:()=>完成执行的回调函数,onStart:()=>动画开始执行)
var maveposition=gsap.to(cube.position,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut",
onComplete:()=>{
console.log("移动完成")
},
onStart:()=>{
console.log("动画开始")
}
});
window.addEventListener('click',()=>{
//isActive()表示是否在运行移动
if(maveposition.isActive()){
maveposition.pause();//动画暂停
}else{
maveposition.resume();//动画继续
}
})
gsap.to(cube.rotation,{x:2*Math.PI,duration:6,ease: "power1.inOut"})
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
效果图
BufferGeometry(设置顶点)
设置顶点创建矩形
BufferGeometry设置顶点创建矩形
/**
* BufferGeometry设置顶点创建矩形
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//导入动画库
import gsap from 'gsap'
//导入gui
import * as dat from 'dat.gui'
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
const cubeGeometry=new $Three.BufferGeometry();
const vertices=new Float32Array([
-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0
]);
cubeGeometry.setAttribute("position",new $Three.BufferAttribute(vertices,3));
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const mesh=new $Three.Mesh(cubeGeometry,cubeMaterial)
scene.add(mesh)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
实现三角形
通过循环创建多个角度不同的三角形,要的就是杂乱无章的感觉
/**
* 使用BufferGeometry实现酷炫三角形
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//导入动画库
import gsap from 'gsap'
//导入gui
import * as dat from 'dat.gui'
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//3、添加物体
//创建几何体
for(let i=0;i<50;i++){
const cubeGeometry=new $Three.BufferGeometry();
const positionArr=new Float32Array(9);
//3个顶点(每个顶点3个值)
for(let j=0;j<9;j++){
positionArr[j]=Math.random()*5-1;
}
cubeGeometry.setAttribute("position",new $Three.BufferAttribute(positionArr,3));
let color=new $Three.Color(Math.random(),Math.random(),Math.random());//随机颜色
const cubeMaterial=new $Three.MeshBasicMaterial({color: color,transparent:true,opacity:0.5});//使用基础材质并设置颜色
//根据几何体和材质创建物体
const mesh=new $Three.Mesh(cubeGeometry,cubeMaterial)
scene.add(mesh)
}
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
材质与纹理
- 通过enableDamping设置阻尼让物体有重量感
- 代码中演示了纹理的一些常用属性
/**
* 材质与纹理
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//导入纹理
const textureloader=new $Three.TextureLoader();
const myTextloader=textureloader.load('../chunyu02.jpg')//加载本地图片
/**
* 纹理常用的属性
*/
myTextloader.offset.set(0.1,0)//偏移
myTextloader.center.set(0.5,0.5)//旋转的原点
myTextloader.rotation=Math.PI/4//旋转45deg
myTextloader.repeat.set(2,3);//重复
myTextloader.wrapS=$Three.RepeatWrapping;//设置重复模式(该值表示无限重复)
//添加物体
const geometry=new $Three.BoxBufferGeometry(1,1,1);
//材质
const basicMaterial=new $Three.MeshBasicMaterial({
color:"#ffff00",
map:myTextloader
})
const cube=new $Three.Mesh(geometry,basicMaterial);
scene.add(cube)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//6、使用渲染器,通过相机将场景渲染进来
// renderer.render(scene,camera);
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
以上代码主要是对材质与纹理的一个了解使用
标准网格材质
通过MeshStandardMaterial创建标准网格材质
/**
* 标准网格材质
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
let event={}
//单张纹理图的加载
event.onLoad=function(){
console.log("加载完成...")
}
event.onProgress=function(e,sum,total){
console.log("正在加载的路径",e)
console.log("加载进度",sum)
console.log("需要加载的总进度:",total)
console.log("加载进度百分比:",((sum/total)*100).toFixed(2)+'%');
}
event.onError=function(){
console.log("加载失败")
}
//设置加载管理器
const loadingManager=new $Three.LoadingManager(
event.onLoad,
event.onProgress,
event.onError
);
//导入纹理
const textureloader=new $Three.TextureLoader(loadingManager);
const myTextloader=textureloader.load('../chunyu02.jpg')//event.onLoad,event.onProgress,event.onError加载本地图片
/**
* 纹理常用的属性
*/
myTextloader.offset.set(0.1,0)//偏移
myTextloader.center.set(0.5,0.5)//旋转的原点
myTextloader.rotation=Math.PI/4//旋转45deg
myTextloader.repeat.set(2,3);//重复
myTextloader.wrapS=$Three.RepeatWrapping;//设置重复模式(该值表示无限重复)
//添加物体
const geometry=new $Three.BoxBufferGeometry(1,1,1);
//材质
const material=new $Three.MeshStandardMaterial({
color:"#ffff00",
map:myTextloader,
roughness:0,//粗糙度
metalness:0,//金属度
})
//灯光
const light1=new $Three.AmbientLight(0xffffff,0.5);//环境光
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.position.set(10,10,10)//设置平行光照的位置
scene.add(light2)
const cube=new $Three.Mesh(geometry,material);
scene.add(cube)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//6、使用渲染器,通过相机将场景渲染进来
// renderer.render(scene,camera);
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
效果图
环境贴图
这里我要推荐一个素材网:[Textures - Poliigon](https://www.poliigon.com/textures)
自行去下载hdr图片,这里再推荐个图片格式转换:
[Convertio — 文件转换器](https://www.poliigon.com/textures)
/**
* 环境贴图
*/
import * as $Three from 'three'
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//加载hdr环境图
const rgbeLoader=new RGBELoader();
rgbeLoader.loadAsync('./public/HdrOutdoorBeachBlueHourCloudy002_HDR_4K.hdr').then(res=>{
res.mapping=$Three.EquirectangularReflectionMapping;//设置映射
scene.background=res;
scene.environment=res;
})
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
//设置cube纹理加载器
const cubeTextureloader=new $Three.CubeTextureLoader()
// const envMapTexture=cubeTextureloader.load([
// "/public/bg1.jpg",
// "/public/chunyu02.jpg",
// "/public/bg2.jpg",
// "/public/chunyu02.jpg",
// "/public/chunyu02.jpg",
// "/public/chunyu02.jpg",
// ]);
const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const textureloader=new $Three.TextureLoader();
const myTextloader=textureloader.load('./public/HdrOutdoorBeachBlueHourCloudy002_JPG_4K.jpg')
const material=new $Three.MeshStandardMaterial({
metalness: 0.7,
roughness: 0.1,
// envMap:rgbeLoader
map:myTextloader
})
const sphere=new $Three.Mesh(sphereGeo,material);
scene.add(sphere)
//设置环境背景
// scene.background=envMapTexture;
//设置默认环境背景
// scene.environment=envMapTexture;
//灯光
const light1=new $Three.AmbientLight(0xffffff,0.5);//环境光
scene.add(light1)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.position.set(10,10,10)//设置平行光照的位置
scene.add(light2)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
- 通过loadAsync异步加载hdr环境图
- 以上代码即可实现身临其境般的感觉
效果图
还可以360°旋转呢
灯光与阴影
创建一个平面与一个球实现对灯光以及阴影的使用
/**
* 灯光与阴影
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const material=new $Three.MeshStandardMaterial()
const sphere=new $Three.Mesh(sphereGeo,material);
sphere.castShadow=true;//设置球投射阴影
scene.add(sphere)
//创建平面
const planeGeo=new $Three.PlaneBufferGeometry(10,10);
const plane=new $Three.Mesh(planeGeo,material);
plane.position.set(0,-1,0);
plane.rotation.x=-Math.PI/2;
plane.receiveShadow=true//接收阴影
scene.add(plane)
//灯光
const light1=new $Three.AmbientLight(0xffffff,0.5);//环境光
scene.add(light1)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.castShadow=true;//设置光线投射阴影
light2.position.set(10,10,10)//设置平行光照的位置
scene.add(light2)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//开启阴影计算
renderer.shadowMap.enabled=true;
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
- castShadow投射阴影
- receiveShadow接收阴影
- renderer.shadowMap.enabled=true;开启阴影计算
- AmbientLight环境光
- DirectionalLight平行光
效果图
平行光的阴影属性
举例一些常见的
/**
* 平行光阴影属性
*/
light2.shadow.radius=20;//阴影模糊度
light2.shadow.mapSize.set(1080,1080);//阴影贴图分辨率(默认512*512)
//设置平行光投影相机的属性(近端、远端、上、下、左、右)
light2.shadow.camera.near=0.5;
light2.shadow.camera.far=500;
light2.shadow.camera.top=5;
light2.shadow.camera.bottom=-5;
light2.shadow.camera.left=5;
light2.shadow.camera.right=-5;
scene.add(light2)
聚光灯
通过SpotLight去创建聚光灯
/**
* 聚光灯
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const material=new $Three.MeshStandardMaterial()
const sphere=new $Three.Mesh(sphereGeo,material);
sphere.castShadow=true;//设置球投射阴影
scene.add(sphere)
//创建平面
const planeGeo=new $Three.PlaneBufferGeometry(20,20);
const plane=new $Three.Mesh(planeGeo,material);
plane.position.set(0,-1,0);
plane.rotation.x=-Math.PI/2;
plane.receiveShadow=true//接收阴影
scene.add(plane)
//灯光
const light1=new $Three.AmbientLight(0xffffff,0.5);//环境光
scene.add(light1)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.castShadow=true;//设置光线投射阴影
light2.position.set(10,10,10)//设置平行光照的位置
/**
* 平行光阴影属性
*/
light2.shadow.radius=20;//阴影模糊度
light2.shadow.mapSize.set(1080,1080);//阴影贴图分辨率(默认512*512)
//设置平行光投影相机的属性(近端、远端、上、下、左、右)
light2.shadow.camera.near=0.5;
light2.shadow.camera.far=500;
light2.shadow.camera.top=5;
light2.shadow.camera.bottom=-5;
light2.shadow.camera.left=5;
light2.shadow.camera.right=-5;
// scene.add(light2)
/**
* 聚光灯
*/
const light3=new $Three.SpotLight(0xffffff,1);
//调节亮度
light3.intensity=3
light3.position.set(5,5,5);
light3.castShadow=true;
light3.shadow.mapSize.set(1080,1080);
light3.target=sphere;//聚光灯照明目标(设置为球)
sphere.position.x=2//球移动聚光灯追随
light3.angle=Math.PI/6;//聚光灯角度(默认180deg/3)
light3.distance=15;//光的衰减效果
light3.penumbra=0;//伴影的衰减效果
light3.decay=0.1;//沿着光照距离的衰减(需要给渲染器设置)
scene.add(light3)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//开启阴影计算
renderer.shadowMap.enabled=true;
renderer.physicallyCorrectLights=true;//使用物理上正确的光照模式
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//6、使用渲染器,通过相机将场景渲染进来
// renderer.render(scene,camera);
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//编写渲染函数
function render(){
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
- 以上代码并且演示了聚光灯的一些属性
效果图
点光源
通过PointLight创建
/**
* 点光源
*/
import * as $Three from 'three'
//导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、创建一个场景
const scene= new $Three.Scene();
//2、创建一个相机
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
//设置相机位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相机放入场景中
const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const material=new $Three.MeshStandardMaterial()
const sphere=new $Three.Mesh(sphereGeo,material);
sphere.castShadow=true;//设置球投射阴影
scene.add(sphere)
//创建平面
const planeGeo=new $Three.PlaneBufferGeometry(20,20);
const plane=new $Three.Mesh(planeGeo,material);
plane.position.set(0,-1,0);
plane.rotation.x=-Math.PI/2;
plane.receiveShadow=true//接收阴影
scene.add(plane)
//灯光
const light1=new $Three.AmbientLight(0xffffff,0.5);//环境光
scene.add(light1)
/**
* 添加小球
*/
const smallBall=new $Three.Mesh(
new $Three.SphereBufferGeometry(0.1,20,20),
new $Three.MeshBasicMaterial({color: 0xff0000})
)
smallBall.position.set(2,2,2)
scene.add(smallBall)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.castShadow=true;//设置光线投射阴影
light2.position.set(10,10,10)//设置平行光照的位置
/**
* 平行光阴影属性
*/
light2.shadow.radius=20;//阴影模糊度
light2.shadow.mapSize.set(1080,1080);//阴影贴图分辨率(默认512*512)
//设置平行光投影相机的属性(近端、远端、上、下、左、右)
light2.shadow.camera.near=0.5;
light2.shadow.camera.far=500;
light2.shadow.camera.top=5;
light2.shadow.camera.bottom=-5;
light2.shadow.camera.left=5;
light2.shadow.camera.right=-5;
// scene.add(light2)
/**
* 点光源
*/
const light4=new $Three.PointLight(0xfff00f,1);
light4.intensity=2;
scene.add(light4)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//设置渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//宽、高
//开启阴影计算
renderer.shadowMap.enabled=true;
renderer.physicallyCorrectLights=true;//使用物理上正确的光照模式
//5、将渲染的内容添加到dom节点中
document.body.appendChild(renderer.domElement)
//创建轨道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//设置控制器阻尼,更有重量感,然后必须在动画循环调用update()
controls.enableDamping=true;
//创建坐标轴
const xy=new $Three.AxesHelper(5);
scene.add(xy);
//设置时钟
const clock=new $Three.Clock();
//编写渲染函数
function render(){
let time=clock.getElapsedTime()
smallBall.position.x=Math.sin(time)*3;
smallBall.position.z=Math.cos(time)*3;
smallBall.position.y=2+Math.sin(time*10);
controls.update();//调用update实现阻尼
renderer.render(scene,camera);//每一帧就进行一次渲染...
requestAnimationFrame(render);//浏览器自带方法请求帧
}
render();//调用渲染函数
//监听画面变化,更新画面
window.addEventListener('resize',()=>{
//更新摄像头
camera.aspect=window.innerWidth/window.innerHeight;
//更新摄像头投影矩阵
camera.updateProjectionMatrix();
//更新渲染器
renderer.setSize(window.innerWidth,window.innerHeight);
//设置渲染像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
- 实现了小球围绕大球转
效果图
一直转着呢…
了解这些就差不多了,可以去实现一些案例了