WebGL游戏站优化实录【myshmup.com】

news/2025/3/14 22:14:48/

myshmup.com 允许在浏览器中创建 shmup(射击)游戏。 你可以使用具有创意通用许可证的资源或上传自己的艺术作品和声音。 创建的游戏可以在网站上发布。 该平台不需要编码,游戏对象的配置是在用户界面的帮助下执行的。 后端是使用Django框架开发的。 编辑器 UI 用 Javascript 编写并使用 REACT 框架 游戏用 Typescript 编写并调用低级 Webgl API 进行渲染。

在这篇文章中,我将解释我在游戏部分使用的优化,以确保在大多数浏览器中获得流畅的 60PS 体验。

在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

1、Webgl API

Webgl(Web 图形库)API 允许使用现代 GPU 在浏览器内渲染图形。 为了让 GPU 工作,你需要提供两个称为着色器的函数:顶点着色器和片段着色器。 着色器是用类似于 C++ 的 GLSL(GL Shader Language)编写的。

顶点着色器旨在计算场景的顶点位置。 然后,顶点着色器的输出被发送到片段着色器,片段着色器计算渲染的所有像素的颜色。 在 myshmup.com 中,我使用了一对简单的顶点和片段着色器。 它们仅处理 2D 矩形作为原始形状,每个矩形都有自己的纹理要绘制在其表面上。 可以调整纹理颜色以启用闪烁效果。 大多数渲染工作包括向着色器提供每帧所需的数据。

2、简单的实现

在这里插入图片描述

当我第一次尝试使用 Webgl 渲染 2D 游戏时,我编写了一对在屏幕上绘制纹理的着色器。 着色器由打字稿函数处理,该函数一次绘制一个游戏对象。 这个低级函数由绘制函数调用,以游戏对象作为输入。 为屏幕上可见的每个游戏对象调用绘制函数。

gameObjects.forEach( gameObject => draw(gameObject) );

虽然这种方法对于对象数量较少的情况效果很好,但当在最近的 mac book pro 上游戏对象数量超过 50 个时,这种方法的结果非常差。 出事了…

3、尽可能减少Draw Call次数

在这里插入图片描述

每个渲染帧都是 CPU 和 GPU 共同完成工作的结果。 CPU 为 GPU 准备数据和指令。 GPU 内存位于 GPU 上。 它称为 VRAM,与主 RAM 分开。 因此,我们需要在经典 RAM 和 GPU VRAM 之间传输数据。 在每次绘制调用时,GPU 都必须等待。 只有将所需数据从 RAM 推送到 VRAM 后才能开始渲染。 准备就绪后,由于其高并行化级别,显卡可以开始高效地完成其工作。

它就像一家工厂:它的设计目的是在给定批次中生产大量商品,但批次的设置时间可能很长。 你不想使用这条生产线进行手工作业,每批次生产一个物体,你希望每批次生产数百个木托盘,以优化生产成本。

我们现在了解最小化每帧执行的绘制调用次数的重要性。 CPU 到 GPU 的数据传输开销是快速渲染的主要瓶颈。

4、实例绘制

在这里插入图片描述

我们的目标是尽量减少绘制调用的数量。 为此,我们将使用相同纹理的所有游戏对象打包在一起。 想想射击游戏中敌人或英雄的所有子弹。 它们在屏幕上数量众多(因此有“弹幕地狱”的表达方式),但它们具有相同的纹理。 这只是在不同位置绘制相同的精灵。 装饰也是如此,它们通常由屏幕上重复的瓷砖制成。 你无需将游戏对象集处理为简单数组,而是在渲染之前准备数据。 你构建一个贴图,其中键是纹理 ID,值是使用该纹理的对象数组。 然后你可以只为每个纹理调用一次绘制函数。 对于有大量重复精灵的 shmup 来说,这是一个巨大的节省。

textures.forEach( texture => draw(texture.gameObjects))

为了在一批中多次使用相同纹理绘制对象数组,我们应该使用 Webgl 2 的“实例绘制”功能。此功能在 Webgl 1 中作为一个选项提供。为了简单起见,我们决定使用 Webgl 2 尽管它并不与当今所有的浏览器兼容。

5、纹理图集

在这里插入图片描述

我实现了实例绘制,一切都很好。 经过一年的开发,我向公众发布了该网站。 组织了一次游戏开发活动,所有游戏都是使用 myshmup.com 创建的。 每个参与者都在短时间内创造了非常原创的游戏。 Game Jam 的获胜者发布了一个受 TRON 电影启发的带有霓虹灯像素艺术的关卡。 他创造了大量的装饰瓷砖和可破坏的地面敌人来提供丰富的游戏环境。 然后又出现了这样的情况:在我最先进的、潮人认可的 mac book pro 上,游戏有时会出现滞后。 什么问题? 该游戏在给定时间显示的不同纹理的数量比简单游戏中的要多。 接下来做什么?

灵丹妙药是“纹理图集”技巧。 这个想法是创建一个非常大的纹理:在 myshmup.com 中,图集大小是 4096 x 4096 像素。 然后你只需在这个大纹理中绘制所有游戏对象的纹理即可。 当你将一个纹理复制到图集中时,你可以跟踪与其关联的纹理坐标,以便以后可以检索它。 如果你的图集太小,只需创建另一个图集。

实现纹理图集后,我获得了 Webgl 必杀技。 我每帧只调用一次绘制函数。 好吧,说实话,更准确的说法是每层每帧只调用一次绘制函数。 这意味着 myshmup.com 中有 10 个平局:游戏中有 6 个视差层,另外 4 个用于游戏 UI(得分栏和按钮)。 就是这样。 我可以有 1000 个对象,每帧只会绘制 10 次。 GPU 像天才一样完成繁重的工作和渲染一切。

6、得到的教训

在这里插入图片描述

myshmup.com 纹理图集示例

这次 webgl 优化之旅充满了惊喜。 如果实现实例化绘图和纹理图集看起来像是过度设计,请相信我,事实并非如此。 在浏览器中拥有流畅的动作游戏是关键。 只有在那之后,我才对我的平台提供流畅娱乐的稳健性充满信心。 当你拥有几乎恒定的 60 FPS 帧速率时,喜悦是发自内心的!


原文链接:WebGL射击游戏的优化 — BimAnt


http://www.ppmy.cn/news/1040566.html

相关文章

音视频实时通话解决方案

1、问题提出 想要实现音视频通话,对于大部分人可能会觉得很难,但是实际上,有些事情并没有大家想的那样困难,只要功夫深,铁杵磨成针。 机缘巧合下,在业务中,我也遇到了一个业务场景需要实现音视频通话,我们不可能自己从零开始干,我本次用到的核心是WebRTC。 2、WebRT…

AMD卡启动Stable Diffusion AI绘画的方法

WindowsAMD安装法 1.安装python 3.10.6,在python官网上下载安装程序,***重要*** 在安装的第一个窗口下方勾选“将python添加到path”。 2.安装git 3.WindowsAMD使用AUTOMATIC1111的directml这一个fork,在这个页面的第一段:https:/…

一文教你快速 Cloudreve搭建云盘系统,实现随时访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了,各互联网大厂也纷纷加入战局&#…

【Map】containsKey和containsValue使用案例(114)

containsKey() 是看有没有这个键,也就是有没有这个下标 containsValue() 是看有没有这个键值,也就是有没有这个值 比如 mp.add (10,20); containsKey (10) 是 true containsValue (10) 是 false 而containsValue (20) 是 true 区别就是: 前者…

Docker+Selenium Grid搭建自动化测试平台

安装docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce -y Create a Docker Network docker network create grid 下载镜像 hu…

18万字应急管理局智慧矿山煤矿数字化矿山技术解决方案WORD

导读:原文《18万字应急管理局智慧矿山煤矿数字化矿山技术解决方案WORD》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 目 录 第一章 项目概述 1.1项目…

Vue中Hottable的使用

安装 npm install handsontable handsontable/vue引入 <template><HotTable :root"root" :data"tableValue" ref"testHot" :settings"hotSettings"></HotTable> </template><script> import HotTable…

基于java远程同步课堂系统设计与实现

摘要&#xff1a;在这样一个网络数据大爆炸的时代&#xff0c;人们获取知识、获取信息的通道非常的多元化&#xff0c;通过网络来实现数据信息的获取成为了现在非常常见的一种方式&#xff0c;而通过网络进行教学&#xff0c;在网络上进行远程的课堂培训&#xff0c;能够根据学…