Preloaded Textures

Textures inside the UI

This feature allows users to efficiently share Unreal textures between the Engine and the UI.

Usually, whenever a texture is needed, Prysm would read it from disk, decode it and upload it to the GPU. There are use cases when this would not be the optimal thing to do. For example:

  • The game and the UI share textures (this will result in double processing & memory)
  • You don’t want to keep the raw images around, just the imported .uasset files.

Unreal textures are static assets that are usually located on disk and before using them, they have to be loaded by the Engine. That incudes reading from disk, decoding and uploading them to the GPU, but once loaded, they will be kept in Unreal’s cache if they are referenced.

The loading of textures happens when Prysm requests them, which normally involves asynchronous loading of the uassets, unless they are preloaded. This will happen when the whole HTML page is parsed and its resources are requested, which includes the Unreal textures and Live Views present in the page declaration. Unreal will not load them into memory in advance when Prysm is initialized.

Once the HTML page is parsed and the UE textures are requested, their loading will be handled by the FStreamableManager class. The FStreamableManager implementation in Unreal Engine could load the texture instantly, in case the .uasset is already loaded into memory, otherwise it will be streamed from disk.

To use Unreal textures instead of normal images, use the Unreal object paths to reference your images from HTML/CSS, instead of standard URLs, e.g. instead of this:

<img src="foo.png"></img>

use this:

<img src="Texture2D'/Game/uiresources/foo.foo'"></img>

To get the object path for your texture, you can right-click it in the Editor’s Content Browser and click Copy Reference, then paste the result in your HTML page.

To make sure that there are no visual differences when using Unreal textures, please follow these guidelines:

  • Prysm expects images to have premultiplied alpha, Unreal does not. As a result, transparent images will cause the transparent areas to receive a non-transparent color unless premultiplied.
  • By default UE stores images in sRGB (i.e. it applies gamma-correction). This will result in textures showing darker in some parts. To prevent this issue, make sure that the sRGB property of the texture asset is checked off.
  • Make sure you select the proper texture compression for your texture. For example, DXT is a lossy format and this may cause artifacts, which may, or may not be acceptable for your use case.

How to import raw images as UTextures

Prysm integration gives you an easy solution to do a bulk import of raw images that will create UTexture2D assets. These assets are created in a way that should be working as expected with Prysm - the issues with the premultiplied alpha and sRGB settings, described above, will be automatically solved, ensuring the resulting textures will be looking as expected inside the UI.

To access this feature, all you have to do is select the directory (or directories) in the Unreal Engine Editor’s Content Browser, right click and under the “Prysm Operations” category select Import Raw Images in Folder.

Here is an example:

You can also change some of the settings of this functionality in your Prysm options, like the Texture Group and Compression Settings of your imported images, as well as if these assets should be automatically saved after being imported. In addition to this, you can modify the Image Extensions array to include, or exclude certain file extensions that should be considered during importing.

Texture Preloading

For optimal UI loading time, Unreal textures that will be used in the UI should be loaded in advance and kept referenced, to ensure the Engine will keep them cached in memory. The loading of specific textures ahead of time can be done using the provided Prysm integration API, part of the HUD’s UCohtmlBaseComponent and UCohtmlWidget:

  • UCohtmlBaseComponent::PreloadTextureSync - loads texture from UE object paths synchronously, keeping it referenced
  • UCohtmlBaseComponent::PreloadTextureAsync - loads texture from UE object paths asynchronously, keeping it referenced
  • UCohtmlBaseComponent::AddPreloadedTexture - adds a reference to already loaded texture
  • UCohtmlBaseComponent::RemovePreloadedTexture - removes referenced texture
  • UCohtmlBaseComponent::RemovePreloadedTextureFromPath - removes referenced texture from UE object paths
  • UCohtmlBaseComponent::RemoveAllPreloadedTextures - removes all referenced textures

The functionality listed above is also mirrored in UCohtmlWidget, and is exposed to Blueprints and available in the TexturePreloading category. The references for the added textures will be cleared automatically on HUD and Widget destruction.

The example code below shows how to preload textures from a given directory as early as possible in the HUD:

void ACoherentSampleHUD::PreInitializeComponents()
{
    FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
        FName("AssetRegistry"));
    IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();

    TArray<FString> PathsToScan;
    PathsToScan.Emplace("/Game/uiresources/textures");
    AssetRegistry.ScanPathsSynchronous(PathsToScan);

    TArray<FAssetData> Assets;
    for (auto& Path : PathsToScan)
    {
        AssetRegistry.GetAssetsByPath(*Path, Assets);
    }

    auto HUD = GetCohtmlHUD();
    for (auto& Item : Assets)
    {
        // Start preloading textures as early as possible
        HUD->PreloadTextureAsync(Item.ObjectPath.ToString());
    }
    Super::PreInitializeComponents();
}

Lifetime of preloaded resources

Reference flow when using preloaded resources as background-image:

  1. Create an element with a style which has preloaded resource for a background-image.
  2. When the element’s style is evaluated, the style will add a reference to the resource.
  3. The reference will be removed when:
  • The background-image in the element’s style is changed.
  • The style of the element is removed, or the whole element is removed from the DOM tree.

Lifetime flow in <img>:

  1. Create an <img> element with a preloaded resource specified by the src attribute.
  2. The element will add a reference to the resource.
  3. The reference will be removed when:
  • The src attribute is changed.
  • The Garbage Collector destroys the element.

How to turn raw image resource paths into preloaded resource paths without doing UI changes

If enabled, the Prysm plugin setting TryLoadUTexturesFromRawImages will make the integration handle raw image requests as if they were requests for Texture2D objects and try to load them with priority over the raw images. The Texture2D objects are expected to be stored in the same location as the raw images.

In case you have already created your UI using raw images, you can easily translate all image URL’s into Texture2D object paths at runtime. This can help you transition from raw image resources to Texture2D objects and thus save disk space and memory, without the need of any UI front-end modifications. It may even help you optimize the initial UI loading times, provided that the textures are properly preloaded ahead of time, as described in the sections above.

For properly importing images, you can use the Prysm Raw Image Importer tool, as described in the above section.