Same here, no depth rendering on M3 Pro. I asked claude to diagnose and fix it. It seems mac specific. With the fix it renders correctly:
It should open a PR on the repo shortly.
Diagnosis: reading a VTK shader variable that no longer exists
I drove your running Slicer over the MCP server on localhost:2026, reproduced the thread’s exact steps (Mitral sample → Echo Volume Render), and instrumented the GLSL. It is not a Mac driver bug in the general sense — it’s a real bug in SlicerHeart that only manifests on your driver.
Environment: Slicer 5.12.3 (rev 34627), macOS 26.6.1, Apple M3 Pro, OpenGL 4.1 Metal, VTK 9.6.2.
Root cause
EchoVolumeRender.py:659 computes the camera position for the depth ramp from a shader global:
vec3 camInTexCoord = (ip_inverseTextureDataAdjusted * vec4(g_eyePosObj.xyz,1.0)).xyz;
g_eyePosObj was assigned by VTK’s ray-cast shader up to VTK 9.2:
g_eyePosObj = in_inverseVolumeMatrix[0] * vec4(in_cameraPos, 1.0); // vtkVolumeShaderComposer.h, v9.2.6:435
VTK 9.3 deleted that assignment and replaced it with the uniform in_eyePosObjs[]. The bare declaration vec4 g_eyePosObj; still sits in raycasterfs.glsl:32, so the shader compiles cleanly — it just reads an uninitialized variable. I dumped the linked fragment shader from your GPU to confirm: g_eyePosObj appears exactly twice, the declaration and SlicerHeart’s read. It is never written.
Evidence from your GPU
Rendering dist (the near↔far interpolation ratio) directly as greyscale, over the volume region:
| eye-position expression |
dist @00° (mean, std) |
dist@90@90° |
g_eyePosObj (shipped) |
0.0, 0.0 |
0.0, 0.0 |
vec3(0.0) (what a zero-init driver gives) |
61.9, 102.6 |
47.6, 84.3 |
in_eyePosObjs[0] (correct) |
49.8, 82.3 |
40.1, 71.7 |
dist collapses to exactly 0 everywhere, so mix(rgbNear, rgbFar, 0) returns rgbNear for every voxel. That is precisely the reported symptom: the Depth coloring slider still moves hueNear, so the whole volume shifts hue uniformly, and no other slider does anything visible.
Hue statistics confirm the shipped shader is completely camera-independent, while the fixed one tracks the camera:
| camera azimuth |
shipped (hue mean, std) |
fixed |
| 0° |
0.577, 0.059 |
−0.181, 0.193 |
| 45° |
0.581, 0.056 |
−0.111, 0.209 |
| 90° |
0.579, 0.060 |
−0.042, 0.260 |
| 135° |
0.580, 0.057 |
−0.092, 0.245 |
Visual comparison written to /tmp/echo_depth_comparison.png — top row shipped (0°, 90°), bottom row fixed:
The fix produces exactly the tutorial appearance: near structures warm/tan, far structures blue, and the ramp rotates with the view.
Why Mike couldn’t reproduce it on Windows
Reading an uninitialized GLSL global is undefined behavior. NVIDIA/Windows drivers zero-initialize, so g_eyePosObj reads as (0,0,0,0) and camInTexCoord becomes a fixed point near the world origin — which still yields a plausible-looking gradient (row 2 of the table above), so it looks like it works. It’s actually anchored to the world origin rather than the camera, i.e. a latent bug there too. Apple’s compiler leaves the register with garbage far outside the volume, dist clamps to 0, and the effect vanishes entirely. Any Mac vs. Windows split here is a coin flip on driver behavior, not a designed difference.
Fix
Three lines in EchoVolumeRender.__init__, patch at /private/tmp/claude-1950572333/-Users-amaga/74cd5809-e665-448d-b0fd-43749d08a8fd/scratchpad/echovolumerender-depth-coloring.patch:
if vtkVersion >= 903:
self.computeColorReplacement = self.computeColorReplacement.replace(
"g_eyePosObj.xyz", "in_eyePosObjs[0].xyz")
in_eyePosObjs[i] is the eye position in dataset space (vtkOpenGLGPUVolumeRayCastMapper.cxx:3519) — the same space the old g_eyePosObj held, so it’s a drop-in. VTK ≤ 9.2 keeps the old path. SlicerHeart master still has the bug at line 659, and I found no existing issue for it.
Two notes:
- I left the fixed shader active in your running Slicer session only — the installed module file is untouched, so it reverts on restart.
- Separately, your log shows
vtkOpenGLVolumeOpacityTable: does not support the required texture size of 262144, falling back to 16384. That’s macOS’s max texture size and is unrelated to this — worth knowing but not the cause.