diff --git a/RtxOptions.md b/RtxOptions.md
index 108a504f..567d2c56 100644
--- a/RtxOptions.md
+++ b/RtxOptions.md
@@ -281,7 +281,9 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
|rtx.freeCam.keyPitchUp|unknown type|unknown type|Pitch up in free camera mode\.
Example override: 'rtx\.rtx\.freeCam\.keyPitchUp = P'|
|rtx.freeCam.keyYawLeft|unknown type|unknown type|Yaw left in free camera mode\.
Example override: 'rtx\.rtx\.freeCam\.keyYawLeft = P'|
|rtx.freeCam.keyYawRight|unknown type|unknown type|Yaw right in free camera mode\.
Example override: 'rtx\.rtx\.freeCam\.keyYawRight = P'|
+|rtx.freeCameraInvertY|bool|False|Invert free camera pitch direction\.|
|rtx.freeCameraSpeed|float|200|Free camera speed \[GameUnits/s\]\.|
+|rtx.freeCameraTurningSpeed|float|1|Free camera turning speed \(applies to keyboard, not mouse\) \[radians/s\]\.|
|rtx.froxelDepthSliceDistributionExponent|float|2|The exponent to use on depth values to nonlinearly distribute froxels away from the camera\. Higher values bias more froxels closer to the camera with 1 being linear\.|
|rtx.froxelDepthSlices|int|48|The z dimension of the froxel grid\. Must be constant after initialization\.|
|rtx.froxelFilterGaussianSigma|float|1.2|The sigma value of the gaussian function used to filter volumetric radiance values\. Larger values cause a smoother filter to be used\.|
diff --git a/src/dxvk/rtx_render/rtx_camera.cpp b/src/dxvk/rtx_render/rtx_camera.cpp
index e0d4d5ac..5c0b2a12 100644
--- a/src/dxvk/rtx_render/rtx_camera.cpp
+++ b/src/dxvk/rtx_render/rtx_camera.cpp
@@ -398,9 +398,11 @@ namespace dxvk
float coordSystemScale = m_context.isLHS ? -1.f : 1.f;
+ float pitchDirection = freeCameraInvertY() ? -1.f : 1.f;
+
if (isKeyAvailable) {
float speed = elapsedSec.count() * RtxOptions::Get()->getSceneScale() * freeCameraSpeed();
- float angularSpeed = elapsedSec.count() * M_PI;
+ float angularSpeed = elapsedSec.count() * M_PI * freeCameraTurningSpeed();
// Speed booster
if (dxvk::ImGUI::checkHotkeyState(RtxOptions::FreeCam::keyMoveFaster(), true)) {
speed *= 4;
@@ -424,16 +426,16 @@ namespace dxvk
moveDownUp -= speed;
}
if (dxvk::ImGUI::checkHotkeyState(RtxOptions::FreeCam::keyPitchDown(), true)) {
- freeCameraPitchRef() -= angularSpeed;
+ freeCameraPitchRef() += coordSystemScale * pitchDirection * angularSpeed;
}
if (dxvk::ImGUI::checkHotkeyState(RtxOptions::FreeCam::keyPitchUp(), true)) {
- freeCameraPitchRef() += angularSpeed;
+ freeCameraPitchRef() -= coordSystemScale * pitchDirection * angularSpeed;
}
if (dxvk::ImGUI::checkHotkeyState(RtxOptions::FreeCam::keyYawLeft(), true)) {
- freeCameraYawRef() += angularSpeed;
+ freeCameraYawRef() +=coordSystemScale * angularSpeed;
}
if (dxvk::ImGUI::checkHotkeyState(RtxOptions::FreeCam::keyYawRight(), true)) {
- freeCameraYawRef() -= angularSpeed;
+ freeCameraYawRef() -= coordSystemScale * angularSpeed;
}
}
@@ -443,7 +445,7 @@ namespace dxvk
if (GetCursorPos(&p)) {
if (!lockFreeCamera() && ImGui::IsMouseDown(ImGuiMouseButton_Left) && ((m_mouseX != p.x) || (m_mouseY != p.y))) {
freeCameraYawRef() += coordSystemScale * (m_mouseX - p.x) * 0.1f * elapsedSec.count();
- freeCameraPitchRef() += coordSystemScale * (m_mouseY - p.y) * 0.2f * elapsedSec.count();
+ freeCameraPitchRef() += coordSystemScale * pitchDirection * (m_mouseY - p.y) * 0.2f * elapsedSec.count();
}
m_mouseX = p.x;
@@ -878,8 +880,24 @@ namespace dxvk
ImGui::DragFloat("Yaw", &freeCameraYawObject(), 0.1f, -Pi(2), Pi(2), "%.3f", sliderFlags);
ImGui::DragFloat("Pitch", &freeCameraPitchObject(), 0.1f, -Pi(2), Pi(2), "%.3f", sliderFlags);
ImGui::DragFloat("Speed", &freeCameraSpeedObject(), 0.1f, 0.f, 5000.0f, "%.3f");
+ ImGui::DragFloat("Turning Speed", &freeCameraTurningSpeedObject(), 0.01f, 0.f, 3.0f, "%.3f");
+ ImGui::Checkbox("Invert Y", &freeCameraInvertYObject());
ImGui::Checkbox("View Relative", &freeCameraViewRelativeObject());
+ if (ImGui::CollapsingHeader("Show Camera Controls", collapsingHeaderClosedFlags)) {
+ ImGui::Text("MoveFaster:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveFaster()));
+ ImGui::Text("MoveForward:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveForward()));
+ ImGui::Text("MoveLeft:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveLeft()));
+ ImGui::Text("MoveBack:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveBack()));
+ ImGui::Text("MoveRight:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveRight()));
+ ImGui::Text("MoveUp:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveUp()));
+ ImGui::Text("MoveDown:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyMoveDown()));
+ ImGui::Text("PitchDown:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyPitchDown()));
+ ImGui::Text("PitchUp:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyPitchUp()));
+ ImGui::Text("YawLeft:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyYawLeft()));
+ ImGui::Text("YawRight:"); ImGui::SameLine(150); ImGui::Text("%s", buildKeyBindDescriptorString(RtxOptions::FreeCam::keyYawRight()));
+ }
+
ImGui::Unindent();
}
}
diff --git a/src/dxvk/rtx_render/rtx_camera.h b/src/dxvk/rtx_render/rtx_camera.h
index cc3c0221..77b96f9a 100644
--- a/src/dxvk/rtx_render/rtx_camera.h
+++ b/src/dxvk/rtx_render/rtx_camera.h
@@ -112,6 +112,8 @@ namespace dxvk
RW_RTX_OPTION("rtx.camera", bool, lockFreeCamera, false, "Locks free camera.");
RW_RTX_OPTION("rtx.camera", bool, freeCameraViewRelative, true, "Free camera transform is relative to the view.");
RW_RTX_OPTION("rtx", float, freeCameraSpeed, 200, "Free camera speed [GameUnits/s].");
+ RW_RTX_OPTION("rtx", float, freeCameraTurningSpeed, 1, "Free camera turning speed (applies to keyboard, not mouse) [radians/s].");
+ RW_RTX_OPTION("rtx", bool, freeCameraInvertY, false, "Invert free camera pitch direction.");
long m_mouseX = 0, m_mouseY = 0;
uint32_t m_renderResolution[2] = { 0, 0 };