前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最佳ThreeJS实践 · 实现赛博朋克风格的三维图像气泡效果

最佳ThreeJS实践 · 实现赛博朋克风格的三维图像气泡效果

原创
作者头像
不惑
发布2024-09-25 08:29:19
420
发布2024-09-25 08:29:19
举报
文章被收录于专栏:Goboy

在现代计算机图形学和游戏开发中,创建引人入胜且逼真的三维场景是至关重要的。赛博朋克风格,以其鲜艳的色彩、充满未来感的细节以及复杂的光影效果,成为了许多开发者和艺术家的热门选择。在本文中,我们将深入探讨如何利用 Three.js 创建一个高质量的赛博朋克风格三维场景,特别是如何优化纹理的清晰度和材质设置,以实现最佳的视觉效果。

Three.js 简介

Three.js 是一个开源的 JavaScript 库,用于在网页上创建和显示三维图形。它提供了强大的工具和功能,使得开发者可以轻松地创建复杂的三维场景。Three.js 支持多种材质和纹理配置,使得开发者能够对每个细节进行精确控制。

整体思路

赛博朋克风格

赛博朋克风格源于对未来科技与破碎社会之间关系的描绘。这种风格通常包括霓虹灯光、复杂的建筑结构和阴暗的背景。为了捕捉这种独特的美学,我们需要精心设计场景的每一个细节,从背景色彩到纹理质量,每一部分都需要与赛博朋克风格的主题相辅相成。

创建赛博朋克风格场景

在创建赛博朋克风格场景时,我们首先需要搭建基本的 Three.js 环境。

初始化项目

🌶️ 创建一个文件夹叫ThreeJsDemo,然后在当前的这个文件夹下面执行如下命令:

代码语言:javascript
复制
npm init -y

🌶️ 安装Three.js

代码语言:javascript
复制
npm install three

将Vite安装成开发时依赖,使用vite启动开发服务

代码语言:javascript
复制
npm i vite -D

纹理优化

为了在赛博朋克风格场景中实现最佳的视觉效果,我们需要关注纹理的清晰度。以下几个参数对纹理的显示效果有显著影响:

过滤方式: minFilter 和 magFilter 控制纹理的缩小和放大效果。我们选择了 THREE.LinearMipMapLinearFilter 和 THREE.LinearFilter,这能在不同的缩放比例下提供更平滑的效果,避免了锯齿状的边缘。

各向异性过滤: anisotropy 设置了纹理的各向异性过滤等级。通过 renderer.capabilities.getMaxAnisotropy() 自动获取最大等级,确保在远处或倾斜视角下纹理仍然清晰。

编码方式: encoding 参数设置了纹理的颜色编码方式。THREE.sRGBEncoding 用于处理 gamma 校正,使得纹理颜色更加准确和生动。

调整图片大小和气泡感效果

为了增强赛博朋克风格的视觉效果,我们在代码中实现了动态调整图片大小和发光效果。adjustImageSizes 函数用于根据摄像机与图片之间的距离调整图片的缩放和发光强度。最近的图片会被放大并增强发光效果,而较远的图片则会缩小并减弱发光效果,这种效果能够增强场景的深度感和立体感。

构建一个赛博朋克风格的三维场景

使用 Three.js 构建一个赛博朋克风格的三维场景,并且在该场景中创建一种“气泡感”的动态效果。该效果能够根据相机的位置动态调整图片的大小和发光强度,给用户带来沉浸式的视觉体验。具体实现过程如下:

一、场景搭建

首先,我们利用 Three.js 构建基本的三维场景。在这个场景中,添加了相机、渲染器、光照以及一个赛博朋克风格的背景渐变。该背景渐变使用 CanvasTexture 创建,颜色范围从深紫色渐变到亮粉色,营造出一种赛博朋克特有的霓虹灯氛围。

代码语言:javascript
复制
// 创建赛博朋克风格的背景渐变
const gradientTexture = new THREE.CanvasTexture(createGradientCanvas()); // 创建渐变纹理
scene.background = gradientTexture; // 将背景设置为渐变纹理

函数 createGradientCanvas 用于创建渐变背景:

代码语言:javascript
复制
// 创建渐变背景
function createGradientCanvas() {
  const canvas = document.createElement('canvas'); // 创建一个 canvas 元素
  canvas.width = 512; // 设置 canvas 的宽度
  canvas.height = 512; // 设置 canvas 的高度
  const context = canvas.getContext('2d'); // 获取 2D 上下文
  const gradient = context.createLinearGradient(0, 0, 512, 512); // 创建线性渐变
  gradient.addColorStop(0, '#2c003e'); // 渐变开始颜色(深紫色)
  gradient.addColorStop(1, '#ff007d'); // 渐变结束颜色(亮粉色)
  // gradient.addColorStop(0, '#FFFFFF'); // 渐变开始颜色(深紫色)
  // gradient.addColorStop(1, '#EEE000'); // 渐变结束颜色(亮粉色)
  context.fillStyle = gradient; // 设置填充样式为渐变
  context.fillRect(0, 0, 512, 512); // 填充整个 canvas
  return canvas; // 返回创建的 canvas
}

二、添加光照

为了增强赛博朋克风格的灯光效果,场景中加入了环境光和方向光。环境光用来提供基础的整体照明,方向光则用来模拟从某个方向照射的光源,增加物体的立体感。

代码语言:javascript
复制
// 添加环境光
// const ambientLight = new THREE.AmbientLight(0x444444); // 创建环境光,颜色较暗
const ambientLight = new THREE.AmbientLight(0xffffff); // 创建环境光,颜色较暗
scene.add(ambientLight); // 将环境光添加到场景中

// 添加方向光
// const directionalLight = new THREE.DirectionalLight(0x00ffff, 1); // 创建方向光,颜色为青色
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 创建方向光,颜色为青色
directionalLight.position.set(10, 10, 10).normalize(); // 设置光源的位置并归一化
scene.add(directionalLight); // 将方向光添加到场景中

三、加载图片并设置材质

场景的核心元素是均匀分布在球体表面的图片。这些图片作为网格(Mesh)添加到场景中,并且使用 CircleGeometry 创建圆形几何体来显示图片。

代码语言:javascript
复制
  const geometry = new THREE.CircleGeometry(circleRadius, 32); // 创建圆形几何体
  const texture = textureLoader.load(url); // 加载纹理

  // 设置纹理的过滤方式
  texture.minFilter = THREE.LinearMipMapLinearFilter;
  texture.magFilter = THREE.LinearFilter;

  // 设置各向异性过滤
  texture.anisotropy = renderer.capabilities.getMaxAnisotropy();

  // 设置纹理的颜色编码方式
  texture.encoding = THREE.sRGBEncoding;

  const material = new THREE.MeshStandardMaterial({
    map: texture,
    emissive: new THREE.Color(0x000000), // 默认不发光
    emissiveIntensity: 0, // 默认发光强度为0
    side: THREE.DoubleSide, // 双面渲染
    roughness: 0.2, // 低粗糙度
    metalness: 0.5, // 适度金属光泽
  });

为了保持视觉效果的一致性,配置了纹理的过滤方式(minFiltermagFilter),并设置了最大各向异性过滤(anisotropy),确保在不同视角和距离下纹理显示清晰。

四、相机控制与自适应窗口大小

使用 OrbitControls 实现相机的平滑控制,用户可以自由旋转、缩放和移动场景。同时,通过监听窗口的大小变化,自适应调整相机和渲染器的尺寸,确保场景始终保持最佳比例。

代码语言:javascript
复制

// 创建 OrbitControls 实例,用于相机的平滑控制
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 启用平滑阻尼效果
controls.dampingFactor = 0.25; // 设置阻尼因子
controls.enableZoom = true; // 启用缩放
controls.enableRotate = true; // 启用旋转


// 自适应窗口大小
window.addEventListener('resize', () => {
  const width = window.innerWidth;
  const height = window.innerHeight;
  renderer.setSize(width, height); // 调整渲染器大小
  camera.aspect = width / height; // 调整相机的宽高比
  camera.updateProjectionMatrix(); // 更新相机投影矩阵
});

五、动态调整图片大小和发光效果

场景的核心是“气泡感”效果,它通过根据相机与图片之间的距离动态调整图片的大小和发光强度。最近的图片会逐渐变大并增强发光效果,而较远的图片会缩小,营造出一种动态的深度感。

实现该效果的关键是相机视锥体(Frustum)的使用。首先计算相机的视锥体,然后检查每个图片网格是否在视锥体内,最后根据距离调整图片的缩放和发光效果:

代码语言:javascript
复制
// 调整图片大小和气泡感效果
function adjustImageSizes() {
  let closestCircle = null; // 存储距离相机最近的图片
  let minDistance = Infinity; // 初始设置为无穷大

  // 找到距离相机最近且在视锥体内的图片
  circles.forEach((circle) => {
    const distance = camera.position.distanceTo(circle.position); // 计算相机到图片的距离

    // 检查图片是否在相机视锥体内
    const circleBoundingBox = new THREE.Box3().setFromObject(circle); // 获取图片的包围盒
    if (frustum.intersectsBox(circleBoundingBox)) { // 检查包围盒是否与视锥体相交
      if (distance < minDistance) { // 如果距离更近,更新最近的图片
        minDistance = distance;
        closestCircle = circle;
      }
    }
  });

  // 为每个图片设置缩放效果
  circles.forEach((circle) => {
    if (circle === closestCircle) {
      // 最近的图片放大到 1.8 倍,使用缓动效果
      circle.scale.lerp(new THREE.Vector3(1.8, 1.8, 1.8), 0.1);
      // circle.material.emissive = new THREE.Color('#ff007d'); // 设置发光颜色
      circle.material.emissiveIntensity = 0.5; // 设置发光强度
    } else {
      // 其他图片缩小到 0.5 倍,模拟气泡挤压感
      circle.scale.lerp(new THREE.Vector3(0.5, 0.5, 0.5), 0.1);
      circle.material.emissive = new THREE.Color('#000000'); // 无发光效果
      circle.material.emissiveIntensity = 0; // 发光强度为0
    }
  });
}

该函数通过缓动(lerp)效果平滑地调整图片大小,保证视觉效果的连贯性。最靠近相机的图片会被放大到 1.8 倍,并且增强其发光效果,而其他图片则逐渐缩小,模拟出类似气泡挤压的效果。

总结

通过利用 Three.js 的丰富功能,我们能够轻松实现一个具有赛博朋克风格的动态三维场景。本文重点介绍了如何通过材质、纹理和光照的优化,来提升场景的视觉效果。同时,基于相机位置的动态调整图片大小和发光效果,为场景添加了更具沉浸感的气泡效果。

无论是用于游戏开发、虚拟现实项目,还是网页三维可视化,Three.js 都是一个强大且灵活的工具。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 整体思路
  • 构建一个赛博朋克风格的三维场景
    • 一、场景搭建
      • 二、添加光照
        • 三、加载图片并设置材质
          • 四、相机控制与自适应窗口大小
            • 五、动态调整图片大小和发光效果
            • 总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档