When transforming a directional light, why to use XMVector3TransformNormal()?

Started by
5 comments, last by AireSpringfield 6 years, 7 months ago

Hi,

    When reading Frank Luna's book Introduction to 3D Game Programming with DX11, chapter 10 stenciling, the author made a demo to achieve mirror reflection effect. He made tranformation matrix and transform directional lights as following:


// Build reflection matrix to reflect the skull.
XMVECTOR mirrorPlane = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); // xy plane
XMMATRIX R = XMMatrixReflect(mirrorPlane);
XMMATRIX world = XMLoadFloat4x4(&mSkullWorld) * R;
…/
/ Reflect the light source as well.
// Cache the old light directions, and reflect the light directions.
XMFLOAT3 oldLightDirections[3];
for(int i = 0; i < 3; ++i)
{
oldLightDirections = mDirLights.Direction;
XMVECTOR lightDir = XMLoadFloat3(&mDirLights.Direction);
XMVECTOR reflectedLightDir = XMVector3TransformNormal(lightDir, R);
XMStoreFloat3(&mDirLights.Direction, reflectedLightDir);
}

    But I think the direction of a light source is no more than a vector, not a normal. Why did the author use XMVector3TransformNormal to flip the lights? Thanks!

Advertisement

XMVector3TransformNormal() leaves out any translation, which is appropiate for a direction vector :)

.:vinterberg:.

21 minutes ago, vinterberg said:

XMVector3TransformNormal() leaves out any translation, which is appropiate for a direction vector

So calling XMVector3TransformNormal() doesn't mean to transform a "surface normal" by multiplying inverse transpose of M, "normal" is for ignoring translation, is it?

 

The docs say so, yeas: 

Quote

XMVector3TransformNormal performs transformations using the input matrix rows 0, 1, and 2 for rotation and scaling, and ignores row 3.

(row 3 is where translations are stored)

You normally achieve the same thing by setting your vector's w component to 0 or 1 (for ignore / don't ignore row 3), but I guess this function is more optimal as it's hard-coded to always ignore row 3.

57 minutes ago, AireSpringfield said:

So calling XMVector3TransformNormal() doesn't mean to transform a "surface normal" by multiplying inverse transpose of M, "normal" is for ignoring translation, is it?

 

No. DirectXMath uses a completely wrong and misleading name. It has nothing to do with normals which typically require a special transform since they originate from cross products. Furthermore, normals are by definition normalized vectors, which would not be preserved by this method if you have an arbitrary uniform or non-uniform scale component.

XMVector3TransformNormal() transforms 3D directions (w-coordinate is implicitly set to 0), XMVector3TransformCoord() transforms 3D points (w-coordinate is implicitly set to 1).

XMVector3TransformPosition() and XMVector3TransformDirection() would be way better names. (You can create a wrapper function in the DirectX namespace.)

🧙

Thanks for all your help!

This topic is closed to new replies.

Advertisement