最有效的多重纹理方法 - iOS、OpenGL ES2、优化

2023-12-29

我正在尝试找到在 iOS 上处理 OpenGL ES2 中多重纹理的最有效方法。我所说的“高效”是指即使在较旧的 iOS 设备(iPhone 4 及更高版本)上也能实现最快的渲染 - 但同时还要平衡便利性。

我考虑过(并尝试过)几种不同的方法。但遇到了一些问题和疑问。

Method 1- 我的基本值和正常值是 rgb,没有 ALPHA。对于这些对象我不需要透明度。我的发射和镜面反射信息都只有一个通道。减少texture2D()我想我可以将发射存储为基础的 Alpha 通道,将镜面反射存储为法线的 Alpha。每个文件都在自己的文件中,看起来像这样:

到目前为止,我的问题是找到一种支持完整非预乘 Alpha 通道的文件格式。 PNG 对我来说不起作用。我尝试将其另存为 PNG 的每一种方法都会将 .alpha 与文件保存时的 .rgb 预乘(通过 Photoshop),基本上会破坏 .rgb。当我重新加载文件时,任何具有 0.0 alpha 的像素都会显示黑色 rgb。我发布了这个问题here https://stackoverflow.com/questions/21752582/how-to-encode-emission-or-specular-info-in-the-alpha-of-a-open-gl-texture没有任何活动。

我知道如果我能找到一种方法来保存和加载这个独立的第四通道,这种方法会产生更快的渲染速度。但到目前为止,我还无法做到这一点,不得不继续前进。

Method 2- 当这不起作用时,我转向单个 4 向纹理,其中每个象限都有不同的贴图。这并没有减少texture2D()调用,但它减少了着色器内访问的纹理数量。

4 路纹理确实需要我修改着色器内的纹理坐标。为了模型的灵活性,我将纹理坐标保留在模型结构中,并在着色器中修改它们,如下所示:

v_fragmentTexCoord0 = a_vertexTexCoord0 * 0.5;
v_fragmentTexCoord1 = v_fragmentTexCoord0 + vec2(0.0, 0.5);     // illumination frag is up half
v_fragmentTexCoord2 = v_fragmentTexCoord0 + vec2(0.5, 0.5);     // shininess frag is up and over
v_fragmentTexCoord3 = v_fragmentTexCoord0 + vec2(0.5, 0.0);     // normal frag is over half

避免动态纹理查找 https://stackoverflow.com/questions/9946572/shader-optimization-for-retina-screen-on-ios(谢谢布拉德·拉尔森 https://stackoverflow.com/users/19679/brad-larson)我将这些偏移量移至顶点着色器,并将它们保留在片段着色器之外。

但我的问题是:减少着色器中使用的纹理采样器的数量是否重要?或者我在这里使用 4 个不同的较小纹理会更好吗?

我遇到的一个问题是不同地图之间的渗色。由于线性纹理映射,一些蓝色法线像素的 texcoord 被平均为 1.0。这在接缝附近的对象上添加了蓝色边缘。为了避免这种情况,我必须更改 UV 贴图,以免太靠近边缘。对于很多对象来说这是一件痛苦的事情。

Method 3将方法 1 和 2 结合起来,一侧为 base.rgb + Emission.a,另一侧为 Normal.rgb + Specular.a。但我仍然遇到了将独立的 alpha 保存在文件中的问题。

也许我可以将它们保存为两个文件,但在加载期间将它们组合起来,然后再将其发送到 openGL。我得尝试一下。

Method 4最后,在 3D 世界中,如果我有 20 种不同的墙壁面板纹理,这些应该是单独的文件还是全部打包在单个纹理图集中?我最近注意到,在某种程度上,《我的世界》从地图集转移到了单独的纹理 - 尽管它们都是 16x16。

使用单个模型并通过修改纹理坐标(我已经在上面的方法 2 和 3 中进行了操作),您可以轻松地将偏移量发送到着色器以选择图集中的特定贴图:

v_fragmentTexCoord0 = u_texOffset + a_vertexTexCoord0 * u_texScale;

这提供了很大的灵活性并减少了纹理绑定的数量。这基本上就是我现在在游戏中所做的。但IS IT更快地访问较大纹理的一小部分并在顶点着色器中进行上述数学运算?或者一遍又一遍地重复绑定较小的纹理是否更快?特别是如果您不按纹理对对象进行排序。

我知道这很多。但这里的主要问题是,考虑到速度+便利性,最有效的方法是什么?对于多个纹理,方法 4 会更快还是多次重新绑定会更快?或者还有其他我忽略的方式。我看到所有这些 3D 游戏都有大量的图形和区域覆盖。他们如何保持较高的帧速率,尤其是在 iPhone4 等较旧的设备上?

**** 更新 ****

由于这几天我突然有了两个答案,我就这么说。基本上我确实找到了答案。或者AN回答。问题是哪种方法更有效?这意味着哪种方法会产生最佳帧速率。我已经尝试了上面的各种方法,在 iPhone 5 上它们都差不多快。 iPhone5/5S 拥有速度极快的 GPU。重要的是在 iPhone4/4S 等较旧的设备上,或视网膜 iPad 等较大的设备上。我的测试不科学,而且我没有毫秒速度可供报告。但是4texture2D()对 4 个 RGBA 纹理的调用实际上与 4 个 RGBA 纹理一样快,甚至可能更快texture2d()调用带有偏移量的单个纹理。当然,我在顶点着色器而不是片段着色器中进行这些偏移计算(从来不在片段着色器中)。

所以也许有一天我会做测试并制作一个包含一些数据的网格来报告。但我现在没有时间这样做并自己写出正确的答案。我无法真正勾选任何其他未回答问题的答案,因为这不是这样的工作原理。

不过还是谢谢那些回答的人。看看我的另一个问题,它也回答了其中的一些问题:在 iOS 上从两个 jpeg 加载 RGBA 图像 - OpenGL ES 2.0 https://stackoverflow.com/questions/22263863/load-an-rgba-image-from-two-jpegs-on-ios-opengl-es-2-0


在内容管道中有一个后期处理步骤,将 RGB 与 alpha 纹理合并并将其存储在 a 中。打包游戏时的 Ktx 文件或编译时的构建后事件。

这是一种相当简单的格式,并且很容易编写这样的命令行工具来加载 2 个 png 并将它们合并为一个 Ktx、rgb + alpha。

这样做的一些好处是 - 游戏启动时加载文件时的 CPU 开销更少,因此游戏启动得更快。 - 某些 GPUso 本身不支持 rgb 24 位格式,这将强制驱动程序在内部将其转换为 rgba 32 位。这会增加加载阶段的时间和临时内存使用量。

现在,当您在纹理对象中获取数据时,您确实希望最小化纹理采样,因为这意味着大量 GPU 操作和内存访问(具体取决于过滤模式)。

我建议使用 2 个纹理,每个纹理有 2 层,因为如果您将所有纹理添加到同一个纹理中,则在使用双线性或 mipmap 采样时可能会出现潜在的伪影,因为它可能包括靠近一个纹理层结束的边缘的相邻像素,并且第二个开始,或者如果您决定生成 mipmap。

作为额外的改进,我建议不要在 Ktx 中使用原始 rgba 32 位数据,而是将其实际压缩为 dxt 或 pvrtc 格式。这将使用更少的内存,这意味着 GPU 的加载时间更快,内存传输更少,因为内存带宽有限。 当然,将压缩器添加到后处理工具稍微复杂一些。 请注意,压缩纹理确实会降低一些质量,具体取决于算法和实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最有效的多重纹理方法 - iOS、OpenGL ES2、优化 的相关文章

  • 当应用程序处于后台时,替代 UserNotificationCenter Delegate 的 willPresent

    我正在尝试弄清楚是否可以通过本地通知来实现我的目标 或者是否需要切换到远程通知 我正在练习 iOS 10 Swift 3 方法是构建一个闹钟程序 该程序在一天中的设定时间播放 RSS 更新的广播节目的最新一集 当应用程序位于前台时 可以通过
  • 如何在一个视图控制器中使用两个自定义 UITableViewCell 创建两个表视图?

    我正在尝试创建两个UITableViews在一个视图控制器中使用两个自定义UITableViewCells 我有以下内容 func tableView tableView UITableView cellForRowAtIndexPath
  • 防止 Realm 在更新对象时覆盖属性

    我已经在 iOS 中设置了一个 REST API 来连接领域对象 然而 我发现在我的对象中创建最喜欢的标志存在问题 我创建了一个最喜欢的布尔值 但是每次从 API 更新该对象时 它都会再次将最喜欢的值设置为默认 false 在这里 我希望这
  • 使用静态库在 ios 项目中设置构建配置以在 xcode 4 中创建存档的正确方法是什么?

    我有一个依赖于多个静态库的工作应用程序 我已将其作为依赖项添加到应用程序中 并在构建阶段添加到与静态库位的链接中 一切都在模拟器和我连接的 iPad 上构建并运行良好 我想创建一个用于试飞的 ipa 文件 因此我按照试飞网站上的说明进行操作
  • 更新 iOS 应用程序的应用内购买内容?

    我似乎无法在任何地方找到这个问题的答案 所以这里 我正在开发一个 iOS 应用程序 该应用程序将具有非消耗性应用内购买 扩展包 例如 假设我出售一个包含 10 个级别的包 并且在一个月内我想将应用内购买更新为包含 15 个级别 用户无需重新
  • 在 iMessage 应用程序中检查横向/纵向方向(扩展)

    见过很多检查方向的解决方案 但奇怪的是 没有一个有效 下面是代码片段 override func viewWillTransition to size CGSize with coordinator UIViewControllerTran
  • iOS wifi扫描、信号强度

    据我所知 不可能扫描范围内的热点并读取它们的 bssid 和信号强度 这在 iOS 4 上可以通过使用私有 API 实现 但在不越狱的 iOS 5 上则不再可能 即使可能 该应用程序也会在 App Store 上被拒绝 是对的吗 一家拥有室
  • 金属中的 SCN 着色器修改器 - 将统一传递给着色器

    我正在尝试将着色器修改器与 Metal 一起使用 我无法弄清楚如何声明制服 到目前为止我的片段修饰符是 color changes pragma arguments float4x4 u color transformation pragm
  • Dropbox iOS SDK 始终为 isLinked 返回“YES”:

    我正在使用 iOS Dropbox SDK 想要检查我的应用程序是否已与 Dropbox 帐户链接 所以我这样做 if self isLinked NSLog linked However self isLinked总是返回YES 即使在清
  • Three20 和 iOS 6 不工作

    我刚刚尝试了我的一个项目 其中包含 Three20 但它似乎无法编译 给我构建错误 似乎是因为一些 UITouch 界面发生了变化 想知道是否有快速修复方法可以做到这一点 看来问题是在这里 UITouch ivars 已从 iOS 6 SD
  • 如何在 UIView 中获取父导航控制器

    我创建了一个UITabBarController在我的应用程序委托中 其中每个选项卡栏项目都有不同的UINavigationController加载自定义的UIViewController带NIB 使用 pushViewController
  • 新的自动引用计数机制如何工作?

    有人可以简单地向我解释一下 ARC 的工作原理吗 我知道它与垃圾收集不同 但我只是想知道它到底是如何工作的 另外 如果 ARC 的作用与 GC 的作用相同且不影响性能 那么 Java 为什么要使用 GC 为什么它不使用 ARC 呢 每个接触
  • IOS 无法从 Google Drive 获取文件

    这是我的代码 GTLQueryDrive query GTLQueryDrive queryForFilesList query q NSString stringWithFormat IN parents root self driveS
  • 修改多张照片时只有一个 iOS 权限对话框

    我的应用程序允许用户从相机胶卷中选择多个图像并对这些图像应用编辑 但是 它会提示用户获得每个图像编辑的权限 编辑用户图像时是否可以只显示一个权限对话框 如果是 我该如何将我的编辑分组为一项权限 这是我的应用程序的屏幕截图 我在应用商店中发现
  • “找不到开发者磁盘映像”

    最近我收到错误 找不到开发人员磁盘映像 我认为自从我将 iPhone 上的 iOS 更新到 9 1 后就会发生这种情况 如何解决该问题并使 Xcode 支持 iOS 9 1 设 备 Xcode 7 0 1 和 iOS 9 1 不兼容 您需要
  • 处理具有不同缩放/分辨率的所有 iPhone 中的 UI [重复]

    这个问题在这里已经有答案了 在 iOS 中处理 iPhone 4 iPhone 5 iPhone 6 iPhone 6 UI 屏幕的最佳方法是什么 iPhone 6 的尺寸 3 倍缩放 坐标空间 414 x 736 像素 iPhone 6
  • exc_bad_access 于 [NSDate timeIntervalSinceReferenceDate]

    我的行为很奇怪 NSDate timeIntervalSinceReferenceDate 我有以下功能 void insertRow NSTimeInterval timeNow NSDate timeIntervalSinceRefer
  • 如何使用 UIScrollView?

    我该如何使用UIScrollView 请给我一个带有一张滚动图像的简单示例 这将使您深入了解UIScrollView控制 学习 UIScrollView 的基础知识 https stackoverflow com questions 159
  • iOS HTTP 请求在后台运行

    当应用程序处于后台时 可以向 PHP 服务器发出 HTTP 异步请求吗 该应用程序是基于位置的应用程序 应收集当前位置并每 5 或其他值 分钟将坐标发送到服务器 即使应用程序处于后台 我也可以将 http 帖子发送到服务器吗 我读到了很多关
  • 如何在 iOS 11 上的 Swift 中获取 FLAC 文件元数据?

    我需要获取 FLAC 文件的元数据 我尝试了以下代码 let item AVPlayerItem url URL fileURLWithPath path let commonMetadata item asset commonMetada

随机推荐

  • 如何创建一个在 inputText 和 inputSecret 之间切换的复合组件?

    我正在编写一个 Facelets 复合组件 它根据参数在使用 inputText 和 inputSecret 之间切换
  • “serve”不被识别为运行反应应用程序的内部或外部命令

    serve已使用全局安装npm install g serve命令并且它在本地工作 但部署到Windows服务器给出以下错误 serve 不被识别为内部或外部命令 如何修复这个错误 还有 这个有什么用server js文件在一个react项
  • 从关闭中返回?

    如何从闭包返回而不从包含函数返回 在下面的函数中 return语句实际上返回自GM xmlhttpRequest 不是关闭 当然 我可以看到我可以安排我的代码 以便执行在闭包结束时停止 但我很好奇如何在示例中提前返回 function GM
  • iPhone SDK - 将触摸从 UIViewController 转发到子视图

    我有一个UIViewController其子类为UIView上面叫customSubView1 然后在 customSubView1 上我有另一个子类UIView called customSubView2 当我放置时 我可以捕获所有子视图
  • 违反 MISRA 2012 - 类型不匹配(规则 10.1、10.4)

    我面临着 MISRA C 2012 违规 我无法理解 以下是代码 define I2C CCRH FS uint8 t 0x80 define I2C CCRH DUTY uint8 t 0x40 define I2C CCRH CCR u
  • UIActionSheet 与 swift

    我创建了一个操作表 但问题是没有调用委托方法 myActionSheet UIActionSheet myActionSheet addButtonWithTitle Add event myActionSheet addButtonWit
  • 汇编语言 - masm32 - 乘法

    我将 3 个数字相乘 即使有进位也能很好地工作 我想添加第四个数字来相乘 只是为了学习目的 在我乘以 3 个数字后 我转移到 EDX 并打印 效果很好 在我添加第四个数字后 我认为我正在乘以 32 位 x 32 位 那么它存储到 EDX E
  • 通过接口动态创建类

    我有一些经验 Net Expressions 当我能够动态生成方法时 没关系 很好 但现在我需要生成一个完整的类 似乎唯一的方法就是发出整个IL 这是完全不可接受的 不可能支持 假设我们有以下接口 public interface IFoo
  • 如何以及在哪里处理关联记录的更新过程?

    我正在使用 Ruby on Rails 4 我想通过以下方式正确处理关联记录的更新和创建过程update attributes方法 也就是说 我有以下内容 Model class Article lt ActiveRecord Base h
  • 替换除
     标记之间的换行符之外的换行符                
                

    我正在寻找替换 删除给定字符串中的所有换行符 嵌套在 a 中的换行符除外 pre 标签 因此对于以下字符串 var text Some contents which is formatted over multiple lines but
  • 将 3d 4x4 旋转矩阵转换为 2d

    假设我们有一个 4x4 矩阵 其索引如下 00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33 如何将该矩阵中包含的旋转数据 忽略 z 轴 如果有帮助的话 转换为单个 2d 旋转角度 以弧度为单位
  • VSTS 缺少某些构建标志:env:BUILD_SOURCEVERSIONMESSAGE

    在我的 Visual Studio Team Services 构建中 我从 bitbucket 存储库中提取 我正在尝试获取提交消息并在 powershell 脚本中使用它 在我的 powershell 脚本中 我有以下代码 param
  • 不明白这个 TypeError: 'list' object is not callable

    我有一个名为im py其中包含几个函数和几个类 第一个函数和类失败了 TypeError list object is not callable 问题似乎是在函数中创建的列表的第一个元素 然后将其传递给类 列表的大部分可以由类处理 但第一个
  • 如何在 C# 中使用管道和 let 参数进行 $lookup (MongoDB.Driver 2.7.2)

    我需要在我的 C 代码中在 MongoDB 中运行以下查询 我使用 MongoDB Driver 2 7 2 和 MongoDB 4 0 我想使用 lookup 而不是 project unwind 以防止命名集合的每个可能字段 db ge
  • std::initializer_list 的实现

    我一直在研究如何initializer list已实现 所以我找到了标准的第 18 9 节 并找到了一个看起来足够简单的界面 我认为制作我自己的版本 我命名为 会很有启发性MyNamespace InitializerList和一个用例 t
  • 在mfc中如何将控件置于前面

    如何更改 MFC 中控件的 Z 顺序在设计时 即我无法使用 SetWindowPos 或在运行时执行此操作 我想在设计器中查看更改后的 z 顺序 即使我必须诉诸直接编辑 rc 代码 我有一个 MFC 对话框 要向其中添加控件 如果控件的边缘
  • 在 tvOS 上对 Dropbox 进行身份验证

    我在我的 ios 移动应用程序中使用 dropbox sdk 它使用 dropbox 身份验证从我的应用程序中的 dropbox 中获取用户文件 它在我的 ios 应用程序上完美运行 并上传到苹果商店 我想让它也适用于 tvos 苹果商店
  • EC2 上的轻度、中度或重度利用率预留实例之间有什么区别?

    他们讨论了不同的利用率实例 但除了价格之外 我找不到任何一个地方可以实际说明轻利用率大型实例和重利用率大型实例之间的区别 有人可以告诉我有什么区别吗 实例是相同的 这只是价格差异 因此如果您知道自己将大量使用该实例 则可以通过支付预付费用来
  • Mandelbrot 集渲染的平滑频谱

    我目前正在编写一个程序来生成非常巨大的 65536x65536 像素及以上 Mandelbrot 图像 我想设计一个光谱和着色方案来使它们公正 这维基百科精选曼德尔布罗图像 http en wikipedia org wiki File M
  • 最有效的多重纹理方法 - iOS、OpenGL ES2、优化

    我正在尝试找到在 iOS 上处理 OpenGL ES2 中多重纹理的最有效方法 我所说的 高效 是指即使在较旧的 iOS 设备 iPhone 4 及更高版本 上也能实现最快的渲染 但同时还要平衡便利性 我考虑过 并尝试过 几种不同的方法 但