Sprites with different textures, depending on camera

I suspect the answer might be “no” as it doesn’t feel like Cameras are that sophisticated but …

For a given sprite, could you show one texture when displayed from one Camera, and a different texture for another?

so if mySprite was visible within the Viewport of myCamera1, mySprite would show one texture; while if mySprite was within the viewport of myCamera2, the camera would show a different texture?

And if not specifically like that, any thoughts on how to get around it? Can a given GameObject control what it shows to a given Camera?

Maybe you could have a frame for every camera. Then use setGameObject in a custom pipeline.

https://photonstorm.github.io/phaser3-docs/Phaser.Renderer.WebGL.WebGLPipeline.html#setGameObject__anchor

1 Like

I can’t think of a way to do that with the camera itself. You might use a Render Texture instead of a second camera.

1 Like

Interesting, I’ve never really touched something that deep into the code- there any examples of this kind of thing in action?

Let’s see if @Telinc1 is around.
I’m sure he has some codepens.

No codepens, but I can offer advice. Cameras are only a view into the game world, so showing different textures for the same doesn’t make sense, conceptually. In my opinion, the cleanest solution is to use two game objects. One of them should be used by all of your logic and ignored by the second camera, while the second should just follow the first and be ignored by the first camera. Of course, this will break down if you need mouse input.

That said, it’s possible to hack this without even using pipelines. Game objects’ render methods get a reference to the camera. Technically, nothing prevents you from overriding them and changing the texture right before the object is rendered:

const image = this.add.image(0, 0, "one");

const originalRenderWebGL = image.renderWebGL;

image.renderWebGL = function(renderer, src, camera, parentMatrix){
    this.setTexture((camera.id === 1) ? "one" : "two");

    originalRenderWebGL.call(this, renderer, src, camera, parentMatrix);
};

// do the same for renderCanvas if you use/support the canvas renderer

This appears to work, but I’m not sure what its ramifications are, if any.

2 Likes

Yeah, I’ve been thinking on the issue a little more and as you say, the simpler / better solution might simply be to use two game-objects, controlled by a root class (either extending GameObjects.Group or not). For reference, my idea has two separate radar-like displays (cameras), so was trying to contextualise the info displayed in each camera - but only one relies on mouse input and Ive already used pointer.positionToCamera() to get the exact position. I was trying to shortcut having to pull apart my game actor sprites and do the switch “upstream”. Ah well :grin:

Thanks to all for the help :+1: