Huh, the outer edge should only bring in black via async timewarp. My guess is that you’re actually seeing timewarp tearing. Which shouldn’t happen, but can occasionally if the GPU is stuck with a very time consuming draw call. If you have a single draw call with a ton of time consuming geometry in it, and this is totally counterintuitive, try breaking it up into 2 or more draw calls. That can sometimes be enough to fix any tearing issues.
I haven’t had a chance to clean it up and check it in, but here’s a change to CalculateStereoViewOffset() that should give you a basic head/neck model that matches what we were using for DK1:
if( StereoPassType != eSSP_FULL )
{
check(WorldToMeters != 0.f)
const int idx = (StereoPassType == eSSP_LEFT_EYE) ? 0 : 1;
float EyeMul = (StereoPassType == eSSP_LEFT_EYE) ? -0.5f : 0.5f;
const FVector HeadModel
FVector TotalOffset = FVector(0, InterpupillaryDistance * EyeMul, 0);
if ( 1 ) //bUseHeadModel)
{
TotalOffset += FVector(0.12f, 0.0f, 0.17f); // head/neck offset in meters
}
TotalOffset *= WorldToMeters;
ViewLocation += ViewRotation.Quaternion().RotateVector(TotalOffset);
// The HMDPosition already has HMD orientation applied.
// Apply rotational difference between HMD orientation and ViewRotation
// to HMDPosition vector.
const FVector vHMDPosition = DeltaControlOrientation.RotateVector(CurHmdPosition);
ViewLocation += vHMDPosition;
LastHmdPosition = CurHmdPosition;
}