Pixelation postprocessing issues: render order and official example

I’m working with react-three-fiber, but this code directly relates to Three.js internals and an official example so I think it should fit this forum. Let me know if it doesn’t!

I’m attempting to apply a pixelation postprocessing effect to a specific layer in my game. After some trying I managed to apply the official PixelationEffect.

I then found this example for a more complex pixelation pass and wanted to give it a go. Unfortunately despite the example’s code being quite similar to mine I’m having some issues.

I have a Codesandbox with my code here. With <SelectivePixelation toggle={false} /> It stops working with: TypeError: pass.setRenderer is not a function.

Typescript does warn me in my IDE. renderPixelatedPass:

I think this is some kind of versioning issue. The example in the repo seems to use its own Pass (which I’ve replicated in the Codesandbox) which is different from the current Pass exported by postprocessing.

With <SelectivePixelation toggle={true} /> it uses Three’s internal PixelationEffect which does work… But causes my layer 0 to always render on top:

Any idea how I can fix these issues?

Spent the day looking at this. I think the post-processing not working can be attributed to legacy code, but I’ve been able to make it function by exclusively importing all the legacy pieces the example uses.

On the other end rendering the two layers separately with a composer render in between I cannot get to work. Either layer 0 doesn’t render or it renders on top of layer 1.

Simplified the codesandbox further for anyone that wants to take a look!

https://codesandbox.io/p/devbox/wonderful-pateu-forked-swr8rl?file=%2Fsrc%2FEffects.ts%3A9%2C6&workspaceId=ws_66zVdFAwUL9dpLoo8Ko78m

Maybe the pixelation pass flattens the depth buffer for the blue cube (how far it is from us), so the red circle get confused, as it cannot determine whether it is in front or behind the cube?

Not a good solution, but until you find it, try this one:

camera.layers.disableAll();
camera.layers.enable(0);
gl.render(scene, camera); // <-- added this line
composerRef.current.render();
1 Like

This works! why isn’t it a good solution?

1 Like

I see two issues:

  1. the layer is rendered twice, once to get the depth, and once for the pixelization;
  2. the contour of the pixelated object is not pixelated

Ah you’re right, I see it as well. It’s enough to get me unblocked though, thank you!

1 Like