这个立方体纹理图应该就是cubemap,从上面的描述可以看出,每个三角网格还可以存储str坐标。摄像机看下三角面,
获得的反射信息存储在cubemap中,然后把摄像机拉走,三角面也可以通过str坐标去cubemap取到反射信息了。
规格化的cubemap是将x,y,z映射到0-1的范围内,像素级光照需要对法线进行插值。法线插值暂时没看到细节,需要后面看。
首先看Kprimary, E是自发光颜色,暂时不知道意思,D是漫反射颜色,A是环境管强度。同时,利用N.L可以算出视角的光强。
再看Ksecondary,S是反射颜色,C是入射光强度,NH依然是视角算出的光强。
这里我突然意识到,法线插值其实在前面就讲过了,就是顶点属性的插值,法线作为顶点的一个属性,是可以根据深度进行插值的。
E是自发光,M应该是自发光强度,D是漫反射颜色,A是强度,T是纹理颜色,C是入射光强度,s是反射颜色,G是高光图颜色,
这个经过和别人的探讨得到一个信息:除了坐标插值,其他插值都是有误差的。
通过解方程其实我们可以得到切线向量TNB空间的三个向量。
因为法向量永远对应0,0,1那么我们就可以得到矩阵最后一列是Nx, Ny, Nz。
从切线空间映射到模型空间,我们可以理解为先平移到模型原点,在进行一定程度的旋转。
然后我们看看为什么Tx Ty Tx, Bx, By, Bz, Nx, Ny, Nz构成的矩阵就是从切线空间到对象空间的转化。
坐标系的转化,其实就是将新的坐标系用老的坐标系去表示,就是Xnew = ax + by + cz
我们可以看到Xnew = Txx + Bxy + Nxz. 取其中顶点P, 我们已经证明
Px = s1Tx + t1Bx
而s1 t1代表的是两个坐标的纹理方向的差,也就是刚好就是我们定的x和y
那么就可以证明在二维上Xnew = Txx+Bxy是成立的。继续推广到三维,就证明了结论的正确。
从理解的角度上来说,两个坐标系的转化,是可以直接立方程求解,但其中一个坐标系不确定,于是我们提出了约束,从而算出了坐标系本身。也得出了变换矩阵。
接下来我没看unity里面对法线贴图的使用,
首先是case1,也就是标准情况:
worldPos是顶点的世界坐标,worldNormal是世界法线坐标,worldTanget是世界切线坐标,然后通过cross以及w算出副法线坐标,可以构造出矩阵,从切线空间变到世界空间。
case1非常好理解,也符合书本所讲,然后我们看下case2
case2是将法线乘以一个矩阵,我们知道右成相当于左乘这个矩阵的转置矩阵。我们可以明白case2认为这个东西的转置矩阵就是逆矩阵本身,也就是说从切线坐标到世界坐标的变换。
我们看到WtoT是将世界坐标2物体坐标放在右边,其实就相当于World_Object的转置左乘,相当于将右边的法线转到世界坐标中。
-
#define TANGENT_SPACE_ROTATION \
-
float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w; \
-
float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal )
-
rotation其实就是从切线空间到模型空间的变换,那么再加上从模型空间到世界空间的变换,应该等价。
-
但其实不是的,我们知道法线变换的矩阵是顶点变换矩阵的逆转置矩阵,证明过程是通过切向向量和法线向量相互垂直来证明的。case1完全通过变换矩阵一个个算,而case2就有投机取巧,反而错了,因为除了法线,切线其实就是按照正常变换,而副法线和切线垂直,虽然也可以用类似法线的证明方法,但实际上这些都不一定保证垂直的。那为什么结果还可以呢,因为正交矩阵的逆矩阵就是转置矩阵,我们可以看到,对于需要Object2World * 坐标的切线坐标,你用mul(坐标,World2Object)其实就是相当于World2Object的转置成坐标,刚好转置就是Object2World本身,所以结果恰巧一样,仅此而已。