过去一周左右,我使用 gerstner 波渲染了一个简单的海洋,但遇到了平铺问题,所以我决定开始“正确”渲染它们,并将我的脚趾浸入使用 iFFT 渲染高度场的浑水。
有很多论文解释了基本要点 -
1) 计算频谱
2) 使用 ifft 创建一个高度场,将频域转换为空间域 - 使用时间 t 进行动画处理
自从这次旅程开始以来,我已经了解了复平面、复指数方程、更详细的 FFT 等内容,但在创建初始频谱的初始步骤之后(渲染一个充满高斯数的纹理,均值为 0 和 sd 1,由菲利普斯谱过滤)我仍然完全迷失了。
我创建初始数据的代码在这里(GLSL):
float PhillipsSpectrum(vec2 k){
//kLen is the length of the vector from the centre of the tex
float kLen = length(k);
float kSq = kLen * kLen;
// amp is wave amplitude, passed in as a uniform
float Amp = amplitude;
//L = velocity * velcoity / gravity
float L = (velocity*velocity)/9.81;
float dir = dot(normalize(waveDir),normalize(k));
return Amp * (dir*dir) * exp(-1.0/(kSq * L * L))/ (kSq * kSq) ;
}
void main(){
vec3 sums;
//get screenpos - center is 0.0 and ranges from -0.5 to 0.5 in both
//directions
vec2 screenPos = vec2(gl_FragCoord.x,gl_FragCoord.y)/texSize - vec2(0.5,0.5);
//get random Guass number
vec2 randomGuass = vec2(rand(screenPos),rand(screenPos.yx));
//use phillips spectrum as a filter depending on position in freq domain
float Phil = sqrt(PhillipsSpectrum(screenPos));
float coeff = 1.0/sqrt(2.0);
color = vec3(coeff *randomGuass.x * Phil,coeff * randomGuass.y * Phil,0.0);
}
它创建了这样的纹理:
现在我完全迷失了如何:a)从初始纹理中获得三个方向的光谱
b) 根据幻灯片 5中提到的时间 t 制作动画(https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/sdk/11/OceanCS_Slides.pdf )
我可能完全愚蠢,忽略了一些非常明显的东西——我看过一堆论文,即使在熟悉了它们的含义之后,也只是迷失在公式中。请帮忙。