我正在研究C ++中的行星生成工具,目前我正在尝试生成纹理和高度图。
我正在使用3d perlian噪声函数,因此每次生成纹理或高度图时,我都会计算球体表面上每个顶点的噪声函数值。
这些坐标不会改变。最初我是通过使用this method将立方体映射到球体来计算这些。
如果我知道这些值每次都是相同的,那么我想好了,为什么不计算它们一次并将它们输出到头文件中,在那里它们可以被定义为静态数组。
我想创建纹理512x512这意味着每面生成260,000+个坐标 :(
生成的坐标存储在一个数组中:
float textureMapSaved[6][512][512][3] = {etc};
由于立方体的 6个面,每个面 512x512像素, 3个坐标(x,y& z)。
这有望允许我循环遍历数组,获得我感兴趣的perlian噪声函数中的值的坐标。
到目前为止,我只是设法将我的计算机变成了一个令人讨厌的混乱。
我的问题是:
有可行的方法吗?
如果不创建输出文件,程序大约需要15分钟来计算球体。我实际上无法使用标题进行编译,它使我的计算机崩溃了。
然后我尝试了256x256,这样做效果好一点,但我的电脑还在忙碌;我猜这是因为它无法有效地为4D阵列分配内存。
感谢您的快速回复!
目前我正在做以下事情:
std::vector<std::vector<std::vector<std::vector<float>>>> textureFaces = GenerateSphereCoordinates(TEXTURE_MAP);
std::ofstream myfile;
myfile.open ("spheremapping.h");
myfile << "#ifndef _SPHEREMAP \n#define _SPHEREMAP \n\nfloat textureMapSaved[6][" << textureRes << "][" << textureRes << "][3] = {";
for(int i = 0; i < 6; i++)
{
myfile << "{";
for(int j = 0; j < textureRes; j++)
{
myfile << "{";
for(int k = 0; k < textureRes; k++)
{
if(k != textureRes - 1)
{
myfile << "{ " << textureFaces[i][j][k][0] << ", " << textureFaces[i][j][k][1] << ", " << textureFaces[i][j][k][2] << "}, " ;
}
else
{
myfile << "{ " << textureFaces[i][j][k][0] << ", " << textureFaces[i][j][k][1] << ", " << textureFaces[i][j][k][2] << "}" ;
}
}
if(j != textureRes - 1)
{
myfile << "}, \n";
}
else
{
myfile << "} \n";
}
}
if(i != 5)
{
myfile << "}, \n\n";
}
else
{
myfile << "} \n\n";
}
}
myfile << "};\n\n#endif";
myfile.close();
如何将其保存为二进制文件并将其直接读入内存?
答案 0 :(得分:4)
您描述的方法是效率和简单性的最佳组合。如果您的编译器无法同时处理整个数组定义,请将问题分解为多个部分。例如:
typedef float CubeFace[512][512][3];
CubeFace face1 = {etc};
...
CubeFace * textureMapSaved[6] = {&face1, &face2, &face3, &face4, &face5, &face6};
作为替代方案,请停止尝试将您的定义设置为可编译的文本文件并使其成为二进制文件。您可以在一次操作中将其读入内存,或者将其作为内存映射文件,并让操作系统根据需要进行交换。
答案 1 :(得分:0)
单独保存您的面孔。另外,我严重怀疑每个像素需要三个坐标;我敢打赌,单个标量与阵列坐标中固有的x,y值相结合就足够了。
答案 2 :(得分:0)
正如其他人所指出的那样,阵列大小没什么大不了的。还有其他问题,例如:你试图将它作为一个自动变量放在堆栈上。
我将补充说,在处理这种大小的数据集时,缓存效率在性能方面起着重要作用。您的算法应该尝试做两件事: 1)在时间和内存地址中保持数组读取彼此靠近。这意味着不要在高阶尺寸中跳转,例如立方体面,直到您完成处理低阶维度,例如个别顶点。根据需要重新组织数组维度以帮助实现此目的。 2)尝试按照内存地址以可预测的增量模式触摸阵列。这允许缓存预取程序提前主动将数据引入缓存。
你也可以把工作分成并行任务。