【Three.js】实现护罩(防御罩、金钟罩、护盾)效果

news2024/11/23 11:14:13

在这里插入图片描述


前言:

在这篇博客中,我们将使用 Three.js 从零开始生成一个护罩效果。护罩将使用自定义的 Shader 材质,带有动画效果,最终呈现一个视觉上酷炫的护罩。此篇文章的重点将放在如何生成一个3D护罩,其它功能将在之后的博客中讨论,后续会有很多酷炫的效果~


实现技术简介:

要实现这个护罩,我们需要掌握以下技术:

  • Three.js: 一个强大的 3D 图形库,简化了 WebGL 的使用。
  • Shader: 我们将用到 GLSL(OpenGL 着色语言)编写自定义着色器,为护罩增添独特的效果,比如渐变、透明度和动态变化。
  • WebGLRenderer: Three.js 的核心渲染器,用于将 3D 场景渲染到网页上。

第一步:设置基础的场景

任何使用three.js的项目都会设置基础的场景,且大同小异

在开始生成护罩之前,我们需要一个 Three.js 基础场景。这个场景包括相机、渲染器和一些光源,以便能够观察到护罩的效果。

代码:
// 创建一个场景
const scene = new THREE.Scene();

// 设置透视相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 7, 10);

// 创建 WebGL 渲染器并设置其尺寸
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 添加环境光和方向光到场景中
const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4); // 柔和的环境光
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); // 模拟太阳光的方向光
directionalLight.position.set(0, 5, 5);
scene.add(directionalLight);
解释:
  • 场景(Scene):Three.js 中所有对象的容器,所有物体都会添加到场景中。
  • 相机(Camera):用于查看场景。这里我们使用透视相机,能模拟人眼的视角。
  • 渲染器(Renderer):负责将 3D 场景绘制到网页上,我们选择了 WebGLRenderer 并将其尺寸设置为浏览器窗口大小。
  • 光源(Light):环境光均匀地照亮场景,方向光模拟来自一个方向的强光,给物体添加阴影效果。

第二步:创建自定义护罩材质

为了让护罩看起来与众不同,我们需要自定义材质。我们将使用 GLSL 编写顶点着色器和片段着色器,来控制护罩的颜色、透明度和动画效果。

代码:
// 创建护罩的自定义 Shader 材质
class ShieldMaterial extends THREE.ShaderMaterial {
  constructor() {
    super({
      uniforms: {
        time: { value: 0 }, // 动态变化的时间
        color: { value: new THREE.Color(0x00ffff) } // 护罩的颜色
      },
      vertexShader: `
        varying vec3 vNormal;
        void main() {
          vNormal = normalize(normalMatrix * normal);
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform float time;
        uniform vec3 color;
        varying vec3 vNormal;
        void main() {
          float intensity = pow(0.5 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0);
          gl_FragColor = vec4(color * intensity, 1.0);
        }
      `,
      transparent: true, // 设置材质为透明
      blending: THREE.AdditiveBlending, // 使用叠加效果
    });
  }

  update(time) {
    this.uniforms.time.value = time;
  }
}
解释:
  • ShaderMaterial:我们继承了 THREE.ShaderMaterial 类来创建自定义的护罩材质。
  • 顶点着色器(Vertex Shader):用于处理每个顶点的位置。这里我们计算了每个顶点的法线信息。
  • 片段着色器(Fragment Shader):控制护罩的颜色和透明度。我们通过法线计算光照的强度,并将护罩设置为半透明效果。
  • uniforms:用于在 GPU 上保存变量。我们定义了 time 来让护罩产生动态效果,color 控制护罩的颜色。
  • blending:使用叠加混合模式,使护罩看起来有发光效果。

第三步:生成护罩几何体

接下来,我们需要生成一个 3D 几何体来承载我们的材质。我们使用 Three.js 提供的 SphereGeometry 来生成一个球体,代表护罩的形状。

代码:
// 创建护罩
const createShield = () => {
  // 创建球体几何体,表示护罩
  const geometry = new THREE.SphereGeometry(1.5, 64, 64); // 半径为1.5的球体,使用64段分割
  const material = new ShieldMaterial(); // 使用自定义的护罩材质

  // 创建网格并将几何体和材质绑定
  const shield = new THREE.Mesh(geometry, material);
  
  // 将护罩添加到场景中
  scene.add(shield);

  return shield;
};

const shield = createShield();
解释:
  • SphereGeometry:生成一个球体,半径为 1.5,几何体细分为 64 段,使球体看起来更加平滑。
  • Mesh:将几何体与材质结合生成一个网格,并将这个护罩网格添加到场景中。

第四步:渲染和动画

为了让护罩动画起来,我们可以通过不断更新时间 time 变量,使其动态变化。在动画循环中,更新 ShieldMaterial 的时间。

代码:
// 创建动画循环
const clock = new THREE.Clock(); // 用于追踪时间

const animate = () => {
  requestAnimationFrame(animate); // 不断调用 animate 函数
  const elapsedTime = clock.getElapsedTime(); // 获取流逝的时间

  // 更新护罩的时间,使其产生动态效果
  shield.material.update(elapsedTime);

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

animate(); // 开始动画循环
解释:
  • Clock:Three.js 中的 Clock 对象用于获取经过的时间,使我们可以根据时间变化来创建动画效果。
  • requestAnimationFrame:浏览器内置的动画函数,确保动画以最佳帧率运行。
  • update:我们将流逝的时间传递给护罩材质的 time 参数,让护罩随时间变化而动态变动。

总结:

通过以上步骤,我们使用 Three.js 和自定义 Shader 成功生成了一个带有动画效果的护罩。你可以根据需求自定义护罩的颜色、动画速度和透明度。

在未来的博客中,我们将深入探讨如何扩展这个护罩效果,比如添加交互、生成多个护罩或是为护罩之间添加飞线特效。


ps:最近的项目使用three.js的地方很多,且拓展了很多功能,我会将一个个的功能点拆分出来。因为之前查找相关博客发现很多都是整个一起的,对于只想要其中一部分而言会增加很多不必要的时间成本,所以我会将功能点拆解出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SprinBoot+Vue旅游网站的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…

AI和新基建赋能智慧工地超融合管理平台解决方案

1. 项目背景与需求 电力行业的工程管理正朝着智慧化发展,但目前仍处于起步阶段。为满足数字化、网络化、智能化的发展需求,需要构建一个高效综合监控平台,实现对电力项目全过程的精益化管控。 2. 综合管理平台的构建 该平台集成了超融合实…

【Visual Studio 报错】未加载 wntdll.pdb(一种可行的解决办法)

调试程序时,会出现下面这个报错 分析原因: 出现未加载 wntdll.pdb 报错大概率是你的指针使用错误 ,比如使用野指针、越界访问、或者堆区空间释放方式错误等。 这里以 堆区空间释放方式错误 为例子 1、堆区开辟的数组空间使用 delete 释放 …

Java 日志

日志就是为了将程序的运行状况保存到文件中去。 命名的一个小细节: 比如把信息保存到文件中这个方法的名字可以写为infoToFile,有个人为了偷懒,写成info2File,发现效果还挺好,一下就能分清两个单词,所以后…

windows版本mysql8.2忘记密码

忙了一年的项目终于有点空闲时间了(996累成狗),想折腾点开源项目, 结果发现忘了本地mysql密码,查了一些资料,记录如下: --windows mysql8.2忘记密码(思路整理:先无密码…

【信创建设】信息系统信创建设整体技方案(word原件完整版)

信创,即“信息技术应用创新”。我国自主信息产业聚焦信息技术应用创新,旨在通过对IT硬件、软件等各个环节的重构,基于我国自有IT底层架构和标准,形成自有开放生态,从根本上解决本质安全问题,实现信息技术可…

Superset二次开发之新增复选框Checkbox筛选器

一. 背景 Superset目前支持的筛选类型:值、数值范围、时间列、时间粒度、时间范围 5种类型,显然无法满足业务需求。根据产品需要,需要支持复选框、单选框、级联选择等类型的筛选器。本文探讨复选框、单选框的技术实现方式。 二. 效果预览 三. 实现思路 复用 值 筛选器模块,…

计算蛋白质结构中氨基酸之间的方向和方位

在蛋白质结构分析中,方向(direction)和方位(orientation)是描述相邻氨基酸(残基)之间相对空间关系的重要几何参数。可以通过原子坐标来计算相邻氨基酸之间的方向向量和方位关系。以下是这些概念的详细解释以及如何通过 PyTorch 来计算它们。 1. 方向 (Direction) 方向…

二、Maven工程的创建--JavaSEJavaEE

1、idea创建Maven JavaSE工程: 2、idea创建Maven JavaEE工程: (1)手动创建 (2)插件方式创建 在idea里安装插件JBLJavaToWeb; 选择需要生成的项目文件后,右击: 项目…

拉普拉斯分布-简要介绍

拉普拉斯分布,又称双指数分布,是概率论中的一种连续概率分布。拉普拉斯分布是由法国数学家皮埃尔-西蒙拉普拉斯在研究误差理论时提出的,在数据集中经常用于描述具有尖峰和长尾特征的分布。 拉普拉斯分布的定义 拉普拉斯分布的概率密度函数&…

HOT 100(七)栈、堆、贪心算法

一、栈 1、每日温度 使用单调递减栈来解决。主要思路是遍历temperatures数组,利用栈来存储还没有找到比当前温度高的天数的索引。当遇到比栈顶索引所对应温度更高的温度时,就可以确定当前这一天的温度比之前那一天高。索引的差值就是等待的天数。 求一…

前端 Vue3 项目开发—— ESLint prettier 配置代码风格

ESLint & prettier 介绍 如果你用的是 pnpm create vue 来创建项目,那么创建项目时就会让你选择是否添加 ESLint 和 prettier 我们在上一篇博客中详细介绍过 ESLint,可以说上一篇博客是这篇博客的先修知识,所以各位小伙伴们请先去看看我…

微信小程序页面制作——个人信息

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

Docker | 虚拟机 是一个东西吗

文章目录 虚拟机与Docker如果要在linux环境下运行程序,那么docker会给我下载整个linux操作系统吗?Docker的一些名词 虚拟机与Docker 虚拟机就相当于买了一台新电脑,有了完整的独立的一个操作系统Docker 不需要创建完整的虚拟操作系统&#xf…

el-table行编辑

需求&#xff1a;单点行编辑并且请求接口更新数据&#xff0c;表格中某几个字段是下拉框取值的&#xff0c;剩下的是文本域&#xff1b;展示的时候 需要区分下拉框编码还是中文 故障模式这个展示的是fault_mode编码,但要显示的文字fault_mode_chn 这点需要注意 <el-tablere…

【H2O2|全栈】关于Photoshop | PS(4)

PS的一些杂谈&#xff08;亖&#xff09; 目录 PS的一些杂谈&#xff08;亖&#xff09; 前言 准备工作 图形工具 基本属性 混合选项 形状图层 文字工具 基本属性 进一步变化文字 组和图层 UI设计案例 预告和回顾 后话 前言 这一篇博客我将会写一下图形工具和…

数据链路层以太网技术与DNS、ICMP协议

我们前面学习到的传输层、网络层。传输层是保证数据可靠传输。而网络层是实现在复杂的网络环境中确定一个合适的路径。我们接下来所说的数据链路层其实就是用于两个设备(同一种数据链路节点)之间进行传递。其实也就是如数次的局域网中设备之间的转发过程。 认识以太网 "…

大数据-124 - Flink State 01篇 状态原理和原理剖析:状态类型 执行分析

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Pr:首选项 - 音频硬件

Pr菜单&#xff1a;编辑/首选项 Edit/Preferences Premiere Pro 首选项中的“音频硬件” Audio Hardware选项卡可以指定计算机的音频设备和设置&#xff0c;还可以指定 Pr 用于音频回放和录制的 ASIO 和 MME 设置&#xff08;仅限 Windows&#xff09;或 CoreAudio 设置&#x…

C#使用GDI+实现生成验证码

目录 下面是代码的详细解释&#xff1a; 类声明和成员变量 构造函数 窗体加载事件 生成验证码方法 pictureBox1 点击事件 按钮点击事件 完整代码&#xff1a; 总结 这段代码是一个C# Windows Forms应用程序的一部分&#xff0c;用于生成和验证验证码。 下面是代码的详细解…