How to efficiently look up RenderTarget in C++?


I am making a plugin for scattering large amount of instances and one of the features I want to have is ability to drive instancing based on material. I have it already somewhat working, by doing line traces, gathering UV from the trace hits and then looking up the material color value from the render target generated by DrawMaterialToRenderTarget(). The function I am using to look up the color on the render target is ReadRenderTargetRawUV(), which is described as “Incredibly slow and inefficient” in the documentation, and rightly so, as the lookup of the render target values takes 10 times longer than the entire rest of the scattering plugin.

My question therefore is, what’s the proper way to do this so it’s not “Incredibly slow and inefficient”? I am having really hard time figuring out anything else.

Thanks in advance.

EDIT: To kind of simplify the problem.

What I have available as an input is an unlit material with texture in the emissive slot and UV coordinates retrieved from line trace. I need to use this to retrieve emissive slot colors at those specific UV positions and then store them within each traced point struct, so once I am placing instances, I know the texture value at given point and can decide if the texture value is high enough to place the instance or not.

I’ve gotten somewhere. I’ve been able to find something that dumps render target into Color Buffer, but unfortunately I have absolutely no idea how to stop GetRenderTargetResource() crashing build with the "Assertion failed: IsInRenderingThread() || (IsInParallelRenderingThread() && (!Resource || Resource->IsInitialized())) [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/Engine/Private/TextureRenderTarget.cpp] [Line: 31] " assert.

This is the code snippet where it happens:

ScatterSurface.DistributionTexture = UKismetRenderingLibrary::CreateRenderTarget2D(GetWorld(), 256, 256, ETextureRenderTargetFormat::RTF_RGBA8);
UKismetRenderingLibrary::DrawMaterialToRenderTarget(GetWorld(), ScatterSurface.DistributionTexture, ScatterSurface.DistributionMaterial);

FTextureRenderTargetResource* Resource = ScatterSurface.DistributionTexture->GetRenderTargetResource(); //<- Breakpoint triggers here

From what I have read, I have to somehow pause the rendering thread, but that is WAY beyond my skill level :frowning: