我只是想熟悉Three.js并遇到一些奇怪的事情,我无法完全理解。
在我使用的大多数其他系统(非基于网络)中,法线贴图的照明是在切线空间中计算的。但在Three.js中,事情有点不同。例如,如果您在第2643行考虑WebGLShaders.js中的代码:
"mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );",
"vec3 finalNormal = tsb * normalTex;",
他们为切线空间建立了正交基础矩阵,然后将法线转换为该空间。到目前为止一切都很好。
问题是......这似乎是他们将矢量转换为切线空间的唯一地方???
所以他们计算的光方向矢量没有转换为切线空间,也没有眼睛方向矢量???两者随后用于计算2692-2694行的照明:
"vec3 pointHalfVector = normalize( pointVector + viewPosition );",
"float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
"float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );",
这是一种与我习惯的计算镜面反射略有不同的方法。所以我想知道是否有人能解释他们在做什么?我想知道这个着色器是如何工作的,这样我就可以在输出three.js时正确地转换单位设置。这是我的最终目标。
答案 0 :(得分:4)
没有。照明计算正在相机空间进行。
tsb
矩阵(可能应命名为tbn
矩阵)将法线从切线空间转换为相机空间。
你可以亲自看看:如果normalMap
是平的,那么normalTex
将是( 0, 0, 1 )
,当你用tbn
矩阵对其进行转换时,你会得到结果标准化vNormal
。
three.js r.59