Shared View Render Targets
In cases where there are multiple cohtml::Views, the memory/performance overhead of the UTextureRenderTarget2Ds that will be needed could potentially become far from negligible, because each View uses its own render target texture. This can impact memory when the textures are very high resolution, in addition to impacting performance because each render target texture will have to be managed individually (for example, during resizes).
In such scenarios where GPU memory needs to be reduced and/or achieve better performance, Gameface allows multiple cohtml::Views to share a single render target texture between them.
How to use
Section titled “How to use”When a FCohtmlViewWrapper is created, normally it would also automatically request the creation of a FCohTexture of type ViewRenderTargetTexture and from then on, this FCohTexture will be tied to the lifetime of the FCohtmlViewWrapper. This is done through the FCohTexture::AcquireAutoManagedTexture API, which makes the internal FCohTextureCollector “collect” the created FCohTexture and provide a raw pointer to it.
In order to make multiple FCohtmlViewWrappers share the same FCohTexture (and thus the used render target textures), two things need to be done:
- You have to subscribe to the
ICohtmlPlugin::OnProvideUITextureForViewWrapperevent, which will be fired when anFCohtmlViewWrapperis created, just before it has to create itsFCohTexture, allowing you to instead provide it with aFCohTexturethat you have created on your own. - To bypass the
FCohTextureCollectorlifetime management, we’ve provided aFCohTexture::AcquireManuallyManagedTextureAPI, which returns a shared pointer to the createdFCohTexture.
Doing the above steps will enable you to determine if you want to provide a manually-managed FCohTexture or an auto-managed FCohTexture based on some custom conditions. The code would look something like this:
bool bSomeCustomCondition = false; TSharedPtr<FCohTexture> ManuallyManagedCohTexture = FCohTexture::AcquireManuallyManagedTexture(ECohTextureType::ViewRenderTargetTexture); ICohtmlPlugin::Get().OnProvideUITextureForViewWrapper.BindLambda([ManuallyManagedCohTexture, bSomeCustomCondition]() { // Use the FCohTexture that will be manually managed or the FCohTextureCollector-managed one return bSomeCustomCondition ? ManuallyManagedCohTexture : FCohTexture::AcquireAutoManagedTexture(ECohTextureType::ViewRenderTargetTexture); });For a more complete example of how similar code can work, we’ve created a Shared Render Targets map sample that you can check out.
Resizing
Section titled “Resizing”There are a few things to note when deciding to share render targets between Views:
- If you have a UI element that will cover the size of your viewport and an in-world UI element which won’t be the same size as the viewport, but they share the same render target texture, you won’t be able to have both of them displayed at the same time without having visual artifacts, due to the size mismatch.
- Instead, it is recommended to either show only one of those components at a time, and when showing the other, ensure that you are also manually resizing the
FCohtmlViewWrapperto the expected size (this may potentially also require a clear of the render target texture). This process is showcased in theShared Render Targetssample. - An even better approach would be to split your shared render targets based on the types of components. For example, share only render targets between UI elements of the same size (e.g., in-world
Views), so that you won’t have to resize each time you switch between UI elements that will draw to a given render target.
- Instead, it is recommended to either show only one of those components at a time, and when showing the other, ensure that you are also manually resizing the
How Gameface Views work with textures
Section titled “How Gameface Views work with textures”While Unreal’s render target class is technically UTextureRenderTarget2D, what Gameface is interested in is the underlying FRHITexture and ensuring its lifetime. This is why Gameface‘s systems work with FCohTexture primarily. This doesn’t only go for render target textures that will be used by a cohtml::View, but also extends to every other Unreal texture type that is supported.
When a Gameface UI element is created (be it Component-based or UMG-based), there are two main things that happen:
- Each UI element will create a
FCohtmlViewWrapper, which, as the name implies, is a class wrapper around thecohtml::Viewwhich will render your HTML page. - To render things, a
cohtml::Viewrequires a render target texture. Such a texture is automatically created by theFCohtmlViewWrapperwhen it is initialized. Internally, this render target texture is wrapped in aFCohTextureclass whose main purpose is to work with Unreal APIs to retrieve a reference to theUTextureRenderTarget2D’sFRHITexture, in order to prevent Unreal from deleting it too early, while Gameface is still in the process using it in its rendering pipeline.- This
FCohTexture’s lifetime is tied to aFCohtmlViewWrapper’s lifetime, but it is not managed by it. That is the job of theFCohTextureCollectorsingleton class.
- This
Limitations
Section titled “Limitations”- Displaying UI elements that share the same render target texture and size at the same time is possible, however, if all
Viewsdraw over the same section of the texture, you will see visual errors due to the overlap.- For such a scenario to work (given two
Viewslet’s say) you would need to only draw to one section of the texture with oneView, and another section of the texture with the otherView. This behavior would very closely resemble our Surface Partitioning feature, so perhaps that would be a better solution depending on the case.
- For such a scenario to work (given two
© 2026 Coherent Labs. All rights reserved.