I have a component which renders a few different cameras and the images. However, this obscures my UI when in Screen Space - Overlay
mode.
I can put the canvas in WorldSpace
mode, which works, but then the UI is affected by the image effect I've built and is, of course, not locked to the camera.
Suggestions?
Update - additional details
At design time, the OVR camera rig contains a single camera centered between the "eyes." This component is attached to the camera rig's centerEyeAnchor
.
At run time, the rig creates two additional cameras - one for each eye. These aren't supposed to be modified by user code. (Among other things, their projection matrices are pretty weird.)
I need to modify the image per eye.
I created a new component which create two additional cameras per eye. One renders a low-res version of the entire scene, the other renders a high-res image of a portion of the screen, each to a dedicated RenderTexture
.
Pseudocode:
void Update()
{
/// called once per frame
}
/// called twice per frame - once per eye
void OnPreRender()
{
}
/// called twice per frame - once per eye
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
/// low-res render of entire scene
var camOuter = m_cameras[...];
/// hi-res render of part of the scene - 10-20% of original image area
var camInner = m_cameras[...];
/// update cameras to match current eye camera
camOuter.copyFrom(Camera.current);
camOuter.targetTexture = m_outerTexture;
/// render scene to low-res texture
camOuter.Render();
camInner.copyFrom(Camera.current);
camInner.targetTexture = m_innerTexture;
/// target texture that the Oculus wants to render to
var ovrTexture = Camera.current.targetTexture;
/// save projection matrix
var originalProjectionMatrix = camInner.projectionMatrix;
var scale = new Vector3(m_innerTexture.width * 1.0f / ovrTexture.width, m_innerTexture.height * 1.0f / ovrTexture.height);
/// zoom/pan matrix to clip to part of the scene
var gazeMatrix = Matrix4x4.Scale(scale);
/// offset projection
gazeMatrix.m03 += (1 - 2 * gaze.x) * scale.x;
gazeMatrix.m13 += (1 - 2 * gaze.y) * scale.y;
camOuter.projectionMatrix = gazeMatrix & originalPRojectionMatrix;
/// render hi-res portion of the scene centered at gaze pixel
camOuter.Render();
/// restore projection matrix
cam.projectionMatrix = originalProjectionMatrix;
/// composite images
m_material.SetTexture("InnerTexture", m_innerTexture);
m_material.SetTexture("OuterTexture", m_outerTexture);
Graphics.Blit(null, destination, m_material);
}
(I'm also worried that there may be additional scene renders happening in the background.)
The problem is that the UI does not render if set to Screenspace - Overlay
or Screenspace - Camera
. I can get it to render in Worldspace
, which may be the only way to do this, but then it seems I'd need to create yet another hi-res texture matching the viewport dimensions and render the UI layer to that, and keep it locked to the current eye's camera position. Alternatively, I could re-use one of the current cameras, I guess, and just tweak its settings.
Is there a better way to do this?
Ideally, I'd like to have the engine just render the UI as it does in other applications without having to jump through hoops. However, at this point, I'll take anything I can get that works and looks good.
Update the 2nd
Okay, it looks like the UI is rendered perfectly if I use a regular camera instead of the OVR rig. :( Having the rig in the scene, though, prevents it from drawing at all.
Depth
property of your cameras. Camera that renders UI should have the highest depth to render on top of other cameras. – Exerion Sep 22 '15 at 6:27RenderTexture
or another technology? What about UI, how it looks, wich camera renders it, what about the properties? Also, what kind of scripts are attached to cameras? Etc. You need to provide more full, complex information and add it to your question, so everyone can see it. – Exerion Sep 22 '15 at 14:19tl;dr
would seem an appropriate response at this point.) – David Lively Sep 22 '15 at 15:49