2
\$\begingroup\$

I am using WebGL. I have an isometric grid which contains tiles. Some have 'tree' sprites on them. If I have my tree sprite loaded from a texture with a fixed resolution, when I zoom into the grid (scale things up), the sprite texture looks poor. How can I render sprites such that quality is maintained when the player zooms in?

Some provisos:

  • I can't use vector graphics, as the textures are far too detailed.
  • The scaling needs to be smooth.
\$\endgroup\$
6
  • 4
    \$\begingroup\$ Need more information. Are the sprites pixel art, rendered, hand-painted? If they're pixel art, you're best off just scaling them up with nearest-neighbor filtering, or perhaps hq4x. If they're high-resolution, you're best off either with a level-of-detail appraoch like you described, or simply using a very high resolution texture. \$\endgroup\$
    – mklingen
    Commented Feb 12, 2015 at 17:26
  • \$\begingroup\$ @mklingen - The sprites are currently PNG files. However, I'm happy to re-create them using whichever method is commonly most appropriate (or likely to give the best results). I could re-create them in any format or style. Voted up your comment, particularly because I never knew about hq4x and it looks interesting. \$\endgroup\$
    – Jordan
    Commented Feb 12, 2015 at 17:29
  • \$\begingroup\$ Welcome to the site; there is no "best" way in general and questions asking for such are generally too broad. Similarly, it's not a good idea to post potential solutions in your question itself. You can instead post them as answers yourself, and let the community's voting mechanism tell you if they're good; or you can just let somebody pose the same answer for the same general effect. I've made edits to your post accordingly. \$\endgroup\$
    – user1430
    Commented Feb 12, 2015 at 17:43
  • \$\begingroup\$ @JoshPetrie - Out of interest, surely there is a 'most efficient' way is there not? \$\endgroup\$
    – Jordan
    Commented Feb 12, 2015 at 18:12
  • 1
    \$\begingroup\$ Well, you didn't ask about efficiency, you asked about quality. The "most efficient" way to scale a texture is likely the least visually appealing. In general these sorts of things are all about balancing the various pros and cons of an approach against your specific needs, implementation, and bar for "good enough." Which is what makes them off-topic here. \$\endgroup\$
    – user1430
    Commented Feb 12, 2015 at 18:27

4 Answers 4

2
\$\begingroup\$

Assuming you are using the DOM (not canvas) for your Isometric grid, these ways may be possible:

  • Draw your Images at 10× the highest resolution you display them at, e.g. (1200×1200 for an image being displayed at 120×120).

  • Vector (SVG) is another choice, but fine detail is an issue for them, and, somewhat, performance difference also (Rasterising the image everytime you scale it down by a fraction of a pixel).

  • Spritesheets of different sizes for one sprite.

  • Everything can be relative to the size of the image/sprite, e.g. sprite is 44×44px and the isometric squares are 32×32px so the sprite is larger than the tile (e.g. boss enemies) or the sprite is 22×22px or 16×16px for infantry or player sprites. This can make scaling a lot smoother and easier to work around, everything divisible by 8 (a Byte) or 2 (2 bits) seems to do the trick.

\$\endgroup\$
3
  • \$\begingroup\$ This sounds like an interesting approach. However, i'm using WebGL, not canvas nor the DOM. (Using PIXI JS) as the rendering engine. \$\endgroup\$
    – Jordan
    Commented Feb 15, 2015 at 13:33
  • 2
    \$\begingroup\$ Ah, the PIXL rendering engine is good, I don't think I could help you with WebGL (Haven't done much with WebGL). I hope you find the answer you're looking for. \$\endgroup\$ Commented Feb 15, 2015 at 14:06
  • 1
    \$\begingroup\$ @JordanDolan You are using WebGL? Why didn't you say so in your question? You should be able to set different interpolation algorithms in that case. \$\endgroup\$
    – Philipp
    Commented Mar 17, 2015 at 14:42
2
\$\begingroup\$

You can't. No processing can add quality or resolution to your textures if it wasn't there from the beginning. If you really need better quality, then you must use bigger assets. Then your question will become: "how to save quality when scaling textures down", and the answer will be - by using mipmaps.

You can cheat by:

  • blurring pixels when they become too big (looks better for realistic look),
  • never blurring pixels when they become too big (looks better for pixel art)
  • for single color images you can use distance maps, which is basically a way of packing flat vector graphics into a texture and displaying them with a fragment shader. In practice, this is only useful for displaying fonts.
\$\endgroup\$
1
\$\begingroup\$

If you are doing webgl and can make pixel shaders, check out signed distance textures. They are textures but scale like vector graphics. http://blog.demofox.org/2014/06/30/distance-field-textures/

\$\endgroup\$
1
  • \$\begingroup\$ This is a link-only answer. Could you extract the relevant points from it into the answer body in case the link goes down? \$\endgroup\$
    – Anko
    Commented Oct 14, 2015 at 8:53
1
\$\begingroup\$

What you need, at least I guess, is an implementation of mipmaps for your 2D trees.

A mipmap are a large frame in which the same object is present in different resolutions. For example, you can have a texture with a 1024x1024 tree image, next to it another one at 512x512, then a 256x256 one and so on... Then your tree object checks for the zoom level the user is currently experiencing (you can easily implement a method for that), and uses the right frame for rendering the tree.

Result is, if you zoom out enough won't need to draw a high-res image, whilst a 128x128 would be enough. On the other hand, if the user zooms in at a 10x level, he expects to see more detail than a 1x zoom view; and he would be bored to see just giant pixels, independently from smoothing filters (bilinear, trilinear...) applied.

So, actually, you draw inside the same box area (smaller or bigger due to zoom level), but:

  • Drawing lower-quality images in a small box is faster than drawing a high-quality image inside the same box;
  • Drawing high-res images when zooming in resolves the problem you asked for: better quality on zooming.

Also, always remember that downscaling when drawing is slower than upscaling; this is important to decide when a low-res frame should be replaced by a high-res frame (tipically you do this just before the low-res frame would be upscaled, in order to not lose visual quality on a gamer's point of view).

Sources: good old Wikipedia - Mipmap

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .