Texture stretching

This post i’ll be writing about a technique i call texture stretching. I use this technique to be able to draw nodes of various sizes using a single texture. This approach solves problems with differing texture scale factors that are caused by the varying sizes of the nodes.

The problem

The problem when scaling 2d images while rendering them to the screen is that you need to retain the original image’s aspect ratio. The aspect ratio is the ratio between the image’s width and it’s height. An image’s aspect ratio needs to be retained because otherwise the image’s contents will be deformed. For example, if you have an image of a circle which you scale without preserving it’s aspect ratio, the scaled image would show an oval.

To scale an image while retaining it’s aspect ratio you can only use uniform scaling. This means that you have to scale the width of the image by just as much as you scale the height. The problem with nodes is that these have all sorts of widths and heights. The width is determined by the length of the node name and the names of it’s pins. This is required to properly fit the pin names within the nodes. The height of the node is determined by it’s number of input and output pins. Since nodes themselves can specify their name, their pin names and their number of pins this means that we cannot use uniform scaling for nodes. We need to use a scaling mechanism that is non-uniform, but retains the aspect ratio for important parts of the image.

The solution

I’ve already hinted a bit at the solution in the problem description. What you want to do is target specific parts of the image that need to retain their aspect ratio, and then use ‘unimportant’ parts of  the image to do the scaling. Our node textures are made of rounded rectangles. The most important parts of the image are the corners. Those cannot be scaled non-uniformly because that would cause the roundings to go out of their proportions. Between the corners there’s four edges, these contain borders at the sides of the node where we show pins and to the top of the node where we show the node’s title. We want these edges to only be scaled in a single direction. The horizontal edges can only be scaled horizontally, while the vertical edges can only be scaled vertically. If we apply these scaling restrictions we’re sure that the size of the area in between the borders doesn’t change in the directions that matter.

To respect these restrictions we can no longer render a single quad that stretches the entire texture over it. Instead we’re now required to render nine quads. Four quads for the corners, four for the edges, and the remaining quad in the center. Here’s now it’ll look:

In the image above you can see two samples of nodes rendered with a single quad, and nodes rendered with nine quads each respecting the scaling restrictions of the image.
Take for example the Add node. On the left you can see that if we’re rendering the node texture using a single quad that the corners are blown up and that the borders in between the areas we defined before are much thicker than intended. In the second Add node you can see that nine quads are used. The corner quads aren’t scaled at all which leave the roundings  nice and smooth. The horizontal scaling is only applied in the horizontal edges and the center area, thus no thick borders appear in the vertical edges. Similarly the vertical scaling is only applied in the vertical edges and the center area, thus no thick borders appear in the horizontal edges either. The center area is scaled in both the horizontal and vertical directions, but since this area doesn’t contain any shape that needs to retain it’s aspect ratio you dont see any issue here.
As a reference the Sine Wave node is in the image aswell, you can see that it shows the exact same corners and borders as the Add node, but it does provide extra room for the longer pin names.


©2021 Echo Gaming Entries (RSS) and Comments (RSS)  Raindrops Theme