diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 30df54352c..21fd41ea1e 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -613,6 +613,11 @@ bool StartVRRender() { if (VR_InitFrame(VR_GetEngine())) { + // VR flags + bool vrIncompatibleGame = PSP_CoreParameter().compat.vrCompat().ForceFlatScreen; + bool vrScene = !vrFlatForced && (g_Config.bManualForceVR || (vr3DGeometryCount > 15)); + bool vrStereo = !PSP_CoreParameter().compat.vrCompat().ForceMono && g_Config.bEnableStereo; + // Get OpenXR view and fov XrFovf fov = {}; XrPosef invViewTransform[2]; @@ -708,7 +713,6 @@ bool StartVRRender() { float M[16]; XrQuaternionf_ToMatrix4f(&invView.orientation, M); - memcpy(&M, M, sizeof(float) * 16); // Apply 6Dof head movement if (!flatScreen && g_Config.bEnable6DoF && !g_Config.bHeadRotationEnabled && (g_Config.iCameraPitch == 0)) { @@ -744,18 +748,20 @@ bool StartVRRender() { M[11] += side.z; } // Stereoscopy - if (matrix == VR_VIEW_MATRIX_RIGHT_EYE) { + if (vrStereo) { + bool mirrored = vrMirroring[VR_MIRRORING_AXIS_Z] ^ (matrix == VR_VIEW_MATRIX_RIGHT_EYE); float dx = fabs(invViewTransform[1].position.x - invViewTransform[0].position.x); float dy = fabs(invViewTransform[1].position.y - invViewTransform[0].position.y); float dz = fabs(invViewTransform[1].position.z - invViewTransform[0].position.z); float ipd = sqrt(dx * dx + dy * dy + dz * dz); - XrVector3f separation = {ipd * scale, 0.0f, 0.0f}; + XrVector3f separation = {ipd * scale * 0.5f, 0.0f, 0.0f}; separation = XrQuaternionf_Rotate(invView.orientation, separation); - separation = XrVector3f_ScalarMultiply(separation, vrMirroring[VR_MIRRORING_AXIS_Z] ? -1.0f : 1.0f); - M[3] -= separation.x; - M[7] -= separation.y; - M[11] -= separation.z; + separation = XrVector3f_ScalarMultiply(separation, mirrored ? -1.0f : 1.0f); + M[3] += separation.x; + M[7] += separation.y; + M[11] += separation.z; } + memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else { assert(false); @@ -763,14 +769,12 @@ bool StartVRRender() { } // Decide if the scene is 3D or not - bool vrIncompatibleGame = PSP_CoreParameter().compat.vrCompat().ForceFlatScreen; - bool vrScene = !vrFlatForced && (g_Config.bManualForceVR || (vr3DGeometryCount > 15)); VR_SetConfigFloat(VR_CONFIG_CANVAS_ASPECT, 480.0f / 272.0f); if (g_Config.bEnableVR && !vrIncompatibleGame && (appMode == VR_GAME_MODE) && vrScene) { - VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF); + VR_SetConfig(VR_CONFIG_MODE, vrStereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF); vrFlatGame = false; } else { - VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_SCREEN : VR_MODE_MONO_SCREEN); + VR_SetConfig(VR_CONFIG_MODE, vrStereo ? VR_MODE_STEREO_SCREEN : VR_MODE_MONO_SCREEN); if (IsGameVRScene()) { vrFlatGame = true; } @@ -807,7 +811,8 @@ int GetVRFBOIndex() { } int GetVRPassesCount() { - if (!IsMultiviewSupported() && g_Config.bEnableStereo) { + bool vrStereo = !PSP_CoreParameter().compat.vrCompat().ForceMono && g_Config.bEnableStereo; + if (!IsMultiviewSupported() && vrStereo) { return 2; } else { return 1; diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index c8dd83ef47..da7746cfca 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -134,6 +134,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { void Compatibility::CheckVRSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "ForceFlatScreen", &vrCompat_.ForceFlatScreen); + CheckSetting(iniFile, gameID, "ForceMono", &vrCompat_.ForceMono); CheckSetting(iniFile, gameID, "IdentityViewHack", &vrCompat_.IdentityViewHack); CheckSetting(iniFile, gameID, "Skyplane", &vrCompat_.Skyplane); CheckSetting(iniFile, gameID, "UnitsPerMeter", &vrCompat_.UnitsPerMeter); diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 9e9f0d00cb..3fdf284631 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -103,6 +103,7 @@ struct CompatFlags { }; struct VRCompat { + bool ForceMono; bool ForceFlatScreen; bool IdentityViewHack; bool Skyplane; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 13a0f33761..884fea84d4 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -565,7 +565,7 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin if (dirty & DIRTY_WORLDMATRIX) { SetMatrix4x3(render_, &u_world, gstate.worldMatrix); } - if (dirty & DIRTY_VIEWMATRIX) { + if ((dirty & DIRTY_VIEWMATRIX) || IsVREnabled()) { if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) { float leftEyeView[16]; float rightEyeView[16]; diff --git a/assets/compatvr.ini b/assets/compatvr.ini index 55c2f84291..c4154298af 100644 --- a/assets/compatvr.ini +++ b/assets/compatvr.ini @@ -60,6 +60,18 @@ ULUS10541 = true ULUS10581 = true +[ForceMono] +# Forces disabled stereo as the game rendering cannot be called twice + +# MotorStorm: Arctic Edge +NPJG00047 = true +UCAS40266 = true +UCES01250 = true +UCJS10104 = true +UCKS45124 = true +UCUS98743 = true + + [IdentityViewHack] # Disables head tracking for render passes where view matrix is Identity