法线从object space到eye space的转换((normal matrix)

本文探讨了三维图形渲染中顶点及其法线从物体空间到视图空间的变换过程。指出常用的模型视图矩阵并不适用于法线变换,并详细推导了正确的法线变换矩阵——即模型视图矩阵的逆矩阵的转置。

对于顶点来说,从object Space转换到eye space, 使用model-view矩阵就好了.那么顶点的法线是否也可以直接使用model-view矩阵转化?

  通常情况下是不行的.

  如下两张图是顶点的tangent和normal向量使用m-v矩阵从object space到eye space的变换:

  >>>>>>>>>>>>>>>>  

  可以看到在eye-space中,tangent的方向仍符合定义,normal则不再垂直于tangent了.m-v矩阵不适用于normal.

  令T为tangent,MV为model-view矩阵.P1, P2为tangent联系的2个顶点.

  T = P2 - P1

  T' = T * MV = (P2 - P1) * MV = P2 * MV - P1 * MV = P2' - P1'

  因此T'保留了tangent的定义.但对于normal,你也可以找到N=Q2-Q1代表它,但是变换后Q2'-Q1'却不能保证垂直于T'.object space到view space,角度关系被改变了.

  如何求出normal的变换,维持与tangent垂直?假设该变换为G.

  normal与tangent垂直:
  N'.T' = (GN).(MT) = 0

  点积转化为叉积:

  (GN).(MT) = (GN)T * (MT) = (GN)T(MT) =  (NTGT)(MT) = NTGTMT = 0

  注意到NTT为0:

  若GTM = I,则上式成立.因此G=(M-1)T.

  即normal matrix是model-view矩阵的逆矩阵的转置矩阵.

  若model-view矩阵是一个正交矩阵,则G=M.这便是例外情况下normal matrix为model-view矩阵.

在HLSL中,将法线从物体空间Object Space转换到裁剪空间(Clip Space),通常涉及三个关键步骤: 1. **世界变换** (World-to-View Transformation): 这一步将物体空间的位置(pos)和法线normalOS)转换成视口空间(Viewport Space)。你需要使用相机矩阵(View Matrix)乘以物体的空间位置和法线,`o.normalCS = TransformWorldToViewDir(v.normalOS)`。 2. **投影变换** (View-to-Clip Transformation): 视口空间的数据接着通过投影矩阵(Projection Matrix)映射到裁剪空间。这一步通常会压缩空间,移除不必要的范围(如Z轴的近裁剪和远裁剪平面)。对于法线,这通常意味着它们会被缩放并保持正交关系,因为法线不需要深度信息。表达式可能是`o.normalCS = mul(o.normalCS, ProjectionMatrix)`。 3. **归一化** (Normalization): 由于裁剪空间可能包含非标准化的数值,特别是Z轴,法线还需要进行归一化,确保其长度为1,以便于后期处理和纹理采样。`o.normalCS = normalize(o.normalCS)`。 完整的代码片段如下: ```hlsl // 假设worldToObject已经包含了世界转换 half4 posVS = mul(float4(v.pos, 1.0), worldToObject); half3 normalVS = mul(float3(v.normalOS, 0), worldToObject).xyz; // 视口空间到裁剪空间 normalVS = mul(normalVS, ViewMatrix); normalVS = mul(normalVS, ProjectionMatrix); normalVS = normalize(normalVS); // 接下来的vert部分,将pos也做相应变换 o.pos = mul(posVS, ViewProjectionMatrix); // 然后保留其他属性,如uv和color o.uv = v.uv; o.color = ...; return o; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值