我正在关注J. Tessendorf论文“Simulating Ocean Water”,我设法使用有限差分法得到高度图和法线贴图,但我很难使用这些法线。
据我了解,这些法线处于切线空间,因此我需要一种方法将它们转换为世界空间进行光照计算。问题是,我不知道如何生成TBN矩阵,这将允许我转换法线。
我试过了Normal Mapping Without Precomputed Tangents,但我没有成功,我不确定它是否可以在这里应用。
我真的不知道接下来要尝试什么,我正在使用在顶点着色器中变形的计划,因此TBN无法真正在CPU上计算,无论如何,如果每一帧计算它都会很慢变化
在论文中,作者建议使用另一个iFFT来计算斜率向量(不确定斜率向量是什么,与切线/比特相比),然后给出一个公式来得到正态值(本文中的公式为36) )。我很确定这些法线也会出现在切线空间中。
你能帮助我改变世界空间中的这些法线吗?我应该使用有限差分法,还是使用其他iFFT来获得法线?
这是我现在所拥有的,所以你可以检查我如何计算法线并使用它们(cg着色器)。我正在使用unity和_WorldSpaceCameraPos是一个内置着色器变量,它具有相机在世界空间中的位置。
顶点着色器:
v2f vert(appdata_full v) {
v2f o;
float3 D = tex2Dlod(_MainTex, float4(v.texcoord.xy, 0, 0));
//128.0 hard coded to be sure it's working, I'm using 128x128 textures
float3 off = float3(-1.0 / 128.0, 0.0, 1.0 / 128.0);
float s11 = D.x;
float s01 = height(texcoord + off.xyyy);
float s21 = height(texcoord + off.zyyy);
float s10 = height(texcoord + off.yxyy);
float s12 = height(texcoord + off.yzyy);
float3 va = normalize(float3(2, 0, s21 - s01));
float3 vb = normalize(float3(0, 2, s12 - s10));
float4 bump = float4(cross(va, vb), s11);
o.pos = mul(UNITY_MATRIX_MVP, (float4(v.vertex.x + D.x, v.vertex.y + D.y, v.vertex.z + D.z, 1.0)));
o.color = float4(bump.xyz * 0.5 + 0.5, bump.w);
o.texcoord = v.texcoord.xy;
o.viewVector = _WorldSpaceCameraPos - o.pos.xyz;
return o;
}
片段着色器:
fixed4 frag(v2f i) : COLOR {
float4 N = i.color * 2.0 - 1.0;
float3x3 tbn = cotangent_frame(N.xyz, -i.viewVector, i.texcoord);
N.xyz = normalize(mul(tbn, N.xyz));
return float4(N.xyz * 0.5 + 0.5, 1.0);
}
cotangent_frame函数来自文章,我只是试图想象我的世界空间中的法线,但我得到的只是蓝色法线。
顶点着色器中从高度图获取法线的代码来自this post