Verse Colors are Broken

Summary

After 36.20 update, Verse colors are broken - they look different from how they’re supposed to look.
It doesn’t matter which exact function is used to get color or even if its just a named color keyword - the result is always the same.

Please select what you are reporting on:

Verse

What Type of Bug are you experiencing?

Verse

Steps to Reproduce

  1. Write code that shows a color block in any color of your choice
  2. (optional) Create a widget with color block of the same color and add it to hud message device to auto show up at game start
  3. Launch session

Expected Result

Color block must show the right color

Observed Result

Color block shows color with shifted Hue, Saturation and Value

Platform(s)

PC

Upload an image

Additional Notes

Screenshot shows two Verse color blocks on top and two color blocks from the HUD Message Device widget below — with matching colors in each column.
Also tested it with setting color for material parameters with Verse - same problem there.

Getting someone to check into this.

1 Like

@Macilvoy Can you share your Verse script for setting up your color_block?

Happening to me too, I was using NamedColors.Green yesterday and it looked desaturated.

oh, I messed up while writing the issue, Im sorry.
I tested it on materials and wrote ‘color block’ figuratively (because of the blocky form), forgetting that there’s an actual color_block widget.

Previously, I hadn’t tested colors with all widgets, but now that I have, it turns out only materials have issues with Verse colors:


using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /Verse.org/Colors }
using { /Verse.org/Colors/NamedColors }

S2M<public><localizes>(S:string):message="{S}"

CD_Test := class(creative_device):

    @editable TestButton:button_device=button_device{}

    OnBegin<override>()<suspends>:void=
        Sleep(1.0)
        TestButton.InteractedWithEvent.Subscribe(Test)

    Test(a:agent):void=
        DrawTestUI(a)

    DrawTestUI(a:agent):void=
        if:
            p := player[a]
            PlayerUI:= GetPlayerUI[p]
        then:
                NewUI := TestUI()
                set NewUI(1).Param = Red
                set NewUI(2).Param = MakeColorFromHSV(45.0,1.0,1.0)
                PlayerUI.AddWidget(NewUI(0),player_ui_slot{ZOrder:=0,InputMode := ui_input_mode.None})

    TestUI():tuple(canvas,M_TestColor_Inst_material,M_TestColor_Inst_material)=

        TestMat1:=M_TestColor_Inst_material{}
        TestMat2:=M_TestColor_Inst_material{}

        Canvas:= canvas:
            Slots := array:
                canvas_slot:
                    Anchors := anchors{Minimum := vector2{X := 0.5, Y := 1.0}, Maximum := vector2{X := 0.5, Y := 1.0}}
                    Offsets:=margin{}
                    Alignment := vector2{X := 0.5, Y := 1.2}
                    SizeToContent := true
                    Widget := stack_box:
                        Orientation := orientation.Vertical
                        Slots := array:
                            stack_box_slot:
                                HorizontalAlignment := horizontal_alignment.Center
                                VerticalAlignment := vertical_alignment.Center
                                Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                Distribution := option{1.0}
                                Widget :=  stack_box:
                                    Orientation := orientation.Horizontal
                                    Slots := array:
                                        stack_box_slot:
                                            HorizontalAlignment := horizontal_alignment.Center
                                            VerticalAlignment := vertical_alignment.Center
                                            Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                            Distribution := option{1.0}
                                            Widget :=  text_block:
                                                DefaultText:= S2M("RED TEXT")
                                                DefaultTextColor:=MakeColorFromHex("FF0000FF")
                                        # stack_box_slot:
                                        #     HorizontalAlignment := horizontal_alignment.Center
                                        #     VerticalAlignment := vertical_alignment.Center
                                        #     Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                        #     Distribution := option{1.0}
                                        #     Widget := texture_block:
                                        #         DefaultImage:=Star_mask
                                        #         DefaultDesiredSize:=vector2{X:=250.0,Y:=250.0}
                                        #         DefaultTint:=MakeColorFromSRGB(1.0,0.75,0.0)
                            stack_box_slot:
                                HorizontalAlignment := horizontal_alignment.Center
                                VerticalAlignment := vertical_alignment.Center
                                Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                Distribution := option{1.0}
                                Widget :=  stack_box:
                                    Orientation := orientation.Horizontal
                                    Slots := array:
                                        stack_box_slot:
                                            HorizontalAlignment := horizontal_alignment.Center
                                            VerticalAlignment := vertical_alignment.Center
                                            Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                            Distribution := option{1.0}
                                            Widget :=  material_block:
                                                DefaultImage:=TestMat1
                                                DefaultDesiredSize:=vector2{X:=250.0,Y:=250.0}
                                        stack_box_slot:
                                            HorizontalAlignment := horizontal_alignment.Center
                                            VerticalAlignment := vertical_alignment.Center
                                            Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                            Distribution := option{1.0}
                                            Widget := material_block:
                                                DefaultImage:=TestMat2
                                                DefaultDesiredSize:=vector2{X:=250.0,Y:=250.0}
                            stack_box_slot:
                                HorizontalAlignment := horizontal_alignment.Center
                                VerticalAlignment := vertical_alignment.Center
                                Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                Distribution := option{1.0}
                                Widget :=  stack_box:
                                    Orientation := orientation.Horizontal
                                    Slots := array:
                                        stack_box_slot:
                                            HorizontalAlignment := horizontal_alignment.Center
                                            VerticalAlignment := vertical_alignment.Center
                                            Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                            Distribution := option{1.0}
                                            Widget :=  color_block:
                                                DefaultColor:=Red
                                                DefaultDesiredSize:=vector2{X:=250.0,Y:=250.0}
                                        stack_box_slot:
                                            HorizontalAlignment := horizontal_alignment.Center
                                            VerticalAlignment := vertical_alignment.Center
                                            Padding := margin{Left:=0.0,Top:=0.0,Right:=0.0,Bottom:=0.0}
                                            Distribution := option{1.0}
                                            Widget := color_block:
                                                DefaultColor:=MakeColorFromHSV(45.0,1.0,1.0)
                                                DefaultDesiredSize:=vector2{X:=250.0,Y:=250.0}

        return (Canvas,TestMat1,TestMat2)

someone on twitter found a workaround. Directly writing color with RGB values should work
like:

color{R:=0.0,G:=1.0,B:=0.0}

Hey there @Macilvoy : Colours in Verse use the ACES 2065-1 colourspace, not sRGB. That being said, however, there are some bugs in the colour conversion APIs that we are aware of. This will be addressed in a future update.

1 Like

Heey @sonictke, also related to verse colors topic, can we get some info or update about the state of color structs in verse being RGB with no Alpha channel? Since UEFN release it has the same problems/limitations and we never received any info, update or aknowledgement about…

Due to the missing Alpha, some usages are impossible and glitchy, specially more noticeable on any material usage, since materials colors takes RGBA (vec4) inputs, but verse color struct does not have that A channel, leading to wrong colors, or completely ignoring the alpha values when displaying. Materials Graphs in general does not have vec3 params, going directly from vec2 to vec4 (also non existent in verse).

Due to that, the only current workaround for this limitation is completely avoiding using vec4 params in materials, and instead using 3 or 4 individual Scalars for each channel instead. This is much more tedious to work due to fragmented nodes, it also removes the color preview from non-verse workflows inside editor (such as editing a material instance), and is not compatible with some built-in read-only material functions and parameters.

I don’t know how that can be fixed in the future, maybe adding alpha channel to the color verse struct, or creating another format that handles it when needing to be used across the engine…

At the Verse API level, the original decision not to make color include alpha was a purposeful one. Alpha math operations are not well-defined, and we did not want to mandate our own standard of what alpha math should be. In a future release, we are planning on adding an official color_alpha API that does include an alpha component, along with some basic (hopefully non-controversial) math operations around it.

That being said, we are aware that some of the existing UIs (like the UE material interface) do work with alpha components, but you shouldn’t be seeing “wrong” colours show up. Could you elaborate on that? The workflow UX issues (e.g. needing to use individual scalar components) are definitely annoying and we are aware of that.

1 Like

FORT-938985 has been added to our ‘To Do’ list. Someone’s been assigned this task.

I need to make some tests to confirm, but since the struct does not have alpha, it’s not clear for us if the alpha on the vec4 will use the default value currently set on the material/material instance, or if it will be overriden by 0.0 or 1.0 when using with verse.

I had problems in the past due to transparency and other color manipulation math (like using alpha channel for extra data not necessarely being transparency), and was confusing to understand what was wrong until I migrated to scalars and everything worked fine.

I would need to make a testing environment to try understanding what happened, if was due to some overriden value, a wrong default in material that I forgot or something else, then I can make a proper bug report related to it if needed.

But thanks for talking about the design behind, it explains a lot! Also having a color_alpha, even with it being just for parameters without the math operations, would be a huge benefit already! (Maybe some conversion such as (Color:color).AddAlpha(Alpha:float):color_alpha would be already enough for most use cases?)