1

过去一周左右,我使用 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 )

我可能完全愚蠢,忽略了一些非常明显的东西——我看过一堆论文,即使在熟悉了它们的含义之后,也只是迷失在公式中。请帮忙。

4

0 回答 0