Download

Runtime Screenshot with Alpha-Mask

Hi!
I implemented a way to take screenshots at runtime with the Console Execute Command “HighResShot”.
This works by overriding the ProcessScreenShots() function of GameViewportClient.


void UFPOViewportClient::ProcessScreenShots(FViewport * InViewport)
{
if (GIsDumpingMovie || FScreenshotRequest::IsScreenshotRequested() || GIsHighResScreenshot) {
TArray<FColor> OutBMP;
FIntRect CropRect = FIntRect(CropPositionX, CropPositionY, (CropPositionX + CropSizeX), (CropPositionY + CropSizeY));
bool bScreenshotSuccessful = GetViewportScreenShot(InViewport, OutBMP, CropRect);

Next Step is to fill the alpha channel, right now with 255:


if (bScreenshotSuccessful) {
                    for (FColor& color : OutBMP)
                    {
                        color.A = 255;
                    }
                }

But at this point, I want to fill the alpha with a mask.
So for the Console Exectue Command i use this command with the flag MaskEnabled:


HighResShot *ResolutionX(int32)xResolutionY(int32) Or Magnification(float) [CaptureRegionX(int32) CaptureRegionY(int32) CaptureRegionWidth(int32) CaptureRegionHeight(int32) MaskEnabled(int32) DumpBufferVisualizationTargets(int32) CaptureHDR(int32)]*

And added lines from FHighResScreenshotConfig::MergeMaskIntoAlpha:



if (bScreenshotSuccessful) {

    TArray<FColor>* MaskArray = FScreenshotRequest::GetHighresScreenshotMaskColorArray();

    if (MaskArray->Num() == OutBMP.Num()) {
        for (int32 i = 0; i < MaskArray->Num(); ++i)
        {
            OutBMP*.A = (*MaskArray)*.R;
        }
    }
    else {
        for (FColor& color : OutBMP)
        {
            color.A = 255;
        }
    }
}


The problem is, that *MaskArray->Num() == OutBMP.Num() *never equals.
This results in a .png image with my isolated actor and a green background where instead I want transparency…

So what is the right way to get the ScreenshotMaskColorArray?

You could first try adding some logging to see what the problem really is:

  • Is the the mask not being the proper size? (= different number of pixels in the TArray)
  • Is it the mask not loading at all? (= 0 pixels in the mask array)

The size of the MaskArray is not equal to the size of the OutBMP array from the screenshot…
For a 200x200 screenshot the OutBmp array has as expected 4000 entries. But the MaskArray has 2,162,832 entries (My display resolution is 1920x1200 = 2,304,000) and it seems every entry is RGBA = 0,0,0,255…
Resizing the Viewport leads to other size values of the MaskArray, while the OutBmp array size stays at 4000…

I have recognized, that by using the Editor High Resolution Screenshot menue, in FHighResScreenshotConfig::MergeMaskIntoAlpha() both arrays are the same size.
The Pixel Color Array stays here the same, even at different capture region sizes… Only the Viewport size matters…

Okay I found out, that changing the settings for r.ScreenPercentage to another value than 100 causes the different Array sizes…

I still got a big problem with this approach:

Models with transparent materials are not visible…