Three.js——基础概念

Three.js系列前言

1年前毕业的时候毕设选了虚拟校园系统,从那会开始接触到three.js。虽然毕设做的很粗糙(不好意思拿出来说的地步)。但到底是自己一点点学了做的,现在也走了前端这条路,最近大数据3D可视化还慢火的,想着再把three.js再捡起来,万一以后转方向还能用到不是?

Three.js是什么?

Three.js 是一个强大的JavaScript库,用于在Web上创建和展示3D图形。它基于WebGL实现,提供了简单的API,能够帮助开发者创建复杂的3D场景。简单的说,就是一个有着无数方法可以用于3d模型web展示的js库。

基础概念

Three.js三要素:场景、相机、渲染器

场景(Scene)

场景是一个容器,包含了所有要渲染的物体和光源。

const scene = new THREE.Scene();

相机(Camera)

相机决定了我们从哪个角度观察场景中的物体。常用的相机有透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)。

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

渲染器(Renderer)

渲染器负责将场景和相机渲染成2D图像并显示在屏幕上。Three.js 提供了WebGLRenderer来进行渲染。

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

核心组件

几何体(Geometry)

几何体是构成3D物体的形状,例如立方体、球体等。three.js可以在web上生成几何体。

const geometry = new THREE.BoxGeometry();

不过我个人没怎么用到这一块,毕竟都是自己建好了模型直接展示的。

材质(Material)

材质定义了物体的表面属性,如颜色、纹理等。

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

当年那个材质丢失真的搞人心态,莫名其妙的丢失,又莫名其妙的解决,有懂的朋友可以在评论区不吝赐教。

网格(Mesh)

网格是由几何体和材质组合而成的可渲染物体。

const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

光源(Light)

光源影响场景中物体的照明效果。

const light = new THREE.PointLight(0xffffff);
light.position.set(10, 10, 10);
scene.add(light);

常用功能

动画(Animation)

使用requestAnimationFrame实现动画效果。

function animate() {
  requestAnimationFrame(animate);
  
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  
  renderer.render(scene, camera);
}

animate();

纹理(Texture)

纹理是图像映射到几何体表面,使其看起来更加真实。

const texture = new THREE.TextureLoader().load('path/to/texture.jpg');
const materialWithTexture = new THREE.MeshBasicMaterial({ map: texture });

控制器(Controls)

使用OrbitControls可以实现交互操作,如旋转、缩放和拖拽视角。

const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 使动画更加流畅
controls.dampingFactor = 0.25;
controls.screenSpacePanning = false;
controls.maxPolarAngle = Math.PI / 2;

DEMO

以下是一个完整的示例代码,展示了如何创建一个简单的3D场景,并使用动画和交互控制。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Three.js Example</title>
  <style>
    body { margin: 0; }
    canvas { display: block; }
  </style>
</head>
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/controls/OrbitControls.js"></script>
  <script>
    // 创建场景
    const scene = new THREE.Scene();

    // 创建透视相机
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 5;

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // 创建几何体和材质
    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

    // 创建网格对象并添加到场景中
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    // 添加光源
    const light = new THREE.PointLight(0xffffff, 1);
    light.position.set(10, 10, 10);
    scene.add(light);

    // 添加控制器
    const controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.25;
    controls.screenSpacePanning = false;
    controls.maxPolarAngle = Math.PI / 2;

    // 渲染循环
    function animate() {
      requestAnimationFrame(animate);

      // 旋转立方体
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;

      // 更新控制器
      controls.update();

      // 渲染场景
      renderer.render(scene, camera);
    }

    animate();
  </script>
</body>
</html>

高级功能

加载器(Loaders)

Three.js 提供了多种加载器来加载外部资源,如模型、纹理等。

// 加载GLTF模型
const loader = new THREE.GLTFLoader();
loader.load('path/to/model.gltf', function(gltf) {
  scene.add(gltf.scene);
});

后期处理(Post-processing)

使用EffectComposer可以进行后期处理效果,如抗锯齿、景深等。

const composer = new THREE.EffectComposer(renderer);
const renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);

const effectPass = new THREE.ShaderPass(THREE.FilmShader);
effectPass.renderToScreen = true;
composer.addPass(effectPass);

function animate() {
  requestAnimationFrame(animate);
  composer.render();
}

常见问题与解决方案

性能优化:

使用requestAnimationFrame进行动画渲染。
尽量减少实时计算,使用缓存。
使用低多边形模型和贴图LOD技术。

兼容性问题:

确保WebGL支持。
使用Polyfill以支持老旧浏览器。

调试与开发工具:

使用Three.js开发者工具(如Three.js Inspector)进行调试。
使用Dat.GUI库调试和调整场景参数。

最后,我想说这个方向只是作为了解,不会整的太深。因为我其实并不是非常看好这个方向,除非经济大环境迅速回升,不然这个方向就起不来,因为它不直接创造价值,目前的情况是很多公司工厂连2D可视化都没整明白,直接上3D的一个是费用问题,还有一个是没必要。而且因为它是可有可无的部分,所以一旦遇到点什么事,甲方降本增效首先就会把这类项目砍掉。如果大环境长期不景气,说实话这一块的业务仅仅只会停留在试行阶段,甚至是突然暴死。

第二个原因是硬件发展的还不够。我接触过三维激光扫描,处理过点云数据。深深的明白当前硬件发展,包括通信发展是无法支撑大量的点云数据在web端预览的。虽然现在硬件对于一般软件已经完全够用了,但是这太超前了,也就是说可能很长一段时间内都不会有适配的硬件出现,那还怎么发展,前景在哪里。

但是总还是有万一,只要能解决上述的经济大环境和硬件发展问题,这一定会是风口。不管机会来没来,总之多学点东西是没错的。

  • 33
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值