New convergence formular added.
Posted: Tue Sep 03, 2013 6:28 am
Based on explanaitons from NVidia i added new convergence functionality.
Here is the new method to update the projection matrices for both left/right eye:
(please post if you find anything dubious here)
Convergence is now specified in real, physical meters, since IPD is also specified in physical meters now.
That means, if convergence is set to 3.0f, the neutral plane is 3 meters ahead. Here is a video of Left4Dead anaglyph rendering using the new driver architecture : (In this case i did set convergence to 3.0f - 3 meters, world scale is set game-specific to 4.15f - so our view is focused to 3 meters ahead)
[youtube-hd]http://www.youtube.com/watch?v=yTQXFPwE ... e=youtu.be[/youtube-hd]
Here is the new method to update the projection matrices for both left/right eye:
(please post if you find anything dubious here)
Code: Select all
/**
* Updates left and right projection matrices.
* Now, the convergence point is specified in real, physical meters, since the IPD is also specified
* in physical meters. That means, if the game-specific world scale is set correctly, a convergence
* value of 3.0f would mean that the virtual screen, neutral point or convergence point is 3 meters
* ahead of us.
* @param aspectRation The aspect ratio for the projection matrix.
***/
void ViewAdjustment::UpdateProjectionMatrices(float aspectRatio)
{
t = 0.5f / aspectRatio;
b = -0.5f / aspectRatio;
D3DXMatrixPerspectiveOffCenterLH(&matProjection, l, r, b, t, n, f);
D3DXMatrixInverse(&matProjectionInv, 0, &matProjection);
// convergence frustum adjustment, based on NVidia explanations
//
// It is evident that the ratio of frustum shift to the near clipping plane is equal to the ratio of
// IOD/2 to the distance from the screenplane. (IOD=IPD)
// frustumAsymmetryInMeters = ((IPD/2) * nearClippingPlaneDistance) / convergence
// <http://www.orthostereo.com/geometryopengl.html>
//
// (near clipping plane distance = physical screen distance)
// (convergence = virtual screen distance)
// ALL stated in meters here !
const float nearClippingPlaneDistance = 1; // < TODO !! Assumption here : near clipping plane distance = 1 meter
float frustumAsymmetryInMeters = ((ipd/2) * nearClippingPlaneDistance) / convergence;
// divide the frustum asymmetry by the assumed physical size of the physical screen
const float physicalScreenSizeInMeters = 1; // < TODO !! Assumption here : physical screen size = 1 meter
float frustumAsymmetryLeftInMeters = (frustumAsymmetryInMeters * LEFT_CONSTANT) / physicalScreenSizeInMeters;
float frustumAsymmetryRightInMeters = (frustumAsymmetryInMeters * RIGHT_CONSTANT) / physicalScreenSizeInMeters;
// get the horizontal screen space size and compute screen space adjustment
float screenSpaceXSize = abs(l)+abs(r);
float multiplier = screenSpaceXSize/1; // = 1 meter
float frustumAsymmetryLeft = frustumAsymmetryLeftInMeters * multiplier;
float frustumAsymmetryRight = frustumAsymmetryRightInMeters * multiplier;
// now, create the re-projection matrices for both eyes using this frustum asymmetry
D3DXMatrixPerspectiveOffCenterLH(&projectLeft, l+frustumAsymmetryLeft, r+frustumAsymmetryLeft, b, t, n, f);
D3DXMatrixPerspectiveOffCenterLH(&projectRight, l+frustumAsymmetryRight, r+frustumAsymmetryRight, b, t, n, f);
}
That means, if convergence is set to 3.0f, the neutral plane is 3 meters ahead. Here is a video of Left4Dead anaglyph rendering using the new driver architecture : (In this case i did set convergence to 3.0f - 3 meters, world scale is set game-specific to 4.15f - so our view is focused to 3 meters ahead)
[youtube-hd]http://www.youtube.com/watch?v=yTQXFPwE ... e=youtu.be[/youtube-hd]