WebGL游戏站优化实录【myshmup.com】
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
相关文章:

WebGL游戏站优化实录【myshmup.com】
myshmup.com 允许在浏览器中创建 shmup(射击)游戏。 你可以使用具有创意通用许可证的资源或上传自己的艺术作品和声音。 创建的游戏可以在网站上发布。 该平台不需要编码,游戏对象的配置是在用户界面的帮助下执行的。 后端是使用Django框架开…...

6、Mysql免安装版本的配置与使用(2023-08)
1、下载 官网:https://www.mysql.com/downloads/ 点击前往 1.1 官网首页 1.2 首页往下翻,到达下图点击 1.3 选择如图Mysql Cimmunity Server 1.4 选择版本 1.5 点击开始下载 2、安装 2.1 配置环境变量 打开电脑环境变量,在环境变量path中…...

docker之简介与安装
环境配置问题 没有虚拟机,我们往往是打包代码发给对方,然后让对方安装相应的环境,比如node、数据库,要是配置不同,项目很有可能无法运行,还会报错,如果多个人想要运行这份代码,那还得…...

vue之动态表单(优化)
代码资源在这儿 ↑ vue之动态表单优化 vue2js动态表单优化vue3ts动态表单优化 vue2js动态表单优化 效果图 目录结构 五个文件的完整代码: 以下是App.vue <template><div><router-view></router-view><Formpage /></div> </templa…...

web连接桌面打开gptmap
一:环境配置 需要的材料: python-3.10.4 我使用的是这个版本的,3.8.10 该版本和以下版本组件组合,验证过能正常运行(python 3.6.8测试异常) websockify 该项目有python版本和node js版本 noVNC 形式的app…...

做好需求分析的4大关键认知
探索如何正确的需求分析?本文详细介绍了4大关键点,帮助您明确用户与产品需求、深入挖掘用户动机,并为产品经理提供筛选需求的实用建议。 一、什么是需求分析以及重要性 需求分析指的是在建立一个新的或改变一个现存的产品时,确定新…...

Max Compute 操作记录
编译 max compute-spark git clone https://github.com/aliyun/MaxCompute-Spark cd spark-3.x mvn clean package -DskipTests在 target 目录下生成 以下两个文件。 spark-examples_2.12-1.0.0-SNAPSHOT-shaded.jar spark-examples_2.12-1.0.0-SNAPSHOT.jar2. DataWorks 上传…...

Windows 11 + Ubuntu20.04 双系统 坑里爬起来
ThinkPad x390 安装双系统,原有的磁盘太小,扩充了磁盘重新装系统,出现的问题,加以记录。 1. windows和ubuntu谁先安装,两个都可以,一般建议先安装windows,后安装ubuntu 2. 安装windows后&…...
touch手势事件及功能封装
文章目录 基本概念事件类型事件对象的属性touch事件封装单击,双击滑动方向(上下左右)距离角度 缩放旋转 常用功能封装滑动图片浏览实现拖拽操作游戏角色移动、跳跃 封装手写板功能 在现代Web开发中,移动设备的普及使得触摸屏交互成…...
面试问题记录
1.多线程,线程池 1.如何创建线程 实现 Runnable 接口,重写run方法;实现 Callable 接口,重写call方法;继承 Thread 类,重写run方法。 2.基础线程机制 Executors:可以创建四种类型的线程池&am…...

ZooKeeper的应用场景(集群管理、Master选举)
5 集群管理 随着分布式系统规模的日益扩大,集群中的机器规模也随之变大,因此,如何更好地进行集群管理也显得越来越重要了。 所谓集群管理,包括集群监控与集群控制两大块,前者侧重对集群运行时状态的收集,后…...
面试算法编程题
面试算法编程题记录 题目 : 羊圈里的狼 题目背景 : 一到了晚上,草原牧民的羊就会被赶进羊圈里。这时,野外的狼群就会打羊羔的主意。为了保护羊羔,牧民需要将羊圈里的狼赶走或杀死。由于来的狼很多,他需要快速甄别哪些狼在羊圈里面…...

JVM——JDK 监控和故障处理工具总结
文章目录 JDK 命令行工具jps:查看所有 Java 进程jstat: 监视虚拟机各种运行状态信息 jinfo: 实时地查看和调整虚拟机各项参数jmap:生成堆转储快照**jhat**: 分析 heapdump 文件**jstack** :生成虚拟机当前时刻的线程快照 JDK 可视化分析工具JConsole:Java 监视与管理控制台连接…...

多维时序 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经网络的数据多变量时间序列预测
多维时序 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经网络的数据多变量时间序列预测 目录 多维时序 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经网络的数据多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 多维时序 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经…...
ZoomIt v7.1
ZoomIt 是用于技术展示和演示的屏幕缩放、注释和录制工具。 还可以使用 ZoomIt 将屏幕截图截取到剪贴板或文件。 ZoomIt 在系统托盘中不显眼地运行,可使用可自定义的热键激活,它能够放大屏幕区域,在缩放时四处移动,并在缩放后的图…...

E8—Aurora 64/66B ip实现GTX与GTY的40G通信2023-08-12
1. 场景 要在贴有K7系列FPGA芯片的板子和贴有KU系列FPGA芯片的板子之间通过光模块光纤QSFP实现40G的高速通信。可以选择的方式有多种,但本质的方案就一种,即实现4路GTX与GTY之间的通信。可以选择8B/10B编码通过GT IP核实现,而不能通过Aurora…...
js下载后端返回的文件
文件流下载 后端返回文件流形式,前端下载 // res 为请求返回的数据对象const file_data res.data // 后端返回的文件流const blob new Blob([file_data]) const href window.URL.createObjectURL(blob) // 创建下载的链接 const file_name decodeURI(res.header…...
计组 | 并行操作
前言 记录一些计组相关联的题集与知识点,方便记忆与理解。 并行 什么是并行处理 广义地讲,并行性有两种含义:一是同时性,指两个或多个事件在同一时刻发生;二是并发性,指两个或多个事件在同一时间间隔内发生…...

rabbitmq容器启动后修改连接密码
1、进入容器 docker exec -it rabbitmq bash 2、查看当前用户列表 rabbitmqctl list_users 3、修改密码 rabbitmqctl change_password [username] ‘[NewPassword]’ 4、修改后退出容器 ctrlpq 5、退出容器后即可生效,不需要重启容器...
PHP中的curl详细解析和常见大坑
这篇文章主要介绍了 PHP 中使用 CURL 之 php curl 详细解析和常见大坑 ,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。好啦,长话短说再长说,祭出今天的工具——CURL(Client URL Library),当然今天以 PHP…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...