mattrdowney / planetaria

A Unity framework for Euclidean 2-sphere games (e.g. 2D virtual reality games) [quasi-MIT license]
Other
10 stars 2 forks source link

Circular Textures #44

Closed mattrdowney closed 5 years ago

mattrdowney commented 6 years ago

Texture with pixels (still picture elements) laid out like so:

Center pixel is a circle with radius 1/sqrt(pixels). Next element is a ring of three pixels surrounding the arc from 1/sqrt(pixels) to 1/(2sqrt(pixels)) - three segments (preferably centered). And so on with sizes 1,3,5,7,9 (sum: 1, 4, 9, 16, 25...), inner radii 1/[(k-1)sqrt(pixels)] to 1/[(k)sqrt(pixels)] The textures have even resolution (i.e.) area = pir^2 and the inner area indeed increases by r squared (hence the 1, 4, 9, 16, 25...).

To run fast on GPU, it's hard to say what would have to be done...

That being said if the pixels were laid out in a texture colors[n]:

the radius essentially gives an additive shift radial_index: +1, +4, + 9, etc the angle combined with the radial_index gives a angular_index: +0, +1, +2, etc

mattrdowney commented 6 years ago

(preferably centered) so that pixel bands appear to be interlaced rather than having a gap along angle=0

mattrdowney commented 6 years ago

Mipmapping, even for power of 2 textures, is non-trivial.

mattrdowney commented 6 years ago

I was wondering how radial textures would be compressed and it turns out it was wayyy simpler than I thought:

If a radial texture uses the following pixels: x xxx xxxxx xxxxxxx xxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxx xxx.xxx.xxx.xxx.xxx

Then it might be said to be a 8×15 texture with extra pixels that are not used being left at the liberty of the programmer: ideally being used to maximize accuracy and minimize file size.

E.g. for JPEG images that compress in 8x8 blocks the following would be a good encoding scheme:

aaaaaaaa abcabcab abcdeabc abcdefga abcdefghiabcdefg abcdefghijkabcde abcdefghijklmabc abcdefghijklmnoa

Where a,b,c... indicate the position of the pixel in the row.

This assumes accuracy is the most important. The final (unrepresented) block would likely match the average color of the other three 8x8 blocks.

mattrdowney commented 6 years ago

On why:

Z-culling isn't particularly relevant in Planetaria, c-distance is more relevant (center distance).

Additionally, if you imagine placing square tiles all over a sphere, the seams between edges would have uneven contours at points (which would be visually distracting). Circles, on the other hand, fare a little better and work better at the vertices of a "subdivided octahedron sphere".

mattrdowney commented 6 years ago

On why (sub-note):

Radial textures are intended for a sparce/flyweight representation of PlanetRenderers that can be run-length encoded. I might call that a texelplex or something for the hell of it.

If it's hard to visualize, this is for "painting the ground of a circle" (e.g. with grass or dirt) and is conceptually similar to reusable tile textures.

Renderer rotation on a Planet must wrap continuously (ideally) for aesthetically pleasing tiling.

mattrdowney commented 6 years ago

The texelplex would probably do best if quasi-recursively defined. E.g. the texelplex stores a reference to the radial textures (sort of like how gifs reference their pixel color definitions) and then maps from the same circular grid as before (storing only a unique index into the texture array).

Conveniently, the number of pixels in a ring is 1 +2r, which increases linearly like the circumference (2pir), which means that c-distance would work well for texturing (without causing graphical artefacts at seams as the radius expands).

mattrdowney commented 6 years ago

Visual note: tiling near the pole will look uncannily similar to the biohazard symbol.

mattrdowney commented 6 years ago

I have come to the conclusion that my favorite texture format is:

2,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62, etc (conveniently symetric and avoids a double radius at the first pixel)

Where compression/packing looks like:

abab.abab.abab.abab efab.cdef.abcd.efab cdef.ghij.abcd.efgh ghij.klmn.abcd.efgh

which ends up being a n x 4n picture (4 columns for every row).

Notably: the center right column always starts with a and list cells in increasing order to the right (and decreasing and wrapping order to the left)

mattrdowney commented 6 years ago

I feel like simpler would be better, since this spiraled out of control and prime numbers make any two radial strips difficult to compress (e.g. a ratio of 3/5, 5/7, etc).

For the moment being, pixels should probably be compressed as a linear strip top-to-bottom, left-to-right, with run-length encoding.

In the future, compression might happen in cartesian-2D or polar coordinates, but for now that feature would be difficult to properly make.

mattrdowney commented 6 years ago

One possible encoding scheme:

Create three radial compression lines: left, right, and center.

E.g. 1,3,5,7,9 would use the left, right and center pixel to determine changes along the radius.

Create n circular compression lines as before.

Then combine results.

mattrdowney commented 6 years ago

A better sequence is 3x (1,3,5,7,9...)

Because 3 ~= pi (the circumference is 2 pi r (Note: the sequence is 1 + 2r))

mattrdowney commented 6 years ago

Name: PlanetariaTexture

mattrdowney commented 5 years ago

Done as of e68ed5f02fe884088a989f20ab09c766e1f9d4d5

(Although some comments are unfinished.)

The compression technique (four quadrants of a square texture) came to mind when looking at the most recent implementation of SphericalRectangleUVCoordinates, where the result of simple stretching of the square approximated a spherical circle, hence the tangent.

mattrdowney commented 5 years ago

I fucked up (twice)

mattrdowney commented 5 years ago

Seems to be done (tested on bivariate color scheme - not a checker board).

mattrdowney commented 5 years ago

Notably, none of this is happening on GPU (so it's slow and must be done in a pre-processing step).

mattrdowney commented 5 years ago

While Cartesian 2D circles follow the PI*r^2 area formula, in spherical coordinates pixels close to the center are larger.

https://www.sciencedirect.com/science/article/pii/S0925772112000296#! Provides some good insights.

This is also similar to some shader I made for brick walls back in the day.