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. |
You can draw stuff even on fraction of pixels, the game will blur/alpha out those edges and the image will look blurry/buggy.
|
Quote:
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). |
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. |
Quote:
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? |
Quote:
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. |
Quote:
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. |
Hi Lombra,
Quote:
I guess it's happening because those edges are positioned between two pixels (as semlar and Resike had mentioned) while they were moving. |
Quote:
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. |
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? |
Quote:
Setting a proper font size and its position was also the pain in the axx which I'm still struggling with :( Quote:
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.) |
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. |
Quote:
Another good example when the GameTooltip border gets screwed, that's also caused by the wrong positioning anchor values. |
Quote:
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. |
Quote:
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. |
Quote:
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. |
Quote:
Lua Code:
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. |
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 04:24 PM. |
vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI