Release notes
What’s new
Content Development
Curly brackets position in Data Binding expressions
The curly brackets in data binding expressions will now automatically expand until the end of the property chain during evaluation. For example, the expression {{model.property1}}.property2 + {{anotherModel}}.property1.property2.property3
will be evaluated as if it was written as {{model.property1.property2}} + {{anotherModel.property1.property2.property3}}
.
That change will have a performance gain for expressions that were unintentionally written with properties outside of the curly brackets, because such expressions were evaluated through a JS function even for C++ models and properties.
In the same time, new properties that were dynamically added to the model in JS will still be accessible. This case also has a performance gain because the expression will be evaluated in C++ without compiling to a JS function.
cppModel.cppProperty.scriptedProperty = 25;
engine.updateWholeModel(cppModel);
engine.synchronizeModels();
...
// The following lines are equivalent
<div data-bind-value="{{cppModel.cppProperty.scriptedProperty}}"></div>
<div data-bind-value="{{cppModel.cppProperty}}.scriptedProperty"></div>
<div data-bind-value="{{cppModel}}.cppProperty.scriptedProperty"></div>
Note that complex expressions which use JS functions and can’t be evaluated by Gameface will still be compiled to a JS function.
Global Backdrop Filter
Gameface now supports an alternative approach to having a backdrop filter effect in UIs - “Global Backdrop Filter”. This alternative to the traditional backdrop filter has better performance and can potentially save up GPU memory. However, it also has the limitation of forcing every DOM element utilizing it to have the same backdrop filter effect.
For more details, see the documentation for Global Backdrop Filter
Unreal Engine
New delegates for modifying Library, System and View options
The Gameface integration for Unreal Engine now provides new ModifyLibraryParams
, ModifySystemSettings
, and ModifyViewSettings
delegates for modifying all Gameface Library, System and View options.
ModifyLibraryParams
, ModifySystemSettings
, and ModifyViewSettings
delegates are located inside ICohtmlPlugin.h
, and are called right before creating a Gameface Library, System and View, passing a pointer to the already populated settings.
Migration guide
Pixel Shader Changes
Changes in the shaders
Color Matrix multiplication
There is a color matrix that is now applied to the pixel color at the end of these shaders: CohColorMixingPS.hlsl
, CohRenoirShaderPS.hlsl
, CohShadeGeometry.ihlsl
and CohShadeGeometryRare.ihlsl
. To extract the offset, which points to the color matrix coefficients (5 float4s), from the pixel shader constant buffer data, you can use the following approach:
int vs, ps, shaderType;
decode(input.VaryingData, vs, ps, shaderType);
float4 perCommandData = Data_PS[ps];
int sharedCBOffset = int(perCommandData.x);
int commonPSCBDataOffset = max(0, sharedCBOffset + SHARED_PS_DATA_OFFSET);
int colorMatrixOffset = int(Data_PS[commonPSCBDataOffset].z);
If the colorMatrixOffset
is not -1, then there is a color matrix at the given offset that needs to be applied to the output color. You can refer to the shader files mentioned above to see how the color matrix is applied in practice. As for an example implementation of the multiplication itself, check out the ApplyColorMatrix()
function inside CohCommonPS.ihlsl
. All custom shaders have to be modified to also apply the color matrix.
Image alpha premultiplication inside the shaders
If you rely on custom shaders, you’ll need to update the pixel shader additional flags in CohCommonPS.ihlsl
with the following new value:
static const int PSAF_ShouldPremultiplyAlpha = 0x40;
This flag specifies whether the shader should manually apply alpha premultiplication to the sampled texture color before applying the color matrix:
float4 outColor = SAMPLE2D(txBuffer, uvPoint);
if (IS_SET(additionalFlags, PSAF_ShouldPremultiplyAlpha))
{
outColor.rgb *= outColor.a;
}
This change is necessary because some images do not come with premultiplied alpha (as indicated by the ImageProperties::IMP_Premultiplied
flag). Previously, alpha premultiplication was handled by the blend mode. However, with the introduction of implicit color matrix calculations in the shader pipeline, the alpha must now be premultiplied manually before the color matrix is applied.
Changes to the gradient shaders
In order to improve the batching of the gradients, we have made some changes to the following shader files - CohRenoirShaderVS.hlsl
, CohRenoirShaderPS.hlsl
and CohStandardCommon.ihlsl
. The changes include moving some calculations from the vertex shader to the pixel shader, some restructuring of the constant buffers, and a data member removal. If you maintain custom shaders you must align them with the new structure. An overview of all impacted files and their changes:
CohRenoirShaderVS.hlsl
:- Removed the
maskScaleAndOffset
calculation (now done in the pixel shader).
- Removed the
CohStandardCommon.ihlsl
- Removed
VaryingParam1
member from thePS_INPUT_RENOIR_SHADER
structure, as it is no longer needed.
- Removed
Constant Buffer Restructuring
maskScaleAndOffset
moved from theData_VS
buffer to theData_PS
buffer.
CohRenoirShaderPS.hlsl
- The
shaderType
andopacity
are now extracted from theperCommandData
in theData_PS
buffer. - Added gradient repeat scale and offset to the per batch data inside the
Data_PS
buffer. See below how they are applied. - Mask UVs are now calculated in the pixel shader using the new
maskScaleAndOffset
location in the per command data of theData_PS
buffer.
Preview of the new changes and how to extract the information mentioned above:
- The
// CohRenoirShaderPS.hlsl
...
int vs, ps, shaderType;
decode(input.VaryingData, vs, ps, shaderType);
float4 perCommandData = Data_PS[ps++];
// Example extraction of the shader type and opacity from their new location in the buffer
shaderType = int(perCommandData.y);
float opacity = perCommandData.w;
...
if (IS_SET(shaderType, PSTF_GradientRepeat))
{
float repeatScale = Data_PS[sharedCBOffset].x;
float repeatOffset = Data_PS[sharedCBOffset++].y;
tVal = Frac(tVal * repeatScale + repeatOffset);
}
else if (IS_SET(shaderType, PSTF_GradientReflect))
{
float repeatScale = Data_PS[sharedCBOffset].x;
float repeatOffset = Data_PS[sharedCBOffset++].y;
tVal = Mirror(tVal * repeatScale + repeatOffset);
}
...
// In the case of a mask we now calculate the UVs using the `maskScaleAndOffset` from the `Data_PS` buffer.
if (IS_SET(shaderType, PSTF_HasMask))
{
float4 maskScaleAndOffset = Data_PS[ps];
float2 maskUV = input.ScreenNormalPosition.xy * maskScaleAndOffset.xy + maskScaleAndOffset.zw;
float mask = SAMPLE2D(txMask, maskUV).a;
colorTemp *= mask;
}
Changelog
Version 1.69.0
Released 11 Aug 2025
API | Changed shaders to allow for improved batching of gradients and applying color matrix in the pixel shaders |
Feature | Allowed the closing }} braces to be anywhere in a data binding expression and still evaluate the expression in the most efficient way |
Feature | Introduced a new way of achieving backdrop filter effect with a focus on performance and memory usage. See the documentation for more information |
Enhancement | Made the HTTPServer and MediaDecoders to be compatible with Android 16KB Pages |
Enhancement | Improved the performance of the provided native DirectX 12 rendering backend by refactoring the logic for GPU descriptors handling, texture updating, and binding of pixel shader textures. See the new DirectX 12 documentation for more performance insights. |
Enhancement | Added a new documentation for the provided native DirectX 12 reference backend. See the documentation for more information |
Enhancement | Removed the ‘Total Memory’ and ‘Spike Memory’ performance counters |
Enhancement | Support for Nintendo Switch SDK 20 |
EnhancementUnreal Engine | Ensured the virtual keyboard is showing when clicking or touching on already focused text input |
EnhancementUnreal Engine | Added delegates for customizing the LibraryParams , SystemSettings and ViewSettings in Unreal Engine |
EnhancementUnreal Engine | Added ICohtmlPlugin::OnGetDataStorageProvider delegate for providing implementation of the cohtml::IDataStorageProvider interface |
EnhancementUnreal Engine | Complete support for Unreal Engine 5.6 |
Fix | Fixed the accumulation of DOM Event instances until the view is navigated to another URL |
Fix | Fixed a bug where the size of the user background for the backdrop filter wasn’t getting properly updated, leading to visual artifacts for a single frame |
Fix | Fixed a crash when navigating a View while there is a dynamic import in flight |
Fix | Fixed spacing between text nodes when the element has no definite size constraints imposed on it (e.g. has no specified width in the styles) |
Fix | Fixed a crash when accessing array elements inside array elements that have been erased |
Fix | Fixed a bug for xml:space attribute with preserve value where whitespace on SVG |
Fix | Fixed a bug where extra whitespace would be incorrectly appended at the end of SVG |
FixUnity | Fixed the backdrop filter effect in HDRP and URP mode in Unity |
FixUnity | Fixed a hang in the Unity Editor with DirectX 12 when the preview window loses focus |
FixUnity | Added the Visual Studio Code plugin for autocomplete in the Unity UPM packages |
Fix | Fixed a bug with the usage of non-standard rendering resolution, causing a one-pixel artifact for some DOM elements |
Fix | Fixed a wrong calculation of color matrices that was observed with the standard invert filter and custom color matrices with color bias |
Fix | Fixed a bug with the unloading of raster fonts, leading to visual artifacts when rendering text |
Fix | Fixed a bug with the drawing of repeated images from image atlases, leading to wrong sections of the atlas being rendered |
Fix | Fixed crash triggered by JavaScript callbacks removing DOM nodes after they were scheduled for style solving |
FixUnreal Engine | Fixed support for multiple touches on physical mobile devices |
FixUnreal Engine | Fixed a false-positive warnings for not yet destroyed UCohtmlWidget objects when changing maps in Unreal Engine |
Fix | Fixed a bug with the gradients that was causing invalid memory access when having invalid color stops in the CSS |
FixUnreal Engine | Fixed a crash in custom effects drawing when UCohtmlWidget are destroyed |
FixUnity | Fixed the rendering on Android with Vulkan rendering API enabled |