目录
前言
原理见
fft海面模拟(一) - 知乎 https://note.youdao.com/ynoteshare/index.html?id=cc4438d7cf28de227151bfe1a7fd1ca9&type=note&_time=1675246942621
真实海洋
P1
rt展示
高斯随机数
- 使用Box-Muller算法,高斯随机数可以由均匀随机数得到Box-Muller——生成高斯分布 - 知乎
- 均匀随机数可以使用Xorshift算法xorshift算法生成随机数的原理是什么? - 知乎
-
Xorshift需要一个随机种子,可以使用WangHash算法常见的哈希算法和用途 - 知乎
高度频谱
- Donelan-Banner方向拓展
- phillips频谱
float2 k = float2(2.0f * PI * id.x / N - PI, 2.0f * PI * id.y / N - PI);
float2 gaussian = GaussianRandomRT[id.xy].xy;
float2 hTilde0 = gaussian * sqrt(abs(phillips(k) * DonelanBannerDirectionalSpreading(k)) / 2.0f);
float2 hTilde0Conj = gaussian * sqrt(abs(phillips(-k) * DonelanBannerDirectionalSpreading(-k)) / 2.0f);
hTilde0Conj.y *= -1.0f;
float omegat = dispersion(k) * Time;
float c = cos(omegat);
float s = sin(omegat);
float2 h1 = complexMultiply(hTilde0, float2(c, s));
float2 h2 = complexMultiply(hTilde0Conj, float2(c, -s));
float2 HTilde = h1 + h2;
HeightSpectrumRT[id.xy] = float4(HTilde, 0, 1);
偏移频谱
- 利用高度频谱对xz方向进行偏移
float2 k = float2(2 * PI * id.x / N - PI, 2 * PI * id.y / N - PI);
k /= max(0.001f, length(k));
float2 HTilde = HeightSpectrumRT[id.xy].xy;
float2 KxHTilde = complexMultiply(float2(0, -k.x), HTilde);
float2 kzHTilde = complexMultiply(float2(0, -k.y), HTilde);
DisplaceXSpectrumRT[id.xy] = float4(KxHTilde, 0, 1);
DisplaceZSpectrumRT[id.xy] = float4(kzHTilde, 0, 1);
FFT变换
置换贴图
法线贴图
- 采用差分近似,取周围的8个点算出两个法线再取平均。
- 通过左右两点和上下两点得到两个向量,再通过叉乘得到法线方向。然后再取斜着的重复
泡沫贴图
- 当xz平面内挤压过头时,就会出现刺穿(如图所示)。恰好对应浪尖破碎形成泡沫的区域。
- 可以用雅可比行列式计算面元有向面积,积分为负时对应浪尖破碎区域
渲染部分
- 菲涅尔
pow五次法线点乘视线,用_FresnelScale加权控制菲涅尔项
fixed fresnel = saturate(_FresnelScale + (1 - _FresnelScale) * pow(1 - dot(normal,viewDir), 5));
- 高光
法线点乘half向量,pow控制高光
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(normal, halfDir)), _Gloss);
- 漫反射
法线点乘光线,用泡沫贴图作mask,混合颜色
fixed3 diffuse = lerp(oceanDiffuse, bubblesDiffuse, bubbles);
- 次表面反射
使用commandbuffer模糊泡沫贴图作mask与sss计算混合
float3 SSSColor(float3 col, float3 lightDir, float3 viewDir, float3 normal, float _Distortion, float waveHeight, float SSSMask)
{
float3 H = normalize(-lightDir + normal * _Distortion);
float I = pow(saturate(dot(viewDir, -H)), _Power)* _SSSscale * waveHeight * SSSMask;
return _SSSColor*I;
}
P2
更新
追加基于摄像机距离的曲面细分,近处顶点数密,远处顶点数疏。
更改了一下距离函数
风格化海洋
对泡沫贴图用膨胀算法,做出风格化效果。