Problems with generating game character portraits (using screenshots, separate canvas)

Hi everyone!

I’m trying to create a portrait image of the character of my game using a separate camera, but I have some issues that I’m not sure how to resolve! This is supposed to be kind of like your profile image.


As you can see, it looks pretty good already and the image also has a transparent background, which is a must. Another thing that is a must is that only the character must be visible in the picture. However, there are issue that I haven’t been able to resolve yet:

  1. How to get rid of the fullscreenui? That health bar is situated on top of the character. Is there any way to do this with CreateScreenshotUsingRenderTarget ? There is a playground visualizing this problem here: CreateScreenshotUsingRenderTargetTexture | Babylon.js Playground

  2. It seems that if the scene has autoClear set as false, the meshes won’t appear in the screenshot. Is there any way to handle this without changing the autoclear to true? Maybe I can have it true when the screenshot is being taken? Playground to illustrate this problem: CreateScreenshotUsingRenderTargetTexture | Babylon.js Playground

  3. I have to turn off the particles since there is no way to exclude them from the screenshot. I have semi global particle effects like rain and leaves, and those appear on the screenshot if I do not turn them off. The problem is that there is a small hiccup when doing this, so it is not ideal… Any way to circumwent this? This is what I do currently

        this.scene.particlesEnabled = false
        const base64Picture = await Tools.CreateScreenshotUsingRenderTargetAsync(
          this.scene.getEngine(),
          this.snapshotCamera,
          { precision: 1.0, width: this.snapshotSize, height: this.snapshotSize },
          undefined,
          undefined,
          false,
          undefined,
          false,
          true,
          false,
          undefined,
          (texture) => {
            texture.renderList = meshes
            texture.useCameraPostProcesses = true
            texture.renderParticles = false
          }
        )
        this.scene.particlesEnabled = true
    

Thank you in advance for any help you can give me :folded_hands:

One thing I’ve been thinking of what I could do to circumvent most of the problems; duplicate the mesh and move it far away to a location where there are no particle effects etc., but that introduces some extra work… :scream:

You would need to hide it before and enable back after.

I guess you could enable before and stop after.

I would highly suggest to have a separate scene for your user snapshots if it is possible. The setup is quite different and it would make sense in this case.

Yeah, I could probably do this pretty easily…

Separate scene would mean that I have to do mesh instantations again since they are bound to the scene, right? That sounds a tiny bit tedious… I think I would need a completely separate the main game code from this, which I would not like…

I have now also managed to kind of get rid of some of the quirks, but there is still a bit weirdness with the screenshotting interfering with the main game loop.

I have also been toying with the idea of animated portraits, a bit like Warcraft 3 style. This would bypass the need for screenshots altogether.

DreadLord_Portrait

So the next question would be; how easily could I render the result of a secondary camera to a separate canvas that is displaying the portrait? That would be super cool, but if it is a ton of work it might not be worth it (my game is getting too big anyways so this kind of stuff is more like cherry coating on top :slight_smile:)

and set the same layerMask for it and for the secondary camera

2 Likes

I guess the separate canvas would be a mission for Babylon.js docs

I would render it in an offscreen canvas, sample the area with the actor and then pass that to a post process that mixes it in with your main scene. You could even then have the camera in isometric and have multiple actors being loaded and ready at the same time kind of like the brady bunches intro scene. Then you would pass the whole capture back and just sample the specific area that you needed at a specific time.

2 Likes

Most flexible way. Right there. Good suggestion. :grin: