FFT Water - 如何获得TBN矩阵

时间:2016-10-19 15:36:43

标签: unity3d graphics shader

我正在关注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

0 个答案:

没有答案