Jump to content

Welcome to Obsidian Forum Community
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more. If you already have an account, login here - otherwise create an account for free today!
Photo

flickering of some "tooltips windows" in UI


  • Please log in to reply
22 replies to this topic

#21
TGPrankster

TGPrankster

    (0) Nub

  • Initiates
  • 2 posts
  • Steam:TGPrankster

This is still happening for me as well in version 3.06.1254.



#22
dustytables

dustytables

    (1) Prestidigitator

  • Members
  • 5 posts

I'm not sure if this will help resolve the issue but changing font scale from the default seems to have fixed the issue in my last play session.  Adjusting it to any number seems to have fixed the jittery ui for the select skill tooltip.  Others who are experiencing the problem, please test and verify if this works for you.  

Playing on 3.06.1254

 

Using 6700k/980ti



#23
AnorZaken

AnorZaken

    (1) Prestidigitator

  • Members
  • 9 posts
  • Pillars of Eternity Backer
  • Deadfire Backer
  • Fig Backer

For playing in 1440p resolution a font scale of 110% seems to have (so far) eliminated it for me.

Excellent advice MaxQuest! :)

That's an old bug, which is still here (v3.06).

If it helps: I've noticed that it is related to global font scale (from settings > graphics).

In my case I had to change it from 130% to 127%, and flickering is gone :)

 

As for why this happens in the first place... I have a partial guess.

 

Basically I think it's a botched update-order of UI-elements / UI-scripts.

Undesired UI behavior, i.e. vibrations, could emerge from the subtle interactions of these points:

1. Each UI text-bubble consists of a couple of grouped UI elements.

2. The position of these elements depends on the size of other elements in the group, basically automatic layout / vertically stacking them.

3. There is some special adjustment going on, causing something akin to coordinate rounding, probably trying to align text to screen pixels?

4. When the layout of elements depend on the layout of other elements, the (element layout) update order becomes vital!

 

To understand why point 4) is so important let me explain to you why and how it can cause UI layout to flicker with a simple but representative example:

Imagine having three UI elements stacked vertically. Lets simply call them Top, Middle and Bottom to make it easy to follow.

One of these elements is our anchor, by which I mean that its coordinates are determined by something external to our example (e.g. by the position of your mouse pointer).

In the case of PoE, bottom-up seems to be the way floating UI elements are "anchored" most of the time - regardless it is what I will go with for this example.

As for the other two elements, i.e. Middle and Top, their coordinates are relative such that the Middle depends on Bottom, and Top depends on Middle.

Basically lets call the vertical coordinate y, and assume the top of the screen is y = 0 in which case the above description can be eloquently expressed by these simple equations:

Bottom.y = [some input value] - Bottom.height
Middle.y = Bottom.y - Middle.height
Top.y = Middle.y - Top.height

So far so good.

What could go wrong, right?

 

 

Well the above coordinates need not be integers, they can be floats, and now imagine that for text rendering we have some pixel-alignment script, that rounds positions in such a way as to give nicely rendered text (to avoid text blur).

Such a script would cause a small change in the elements y-value, which might seem innocent enough until you realize it can cause a cascading effect with a delay of one update cycle.

(The update cycle might or might not be coupled to frames - it's not important but perhaps easier to understand if it is, so for simplicity we can assume it is a 1 frame delay. Don't worry if this sounds confusing I'm going to explain it properly below.)

Specifically if the script and UI-element update order isn't properly determined, then we can randomly get "bad ordering" for some parts of the UI and not others.

So what is a "bad ordering", and how does it actually manifest as flicker?

 

We'll see this in the most clear way by putting in actual numbers into the simple equations above, and then follow the flow of execution for a "bad ordering" case through the rendering of two consecutive frames:

1. Lets assume the mentioned text-to-pixel alignment is applied to all three of our UI elements; Bottom, Middle, and Top.

2. Pick some random value for [some input value], lets say 800.0 for this example (any value will do).

3. Pick some "bad ordering" of UI script execution so we can showcase the issue. For this example lets go with the following order:

[Calculate all height values] --> [Calculate all y values] --> [Perform all text-to-pixel alignment]

Looks deceptively innocent right? Well anyway I also have to specify the relative order in which our UI elements update.

This is also part of the order and we can't look at the execution flow without determining it. Lets assume the following order for our (unfortunate) example:

Top --> Middle --> Bottom

Still looking deceptively safe and sound? Wrong!

 

4. Render the first frame:

a) Calculate all height values - Lets say our UI elements have the following heights:

Top.height = 124.8

Middle.height = 50.4

Bottom.height = 98.2

b) Calculate all y values*:

Top.y = 526.6   (651.4 - 124.8 )

Middle.y = 651.4   (701.8 - 50.4)

Bottom.y = 701.8   (800.0 - 98.2)

c) Perform pixel alignment (basically some rounding scheme, lets go with round-to-nearest):

Top.y = 527   (+0.4)

Middle.y = 651   (-0.4)

Bottom.y = 702   (+0.2)

d) Draw our UI elements (at the above coordinates).

 

*Lets assume that asking for an y-value that has not been previously calculated / cached triggers its calculation,

 so for the very first frame we actually have Bottom->Middle->Top order. Lets refer to this as the "cache assumption".

 (We are doing simple layout on a flat surface so any sane UI configuration should be free of circular dependencies.)

 

5. Render the second frame:

a) Calculate height values - These have not changed so refer to 4.a above.

b) Calculate all y values:

Top.y = 526.2   (651.0 - 124.8 )

Middle.y = 651.6   (702.0 - 50.4)

Bottom.y = 701.8   (800.0 - 98.2)

c) Perform pixel alignment:

Top.y = 526   (-0.2)

Middle.y = 652   (+0.4)

Bottom.y = 702   (+0.2)

d) Draw our UI elements (at the above coordinates).

 

...Oops!

Notice that the coordinates for Top and Middle are no longer the same - they have changed by one pixel!

 

Now there are multiple caveats with this particular example...

1. If you continue to render frame 3, 4, 5, etc. you will discover that our UI elements continue to climb higher and higher on the screen. Obviously this is not the case in practice so this particular example is extremely horrible - i.e. the actual code used in PoE is much better than this, but as an introduction to the importance of execution order and how it can cause small instabilities this example is simple and sufficient enough.

2. Pixel alignment has been over-simplified. In practice for a multi-row piece of text, each line needs to be aligned separately, which might affect the height.

3. The actual gui has a smarter design, but I believe the flaw is of the same nature to the one presented here - i.e. something somewhere in the code is reading a stale value from the previous frame, causing elements to move slightly from one frame to the next.

 

Edit:

Gave it some further thought....

A more probable implementation is that the y-values of each element is independent of the y-values of the other elements - instead depending on a sum of heights, e.g:

Top.y = [some input value] - Top.height - Middle.height - Bottom.height.

The y-values are (seemingly) decoupled from each other thanks to this, affording much more stability.

And (seemingly) pixel alignment wont affect this.

...

Until you realize point 2 above about how multi-row text-to-pixel alignment might affect height very slightly.

Because unlike my first example above, which is completely unstable and derails at the smallest error, this approach would be much more stable.

But a small difference in height of one element, can push another element by a very small amount, even less than a single pixel, and that could still affect how the different rows of that second element gets aligned, which in turn can slightly change the height of the second element, and so and and so forth.

Why this is a resonable hypothesis of what's actually going on is because in this case the "drift" of the elements is bounded by the size of the adjustment that pixel alignment can make and the number of elements involved - it can never drift infinitely like my first example, but it can make small oscillations!

 

Edit2:

By the way, the reason why fiddling with v-sync might seem to help some people is very simple:

The oscillations happen over the frames rendered (fps), which is not the same as frames drawn to the screen.

So if your fps is about twice* the refresh-rate of your monitor, then you will only see every other frame, effectively preventing you from seeing the oscillation.

It is still technically occurring but never visibly displayed on your monitor. (*or any other multiple of 2)


Edited by AnorZaken, 10 November 2017 - 03:37 PM.

  • Messier-31 likes this




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users