Jump to content
  • Advertisement
AireSpringfield

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

Recommended Posts

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!

Share this post


Link to post
Share on other sites
Advertisement
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?

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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.)

Edited by matt77hias

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!