最有效的多纹理方式 - iOS,OpenGL ES2,优化

 同步管理精英 发布于 2023-01-20 16:37

我正在尝试在iOS上找到处理OpenGL ES2中多纹理的最有效方法."高效"我的意思是即使在较旧的iOS设备(iPhone 4及更高版本)上也能实现最快的渲染 - 而且还可以平衡便利性.

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

方法1 - 我的碱基值和正常值是rgb,没有ALPHA.对于这些物体,我不需要透明度.我的发射和镜面反射信息都只是一个通道.为了减少texture2D()调用,我认为我可以将发射存储为基础的alpha通道,将镜面反射存储为法线的alpha.每个都在他们自己的文件中,它看起来像这样:

两个双向纹理

到目前为止我的问题是找到一个支持完整的非预乘alpha通道的文件格式.PNG只是没有为我工作.我试图将此作为PNG保存的每一种方式都将.alpha与.rgb文件保存(通过photoshop)基本上摧毁了.rgb.当我重新加载文件时,任何具有0.0 alpha的像素都有黑色rgb.我在这里发布了这个问题没有活动.

我知道如果我能找到一种方法来保存和加载这个独立的第4通道,这种方法会产生更快的渲染.但到目前为止,我还没有能够继续前进.

方法2 - 当这不起作用时,我转到单个4向纹理,其中每个象限具有不同的地图.这不会减少texture2D()调用,但会减少着色器中正在访问的纹理数量.

一个4向纹理

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

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

为了避免动态纹理查找(感谢Brad Larson),我将这些偏移移动到顶点着色器并将它们保留在片段着色器之外.

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

我遇到的一个问题是在不同的地图之间流血.由于线性纹理映射,1.0的texcoord在一些蓝色正常像素中进行平均.这在接缝附近的物体上添加了蓝色边缘.为了避免这种情况,我不得不将我的UV贴图更改为不太靠近边缘.对很多物体来说,这是一种痛苦.

方法3是组合方法1和2.并且在一侧具有base.rgb + emission.a而在另一侧具有normal.rgb + specular.a.但我仍然有这个问题获得一个独立的alpha保存在文件中.

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

方法4最后,在3D世界中,如果我有20种不同的墙面板纹理,那么它们应该是单个文件还是全部打包在单个纹理图集中?我最近注意到,在某些时候,我的世界从地图集转移到单个纹理 - 尽管它们每个都是16x16.

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

v_fragmentTexCoord0 = u_texOffset + a_vertexTexCoord0 * u_texScale;

这提供了很大的灵活性并减少了纹理绑定的数量.这基本上就是我现在在游戏中的表现.但它是更快地访问更大的纹理的一小部分,并具有在顶点着色器上面的数学吗?或者反复绑定较小的纹理是否更快?特别是如果你没有按纹理排序对象.

我知道这很多.但这里的主要问题是考虑速度+便利性的最有效方法是什么?对于多个纹理,方法4会更快还是多个rebinds会更快?或者还有其他一些我忽视的方式.我看到所有这些3D游戏都有很多图形和区域覆盖.它们如何保持帧速率,特别是在iphone4等旧设备上?

****更新****

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

所以也许有一天我会做测试并制作一个带有一些数字的网格来报告.但我现在没时间做这件事并自己写一个正确的答案.我无法真正勾选任何其他没有回答问题的答案,因为这不是SO的工作方式.

但感谢有回答的人.并查看我的另一个问题,该问题也回答了以下问题:从iOS上的两个jpeg加载RGBA图像 - OpenGL ES 2.0

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有