react-postprocessing icon indicating copy to clipboard operation
react-postprocessing copied to clipboard

SSAO broken with mesh that uses a custom shader with vertex displacement

Open mileshiroo opened this issue 1 year ago • 1 comments

Hello,

I'm using SSAO pass for my scene. It works great for the most part, but when I apply it to a model with vertices that are animated in a custom vertex shader, there's a sort of double image. The AO is applied to the original mesh pre-displacement in addition to the displaced mesh:

Screen Shot 2022-10-20 at 10 08 49 PM

I'm trying to get the AO to only be applied to the final, displaced mesh, and not the original as in the screenshot.

I figured out that if I replace every instance of normalPass with depthPass, the artifact goes away and the AO is rendered correctly:

const SSAO = /*#__PURE__*/forwardRef(function SSAO(props, ref) {
  const {
    camera,
    depthPass,
    downSamplingPass,
    resolutionScale
  } = useContext(EffectComposerContext);
  const effect = useMemo(() => {
    // if (normalPass === null && downSamplingPass === null) {
    //   console.error('Please enable the NormalPass in the EffectComposer in order to use SSAO.');
    //   return null;
    // }

    return new SSAOEffect(camera, depthPass && !downSamplingPass ? depthPass.texture : null, {
      blendFunction: BlendFunction.MULTIPLY,
      samples: 30,
      rings: 4,
      distanceThreshold: 1.0,
      distanceFalloff: 0.0,
      rangeThreshold: 0.5,
      rangeFalloff: 0.1,
      luminanceInfluence: 0.9,
      radius: 20,
      scale: 0.5,
      bias: 0.5,
      intensity: 1.0,
      color: null,
      // @ts-ignore
      normalDepthBuffer: downSamplingPass ? downSamplingPass.texture : null,
      resolutionScale: resolutionScale != null ? resolutionScale : 1,
      depthAwareUpsampling: true,
      ...props
    });
  }, [camera, depthPass, props]);
  return /*#__PURE__*/React.createElement("primitive", {
    ref: ref,
    object: effect,
    dispose: null
  });
});
Screen Shot 2022-10-20 at 10 24 37 PM

This is a hack and I'm not sure if the AO shader is configured to work with depthPass, I also noticed a performance drop when I switched to the depthPass, so I'm looking for a better approach.

What I don't understand is why the animated mesh doesn't get rendered properly in the NormalPass. I saw an issue about AO not working with skinned meshes, and I wonder if this could be related? I have this in my script, which was posted in another issue about SSAO, but it doesn't fix it:

OverrideMaterialManager.workaroundEnabled = true;

If anyone could point me towards a solution I'd really appreciate it.

Please let me know if I can elaborate on or clarify anything!

mileshiroo avatar Oct 21 '22 05:10 mileshiroo