RobertBeckebans / RBDOOM-3-BFG

Doom 3 BFG Edition source port with updated DX12 / Vulkan renderer and modern game engine features
https://www.moddb.com/mods/rbdoom-3-bfg
GNU General Public License v3.0
1.37k stars 244 forks source link

Fast Stereo Rendering for VR #877

Open RobertBeckebans opened 3 weeks ago

RobertBeckebans commented 3 weeks ago

From https://docs.google.com/presentation/d/19x9XDjUvkW_9gsfsMQzt3hZbRNziVsoCEHOn4AercAc/edit#slide=id.g5791d9ed1_015

  1. Use a combined stereo rendertarget with has the size for both eyes. If the res is 2160x2160 it would be 4320x2160.
  2. Form a combined frustum of both eye frustums for culling in the renderer frontend
  3. Only emit 1 3D view and iterate it only once
  4. Use instancing for each drawcall and use InstanceID to offset it between the left or the right eye "fake" stereo rendertarget
  5. Use Shader clipping instead of the Scissor mechanism to avoid leaking meshes into the other eye rendertarget

This probably needs a rewrite of all vertex shaders but it's worth the effort.

Pseudocode:

Matrix WorldToEyeClipMatrix[2] // computed from SDK
Vector4 EyeClipEdge[2]={(-1,0,0,1), (1,0,0,1)}
float EyeOffsetScale[2]={0.5,-0.5}

uint eyeIndex = instanceID & 1   // use low bit as eye index.

Vector4 clipPos = worldPos * WorldToEyeClipMatrix[eyeIndex]
cullDistanceOut.x = clipDistanceOut.x = clipPos · EyeClipEdge[eyeIndex]

clipPos.x *= 0.5; // shrink to half of the screen
clipPos.x += EyeOffsetScale[eyeIndex] * clipPos.w; // scoot left or right.
clipPositionOut = clipPos