android - RenderScript 中的最大三角形数

标签 android renderscript

我编写了一个快速应用程序来感受 RenderScript 的局限性,并发现当达到大约 65,000 个三角形时,系统根本不会绘制任何其他三角形。例如,如果我创建一个包含 70,000 个三角形的圆柱体,则该圆柱体中缺少一个与超过 ~65,000 个三角形相对应的楔形。三角形是有纹理的,为了便于编写应用程序,我只是使用了 TriangleMeshBuilder 类,因此没有进行真正的优化,例如使用 trifans 或 tristrips。硬件是三星 Galaxy Nexus。 LogCat 报告堆大小约为 15MB,其中 3% 空闲。我没有收到有关图形系统或 RenderScript 的错误或警告。

谁能解释一下三角形被丢弃的原因吗?我是否达到了 RenderScript 能够正常处理的硬件限制?

更新发生在 Samsung Galaxy Nexus (4.0.3)、Samsung Galaxy Tab 7.0+ (3.2) 和 Motorola Xoom (3.2) 上。全部位于大约 65,000 个三角形的同一点上。这些设备中的每一个都有不同的 GPU。

更新2为了回应 Steve Blackwell 的见解,我有一些额外的想法。

第 710-712 行确实将 int 索引向下转换为 short,因此正如 Steve 指出的那样,65536 变为 0。此外,第 757 行的“强制转换”与其说是强制转换,不如说是告诉 RenderScript 最终将发送给它的二进制数据的格式。 RenderScript 要求将所有数据打包到名为 Allocation 的 RenderScript 特定数据类型中,以便从 Java 移动到 RenderScript 运行时,并且需要了解数据结构。根据 Steve 认为这是一个错误的观点,第 757 行通知 RenderScript 将索引数据视为短数据(无符号 16 位),但它向其发送一个 32 位有符号值(由于缺少检查并处理无符号,然后仅使用较低的 16 位,这就是为什么我们在低于此阈值时绘制一些东西,并且当我们超过时三角形连接回第一个索引)。

子类化TriangleMeshBuilder来看看我是否可以让它接受所有这些值作为整数来增加这个限制,但没有成功,这让我相信在深层代码中的某个地方我们无法访问,还有一个关于未签名短裤的额外引用。看起来唯一的解决方法是按照 Steve 的建议添加额外的顶点缓冲区,这可以使用现有的 Mesh.AllocationBuilder 类轻松完成。我还将在开发者环聊中向 Google 提出此问题,以确定这实际上是一个错误还是有意为之。

最佳答案

我对 RenderScript 几乎一无所知,所以我不知道这是否是某种固有的限制、硬件问题,或者与 TriangleMeshBuilder 有关,但我敢打赌,在编号 65535 之后,您将用完三角形。

这是一个神奇的数字,因为它是无符号 16 位整数的最大值。 (Wikipedia)

我怀疑代码中的某个地方有一个无符号短来保存三角形的数量。它不会出现在 Java 代码中,因为 Java 没有无符号值。而且限制可能不是硬件,因为 CPU 寄存器/路径 >= 32 位。所以我会检查 TriangleMeshBuilder。

编辑:

这是 line 553 上的一个很棒的发现。每个索引的值都必须适合 short。看起来沮丧正在发生在 line 710-712 .

我假设您正在调用addTriangle()。该函数需要三个 int,然后显式转换为 short。我认为这是一个错误,因为向下转换是悄然发生的,并且这不是您对函数签名的期望。

关于line 768 ,该虚假数据被传递到 Allocation.copy1DRangeFromUnchecked() 。我没有一直遵循它,但我想在某些时候,那些有符号的值会被转换为无符号:-32768到-1又变成32768到65535。所以把索引变成负数看起来很糟糕,但这只是重新解释相同的数据,这并不是真正的问题。

当您发送像 65536 这样的值时,真正的问题就开始了。当 65536 被转换为 short 时,它会变成 0。这是真正的数据丢失。现在您指的是不同的索引,并且转换为 unsigned 并不能修复它。

真正的问题是 copy1DRangeFromUnchecked() 是一个重载函数,并且 overloads takes an int[] 之一,所以这一切都不会成为问题。

对于解决方法,我想您可以子类 TriangleMeshBuilder 并重写成员变量 mIndexData[] 和方法 addTriangle()。或者也许您可以使用多个顶点缓冲区。或者在某个地方提交错误报告?不管怎样,这是一个有趣的问题。

关于android - RenderScript 中的最大三角形数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10824856/

相关文章:

Android 渲染脚本永远不会在 GPU 上运行

android - 如何使用自定义数据正确使用 BugSense?

android - 我可以更改主 Activity 的名称吗?

android - 如何在已安装的 .apk 上运行 monkeyrunner

java - 如何将 ScriptIntrinsic3DLUT 与 .cube 文件一起使用?

android - RenderScript No JNI_OnLoad 发现错误

android - 如何在 renderscript 中制作圆柱体

Renderscript、forEach_root 以及从 OpenCL 移植

java - 在 webView 中阻止键盘

android - 避免 '@' 字符在 POST @FormUrlEncoded 请求期间获取 url 编码