We have this
Oculus example, but unfortunately it is a bit outdated.
The most complicated step in world-space UI is syncing the projection matrix used by your custom engine with the one needed by Noesis (IView)
/// Sets the projection matrix that transforms the coordinates of each primitive to a
/// non-normalized homogeneous space where (0, 0) is at the lower-left corner and
/// (width, height) is at the upper-right corner after projection.
/// The following table compares the clip space used by OpenGL and D3D in comparison.
/// ========= =========== ============ =========
/// System X Range Y Range Z Range
/// ========= =========== ============ =========
/// OpenGL [-1...+1] [-1...+1] [-1...+1]
/// Direct3D [-1...+1] [-1...+1] [0...1]
/// NoesisGUI [0...width] [0...height] [0...1]
/// ========= =========== ============ =========
virtual void SetProjectionMatrix(const Matrix4& projection) = 0;
If this helps, this is how we are converting from Unity camera to Noesis
private static Noesis.Matrix4 NoesisMatrix(Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, float w, float h)
{
float hw = 0.5f * w;
float hh = 0.5f * h;
Matrix4x4 noesisMatrix;
if (SystemInfo.usesReversedZBuffer)
{
noesisMatrix = new Matrix4x4
(
new UnityEngine.Vector4(hw, 0, 0, 0),
new UnityEngine.Vector4(0, -hh, 0, 0),
new UnityEngine.Vector4(0, 0, -0.5f, 0),
new UnityEngine.Vector4(hw, hh, 0.5f, 1)
);
}
else
{
noesisMatrix = new Matrix4x4
(
new UnityEngine.Vector4(hw, 0, 0, 0),
new UnityEngine.Vector4(0, -hh, 0, 0),
new UnityEngine.Vector4(0, 0, 0.5f, 0),
new UnityEngine.Vector4(hw, hh, 0.5f, 1)
);
}
Matrix4x4 _ = noesisMatrix * projectionMatrix * viewMatrix;
return new Matrix4
(
_.m00, _.m10, _.m20, _.m30,
_.m01, _.m11, _.m21, _.m31,
_.m02, _.m12, _.m22, _.m32,
_.m03, _.m13, _.m23, _.m33
);
}