WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Graphics Help (https://www.wowinterface.com/forums/forumdisplay.php?f=14)
-   -   How does WoW manage decimal point on "SetPoint", "SetSize" and so on? (https://www.wowinterface.com/forums/showthread.php?t=55792)

Layback_ 10-05-17 09:32 PM

How does WoW manage decimal point on "SetPoint", "SetSize" and so on?
 
Hi all,

Title says pretty much all.

How does WoW handle decimal point on "SetPoint", "SetSize" and so on?

Last time when I tested it, I captured an image and zoomed in to see how this is managed and seemed like WoW would automatically scale it up or down based on its value.

AFAIK, drawing something like 10.42 pixel by 10.55 pixel is not available (not only on WoW, but on PC in general) as the minimal unit is 1 pixel.

I've previously asked about "pixel perfection" here on WoWI and thankfully got awesome comments and guide regarding it.

But, before I proceed, I would like to understand how those decimal points are actually handled on WoW.

Thank you.

Resike 10-06-17 02:25 PM

You can draw stuff even on fraction of pixels, the game will blur/alpha out those edges and the image will look blurry/buggy.

Layback_ 10-06-17 04:06 PM

Quote:

Originally Posted by Resike (Post 325418)
You can draw stuff even on fraction of pixels, the game will blur/alpha out those edges and the image will look blurry/buggy.

Really?! That's interesting!

Cause, as I said, I wasn't able to recognize those blurry/buggy edges when I zoomed it in while I was testing it.

Maybe I should try it again with another texture (or just a color texture).

semlar 10-06-17 05:22 PM

Fractions get rounded to the nearest pixel, you can't draw something halfway between two pixels.

The client has an internal resolution with a height of 768 pixels (width depends on widescreen format), and that gets stretched to fit the size of the window on the player's monitor. Even if you use whole numbers in your code, those aren't going to map 1:1 with pixels on their screen, so you're generally dealing with rounded fractions anyway.

There are also other factors that come into play like the UI scale setting and the scale of the frame itself.

Layback_ 10-07-17 03:22 AM

Quote:

Originally Posted by semlar (Post 325421)
Fractions get rounded to the nearest pixel, you can't draw something halfway between two pixels.

The client has an internal resolution with a height of 768 pixels (width depends on widescreen format), and that gets stretched to fit the size of the window on the player's monitor. Even if you use whole numbers in your code, those aren't going to map 1:1 with pixels on their screen, so you're generally dealing with rounded fractions anyway.

There are also other factors that come into play like the UI scale setting and the scale of the frame itself.

Hm......... interesting, but complex :confused:

So, would that be the reason for those backdrops with 1 pixel edge (or something that is reasonably small) being extended by 1 pixel especially for (like) nameplates as they are continuously moving and their actual positions are fractions, in fact, which would cause rounding?

Resike 10-08-17 03:36 AM

Quote:

Originally Posted by semlar (Post 325421)
Fractions get rounded to the nearest pixel, you can't draw something halfway between two pixels.

The client has an internal resolution with a height of 768 pixels (width depends on widescreen format), and that gets stretched to fit the size of the window on the player's monitor. Even if you use whole numbers in your code, those aren't going to map 1:1 with pixels on their screen, so you're generally dealing with rounded fractions anyway.

There are also other factors that come into play like the UI scale setting and the scale of the frame itself.

Ofc you can't draw between pixels, however if you don't round the numbers yourself then the engine is going to render those textures differently:



You can clearly see something is wrong with the left/right border of these pet frames, and that would be the not rounded SetPoint x value.

And this is a chain of command, if the frame is not placed pixel pefectly then the topleft border is neither and so on everything that SetPointed to the topleft border so the topright border neither on integer pixels.

Lombra 10-09-17 12:47 PM

Quote:

Originally Posted by Layback_ (Post 325416)
AFAIK, drawing something like 10.42 pixel by 10.55 pixel is not available (not only on WoW, but on PC in general) as the minimal unit is 1 pixel.

This is correct. Well, technically there are subpixels which, while relevant to the topic, is not really necessary to explain the concept.

Put simply, if you have a black texture and a white texture directly next to each other which align perfectly to the pixel grid, things will work as expected. However, if they are positioned such that the border between the two texture ends up (logically) in the middle of a pixel, that one pixel will be be gray.

At least, that's the idea. After testing briefly in game I couldn't actually produce any fractional pixel drawing... :thinking: Not sure under what circumstances it will occur.

Layback_ 10-09-17 10:52 PM

Hi Lombra,

Quote:

Originally Posted by Lombra (Post 325436)
At least, that's the idea. After testing briefly in game I couldn't actually produce any fractional pixel drawing... :thinking: Not sure under what circumstances it will occur.

So, I've been testing this while I was creating custom nameplates with oUF (as I stated above) and even if I set their backdrop edge size to 1px, they (edges) will get extended or shrunk by 1px, recursively, while nameplates are continuously moving.

I guess it's happening because those edges are positioned between two pixels (as semlar and Resike had mentioned) while they were moving.

Resike 10-10-17 02:25 AM

Quote:

Originally Posted by Layback_ (Post 325440)
Hi Lombra,



So, I've been testing this while I was creating custom nameplates with oUF (as I stated above) and even if I set their backdrop edge size to 1px, they (edges) will get extended or shrunk by 1px, recursively, while nameplates are continuously moving.

I guess it's happening because those edges are positioned between two pixels (as semlar and Resike had mentioned) while they were moving.

I don't think you can do anything to prevent this for nameplates since the game is moving them and not you.

There is another case when you move frames and their FontStings are jumping around 1-1 pixels, that's also caused by not setting the x, y values correctly, like centering a FontString with 6 pixel heigth on a 7 pixel height frame, and the game can't decide where to render the FontString. Usual solution is to not to use center, left, right, top and bottom anchors for FontStrings.

Terenna 10-10-17 07:59 AM

So I ran into this issue for some 1 pixel backdrops I was using on rNameplates back before zork performed wizardry and discovered how to let oUF make nameplates. I determined that the ratio of the x-axis of the worldframe (768) and the x-axis pixel count (at the time my 1080p monitor) was a ratio of 32/45 when reduced, by setting my insets on the backdrop to 32/45 instead of 1, I was able to achieve pixel perfection even when the nameplates moved about the screen. I have quit wow since getting my 1440p monitor, so perhaps I'd have to use 8/15 now.

Give this a shot maybe?

Layback_ 10-10-17 08:51 AM

Quote:

Originally Posted by Resike (Post 325442)
I don't think you can do anything to prevent this for nameplates since the game is moving them and not you.

There is another case when you move frames and their FontStings are jumping around 1-1 pixels, that's also caused by not setting the x, y values correctly, like centering a FontString with 6 pixel heigth on a 7 pixel height frame, and the game can't decide where to render the FontString. Usual solution is to not to use center, left, right, top and bottom anchors for FontStrings.

Yeah... was forgetting about FontStrings.

Setting a proper font size and its position was also the pain in the axx which I'm still struggling with :(

Quote:

Originally Posted by Terenna (Post 325443)
So I ran into this issue for some 1 pixel backdrops I was using on rNameplates back before zork performed wizardry and discovered how to let oUF make nameplates. I determined that the ratio of the x-axis of the worldframe (768) and the x-axis pixel count (at the time my 1080p monitor) was a ratio of 32/45 when reduced, by setting my insets on the backdrop to 32/45 instead of 1, I was able to achieve pixel perfection even when the nameplates moved about the screen. I have quit wow since getting my 1440p monitor, so perhaps I'd have to use 8/15 now.

Give this a shot maybe?

Sweet!

I'll give it a shot and see how I go with it :D

-- EDIT# 1

Did you mean by "size"?

-- EDIT# 2

hm..... I've set the size to UIParent:GetEffectiveScale() which would return the value that you've mentioned.

It's working fine with small nameplates, but still extending/shrunk by 1 px for huge nameplates (like boss, etc.)

semlar 10-10-17 05:27 PM

When I made pixel perfect nameplates some years ago, rather than anchor my frame to the existing nameplates I manually calculated their offset relative to the WorldFrame and moved them OnUpdate (later I realized I could do this in response to the nameplate movement instead).



The forum resizing this image is a perfect example of what the game is doing when it blurs your texture by scaling it for the client's window.

There are 2 factors that come into play if you want to prevent the game from blurring your textures:

1) The size/scale of your image on the screen needs to exactly counter any scaling the client is doing to draw it in the window.

2) The offset of the edge of the texture on screen needs to fall on what I generally refer to as a pixel boundary. In other words, the top left (or any edge) of the texture should be aligned with the grid of pixels on screen; if it falls between them the game will round it in either direction and skew your texture.

You need a function to calculate what size your texture should be, but you also need one to calculate the proper offset for your anchors.

Resike 10-11-17 02:23 PM

Quote:

Originally Posted by semlar (Post 325446)
When I made pixel perfect nameplates some years ago, rather than anchor my frame to the existing nameplates I manually calculated their offset relative to the WorldFrame and moved them OnUpdate (later I realized I could do this in response to the nameplate movement instead).



The forum resizing this image is a perfect example of what the game is doing when it blurs your texture by scaling it for the client's window.

There are 2 factors that come into play if you want to prevent the game from blurring your textures:

1) The size/scale of your image on the screen needs to exactly counter any scaling the client is doing to draw it in the window.

2) The offset of the edge of the texture on screen needs to fall on what I generally refer to as a pixel boundary. In other words, the top left (or any edge) of the texture should be aligned with the grid of pixels on screen; if it falls between them the game will round it in either direction and skew your texture.

You need a function to calculate what size your texture should be, but you also need one to calculate the proper offset for your anchors.

The problem with this is extremely hard to do if you have no clue what are you doing, and it can also take up a lot of resources. I think the game engine should do this by itself and it should do it a lot better then the current anchoring system. Anything that is not a 3D object should be rounded to pixel perfect by default.

Another good example when the GameTooltip border gets screwed, that's also caused by the wrong positioning anchor values.

semlar 10-11-17 04:06 PM

Quote:

Originally Posted by Resike (Post 325449)
I think the game engine should do this by itself and it should do it a lot better then the current anchoring system. Anything that is not a 3D object should be rounded to pixel perfect by default.

While pixel-perfection might be desirable when trying to draw straight single-pixel borders, it produces hard, jagged lines everywhere else. A pixel-perfect image also can't be scaled, so will end up looking quite small on a higher resolution monitor.

Anti-aliasing techniques are used to produce a smoother experience for general use. It's a complicated subject, and different applications require different approaches for better results.

Snapping the edge of a frame to the nearest pixel also produces a perceptibly less-smooth movement system than interpolating it the way the game does normally.

Resike 10-12-17 06:37 AM

Quote:

Originally Posted by semlar (Post 325451)
While pixel-perfection might be desirable when trying to draw straight single-pixel borders, it produces hard, jagged lines everywhere else. A pixel-perfect image also can't be scaled, so will end up looking quite small on a higher resolution monitor.

Anti-aliasing techniques are used to produce a smoother experience for general use. It's a complicated subject, and different applications require different approaches for better results.

Snapping the edge of a frame to the nearest pixel also produces a perceptibly less-smooth movement system than interpolating it the way the game does normally.

Ofc it can be scaled, you just have to reapply the pixel perfect methods after every SetScale and OnSizeChanged method/script, that's why i said it can draw a lot of resources.

Basically you make sure the width/height/edgesize are integer pixels by rounding, and you make sure the frame itself (and it's childrens) is not on fraction pixels or you check the GetTop/GetBottom/GetLeft/GetRight boundaries and round them to integer pixels.
And you also have to do this every time the game's resolution/window size or the UIParent scale gets changed.

semlar 10-12-17 03:56 PM

Quote:

Originally Posted by Resike (Post 325454)
Ofc it can be scaled, you just have to reapply the pixel perfect methods after every SetScale and OnSizeChanged method/script, that's why i said it can draw a lot of resources.

A pixel-perfect texture is, by definition, a specific number of pixels. Every pixel is drawn where it's supposed to be.

You can have a repeating pixel-perfect image, like a 1px border around a resizable frame, but scaling a pixel-perfect texture doesn't make any sense.

Resike 10-13-17 06:15 AM

Quote:

Originally Posted by semlar (Post 325458)
A pixel-perfect texture is, by definition, a specific number of pixels. Every pixel is drawn where it's supposed to be.

You can have a repeating pixel-perfect image, like a 1px border around a resizable frame, but scaling a pixel-perfect texture doesn't make any sense.

It does just not the way you imagined it. Lets say You have a resizable frame with a 1px border around it just like you said:

Lua Code:
  1. frame
  2. frame.border
  3. frame.scaled

You start sizing the frame, and you determine a scaling value by it's initial width/height value and the current one, the frame itself never gets scaled just sized, however you apply this scale value to the frame.scaled frame which is basically a virtual clone frame of the frame itself and all of it's child elements also gets scaled properly.

Every time the the sizing is done you make sure the frame is in pixel perfect conditions. (Anchored correctly with integer x, y values and have integer width and height values).
Anything you want to be scaled you parent to frame.scaled, BUT you anchor them to the frame! Which is always on a pixel perfect position. (FontStrings/etc).
Anything you DONT want to scale you parent it the the frame, and you also anchor to the frame too. (StatusBars/SubFrames/etc)

Now all you have left to do is to round the 1px edge size with this scaling value to an even number, means this 1px border only gets 2px big if the scaling value is >=1.5.
You can also use custom values here to set/determine when you want to add another pixel to this border.

This is how it works in action:

https://youtu.be/9EzZ_nUwUV0?t=38

This still does not cover every issue, however it does deals with most of them.

Like if the frame height is 10 pixel and you scale it by an extra 50% to 15 pixel, and initially you had a 4 pixel height FontString centered which fits perfectly, however the scaled FontString becomes 6 pixel height and you cannot fit this even number to the uneven 15 pixel by any way. So the centered FontString will jump a pixel up and down based on the engine's rounding. (If you have a good eye you can see this on the video.)

I can throw an example code for you about this, but i guess you get it how does this works.

Layback_ 10-15-17 07:17 PM

WoW... profound debates were going on while I was away :D

I honestly can't cut in nor have an idea about what to say or ask atm as I haven't gone through all comments.

However, I will definitely read them all :banana:


All times are GMT -6. The time now is 02:36 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI