ThreeJS快速入门

  • ThreeJS开发
    • 学习准备
    • 安装
    • 基本使用
      • 效果图
    • 控制器
    • 物体移动
      • 效果图
    • 物体缩放与旋转
    • Clock跟踪时间
    • Gsap动画
    • 自适应
    • Gui
      • 效果图
    • BufferGeometry(设置顶点)
      • 设置顶点创建矩形
      • 实现三角形
    • 材质与纹理
    • 标准网格材质
      • 效果图
    • 环境贴图
      • 效果图
    • 灯光与阴影
      • 效果图
    • 平行光的阴影属性
    • 聚光灯
      • 效果图
    • 点光源
      • 效果图

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;//缩放scalecube.rotation.x+=0.01//旋转rotationif(cube.position.x>5){cube.position.x=0cube.scale.x=1cube.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设置各种动画效果

官网:https://github.com/greensock/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:rgbeLoadermap: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);
});
  • 实现了小球围绕大球转

效果图

一直转着呢…

了解这些就差不多了,可以去实现一些案例了

Three.js快速入门相关推荐

  1. 54 Node.js快速入门

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.Node开发概述 1.1 为什么要学习服务器端开发基础 能够与后端程序员更加紧密的配合 ...

  2. TensorFlow.js快速入门

    by Pau Pavón 通过保罗·帕文(PauPavón) TensorFlow.js快速入门 (A quick introduction to TensorFlow.js) TensorFlow ...

  3. (vue基础试炼_01)使用vue.js 快速入门hello world

    文章目录 一.需求案例 二.案例实现 2.1. 原始js写法 2.2. 怎样使用vue.js ? 2.3. 使用vue.js 写法 三.案例vue简述? 四.案例趣味延伸 五.表达值作用及嘱咐语 一. ...

  4. Vue.js快速入门之八:实现登录功能

    系统登录是指用户必须提供满足一定条件的信息后,才可以进入系统.最早系统一般是指用户名和密码,如今,登录方式已多元化,系统一般登录方式有:用户名+密码.二维码扫码登录.第三方授权登录.手机号+短信登录等 ...

  5. vue.js快速入门

    以前看到多少天学习系列,我都深感烦躁,短短几天怎么可以精通,那是对于他们而言.但是,今天我要写一个快速入门,本人觉得还是有一点用处,因为,我不可能在一天之内精通某种东西,却可以在一两小时入门. 回到v ...

  6. doodoo.js快速入门教程

    快速入门 我们通过3步演示如何快速创建一个doodoo项目 第一步 # 创建doodoo-demo目录 mkdir doodoo-demo && cd doodoo-demo# 初始化 ...

  7. doodoo.js快速入门教程 1

    快速入门 我们通过3步演示如何快速创建一个doodoo项目 第一步 # 创建doodoo-demo目录 mkdir doodoo-demo && cd doodoo-demo# 初始化 ...

  8. html+css+js+快速入门

    html 1.a标签 <!--使用name作为标记--> <a name="top">顶部</a> <!--target:表示窗口在哪里打 ...

  9. Node.js快速入门

    一.简介 1.什么是Node.js 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎, ...

最新文章

  1. 20180625笔记
  2. Qt中的QBoxLayout
  3. proteus虚拟终端窗口不显示_Linux终端美化工具(ohmyzsh)
  4. java 默认网关,java 获得默认网关 和 子网掩码 本机
  5. Exchange 2010发现拓扑失败
  6. 员工价值——如何体现自己价值,如何被自己的领导认可
  7. PostgreSQL 分页——示例
  8. Tensorflow 迁移学习 识别中国军网、中国军视网Logo水印
  9. wampserver3.2.0_MySQL 8.0 技术详解
  10. Python字符串函数说明(菜鸟教程里面的)
  11. mysql三高讲解(二):2.1 索引组织表
  12. 只用6张图教会AI识别物体,达摩院新方案大幅降低AI数据标注成本
  13. init与clinit 与 类的初始化顺序
  14. [禅悟人生]将所学转化成修行
  15. paip.微信菜单直接跳转url和获取openid流程总结
  16. 牛客 处女座和小姐姐
  17. 药品管理系统java_基于Java的药品管理系统
  18. 哪所985计算机专业招文科,4张表看透36所985大学自主招生专业,收藏起来做备考材料!...
  19. 计算机视觉方向简介 | 深度学习3D重建
  20. jrtplib学习目录及总结

热门文章

  1. [Python]游戏编程--人工智能1
  2. WORKLIST服务
  3. 微信摇一摇插件ios_iOS仿微信摇一摇功能
  4. mysql引擎与优化
  5. 【Delphi】Android 桌面图标添加快捷菜单功能
  6. Jenkins之自动进行360加固
  7. Shell脚本攻略04-玩转文件描述符及重定向
  8. vue中前端实现pdf预览(含vue-pdf插件用法)
  9. 等值连接mysql_数据库等值连接,左连接,右连接的区别
  10. Trinity转录组无参组装