Open SimonCSmith opened 6 months ago
After looking more into it, it turns out that there already is a mode in hdospray that is supposed to return the depth buffer projected along camera z in renderPass.cpp:826. It appears to be a bit off. Working on fixing this.
I believe I have fixed the issue, a deceptively simple one line fix which I'll add into the next release. Let me know if this resolves it:
diff --git a/hdOSPRay/renderPass.cpp b/hdOSPRay/renderPass.cpp
index b8e6e2f..5cef0a0 100644
--- a/hdOSPRay/renderPass.cpp
+++ b/hdOSPRay/renderPass.cpp
@@ -817,7 +817,7 @@ HdOSPRayRenderPass::_CopyFrameBuffer(
GfVec3f dir = _inverseProjMatrix.Transform(pos);
GfVec3f origin = GfVec3f(0, 0, 0);
origin = _inverseViewMatrix.Transform(origin);
- dir = -_inverseViewMatrix.Transform(dir)
+ dir = _inverseViewMatrix.TransformDir(dir)
.GetNormalized();
float& d = depth[static_cast<int>(y * w + x)];
GfVec3f hit = origin + dir * d;
screenshot of hdOSPRay (left) vs hdEmbree (right) depth buffer for visual verification. A quantitative test would be better, we can run that if you are getting odd results.
This fix does result in the depth values now reflecting the distance to the imaging plane, and match what other delegates return on the same scene.
I want to note though that the world depth values across a flat surface do vary and lead to world camera/hit distances fluctuating by around 1% in my test scene (49.81 to 50.30) which I do not see under other delegates using the same aov/calculations such as RenderMan, which gives a solid reading of 50.03 across the face.
I suspect the variance is because the conversion happens in hdOSPRay, assuming the rays go through the pixel center (which they don't for anti-aliasing). This should be solve once the projected depth to the image-plane is directly calculated by OSPRay.
The depth buffer AOV records the depth to the camera rather than what most depth aov's record, which is the depth from the image plane. I think it might be reasonable/expected that hdospray followed this convention when exposing its depth aov through hydra.
This can cause issues if you want to use the depth plane and the camera projection matrix in Hydra to get a world position from an image plane position and the depth value.
To reproduce, put a plane in front of the camera at a known distance, then check out the depth values in the AOV. They will vary across its surface rather than be constant.