Three.js快速入门
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快速入门相关推荐
- 54 Node.js快速入门
技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.Node开发概述 1.1 为什么要学习服务器端开发基础 能够与后端程序员更加紧密的配合 ...
- TensorFlow.js快速入门
by Pau Pavón 通过保罗·帕文(PauPavón) TensorFlow.js快速入门 (A quick introduction to TensorFlow.js) TensorFlow ...
- (vue基础试炼_01)使用vue.js 快速入门hello world
文章目录 一.需求案例 二.案例实现 2.1. 原始js写法 2.2. 怎样使用vue.js ? 2.3. 使用vue.js 写法 三.案例vue简述? 四.案例趣味延伸 五.表达值作用及嘱咐语 一. ...
- Vue.js快速入门之八:实现登录功能
系统登录是指用户必须提供满足一定条件的信息后,才可以进入系统.最早系统一般是指用户名和密码,如今,登录方式已多元化,系统一般登录方式有:用户名+密码.二维码扫码登录.第三方授权登录.手机号+短信登录等 ...
- vue.js快速入门
以前看到多少天学习系列,我都深感烦躁,短短几天怎么可以精通,那是对于他们而言.但是,今天我要写一个快速入门,本人觉得还是有一点用处,因为,我不可能在一天之内精通某种东西,却可以在一两小时入门. 回到v ...
- doodoo.js快速入门教程
快速入门 我们通过3步演示如何快速创建一个doodoo项目 第一步 # 创建doodoo-demo目录 mkdir doodoo-demo && cd doodoo-demo# 初始化 ...
- doodoo.js快速入门教程 1
快速入门 我们通过3步演示如何快速创建一个doodoo项目 第一步 # 创建doodoo-demo目录 mkdir doodoo-demo && cd doodoo-demo# 初始化 ...
- html+css+js+快速入门
html 1.a标签 <!--使用name作为标记--> <a name="top">顶部</a> <!--target:表示窗口在哪里打 ...
- Node.js快速入门
一.简介 1.什么是Node.js 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎, ...
最新文章
- 20180625笔记
- Qt中的QBoxLayout
- proteus虚拟终端窗口不显示_Linux终端美化工具(ohmyzsh)
- java 默认网关,java 获得默认网关 和 子网掩码 本机
- Exchange 2010发现拓扑失败
- 员工价值——如何体现自己价值,如何被自己的领导认可
- PostgreSQL 分页——示例
- Tensorflow 迁移学习 识别中国军网、中国军视网Logo水印
- wampserver3.2.0_MySQL 8.0 技术详解
- Python字符串函数说明(菜鸟教程里面的)
- mysql三高讲解(二):2.1 索引组织表
- 只用6张图教会AI识别物体,达摩院新方案大幅降低AI数据标注成本
- init与clinit 与 类的初始化顺序
- [禅悟人生]将所学转化成修行
- paip.微信菜单直接跳转url和获取openid流程总结
- 牛客 处女座和小姐姐
- 药品管理系统java_基于Java的药品管理系统
- 哪所985计算机专业招文科,4张表看透36所985大学自主招生专业,收藏起来做备考材料!...
- 计算机视觉方向简介 | 深度学习3D重建
- jrtplib学习目录及总结