我有几个关于 Simplex Noise 的问题。我正在使用 Simplex Noise 在 directx 中生成地形,但我目前正在使用类等。我可能也会将它用于纹理,那么是否有必要将其更改为着色器实现?如果是这样,这很容易做到吗?
此外,对于纹理,使用 3D 噪声还是 2D 噪声更好?
我有几个关于 Simplex Noise 的问题。我正在使用 Simplex Noise 在 directx 中生成地形,但我目前正在使用类等。我可能也会将它用于纹理,那么是否有必要将其更改为着色器实现?如果是这样,这很容易做到吗?
此外,对于纹理,使用 3D 噪声还是 2D 噪声更好?
是的,你真的应该把这项工作转移到 GPU 上,这是它最擅长的。
GPU 上的单纯形噪声是一个已解决的问题。您可以在此处找到有关该主题的精彩论文,或者您可以从此处获取实现。
该实现在 GLSL 中,但移植它只是将 vec3 和 vec4 更改为 float3 和 float4 的问题。
使用它后,我发现迄今为止最快的噪声函数实现是 inigo quilez 的 Perlin 噪声实现(下面提供的实现取自 shadertoy.com 网站上的代码。这是一个很棒的网站,看看吧!
#ifndef __noise_hlsl_
#define __noise_hlsl_
// hash based 3d value noise
// function taken from https://www.shadertoy.com/view/XslGRr
// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// ported from GLSL to HLSL
float hash( float n )
{
return frac(sin(n)*43758.5453);
}
float noise( float3 x )
{
// The noise function returns a value in the range -1.0f -> 1.0f
float3 p = floor(x);
float3 f = frac(x);
f = f*f*(3.0-2.0*f);
float n = p.x + p.y*57.0 + 113.0*p.z;
return lerp(lerp(lerp( hash(n+0.0), hash(n+1.0),f.x),
lerp( hash(n+57.0), hash(n+58.0),f.x),f.y),
lerp(lerp( hash(n+113.0), hash(n+114.0),f.x),
lerp( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
}
#endif
我想用上面答案的奇妙功能的图片来完成上面的答案,所以你可以限定它(它类似于 libnoise 库中的 valuenoise)
如您所见,它很棒,需要对其进行调整以处理负空间值(绝对 xyz 轴)……显然它是 3d 的,因此期望在 y 轴上具有相同的形态。
如果您的应用程序没有动态使用噪声网格和纹理,那么您应该保留当前用于网格的离线创建。但是,如果您希望网格和纹理随时间动态变化(想想可变形地形),那么如果高 fps 对您很重要,则有必要将其更改为着色器实现。它可以做到,但我不确定你声称它很容易的能力水平。对于地形网格的情况,它将涉及使用几何着色器(可能还有流出),以及创建纹理的像素着色器。
至于对纹理使用 2d 或 3d 噪声,这取决于您的使用需求。3d 纹理非常适合表示力场、体素场等。但是动态创建它们的成本很高。如果您只是想将纹理用作常规网格材质,那么 2d 是可行的方法。