我正在尝试在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向纹理确实需要我修改着色器中的纹理坐标.为了模型的灵活性,我将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