cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Model Silhouette is wrong when silhouette alpha is not 1

Open jjspace opened this issue 1 year ago • 3 comments

What happened?

Reported on the forum: https://community.cesium.com/t/behavior-of-entity-model-silhouette-color-options-with-alpha/37082

It seems this may have started happening in version 1.121

https://github.com/user-attachments/assets/d2df426e-ec4e-4637-98e3-4e0ef25d2a9c

It looks like something about the model is not getting translated correctly when it's rotated while processing the silhouette color. Could this be related to https://github.com/CesiumGS/cesium/issues/11067?

Reproduction steps

  1. Load the 3D Models Coloring sandcastle
  2. Set the model color to white to avoid confusing the colors
  3. Change the Silhouette alpha to anything lower than 1

Sandcastle example

No response

Environment

Browser: Chrome CesiumJS Version: 1.124 Operating System: Linux

jjspace avatar Dec 05 '24 20:12 jjspace

Given the post processing depth buffer ties, perhaps https://github.com/CesiumGS/cesium/issues/7705 is related?

ggetz avatar Dec 06 '24 14:12 ggetz

Hello. I am the original author of this issue's community post. I would like to share a few discoveries I've made since posting.

1. Disabling MSAA temporarily resolves this issue. Sandcastle

2. When MSAA is enabled, it appears that two silhouette rendering commands are executed in different render passes (OPAQUE and TRANSLUCENT).

Pass 1: Silhouette Model Command [ModelDrawCommand.js]

function deriveSilhouetteModelCommand(command, model) {
  const stencilReference = model._silhouetteId % 255;
  const silhouetteModelCommand = DrawCommand.shallowClone(command);
  const renderState = clone(command.renderState, true);

  renderState.stencilTest = {
    enabled: true,
    frontFunction: WebGLConstants.ALWAYS,
    reference: stencilReference,
    ...
  };
  // ...
}

Pass 2: Silhouette Color Command [ModelDrawCommand.js]

function deriveSilhouetteColorCommand(command, model) {
  const stencilReference = model._silhouetteId % 255;
  const silhouetteColorCommand = DrawCommand.shallowClone(command);
  const renderState = clone(command.renderState, true);

  const silhouetteTranslucent =
    command.pass === Pass.TRANSLUCENT || model.silhouetteColor.alpha < 1.0;
  if (silhouetteTranslucent) {
    silhouetteColorCommand.pass = Pass.TRANSLUCENT;
    renderState.depthMask = false;
    renderState.blending = BlendingState.ALPHA_BLEND;
  }

  renderState.stencilTest = {
    enabled: true,
    frontFunction: WebGLConstants.NOTEQUAL,
    reference: stencilReference,
    ...
  };
}

3. Issue guessing

When alpha = 1.0 (Working Correctly):

  1. silhouetteModelCommand.pass = Pass.OPAQUE
  2. silhouetteColorCommand.pass = Pass.OPAQUE (no reassignment)
  3. Both commands execute in the same pass
  4. Stencil buffer state is consistent within the pass
  5. Silhouette renders correctly

When alpha < 1.0 (Broken):

  1. silhouetteModelCommand.pass = Pass.OPAQUE

    • Writes stencil to MSAA multisampled renderbuffer
    • Stencil reference (e.g., 5) written where model is visible
  2. silhouetteColorCommand.pass = Pass.TRANSLUCENT

    • Reads from MSAA stencil buffer
    • Tests stencil != 5 (NOTEQUAL)
    • In MSAA environment with commands in different passes, stencil state is not properly preserved
    • Stencil appears to be 0 or corrupted
    • NOTEQUAL test passes everywhere (0 != 5 is true)
    • Result: Silhouette renders over entire model, not just outline

I considered save texture (maybe blitStencil() do that?) after the OPAQUE pass to share it with the TRANSLUCENT pass, but I'm still unfamiliar with Graphics, so i haven't tested yet.

Leafmire avatar Oct 27 '25 09:10 Leafmire

The video from the first post here looks different from what I've seen. But the screenshot in the linked forum post looks more like what I reported in https://github.com/CesiumGS/cesium/issues/13074 , so this is now closed as a duplicate, assuming that it will be resolved with whatever change will fix this one as well.

javagl avatar Dec 05 '25 19:12 javagl