Fix for lighting as IPD scale changes.

This commit is contained in:
Anthony J. Thibault 2017-09-15 16:17:41 -07:00
parent fcf8424ec7
commit a260aaaae8
7 changed files with 40 additions and 12 deletions

View file

@ -2413,10 +2413,18 @@ void Application::paintGL() {
auto lodManager = DependencyManager::get<LODManager>();
RenderArgs renderArgs;
float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale();
{
PROFILE_RANGE(render, "/buildFrustrumAndArgs");
{
QMutexLocker viewLocker(&_viewMutex);
// adjust near clip plane to account for sensor scaling.
auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(),
_viewFrustum.getAspectRatio(),
DEFAULT_NEAR_CLIP * sensorToWorldScale,
_viewFrustum.getFarClip());
_viewFrustum.setProjection(adjustedProjection);
_viewFrustum.calculate();
}
renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(),
@ -2570,7 +2578,6 @@ void Application::paintGL() {
float ipdScale = hmdInterface->getIPDScale();
// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly.
float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale();
ipdScale *= sensorToWorldScale;
mat4 eyeProjections[2];
@ -2582,6 +2589,7 @@ void Application::paintGL() {
// in the overlay render?
// Viewport is assigned to the size of the framebuffer
renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height());
auto baseProjection = renderArgs.getViewFrustum().getProjection();
if (displayPlugin->isStereo()) {
// Stereo modes will typically have a larger projection matrix overall,
// so we ask for the 'mono' projection matrix, which for stereo and HMD
@ -2592,17 +2600,11 @@ void Application::paintGL() {
// just relying on the left FOV in each case and hoping that the
// overall culling margin of error doesn't cause popping in the
// right eye. There are FIXMEs in the relevant plugins
_myCamera.setProjection(displayPlugin->getCullingProjection(_myCamera.getProjection()));
_myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection));
renderArgs._context->enableStereo(true);
mat4 eyeOffsets[2];
mat4 eyeProjections[2];
// adjust near clip plane by sensorToWorldScale
auto baseProjection = glm::perspective(renderArgs.getViewFrustum().getFieldOfView(),
renderArgs.getViewFrustum().getAspectRatio(),
renderArgs.getViewFrustum().getNearClip() * sensorToWorldScale,
renderArgs.getViewFrustum().getFarClip());
// FIXME we probably don't need to set the projection matrix every frame,
// only when the display plugin changes (or in non-HMD modes when the user
// changes the FOV manually, which right now I don't think they can.

View file

@ -16,9 +16,6 @@
#include "Overlay.h"
// AJT: keep or remove this.
// #define USE_SN_SCALE
class Base3DOverlay : public Overlay, public SpatiallyNestable {
Q_OBJECT

View file

@ -28,7 +28,7 @@ public:
float getIPD() const override final { return _ipd; }
glm::mat4 getEyeToHeadTransform(Eye eye) const override final { return _eyeOffsets[eye]; }
glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override { return _eyeProjections[eye]; }
glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override final { return _cullingProjection; }
glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override { return _cullingProjection; }
glm::uvec2 getRecommendedUiSize() const override final;
glm::uvec2 getRecommendedRenderSize() const override final { return _renderTargetSize; }
bool isDisplayVisible() const override { return isHmdMounted(); }

View file

@ -76,6 +76,20 @@ glm::mat4 OculusBaseDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& ba
}
}
glm::mat4 OculusBaseDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const {
if (_session) {
ViewFrustum baseFrustum;
baseFrustum.setProjection(baseProjection);
float baseNearClip = baseFrustum.getNearClip();
float baseFarClip = baseFrustum.getFarClip();
auto combinedFov = _eyeFovs[0];
combinedFov.LeftTan = combinedFov.RightTan = std::max(combinedFov.LeftTan, combinedFov.RightTan);
return toGlm(ovrMatrix4f_Projection(combinedFov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_ClipRangeOpenGL));
} else {
return baseProjection;
}
}
// DLL based display plugins MUST initialize GLEW inside the DLL code.
void OculusBaseDisplayPlugin::customizeContext() {
glewExperimental = true;

View file

@ -20,6 +20,7 @@ public:
bool isSupported() const override;
glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override;
glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override;
bool hasAsyncReprojection() const override { return true; }

View file

@ -370,6 +370,19 @@ glm::mat4 OpenVrDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& basePr
}
}
glm::mat4 OpenVrDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const {
if (_system) {
ViewFrustum baseFrustum;
baseFrustum.setProjection(baseProjection);
float baseNearClip = baseFrustum.getNearClip();
float baseFarClip = baseFrustum.getFarClip();
// FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes
return toGlm(_system->GetProjectionMatrix((vr::EVREye)0, baseNearClip, baseFarClip));
} else {
return baseProjection;
}
}
float OpenVrDisplayPlugin::getTargetFrameRate() const {
if (forceInterleavedReprojection && !_asyncReprojectionActive) {
return TARGET_RATE_OpenVr / 2.0f;

View file

@ -39,6 +39,7 @@ public:
const QString getName() const override { return NAME; }
glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override;
glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override;
void init() override;