jnsmalm / pixi3d

The 3D renderer for PixiJS. Seamless integration with 2D applications.
https://pixi3d.org
MIT License
752 stars 43 forks source link

Sprite3D zIndex is not applied to internal ProjectionSprite zIndex #157

Closed lovelle-cardoso closed 1 year ago

lovelle-cardoso commented 1 year ago

The standard pipeline sorts its ProjectionSprites by zIndex, but as far as I can tell, there is no way to set this internal ProjectionSprite zIndex value through Sprite3D.

As a workaround I had to extend Sprite3D like so:

export class Sprite3DWorkaround extends Sprite3D {
  get sprite(): { zIndex: number } {
    return (this as unknown as { _sprite: { zIndex: number } })._sprite;
  }

  override get zIndex(): number {
    return this.sprite.zIndex;
  }
  override set zIndex(value: number) {
    this.sprite.zIndex = value;
  }
}

I believe Sprite3D should redirect getting and setting zIndex to its internal ProjectionSprite, just as it does for other sprite properties (like anchor, tint, texture, and blendMode)

So I've created a simple pull request for that here: https://github.com/jnsmalm/pixi3d/pull/156

jnsmalm commented 1 year ago

Thanks! It's correct, it should have the zIndex property exposed.

But, for this to have any effect right now you also need to set depthTest = false on the sprite renderer (which is available on the standard pipeline, but only as a private property). So right now something like:

app.renderer.plugins.pipeline._spriteRenderer.state.depthTest = false

Just curious, did you do this as well for your zIndex fix to function correctly or did you do anything else?

lovelle-cardoso commented 1 year ago

@jnsmalm I didn't have to change depthTest or anything else to fix my specific layering issue, but to be fair, I just started the process of implementing our sprite system using pixi3d yesterday, so I haven't tested pixi3d too deeply yet!


The layering issue I was encountering can be replicated like so:

  1. Spawn a large Sprite3D with a texture and rotate it to be the "floor" plane.
  2. Set the zIndex of the floor to be very low like -1000.
  3. Spawn a few billboarded Sprite3D's at various positions on top of the floor plane (like the bunnies example)

Result: Any Bunnies rendered at the top half of the screen render with their boundary box incorrectly "obscuring" the floor plane texture.


Simply redirecting the zIndex property fixed that issue for me without needing to change any other code.

lovelle-cardoso commented 1 year ago

@jnsmalm (Just as an overall note, I find it easier to work with typescript libraries that default to using protected backing fields in their classes instead of private ones. That way you can still keep the public-facing interface clean, but us end-users can more easily extend classes with our own functionality or implement temporary workarounds for bugged functionality while we wait for fixes/updates from the library author. Just a suggestion, of course!)