Skip to content

WebGL: pick and depth shaders ignore bumpy_flatmap and use the pre-flatmap displacement #704

Description

@mvdoc

The pick and depth shaders in cortex/webgl/resources/js/shaderlib.js hardcode the old thickness-based cortical-sheet displacement and know nothing about bumpyflat, so the geometry they test against drifts away from the geometry that is actually rendered.

What is inconsistent

surface_pixel and surface_vertex both do this:

"#ifdef CORTSHEET",
    "#ifdef HASFLAT",
        "pos += clamp(surfmix*2., 0., 1.) * normalize(norm) * mix(1., 0., use_thickmix) * flatheight * f_bumpyflat;",
    "#else",
        "pos += clamp(surfmix*2., 0., 1.) * normalize(norm) * .62 * distance(position, wm.xyz) * mix(1., 0., use_thickmix);",
    "#endif",
"#endif",

pick and depth only ever do the #else branch — there is no HASFLAT define and no bumpyflat uniform in either. So whenever the subject has a flatmap (HASFLAT defined, i.e. essentially every real subject), the two disagree:

bumpy_flatmap rendered surface pick / depth
on flatheight bump .62 * thickness
off no displacement at all .62 * thickness

pick backs the click-to-select-a-vertex picker (facepick.js:51); depth backs the occlusion test that hides ROI labels and paths behind the surface (svgoverlay.js:42).

Measured impact

Measured on S1 by projecting both the rendered and the pick-shader vertex positions through the live camera matrices, 1800x1400 drawing buffer, depth slider at its 0.5 default, ~4.1k sampled vertices:

  • Bumpy flatmap on, viewed head-on: mean 0.20 px, max 1.59 px. Negligible — the bump displaces along the surface normal, which points nearly at the camera in this view, so almost all of it is lost to the projection. Expect this to grow as the flatmap is tilted.
  • Inflated surface (unfold 0.5), bumpy flatmap off: mean 3.08 px, max 7.89 px, with 51% of sampled vertices off by more than 3 px. This is the worse case, and it is not about bumpy flatmaps at all — it is the f_bumpyflat = 0 row of the table above, where the surface renders undisplaced but the picker still pushes vertices 0.62 * thickness along their normals.

So the practical symptom is picking that is a few pixels off on inflated/partially-unfolded surfaces, worst near silhouette edges where the normal is perpendicular to the view direction, plus label occlusion that is judged against slightly the wrong surface.

Note on #679

This mismatch has existed for volume data ever since the HASFLAT branch was added to surface_pixel. #679 ports that branch into surface_vertex so vertex and volume data finally shade flatmaps identically — but as a side effect it propagates this same pick/depth mismatch to vertex data, which previously matched pick exactly because both used the .62 * distance formula. Making the two data paths consistent was the point; this issue is the leftover.

Suggested fix

Give pick and depth the same HASFLAT / bumpyflat treatment as the surface shaders — they need the hasflat opt threaded through from mriview_surface.js, the flatheight attribute bound, and the bumpyflat uniform declared. The displacement expression can then be shared rather than copy-pasted a fourth time, which is what let the four copies drift apart in the first place.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions