游戏开发论坛

 找回密码
 立即注册
搜索
查看: 7381|回复: 11

[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

[复制链接]

1

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2009-6-6 11:40:00 | 显示全部楼层 |阅读模式
VS(引用自OGRE的脚本文件 Example_BumpMapping.cg)

  1. void main_vp(float4 position        : POSITION,
  2.                          float3 normal                : NORMAL,
  3.                          float2 uv                        : TEXCOORD0,
  4.                          float4 tangent     : TANGENT0,
  5.                          // outputs
  6.                          out float4 oPosition    : POSITION,
  7.                          out float2 oUv                         : TEXCOORD0,
  8.                          out float3 oTSLightDir         : TEXCOORD1,
  9.                          // parameters
  10.                          uniform float4 lightPosition, // object space
  11.                          uniform float4x4 worldViewProj)
  12. {
  13.         oPosition = mul(worldViewProj, position);
  14.         oUv = uv;
  15.         float3 lightDir = lightPosition.xyz - position ;


  16.         float3 binormal = cross(tangent.xyz, normal);

  17.         float3x3 rotation = float3x3(tangent.xyz, binormal, normal);

  18.         oTSLightDir = mul(rotation, lightDir);//问题处!!!

  19. }
复制代码


为什么是rotation左乘lightDir呢?

照我理解,构成的rotation应该是row-major矩阵
[
tangent.x  ,tangent.y  ,tangent.z,
binormal.x ,binormal.y ,binormal.z
normal.x   ,normal.y   ,normal.z
]  
我觉得应该使用lightDir*rotation;
而其转制矩阵
[
tangent.x, binormal.x, normal.x
tangent.y, binormal.y  normal.y
tangent.z, binormal.z  normal.z
]
才应该用右乘rotation*lightDir啊,
望指教

11

主题

650

帖子

651

积分

高级会员

Rank: 4

积分
651
发表于 2009-6-6 12:49:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

列矩阵:
    三个轴向量为前三列,最后一列为位移变换
    连乘时从右到左接合,右边的变换先应用,注意这和*运算符的接合顺序相反
    变换向量时为matrix * vector
==============================================================
说明那是列矩阵 其内容就是你那个“转制”

1

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-6-8 09:33:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

我也怀疑过是不是用
float3x3 rotation = float3x3(tangent.xyz, binormal, normal);

这样的构造方式会构造出一个列矩阵,通过HLSL的DEBUG观察,我发现没用,构造出来的仍然是个
行矩阵
[
tangent.x  ,tangent.y  ,tangent.z,
binormal.x ,binormal.y ,binormal.z
normal.x   ,normal.y   ,normal.z
]  

并且,计算结果也是  :tangent空间光向量 = 行矩阵*object空间光向量;
而最后得出的效果也完全正确.

1

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-6-8 09:44:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

有可能是其他什么问题影响吗?

11

主题

650

帖子

651

积分

高级会员

Rank: 4

积分
651
发表于 2009-6-8 09:56:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

?濉!?蠢次易约阂裁桓闱宄

似乎现在需要的是 向量*(rotation的逆) = 向量*(rotation的转制) =rotation*向量 吗

1

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-6-9 12:00:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

对对对,你的等式都没错,
我就不明白为什么需要的是rotation的逆

0

主题

15

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2009-6-9 16:43:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

rotation是从切线空间变换到世界坐标空间的矩阵.

从世界坐标空间变换到切线空间自然应该用rotation的逆.
有什么不妥吗?
换句话说.
此时.向量{tangent.x  ,tangent.y  ,tangent.z}.代表的是切线空间中的{1,0,0}.
其他2个类推.
如果把切线空间中的{1,0,0}.变换到世界坐标空间.
显然应该{1,0,0}*rotation={tangent.x  ,tangent.y  ,tangent.z}.
推出世界空间变换到切线空间的公式:
==>
{1,0,0}*rotation*rotation的逆={tangent.x  ,tangent.y  ,tangent.z}*rotation的逆.
===>{1,0,0}={tangent.x  ,tangent.y  ,tangent.z}*rotation的逆


另外:
float3 lightDir = lightPosition.xyz - position ;
这里的position实际上应该先和世界坐标变换矩阵相乘的.
但是估计这个例子中模型的位置在世界坐标的原点.
所以才会省掉这一步.

1

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-6-9 18:08:00 | 显示全部楼层

Re: Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

我是菜鸟2005: Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题
另外:
float3 lightDir = lightPosition.xyz - position ;
这里的position实际上应该先和世界坐标变换矩阵相乘的.
但是估计这个例子中模型的位置在世界坐标的原点.
所以才会省掉这一步.


可能我没把情况说清楚:

输入参数中 uniform float4 lightPosition, // object space
中的lightPosition是 object空间的光照向量(注释已表明)
而输入的position也在object空间,所以可以进行运算.


1

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-6-9 18:08:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

我是菜鸟2005: Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题
rotation是从切线空间变换到世界坐标空间的矩阵.


按照我的理解rotation应该是从object空间变换到tangent空间的变换矩阵.
因为normal,tangent,binormal ,三个基向量都是在object空间的.所以构成的矩阵是object空间->tangent空间的.

我怀疑这个问题 就是我对rotation这个矩阵的含义理解错误 才出现的..
望指教!

11

主题

650

帖子

651

积分

高级会员

Rank: 4

积分
651
发表于 2009-6-9 18:16:00 | 显示全部楼层

Re:[HLSL请教]法线贴图,计算Tangent空间的LightDir问题

法线贴图
要计算两个向量的点乘,这两个向量必须在同一个空间中。所以你要么将光线方向从世界空间转换到切线空间,要么将法线从切线空间转换到世界空间。
你这例子选择了其中一种而已
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 01:07

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表