Thanks. And yeah, I can give you a summary of how it works. In short, I hide the default Unity rendering of UITK and render primitives from scratch. For screenspace, it shouldn’t be too bad, but for 3D/VR/worldspace there are a lot of things to consider.
Rendering
I set the PanelSettings targetTexture to some small 2x2 texture that I don’t use, this way Unity does not render to the screen. I also set the “SetScreenToPanelSpaceFunction” to a function that returns “new Vector2(float.NaN, float.NaN)”, so that the screen space input handling is ignored (so I can provide custom input).
For a simple screenspace implementation you wouldn’t even have to modify the SetScreenToPanelSpaceFunction function as long as you’re rendering matches up with UITK positioning.
For the rendering, a lot of what I do was inspired by the “Shapes” asset by Freya. On update loop, I simply traverse the hierarchy and render quads with properties extracted from the element’s layout and resolved style. In URP, this is done through a ScriptableRenderFeature with cmd.DrawMesh calls. With this you can supply your own custom shaderlab or shadergraph materials.
The shader used is a modification of Inigo Quilez’s Rounded Box SDF to also render borders with optional distinct colors. With this, all UITK element backgrounds and borders are able to be rendered.
To render text, I use TMP, rendering the mesh and submeshes in correct places. (This was very difficult to do, there are a lot of nuances in rendering TMP exactly the way UITK does)
To render images, I use a texture shader. For VR there’s mipmaps and anisotropic sampling that needed to be considered.
For clipping (for example in scroll views) in ShaderGraph, I rendered clip boxes to a custom stencil render texture. For non shadergraph materials and TMP, just make sure to update the stencil buffer.
That should be enough for implementing screenspace UITK with custom shaders.
Other
Just a quick list of other things implemented in XI:
- Distinct event system with similar API (because of issues trying to simulate events in UITK)
- Custom styling supporting css styles (like linear-gradient backgrounds), done by accessing UITK internals with asmref and parsing styles (difficult)
- Local anti-aliasing (inspired by Freya), for fixing jagged borders (maybe not necessary in screen space, but very important especially in VR) (difficult)
- Animations for custom styles
- Additional elements
I had plans on implementing screenspace but as this asset isn’t currently doing too well, I was thinking about instead focusing on moving it to use Jobs/ECS for better performance. Probably will make it more attractive and might open up the possibility to do a lot of other cool things as well. With this I’d probably move away from using UITK by adding a flex layout engine but still keeping support for UI Builder and UXML/USS assets for building UI.