ATI显卡上实现GLSL三维噪声

4
我尝试了很多不同的策略来得到可用的噪声函数,但都没有成功。那么,在ATI显卡上如何在GLSL中实现Perlin噪声呢?
这里是我尝试过的方法: 我试着将置换和梯度数据放入一个GL_RGBA 1D纹理中,并调用texture1D函数。然而,对此噪声实现的一次调用会导致12个纹理调用,从而降低帧率。
我试着将置换和梯度数据上传到一个uniform vec4数组中,但编译器不允许我在数组中获取一个元素,除非索引是常量。例如:
int i = 10;
vec4 a = noise_data[i];

将会产生编译错误:

错误: 0:43: 当使用临时数组间接索引时不支持。

这意味着我只能像这样检索数据:

vec4 a = noise_data[10];

我曾尝试将数组直接编程到着色器中,但是我遇到了相同的索引问题。听说NVIDIA显卡实际上允许这种方法,但ATI不允许。
我尝试创建一个函数,根据输入索引返回特定的硬编码数据点,但该函数被调用12次并具有64个if语句,导致链接时间无法忍受。
ATI不支持glsl的“内置”噪声函数,而且我不能预先计算噪声并将其导入为纹理,因为我正在处理分形。这意味着我需要在运行时计算噪声的无限精度。
所以总体问题是...
如何解决?

哎?你不能在ATI上使用非常量索引访问uniform数组?听起来很奇怪。GLSL规范明确提到这是允许的。来自GLSL 1.50规范:“.. 使用大于或等于数组大小或小于0的非常量表达式索引数组会导致未定义的行为。[..]所有基本类型和结构都可以组成数组。” - Mads Elvheim
我在做更多的研究时发现了这一点。我正在运行glew 1.5.5和最新版本的OpenGL,但我认为ATI驱动程序落后了。 - Ned Bingham
由于我使用的是Linux系统,我安装的是最新版本的freeglut3。 - Ned Bingham
5个回答

2

在github上有一个与GLSL噪声函数相关的项目。它包含了2D、3D和4D的“经典”和较新的噪声函数。(项目链接)

IOS中已经实现了noise函数。


2

嘿,这很酷!生成随机数时非常棒,但是噪声的正常值怎么样?基本上,导数呢? - Ned Bingham

1

noise() 因未被实现而广为人知...

自己动手实现:

int c;
int Xn;
srand(int x, int y, int width){// in pixel
    c = x+y*width;
};

int rand(){
    Xn = (a*Xn+c)%m;
    return Xn;
}

关于a和m的值,请参见wikipedia

虽然不是完美的,但通常已经足够好了。


我喜欢这个答案的样子。给我时间来实现它。 - Ned Bingham
如果您发现像素之间存在太多的视觉相关性,请尝试更复杂的方法来初始化c。也许c = x + y * width; c = rand();。选择a和m也可能会产生很大的差异。 - Calvin1602

0

这个 SimpleX 噪声的东西可能会满足你的需求。


我已经浏览了那个网站。他们对于经典噪声的实现也涉及到12个纹理查找,而他们对于simplex噪声的实现则需要8次纹理查找。8次相对来说好一些,但是仍然会极大地降低帧率。我也看过这个网站: http://www.gamedev.net/community/forums/topic.asp?topic_id=538517 这让我尝试了数组策略。 - Ned Bingham
顺便说一下,它是“simplex”,类似于三角形和四面体的n维几何图形。 - jheriko

-1
尝试在您的着色器顶部添加#version 150。

我收到了以下信息: 片段着色器编译失败,出现以下错误: ERROR: 0:1: '' : GL2不支持版本号 ERROR: 编译错误。没有生成代码。因为我正在Linux上尝试这个,所以我被困在ATI的fglrx中以获得OpenGL支持。该驱动程序仅支持以下版本:状态:使用OpenGL 2.1.8087版 状态:使用GLSL 1.20现在,我正在将我的开发环境移植到Windows机器 :( 它也有一个ATI显卡,但是该驱动程序支持最新版本的OpenGL和GLSL。我仍然对1.5之前的答案感兴趣。 - Ned Bingham
要使用GLSL版本1.50,您需要一个OpenGL 3.2上下文。无论如何,这对他的问题并不重要。变量索引一直允许用于数组。这是AMD的错。 - Mads Elvheim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接