Suggestion: Apply lens offset only in warp shader
The idea here is to apply the lens offset just in the warp shader rather than modifying the projection matrix to have an off-center projection. Since the lens offset just shifts the image around anyway, the warp shader can be easily modified to do the shifting and warping simultaneously by just sampling differently from the input (unwarped) texture.
The main benefit is that then you can leave the camera projection matrices as standard projections, which can be really convenient if you're using an engine that doesn't easily allow direct manipulation of the camera projection matrices. As a secondary benefit, the documentation also gets simpler. (Edit: Also, carelessly modifying the projection matrix can break a lot of things, including view frustum culling and potentially some screen-space effects).
The only real downside is that debugging gets a bit harder, because you can't view the unwarped images in the rift (because they no longer have the critical lens offset). And theoretically you're wasting some screen area because you're rendering too much towards your nose and not enough in your periphery, but I can't see that far out anyway so that screen region is wasted for me no matter what.
Using the GLSL shader from the other thread, the modified shader looks like this (we only need to change LensCenter to ScreenCenter in one line):
The main benefit is that then you can leave the camera projection matrices as standard projections, which can be really convenient if you're using an engine that doesn't easily allow direct manipulation of the camera projection matrices. As a secondary benefit, the documentation also gets simpler. (Edit: Also, carelessly modifying the projection matrix can break a lot of things, including view frustum culling and potentially some screen-space effects).
The only real downside is that debugging gets a bit harder, because you can't view the unwarped images in the rift (because they no longer have the critical lens offset). And theoretically you're wasting some screen area because you're rendering too much towards your nose and not enough in your periphery, but I can't see that far out anyway so that screen region is wasted for me no matter what.
Using the GLSL shader from the other thread, the modified shader looks like this (we only need to change LensCenter to ScreenCenter in one line):
void main()
{
vec2 uv = texCoords.xy;
vec2 theta = (uv - LensCenter.xy) * ScaleIn.xy;
float rSq = theta.x * theta.x + theta.y * theta.y;
vec2 rvector = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq +
HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);
// Note: In the unmodified shader this is LensCenter.xy + Scale.xy * rvector
// Since we do not shift the projection center in the projection matrix, we use the
// screen center instead
vec2 tc = (ScreenCenter.xy + Scale.xy * rvector);
//*** Adjust 0.5,0.5 according to how you render
if (any(bvec2(clamp(tc, ScreenCenter.xy-vec2(0.50,0.5), ScreenCenter.xy+vec2(0.50,0.5))-tc)))
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
else
gl_FragColor = texture2D(albedoMap, tc);
}
