1
0
mirror of https://github.com/microsoft/DirectXMath synced 2024-11-21 20:00:12 +00:00

Code cleanup

This commit is contained in:
Chuck Walbourn 2017-07-13 01:29:17 -07:00
parent f89abe64f4
commit 8a90e9383b
2 changed files with 192 additions and 210 deletions

View File

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------------
// Stereo3DMatrixHelper.h -- SIMD C++ Math helper for Stereo 3D matricies
// Stereo3DMatrixHelper.cpp -- SIMD C++ Math helper for Stereo 3D matricies
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
@ -13,138 +13,128 @@
using namespace DirectX;
namespace
{
inline bool StereoProjectionHelper
(
const STEREO_PARAMETERS& stereoParameters,
_Out_ float* fVirtualProjection,
_Out_ float* zNearWidth,
_Out_ float* zNearHeight,
float FovAngleY,
float AspectRatio,
float NearZ
)
{
// note that most people have difficulty fusing images into 3D
// if the separation equals even just the human average. by
// reducing the separation (interocular distance) by 1/2, we
// guarantee a larger subset of people will see full 3D
// the conservative setting should always be used. the only problem
// with the conservative setting is that the 3D effect will be less
// impressive on smaller screens (which makes sense, since your eye
// cannot be tricked as easily based on the smaller fov). to simulate
// the effect of a larger screen, use the liberal settings (debug only)
// Conservative Settings: * max acuity angle: 0.8f degrees * interoc distance: 1.25 inches
// Liberal Settings: * max acuity angle: 1.6f degrees * interoc distance: 2.5f inches
// maximum visual accuity angle allowed is 3.2 degrees for
// a physical scene, and 1.6 degrees for a virtual one.
// thus we cannot allow an object to appear any closer to
// the viewer than 1.6 degrees (divided by two for most
// half-angle calculations)
static const float fMaxStereoDistance = 780; // inches (should be between 10 and 20m)
static const float fMaxVisualAcuityAngle = 1.6f * (XM_PI / 180.0f); // radians
static const float fInterocularDistance = 1.25f; // inches
float fDisplayHeight = stereoParameters.fDisplaySizeInches / sqrtf(AspectRatio * AspectRatio + 1.0f);
float fDisplayWidth = fDisplayHeight * AspectRatio;
float fHalfInterocular = 0.5f * fInterocularDistance * stereoParameters.fStereoExaggerationFactor;
float fHalfPixelWidth = fDisplayWidth / stereoParameters.fPixelResolutionWidth * 0.5f;
float fHalfMaximumAcuityAngle = fMaxVisualAcuityAngle * 0.5f * stereoParameters.fStereoExaggerationFactor;
// float fHalfWidth = fDisplayWidth * 0.5f;
float fMaxSeparationAcuityAngle = atanf(fHalfInterocular / fMaxStereoDistance);
float fMaxSeparationDistance = fHalfPixelWidth / tanf(fMaxSeparationAcuityAngle);
float fRefinedMaxStereoDistance = fMaxStereoDistance - fMaxSeparationDistance;
float fFovHalfAngle = FovAngleY / 2.0f;
bool ComfortableResult = true;
if (fRefinedMaxStereoDistance < 0.0f || fMaxSeparationDistance > 0.1f * fMaxStereoDistance)
{
// Pixel resolution is too low to offer a comfortable stereo experience
ComfortableResult = false;
}
float fRefinedMaxSeparationAcuityAngle = atanf(fHalfInterocular / (fRefinedMaxStereoDistance));
float fPhysicalZNearDistance = fHalfInterocular / tanf(fHalfMaximumAcuityAngle);
// float fScalingFactor = fHalfMaximumAcuityAngle / atanf(fHalfInterocular / stereoParameters.fViewerDistanceInches);
float fNearZSeparation = tanf(fRefinedMaxSeparationAcuityAngle) * (fRefinedMaxStereoDistance - fPhysicalZNearDistance);
// float fNearZSeparation2 = fHalfInterocular * (fRefinedMaxStereoDistance - fPhysicalZNearDistance) / fRefinedMaxStereoDistance;
(*zNearHeight) = cosf(fFovHalfAngle) / sinf(fFovHalfAngle);
(*zNearWidth) = (*zNearHeight) / AspectRatio;
(*fVirtualProjection) = (fNearZSeparation * NearZ * (*zNearWidth * 4.0f)) / (2.0f * NearZ);
return ComfortableResult;
}
}
//------------------------------------------------------------------------------
void StereoCreateDefaultParameters
void DirectX::StereoCreateDefaultParameters
(
STEREO_PARAMETERS* pStereoParameters
STEREO_PARAMETERS& stereoParameters
)
{
assert( pStereoParameters != nullptr );
// Default assumption is 1920x1200 resolution, a 22" LCD monitor, and a 2' viewing distance
pStereoParameters->fViewerDistanceInches = 24.0f;
pStereoParameters->fPixelResolutionWidth = 1920.0f;
pStereoParameters->fPixelResolutionHeight = 1200.0f;
pStereoParameters->fDisplaySizeInches = 22.0f;
stereoParameters.fViewerDistanceInches = 24.0f;
stereoParameters.fPixelResolutionWidth = 1920.0f;
stereoParameters.fPixelResolutionHeight = 1200.0f;
stereoParameters.fDisplaySizeInches = 22.0f;
pStereoParameters->fStereoSeparationFactor = 1.0f;
pStereoParameters->fStereoExaggerationFactor = 1.0f;
stereoParameters.fStereoSeparationFactor = 1.0f;
stereoParameters.fStereoExaggerationFactor = 1.0f;
}
//------------------------------------------------------------------------------
static inline bool StereoProjectionHelper
XMMATRIX DirectX::StereoProjectionFovLH
(
const STEREO_PARAMETERS* pStereoParameters,
_Out_ float* fVirtualProjection,
_Out_ float* zNearWidth,
_Out_ float* zNearHeight,
float FovAngleY,
float AspectHByW,
float NearZ
)
{
// note that most people have difficulty fusing images into 3D
// if the separation equals even just the human average. by
// reducing the separation (interocular distance) by 1/2, we
// guarantee a larger subset of people will see full 3D
// the conservative setting should always be used. the only problem
// with the conservative setting is that the 3D effect will be less
// impressive on smaller screens (which makes sense, since your eye
// cannot be tricked as easily based on the smaller fov). to simulate
// the effect of a larger screen, use the liberal settings (debug only)
// Conservative Settings: * max acuity angle: 0.8f degrees * interoc distance: 1.25 inches
// Liberal Settings: * max acuity angle: 1.6f degrees * interoc distance: 2.5f inches
// maximum visual accuity angle allowed is 3.2 degrees for
// a physical scene, and 1.6 degrees for a virtual one.
// thus we cannot allow an object to appear any closer to
// the viewer than 1.6 degrees (divided by two for most
// half-angle calculations)
static const float fMaxStereoDistance = 780; // inches (should be between 10 and 20m)
static const float fMaxVisualAcuityAngle = 1.6f * ( XM_PI / 180.0f ); // radians
static const float fInterocularDistance = 1.25f; // inches
bool ComfortableResult = true;
float fDisplayHeight, fDisplayWidth, fHalfInterocular, fHalfPixelWidth, fHalfMaximumAcuityAngle, fHalfWidth;
float fMaxSeparationAcuityAngle, fMaxSeparationDistance, fRefinedMaxStereoDistance, fFovHalfAngle;
float fRefinedMaxSeparationAcuityAngle, fPhysicalZNearDistance, fScalingFactor, fNearZSeparation, fNearZSeparation2;
fDisplayHeight = pStereoParameters->fDisplaySizeInches / sqrtf( AspectHByW * AspectHByW + 1.0f );
fDisplayWidth = fDisplayHeight * AspectHByW;
fHalfInterocular = 0.5f * fInterocularDistance * pStereoParameters->fStereoExaggerationFactor;
fHalfPixelWidth = fDisplayWidth / pStereoParameters->fPixelResolutionWidth * 0.5f;
fHalfMaximumAcuityAngle = fMaxVisualAcuityAngle * 0.5f * pStereoParameters->fStereoExaggerationFactor;
fHalfWidth = fDisplayWidth * 0.5f;
fMaxSeparationAcuityAngle = atanf( fHalfInterocular / fMaxStereoDistance );
fMaxSeparationDistance = fHalfPixelWidth / tanf ( fMaxSeparationAcuityAngle );
fRefinedMaxStereoDistance = fMaxStereoDistance - fMaxSeparationDistance;
fFovHalfAngle = FovAngleY / 2.0f;
if ( fRefinedMaxStereoDistance < 0.0f || fMaxSeparationDistance > 0.1f * fMaxStereoDistance )
{
// Pixel resolution is too low to offer a comfortable stereo experience
ComfortableResult = false;
}
fRefinedMaxSeparationAcuityAngle = atanf( fHalfInterocular / ( fRefinedMaxStereoDistance ) );
fPhysicalZNearDistance = fHalfInterocular / tanf( fHalfMaximumAcuityAngle );
fScalingFactor = fHalfMaximumAcuityAngle / atanf( fHalfInterocular / pStereoParameters->fViewerDistanceInches );
fNearZSeparation = tanf( fRefinedMaxSeparationAcuityAngle ) * ( fRefinedMaxStereoDistance - fPhysicalZNearDistance );
fNearZSeparation2 = fHalfInterocular * ( fRefinedMaxStereoDistance - fPhysicalZNearDistance ) / fRefinedMaxStereoDistance;
(*zNearHeight) = cosf( fFovHalfAngle ) / sinf( fFovHalfAngle );
(*zNearWidth) = (*zNearHeight) / AspectHByW;
(*fVirtualProjection) = ( fNearZSeparation * NearZ * (*zNearWidth * 4.0f) ) / ( 2.0f * NearZ );
return ComfortableResult;
}
//------------------------------------------------------------------------------
XMMATRIX StereoProjectionFovLH
(
const STEREO_PARAMETERS* pStereoParameters,
_In_opt_ const STEREO_PARAMETERS* pStereoParameters,
STEREO_CHANNEL Channel,
float FovAngleY,
float AspectHByW,
float AspectRatio,
float NearZ,
float FarZ,
STEREO_MODE StereoMode
)
{
float fVirtualProjection = 0.0f;
float zNearWidth = 0.0f;
float zNearHeight = 0.0f;
float fInvertedAngle;
XMMATRIX patchedProjection, proj;
STEREO_PARAMETERS DefaultParameters;
assert( Channel == STEREO_CHANNEL_LEFT || Channel == STEREO_CHANNEL_RIGHT );
assert( StereoMode == STEREO_MODE_NORMAL || StereoMode == STEREO_MODE_INVERTED );
assert(Channel == STEREO_CHANNEL_LEFT || Channel == STEREO_CHANNEL_RIGHT);
assert(StereoMode == STEREO_MODE_NORMAL || StereoMode == STEREO_MODE_INVERTED);
assert(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f));
assert(!XMScalarNearEqual(AspectHByW, 0.0f, 0.00001f));
assert(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f));
assert(!XMScalarNearEqual(FarZ, NearZ, 0.00001f));
proj = XMMatrixIdentity();
if( pStereoParameters == nullptr )
STEREO_PARAMETERS DefaultParameters = {};
if (pStereoParameters == nullptr)
{
StereoCreateDefaultParameters( &DefaultParameters );
StereoCreateDefaultParameters(DefaultParameters);
pStereoParameters = &DefaultParameters;
}
assert( pStereoParameters->fStereoSeparationFactor >= 0.0f && pStereoParameters->fStereoSeparationFactor <= 1.0f );
assert( pStereoParameters->fStereoExaggerationFactor >= 1.0f && pStereoParameters->fStereoExaggerationFactor <= 2.0f );
assert(pStereoParameters->fStereoSeparationFactor >= 0.0f && pStereoParameters->fStereoSeparationFactor <= 1.0f);
assert(pStereoParameters->fStereoExaggerationFactor >= 1.0f && pStereoParameters->fStereoExaggerationFactor <= 2.0f);
StereoProjectionHelper( pStereoParameters, &fVirtualProjection, &zNearWidth, &zNearHeight, FovAngleY, AspectHByW, NearZ );
float fVirtualProjection = 0.0f;
float zNearWidth = 0.0f;
float zNearHeight = 0.0f;
StereoProjectionHelper(*pStereoParameters, &fVirtualProjection, &zNearWidth, &zNearHeight, FovAngleY, AspectRatio, NearZ);
fVirtualProjection *= pStereoParameters->fStereoSeparationFactor; // incorporate developer defined bias
@ -152,40 +142,37 @@ XMMATRIX StereoProjectionFovLH
// By applying a translation, we are forcing our cameras to be parallel
//
fInvertedAngle = atanf( fVirtualProjection / ( 2.0f * NearZ ) );
float fInvertedAngle = atanf(fVirtualProjection / (2.0f * NearZ));
proj = XMMatrixPerspectiveFovLH( FovAngleY, AspectHByW, NearZ, FarZ );
XMMATRIX proj = XMMatrixPerspectiveFovLH(FovAngleY, AspectRatio, NearZ, FarZ);
if ( Channel == STEREO_CHANNEL_LEFT )
XMMATRIX patchedProjection;
if (Channel == STEREO_CHANNEL_LEFT)
{
if ( StereoMode > STEREO_MODE_NORMAL )
if (StereoMode > STEREO_MODE_NORMAL)
{
XMMATRIX rots, trans;
rots = XMMatrixRotationY( fInvertedAngle );
trans = XMMatrixTranslation( -fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( XMMatrixMultiply( rots, trans ), proj );
XMMATRIX rots = XMMatrixRotationY(fInvertedAngle);
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
}
else
{
XMMATRIX trans;
trans = XMMatrixTranslation( -fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( trans, proj );
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(trans, proj);
}
}
else
{
if ( StereoMode > STEREO_MODE_NORMAL )
{
XMMATRIX rots, trans;
rots = XMMatrixRotationY( -fInvertedAngle );
trans = XMMatrixTranslation( fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( XMMatrixMultiply( rots, trans), proj );
if (StereoMode > STEREO_MODE_NORMAL)
{
XMMATRIX rots = XMMatrixRotationY(-fInvertedAngle);
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
}
else
{
XMMATRIX trans;
trans = XMMatrixTranslation( fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( trans, proj );
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(trans, proj);
}
}
@ -194,42 +181,37 @@ XMMATRIX StereoProjectionFovLH
//------------------------------------------------------------------------------
XMMATRIX StereoProjectionFovRH
XMMATRIX DirectX::StereoProjectionFovRH
(
const STEREO_PARAMETERS* pStereoParameters,
_In_opt_ const STEREO_PARAMETERS* pStereoParameters,
STEREO_CHANNEL Channel,
float FovAngleY,
float AspectHByW,
float AspectRatio,
float NearZ,
float FarZ,
STEREO_MODE StereoMode
)
{
float fVirtualProjection = 0.0f;
float zNearWidth = 0.0f;
float zNearHeight = 0.0f;
float fInvertedAngle;
XMMATRIX patchedProjection, proj;
STEREO_PARAMETERS DefaultParameters;
assert( Channel == STEREO_CHANNEL_LEFT || Channel == STEREO_CHANNEL_RIGHT );
assert( StereoMode == STEREO_MODE_NORMAL || StereoMode == STEREO_MODE_INVERTED );
assert(Channel == STEREO_CHANNEL_LEFT || Channel == STEREO_CHANNEL_RIGHT);
assert(StereoMode == STEREO_MODE_NORMAL || StereoMode == STEREO_MODE_INVERTED);
assert(!XMScalarNearEqual(FovAngleY, 0.0f, 0.00001f * 2.0f));
assert(!XMScalarNearEqual(AspectHByW, 0.0f, 0.00001f));
assert(!XMScalarNearEqual(AspectRatio, 0.0f, 0.00001f));
assert(!XMScalarNearEqual(FarZ, NearZ, 0.00001f));
proj = XMMatrixIdentity();
if( pStereoParameters == nullptr )
STEREO_PARAMETERS DefaultParameters = {};
if (pStereoParameters == nullptr)
{
StereoCreateDefaultParameters( &DefaultParameters );
StereoCreateDefaultParameters(DefaultParameters);
pStereoParameters = &DefaultParameters;
}
assert( pStereoParameters->fStereoSeparationFactor >= 0.0f && pStereoParameters->fStereoSeparationFactor <= 1.0f );
assert( pStereoParameters->fStereoExaggerationFactor >= 1.0f && pStereoParameters->fStereoExaggerationFactor <= 2.0f );
assert(pStereoParameters->fStereoSeparationFactor >= 0.0f && pStereoParameters->fStereoSeparationFactor <= 1.0f);
assert(pStereoParameters->fStereoExaggerationFactor >= 1.0f && pStereoParameters->fStereoExaggerationFactor <= 2.0f);
StereoProjectionHelper( pStereoParameters, &fVirtualProjection, &zNearWidth, &zNearHeight, FovAngleY, AspectHByW, NearZ );
float fVirtualProjection = 0.0f;
float zNearWidth = 0.0f;
float zNearHeight = 0.0f;
StereoProjectionHelper(*pStereoParameters, &fVirtualProjection, &zNearWidth, &zNearHeight, FovAngleY, AspectRatio, NearZ);
fVirtualProjection *= pStereoParameters->fStereoSeparationFactor; // incorporate developer defined bias
@ -237,44 +219,41 @@ XMMATRIX StereoProjectionFovRH
// By applying a translation, we are forcing our cameras to be parallel
//
fInvertedAngle = atanf( fVirtualProjection / ( 2.0f * NearZ ) );
float fInvertedAngle = atanf(fVirtualProjection / (2.0f * NearZ));
proj = XMMatrixPerspectiveFovRH( FovAngleY, AspectHByW, NearZ, FarZ );
XMMATRIX proj = XMMatrixPerspectiveFovRH(FovAngleY, AspectRatio, NearZ, FarZ);
//
// By applying a translation, we are forcing our cameras to be parallel
//
if ( Channel == STEREO_CHANNEL_LEFT )
XMMATRIX patchedProjection;
if (Channel == STEREO_CHANNEL_LEFT)
{
if ( StereoMode > STEREO_MODE_NORMAL )
if (StereoMode > STEREO_MODE_NORMAL)
{
XMMATRIX rots, trans;
rots = XMMatrixRotationY( fInvertedAngle );
trans = XMMatrixTranslation( -fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( XMMatrixMultiply( rots, trans ), proj );
XMMATRIX rots = XMMatrixRotationY(fInvertedAngle);
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
}
else
{
XMMATRIX trans;
trans = XMMatrixTranslation( -fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( trans, proj );
XMMATRIX trans = XMMatrixTranslation(-fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(trans, proj);
}
}
else
{
if ( StereoMode > STEREO_MODE_NORMAL )
{
XMMATRIX rots, trans;
rots = XMMatrixRotationY( -fInvertedAngle );
trans = XMMatrixTranslation( fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( XMMatrixMultiply( rots, trans), proj );
if (StereoMode > STEREO_MODE_NORMAL)
{
XMMATRIX rots = XMMatrixRotationY(-fInvertedAngle);
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(XMMatrixMultiply(rots, trans), proj);
}
else
{
XMMATRIX trans;
trans = XMMatrixTranslation( fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply( trans, proj );
XMMATRIX trans = XMMatrixTranslation(fVirtualProjection, 0, 0);
patchedProjection = XMMatrixMultiply(trans, proj);
}
}

View File

@ -9,57 +9,60 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//-------------------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma once
#endif
#include "DirectXMath.h"
// Enumeration for stereo channels (left and right).
enum STEREO_CHANNEL
namespace DirectX
{
STEREO_CHANNEL_LEFT = 0,
STEREO_CHANNEL_RIGHT
};
// Enumeration for stereo channels (left and right).
enum STEREO_CHANNEL
{
STEREO_CHANNEL_LEFT = 0,
STEREO_CHANNEL_RIGHT
};
// Enumeration for stereo mode (normal or inverted).
enum STEREO_MODE
{
STEREO_MODE_NORMAL = 0,
STEREO_MODE_INVERTED,
};
// Enumeration for stereo mode (normal or inverted).
enum STEREO_MODE
{
STEREO_MODE_NORMAL = 0,
STEREO_MODE_INVERTED,
};
//------------------------------------------------------------------------------
//
// Stereo calibration settings
//
// * Viewer distance to the display
// * Physical display size
// * Render resolution
//
// The stereo separation factor indicates how much separation is between the left and right
// eyes. 0 is no separation, 1 is full separation. It defaults to 1.0.
//
// The debug stereo exaggeration factor indicates how much to increase the interocular spacing and
// maximum acuity angle from comfortable defaults. For retail builds, this value should always
// be 1.0, but during development, on small screens, this value can be raised to up to 2.0 in
// order to exaggerate the 3D effect. Values over 1.0 may cause discomfort on normal sized
// displays. It defaults to 1.0.
//
struct STEREO_PARAMETERS
{
float fViewerDistanceInches;
float fDisplaySizeInches;
float fPixelResolutionWidth;
float fPixelResolutionHeight;
float fStereoSeparationFactor;
float fStereoExaggerationFactor;
};
//------------------------------------------------------------------------------
//
// Stereo calibration settings
//
// * Viewer distance to the display
// * Physical display size
// * Render resolution
//
// The stereo separation factor indicates how much separation is between the left and right
// eyes. 0 is no separation, 1 is full separation. It defaults to 1.0.
//
// The debug stereo exaggeration factor indicates how much to increase the interocular spacing and
// maximum acuity angle from comfortable defaults. For retail builds, this value should always
// be 1.0, but during development, on small screens, this value can be raised to up to 2.0 in
// order to exaggerate the 3D effect. Values over 1.0 may cause discomfort on normal sized
// displays. It defaults to 1.0.
//
struct STEREO_PARAMETERS
{
float fViewerDistanceInches;
float fDisplaySizeInches;
float fPixelResolutionWidth;
float fPixelResolutionHeight;
float fStereoSeparationFactor;
float fStereoExaggerationFactor;
};
void StereoCreateDefaultParameters( _Out_ STEREO_PARAMETERS* pStereoParameters );
void StereoCreateDefaultParameters(STEREO_PARAMETERS& stereoParameters);
DirectX::XMMATRIX StereoProjectionFovLH( _In_opt_ const STEREO_PARAMETERS* pStereoParameters, STEREO_CHANNEL Channel,
float FovAngleY, float AspectHByW, float NearZ, float FarZ, STEREO_MODE StereoMode );
XMMATRIX StereoProjectionFovLH(_In_opt_ const STEREO_PARAMETERS* pStereoParameters,
STEREO_CHANNEL Channel, float FovAngleY, float AspectRatio, float NearZ, float FarZ,
STEREO_MODE StereoMode = STEREO_MODE_NORMAL);
DirectX::XMMATRIX StereoProjectionFovRH( _In_opt_ const STEREO_PARAMETERS* pStereoParameters, STEREO_CHANNEL Channel,
float FovAngleY, float AspectHByW, float NearZ, float FarZ, STEREO_MODE StereoMode );
XMMATRIX StereoProjectionFovRH(_In_opt_ const STEREO_PARAMETERS* pStereoParameters,
STEREO_CHANNEL Channel, float FovAngleY, float AspectRatio, float NearZ, float FarZ,
STEREO_MODE StereoMode = STEREO_MODE_NORMAL);
}