How to scan a render target for the brightest pixel?

Hi.

I am in the process of creating a stealth system for hiding in the shadows. I am using volumes and traces for checking when the player is hit by directional light, or in the radius of other lights. However, I don’t think that this system is good at calculating the player visibility when not hit by a light source, but just ambient light or baked lighting.

For this, I have a render target that is focused on a octahedron at the player location, to supplement the trace tests and trigger volumes. Now, I am not very families with the engine, or the broader used terminology, so there might be a solution for this that I might not know what I am searching for.

My question is:

How do I scan this rendertarget during gameplay? Somehow find the brightest pixel, or average brightness? Then, give this pixel a value out of 1? And finally communicate this value, out of 1, to my player blueprint to save as a variable to be used in my visibility calculations?

You can use the Blueprint functions “Read render target pixel” and “Read render target pixel raw” to read the value of a render target pixel. With it you can write a loop going over all of the RT pixels to calculate the max/average color.

I think that this loop will run on the CPU, thus you should set the render target to a small resolution. Otherwise your game might be less performant.

Have you figured a good solution? I think that getting data from the render target might be doable if you set the resolution very low. you don’t need every pixel, just larger clumps.

Here is how to read the individual render target pixels:

  • In the .h file:

     UFUNCTION(BlueprintCallable, Category = "Render Target", meta = (Keywords = "ReadRenderTarget", WorldContext = "WorldContextObject"))
     	static void ReadRenderTargetPixels(UObject* WorldContextObject, UTextureRenderTarget* RenderTargetTexture, TArray<FColor>& colors);
    
  • In the .cpp file:

     void FunctionLibraryName::ReadRenderTargetPixels(UObject* WorldContextObject, UTextureRenderTarget *RenderTargetTexture, TArray<FColor>& colors)
    

    {
    FRenderTarget* RenderTarget = RenderTargetTexture->GameThread_GetRenderTargetResource();
    RenderTarget->ReadPixels(colors);}

  • It will look something like this:

350607-001.jpg

  • You can then loop through this unordered list of pixel colors to get the average.

  • After getting the above “rendered Image” array, If you would like to get pixel color from a specific XY coordinate, create the following function: