随着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建模就再好不过了。
  1. 关上资源网站,搜寻模型,关上详情,点击download按钮。
  2. 应用blender导入模型。
  3. 应用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),一起交流学习。