Skip to content

Html does not update visibility when occlude prop changes #2702

Description

@chris-xinhai-li

Description

When using <Html occlude={...}>, changing the occlude prop at runtime does not immediately update the visibility of the Html element.

The visibility only updates after the camera moves or zoom changes.

Calling invalidate() does not help because the occlusion logic inside useFrame is only executed when certain camera or position changes occur.

Reproduction

Example usage:

const refs = // some hook 
const enableOcclusion =  // some hook

// we expect visual changes after refs changes or enableOcclusion setting changes
<Html occlude={enableOcclusion ? refs : undfined} sprite>
  ...
</Html>

When toggling enableOcclusion:

  • the occlude prop changes
  • the component re-renders
  • but the visibility state does not update

Only after moving the camera slightly does the occlusion update.

Root Cause

Inside Html.tsx, the occlusion visibility check is gated behind this condition in useFrame:

if (
  transform ||
  Math.abs(oldZoom.current - camera.zoom) > eps ||
  Math.abs(oldPosition.current[0] - vec[0]) > eps ||
  Math.abs(oldPosition.current[1] - vec[1]) > eps
)

Because of this, occlusion is only recalculated when:

  • camera zoom changes
  • projected screen position changes
  • transform is enabled

Changes to the occlude prop itself do not trigger a recalculation.

Proposed Fix

Track changes to occlude and include them in the recalculation condition.

Example minimal patch:

const prevOcclude = React.useRef<typeof occlude>(undefined)

useFrame(() => {
  const occludeChanged = prevOcclude.current !== occlude
  prevOcclude.current = occlude

  if (
    transform ||
    occludeChanged ||
    Math.abs(oldZoom.current - camera.zoom) > eps ||
    Math.abs(oldPosition.current[0] - vec[0]) > eps ||
    Math.abs(oldPosition.current[1] - vec[1]) > eps
  ) {
    // existing occlusion logic
  }
})

This ensures visibility is recalculated immediately when occlude changes.

I have opened a PR for the proposed change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions