共计 2979 个字符,预计需要花费 8 分钟才能阅读完成。
随着 webGL 的热度越来越高,作为一个老前端也想去理解一下,我抉择入门 three.js 理解一下。
webGL & Three.js 简介
WebGL 是一项在浏览器体现 3D 画面的技术。是一种 3D 绘图规范,容许把 JavaScript 和 OpenGL ES 2.0 联合在一起,通过减少 OpenGL ES 2.0 的一个 JavaScript 绑定,WebGL 能够为 HTML5 Canvas 提供硬件 3D 减速渲染(局部计算 GPU),这样 Web 开发人员就能够借助零碎显卡来在浏览器里更流畅地展现 3D 场景和模型了,还能创立简单的导航和数据视觉化。
Three.js(Javascript 3D library),应用 JavaScript 语言对 WebGL 进行了封装,让前端开发人员在不须要把握很多数学知识和绘图常识的状况下,也可能轻松进行 web 3D 开发。
相干文档
- three.js 中文文档
- 收费 3D 模型下载网站、模型下载
- blender 下载,Blender 是一款收费的三维全功能软件.
- Vite 中文文档
- 素材源码
下载解决模型
在理论我的项目咱们是须要和美术单干的,当然如果你或者你对象懂 3d 建模就再好不过了。
- 关上资源网站,搜寻模型,关上详情,点击 download 按钮。
- 应用 blender 导入模型。
- 应用 blender 导出 glb 模型文件。
应用 vite 搭建我的项目。
Vite 能帮咱们疾速搭建我的项目。
npm create vite@latest
three.js 基本概念
三维的物体要渲染在二维的屏幕上。首先要创立一个场景来搁置物体,那么最终怎么显示三维的内容,就应该找一个相机,将相机放在场景的某个地位,而后想要显示就要把相机拍的内容渲染进去。所以就引出三个基本概念:场景、相机、渲染器。
创立场景
const scene = new THREE.Scene();
创立相机
three.js 中相机分为立方体相机、正交相机、近景相机。这里咱们应用的是近景相机。
构造函数 PerspectiveCamera(fov, aspect, near, far)
- fov — 相机视锥体垂直视角
- aspect — 相机视锥体宽高比
- near — 相机视锥体近裁剪面
- far — 相机视锥体远裁剪面。
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10);
渲染器
three.js 中渲染器分为 Canvas 渲染器(CanvasRenderer)、WebGL 渲染器(WebGLRenderer)这里我应用 WebGL 渲染器。
构造函数 WebGLRenderer(parameters)
parameters 是一个可选对象,蕴含用来定义渲染器行为的属性。当没有设置该参数时,将应用默认值。
- canvas — 一个用来绘制输入的 Canvas 对象。
- context — 所用的 渲染上下文 (RenderingContext) 对象。
- precision — 着色器的精度。能够是 ”highp”, “mediump” 或 “lowp”. 默认为 ”highp”,如果设施反对的话。
- alpha — Boolean, 默认为 false.
- premultipliedAlpha — Boolean, 默认为 true.
- antialias — Boolean, 默认为 false.
- stencil — Boolean, 默认为 true.
- preserveDrawingBuffer — Boolean, 默认为 false.
- depth — Boolean, 默认为 true.
- logarithmicDepthBuffer — Boolean, 默认为 false.
// 创立渲染器
const renderer = new THREE.WebGLRenderer({antialias: true});
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 将 webgl 渲染的 canvas 内容增加到 body 中
document.body.appendChild(renderer.domElement);
光照
three.js 中光照有以下几种:环境光源(AmbientLight)、点光源(PointLight)、聚光光源(SpotLight)、平行光源(DirectionalLight)、半球光源(HemisphereLight)
其中反对暗影的光照有:点光源,聚光灯,平行光源。
这里我应用的是半球光源 DirectionalLight(hex, intensity)
- hex — 光源色彩的 RGB 数值。
- intensity — 光源强度的数值。
创立一个光照,从一个特定的方向,而不是从一个特定的地位。这个光看起来就像光源位于有限远处,因而它产生的光线都是平行的。最好的类比是一个像太阳一样的光源:太阳是如此边远,所有的阳光照射到物体上都简直来自同一个角度。
// 创立环境光
const directionLight = new THREE.DirectionalLight(0xffffff, 0.4);
// 讲环境光增加到场景
scene.add(directionLight);
加载资源
加载模型,播放模型中所有动画。
new GLTFLoader().load('../resources/models/donuts.glb', (gltf) => {scene.add(gltf.scene);
donuts = gltf.scene;
mixer = new THREE.AnimationMixer(gltf.scene);
const clips = gltf.animations; // 播放所有动画
clips.forEach(function (clip) {const action = mixer.clipAction(clip);
action.loop = THREE.LoopOnce;
// 停在最初一帧
action.clampWhenFinished = true;
action.play();});
})
加载环境贴图
new RGBELoader()
.load('../resources/sky.hdr', function (texture) {
scene.background = texture;
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.environment = texture;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.render(scene, camera);
});
动画
应用 requestAnimationFrame
播放动画,设置动画播放参数。
function animate() {requestAnimationFrame(animate);
renderer.render(scene, camera);
controls.update();
if (donuts){donuts.rotation.y += 0.01;}
if (mixer) {mixer.update(0.02);
}
}
animate();
最初
github 残缺代码,感激“大帅老猿”和“胖达”两位老师举办的这次流动,感兴趣同学,退出猿创营 (v:dashuailaoyuan),一起交流学习。