Release notes
On this page
What’s new
Rendering
Support for full-color bitmap fonts
We have added support for full-color bitmap fonts. The flow to add a colorful bitmap font is almost the same as adding a normal single color bitmap font. The only thing that needs to be altered is the cohtml::UserFontDescription
font description’s FontType
to cohtml::Fonts::UFT_ColorBitmap
instead of cohtml::Fonts::UFT_Bitmap
. Note that the bitmap atlas background has to be transparent if you don’t want it to show with the letters. Below are two examples of full-color bitmap font atlases and their text rendering results:
Example 1
Example 2
Unity
Support for the native plug-in profiler on Unity
In this release, we have added support for the native plug-in profiler on Unity. The Unity Profiler is a valuable tool for learning more about the performance of your application. You can even test how your application performs on the platform you plan to release it on by connecting to the desired device. To open the Profiler window, go to Window > Analysis > Profiler in the Unity Editor. The Native Plugin API makes it possible to set up callbacks for events in the Unity Profiler. Some other basic functionalities it provides are the ability to create custom profiler markers, check if the profiler is available and enabled, and begin and end a sample. We used the IUnityProfiler
interface to add some custom markers for functions from our C++ native plug-in code. This means that now, whenever you are recording profiling information, you can also view details of our markers in the Profiler window. Below is a list of our markers' names and how often they are called:
CohtmlBeginFrame
- called once per frame in the beginningCohtmlEndFrame
- called once per frame at the endCohtmlDrawView
- called every frame when a view needs to be painted (execute graphics commands)CohtmlCreateViewRenderer
- called when a view gets createdCohtmlDestroyViewRenderer
- called when a view gets destroyedCohtmlDestroyAllViewRenderers
- called right before a system gets destroyedCohtmlCreateSystemRenderer
- called when a system gets createdCohtmlDestroySystemRenderer
- called when a system gets destroyed
Migration guide
Migrating to 1.52
Shader changes and enhancements
- With this release, we have added additional per command data information, currently holding details about 2 things, which can be extracted by checking if their respective flag is set:
- If the
PSAF_LinearColorSpace
flag is set, the color space is linear - If the
PSAF_ColorTextAtlas
flag is set, the bitmap text is full-color (atlas format is RGBA8)
These flags are defined inside CohCommonPS.ihlsl
, where we’ve also moved the IS_SET()
function, so it can be accessible in more shader files. The ability to check what the color space is inside the shaders aids in writing color space specific shader code. Below is an example of how to extract the information and check if a specific flag is set:
int vs, ps, shaderType;
decode(input.VaryingData, vs, ps, shaderType);
// ps points to the color that should be used for this pixel
// ps + 1 points to a float4 that contains other per command data
float4 perCommandData = Data_PS[ps + 1];
// The additional information is encoded in perCommandData.y
// Check if the color space is linear
if (IS_SET(int(perCommandData.y), PSAF_LinearColorSpace))
{
...
}
- We have altered the
CohRenoirShaderPS.hlsl
shader to apply gradient dithering evenly in linear color space.
Before:
> CohRenoirShaderPS.hlsl
#if defined(APPLY_DITHER)
colorTemp += lerp(-NOISE_GRANULARITY, NOISE_GRANULARITY, Random(input.VaryingParam0.xy));
#endif
After:
> CohRenoirShaderPS.hlsl
#if defined(APPLY_DITHER)
if (isLinearColorSpace && colorTemp.a != 0.f && colorTemp.a != 1.f)
{
// Convert linear color to gamma
colorTemp.rgb = pow(abs(colorTemp.rgb), 1.f / 2.2f) * sign(colorTemp.rgb);
const float4 minMaxColor = colorTemp;
// Apply dithering
colorTemp += lerp(-NOISE_GRANULARITY, NOISE_GRANULARITY, Random(input.VaryingParam0.xy));
// Avoid generating invalid colors
colorTemp = max(colorTemp, min(0.f, minMaxColor));
colorTemp.a = min(colorTemp.a, max(1.f, minMaxColor.a));
// Convert gamma color to linear
colorTemp.rgb = pow(abs(colorTemp.rgb), 2.2f) * sign(colorTemp.rgb);
}
else if (colorTemp.a != 0.f && colorTemp.a != 1.f)
{
colorTemp += lerp(-NOISE_GRANULARITY, NOISE_GRANULARITY, Random(input.VaryingParam0.xy));
}
#endif
You can move the slider in the picture below to see how the noise looks much less noticeable with the new changes in linear color space. The left side is the before, while the right side is the after:
- Improved text rendering and luminance smoothing in different color spaces, as the code previously targeted the gamma color space only. Now, if specified so, our
GetLuminance()
function will return the luminance converted from linear color space to gamma.
Before:
> CohCommonPS.ihlsl;
float GetLuminance(float3 color)
{
return 0.2126f * color.r + 0.7152f * color.g + 0.0722f * color.b;
}
outColor.a = lerp(GetLuminance(outColor.rgb), outColor.a, input.Color.b);
⋮
const float lum = GetLuminance(input.Color.xyz);
outColor = input.Color * pow(abs(dfValue), 1.45f - lum);
After:
> CohCommonPS.ihlsl;
float GetLuminance(float3 color, bool shouldConvertToGamma)
{
float lum = 0.2126f * color.r + 0.7152f * color.g + 0.0722f * color.b;
if (shouldConvertToGamma)
{
lum = pow(lum, 1.f / 2.2f);
}
return lum;
}
outColor.a = lerp(saturate(GetLuminance(outColor.rgb, false)), outColor.a, inColor.b);
⋮
const float lum = GetLuminance(inColor.xyz, IS_SET(int(perCommandData.y), PSAF_LinearColorSpace));
outColor = inColor * pow(abs(dfValue), max(1.45f - lum, 0.f));
Move the slider below to see the difference between the luminance on raster text before(left side) and after(right side) the new changes in linear color space:
Experimental GPU tessellation algorithm
We are currently working on an experimental GPU tessellation algorithm for which we introduced a new shader type ST_FillPathAtlas
, a new pixel shader type PST_FillPathAtlas
, a new vertex type VT_FillPathAtlas
and a new renderer capability SupportsSingleChannelMSAATextures
. As the algorithm is still in development and is not yet enabled, ST_FillPathAtlas
, PST_FillPathAtlas
, VT_FillPathAtlas
and SupportsSingleChannelMSAATextures
can be safely ignored.
Changelog
Version 1.52.0
Released 04 Apr 2024
API | Removed support for the experimental custom elements V0 API |
Feature | Added support for full-color bitmap fonts |
FeatureUnity | Added support for the native plug-in profiler in Unity |
Enhancement | HTMLCollection returned by getElementsByTagName and getElementsByClassName are now live |
Enhancement | Enhance text rendering and luminance smoothing in different color spaces |
Enhancement | Apply gradient dithering evenly in linear color space |
EnhancementUnity | Added UI Surface Partitioning support when using CohtmlView inside UnityUI Canvas |
EnhancementUnity | Added Backdrop Filter when using CohtmlView inside UnityUI Canvas |
EnhancementUnity | Added default gamepad mapping for common gamepad models for Unity InputManager |
EnhancementUnreal Engine | Improve the reporting of used textures inside the UI |
EnhancementUnreal Engine | Added support for Surface partitioning feature in Concurrent Advance mode |
EnhancementUnreal Engine | Added support for Custom Effects feature in Concurrent Advance mode |
Fix | Fixed string values for CSS properties for border, margins and padding |
Fix | Fixed wrongly reported scroll values in some cases |
Fix | Fixed border image property equality comparison bug caused by uninitialized memory |
Fix | Fixed calling attribute related JavaScript handlers before the attribute on the element is updated |
Fix | Fixed infinite recursion when setting attributes to their current values in MutationObserver callback |
Fix | Fixed a crash when using SVG border images with zero sized border sides |
Fix | Fixed a case with a wrong draw order of SVG elements after using an InsertBefore operation |
Fix | Fixed a crash when an InsertBefore operation used for SVG elements fails |
Fix | Fixed wrongly removing the element from the DOM when an InsertBefore used as a move operation fails |
Fix | Fixed a crash when descriptors for constant buffers are not enough for Vulkan |
Fix | Fixed bleeding of big glyphs generated with SDF on the CPU algorithm |
FixUnity | Fixed the import/compilation warnings caused by obsolete CohtmlCanvasRenderer invocations internally |
FixUnity | Fixed loading of plugin libraries for Unity on Linux |
Fix | Fixed a crash when making an inspector connection with Visual Studio Code |
Fix | Fixed Address Sanitizer error on Sony PlayStation when doing Array.shift in JavaScript |
Fix | Fixed using memcpy for overlapping regions on Nintendo Switch |
FixUnreal Engine | Fixed rendering artifacts on Sony PlayStation 5 |