Thread Tools Display Modes
10-05-17, 09:32 PM   #1
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
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.
  Reply With Quote
10-06-17, 02:25 PM   #2
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
You can draw stuff even on fraction of pixels, the game will blur/alpha out those edges and the image will look blurry/buggy.
  Reply With Quote
10-06-17, 04:06 PM   #3
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by Resike View Post
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).
  Reply With Quote
10-06-17, 05:22 PM   #4
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
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.
  Reply With Quote
10-07-17, 03:22 AM   #5
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by semlar View Post
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

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?

Last edited by Layback_ : 10-07-17 at 04:13 AM.
  Reply With Quote
10-08-17, 03:36 AM   #6
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by semlar View Post
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.

Last edited by Resike : 10-08-17 at 03:55 AM.
  Reply With Quote
10-09-17, 12:47 PM   #7
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Originally Posted by Layback_ View Post
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.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
10-09-17, 10:52 PM   #8
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Hi Lombra,

Originally Posted by Lombra View Post
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.

Last edited by Layback_ : 10-10-17 at 12:13 AM.
  Reply With Quote
10-10-17, 02:25 AM   #9
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Layback_ View Post
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.

Last edited by Resike : 10-10-17 at 02:32 AM.
  Reply With Quote
10-10-17, 07:59 AM   #10
Terenna
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 105
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?

Last edited by Terenna : 10-10-17 at 08:04 AM.
  Reply With Quote
10-10-17, 08:51 AM   #11
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by Resike View Post
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

Originally Posted by Terenna View Post
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

-- 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.)

Last edited by Layback_ : 10-10-17 at 09:25 AM.
  Reply With Quote
10-10-17, 05:27 PM   #12
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
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.

Last edited by semlar : 10-10-17 at 11:25 PM.
  Reply With Quote
10-11-17, 02:23 PM   #13
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by semlar View Post
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.
  Reply With Quote
10-11-17, 04:06 PM   #14
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by Resike View Post
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.

Last edited by semlar : 10-11-17 at 04:12 PM.
  Reply With Quote
10-12-17, 06:37 AM   #15
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by semlar View Post
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.

Last edited by Resike : 10-12-17 at 07:00 AM.
  Reply With Quote
10-12-17, 03:56 PM   #16
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by Resike View Post
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.
  Reply With Quote
10-13-17, 06:15 AM   #17
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by semlar View Post
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.

Last edited by Resike : 10-13-17 at 06:51 AM.
  Reply With Quote
10-15-17, 07:17 PM   #18
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
WoW... profound debates were going on while I was away

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

Last edited by Layback_ : 10-15-17 at 07:21 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Graphics Help » How does WoW manage decimal point on "SetPoint", "SetSize" and so on?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off