3

我已经设法使用 Open Gl 和 NVidia 提供的 CGFX SDK 创建了一个简单的 mandelbrot 浏览器。它工作得很好,但目前是基于浮点的,因此没有太多的“深度”——随着从最小复数到最大复数的距离变小,精度会丢失,并且生成的图像是“像素化的”。

不幸的是,CGFX 似乎不支持双精度,即使这样,双精度也仅限于我的意图。因为 CGFX,因为它的预期设计,没有 bignum 类,我认为最好创建我自己的类。

我设法在 C++ 中创建了一个原型——它只使用无符号整数——但是当我试图将它移动到 CGFX 时,FX Composer 2.5 似乎无法编译它。因为我只使用无符号整数、乘法和加法,所以代码包含很多位移操作,根据 FX Composer 2.5,这些操作在我的配置文件中不可用。

我知道这个问题包含很多查询,但不幸的是,我对数值分析、着色器编程或 open gl 并不是很熟悉,此时我感到不知所措——而且很确定我正在尝试修复泄漏用大锤。

因此,如果有人对这些问题中的任何一个有答案,我将不胜感激:

  1. CGFX 或任何其他着色器语言是否支持无符号整数和浮点数的位移运算符(需要将浮点数转换为大浮点数)?

  2. CGFX 或任何其他着色器语言是否支持双精度或更高的浮点?

  3. 有没有更精致的数学方法来处理我的问题,而不是创建一个大的浮点类?

如果有人需要更多说明或代码片段,请随时提出。

4

2 回答 2

3

如果您严格执行 Mandelbrot 集,则最好使用定点表示。您可能希望从小数点左侧的 5 位加上一个符号位开始。所以对于 32 位,小数点右边有 26。对于 64 位,你会得到 58 位,比双精度要好。同样对于定点数学,所有位移都将是固定数量,而不是进行浮点所需的可变位移。

简而言之,定点提供了更好的精度和更简单的实现,但牺牲了在这种情况下不需要的大范围。不过,我不能谈论着色器问题。

于 2010-02-04T15:29:52.013 回答
2

回答您有关位操作的问题

OpenGL 3.1 / GLSL 1.40(核心)和 OpenGL 扩展 GL_ARB_gpu_shader4 增加了对无符号整数算术和位运算(如移位、按位 OR 和按位与)的支持。借助 GLSL 中的此功能,构造函数 int(uint) 和 uint(int) 可以满足您对 C 或 C++ 背景的期望。它将最重要的位字面上视为符号,因此您可以使用构造函数而不是强制转换。更高版本的 GLSL 还允许您设置浮点精度,但目前还没有很多显卡在硬件中支持双精度。

进一步的建议

我和phkahler在这个。你想要的是定点,而不是浮点类型。鉴于 mandelbrot 集位于复平面的半径 2 内,整数部分只需要 3 位。不要进行平方根,而是检查 z 平方的大小是否大于 4。您需要考虑有符号上溢/下溢。下面描述如何计算常见的算术标志。我没有在 GLSL 中测试过这些,但逻辑是合理的。

计算算术标志

传奇:

C = 进位标志(无符号溢出)
V = 溢出标志
Z = 零标志(相等)
N = 负标志

算法

Given: `dst = src1 + src2` then:
C = (unsigned)dst < (unsigned)src1 || (unsigned)dst < (unsigned)src2
V = ((signed)dst < (signed)src1) != ((signed)src2 < 0)
Z = !dst
N = (unsigned)dst & (1<<31)

计算这些标志需要大量的分支,所以如果你的 GPU 讨厌你,不要感到惊讶。当您可以提取这些时,使用进位实现长乘法和加法应该没有问题。

于 2010-03-13T17:43:24.620 回答