3D graphics using arrays?

Discuss game development design and post your game ideas

Post » Wed Mar 15, 2017 10:45 am

R0J0hound wrote:It's more of a point cloud renderer than a voxel one. I'm pretty sure something more efficient is done with voxel renderer's than drawing everything.

Loops in the event sheet are probably the biggest culprit of why it's slow. I've compared equivelent loops in just JavaScript and they're over 20x faster. I guess in general the slowdown is events are interpreted and there is some overhead involved with it.


@R0j0hound, I just had a few ideas on how to speed it up. Since the loops seem to be the problem, and not the actual rendering I was thinking of different ways of how to optimize it.

Event based for each loops are not very good. There's the internal higher level ones that's a lot faster, (like when you pick something by a variable/boolean/family there's an internal for each) so here's my proposal approach.

On start of layout. Create Hidden sprites on a hidden layer and set XY and (and maybe a variable for Z). You could even pin them to a dummy object then Rotate dummy object, or rotate the entire layer, to prevent any picking which also a bit of a performance hog. I'm imagining these sprites would represent a top view in this hidden layer, rotating the dummy object would be a rotation along X axis. (horizontal in a front view). Then have the values from these hidden sprites drive the tile map rendering? Basically no loops would be needed to calculate new point cloud positions when rotating the object. Do you think something like that would work?

If that works Maybe more if these tricks can be used to limit the amount of loops, and increasing the performance without using js.
Follow my progress on Twitter
or in this thread Archer Devlog
B
40
S
17
G
17
Posts: 991
Reputation: 12,654

Post » Wed Mar 15, 2017 9:11 pm

It is faster, although less readable, even when doubling the number of points. It's actually a bit faster just using sprites instead of plotting to a tilemap, although coloring is a bit trickier. You can switch between the two with the use_tilemap variable.
https://drive.google.com/open?id=0B-1_F ... TNuUS04NnM

Loading a model file takes a few seconds right now. Tokenat is inefficient with large amounts of text. There are some topics on loading a dictionary that show faster ways which could be used here.
B
92
S
32
G
109
Posts: 5,291
Reputation: 70,993

Post » Wed Mar 15, 2017 9:35 pm

That is pretty awesome.
B
33
S
18
G
28
Posts: 2,493
Reputation: 20,950

Post » Thu Mar 16, 2017 12:02 am

Nice. I played around with it a little bit and managed to get a constant 60 fps but that was only when rotatating in one axis. I'm going to continue my tests tomorrow to see if I can push it even further.

Using the tile map is very easy on draw calls but heavy on cpu, using sprites is heavier on draw calls but a lighter on the cpu. I'm going to see if I can figure out a way to make it even less cpu intensive. I have some ideas I'm going to try out tomorrow.

I'll get back with results once I've tried it.
Follow my progress on Twitter
or in this thread Archer Devlog
B
40
S
17
G
17
Posts: 991
Reputation: 12,654

Post » Thu Mar 16, 2017 12:33 am

I was also thinking maybe it's possible to store x, y, z in one value using rgb() format. If so.... A one dimensional array could hold all the position values... Maybe you would lose some accuracy with using rgb value, but maybe not noticeable with tile map rendering. Haha ...here's a wacky idea. Theoretically you could pretty much control point translation using color. 0,0,0 (black) would be top left corner deep in z, while 1,1,1 would be bottom right near in z.

If we normalize the hidden point cloud positions based on the window width and height, we could also store these points in a 2d array the same size as the tile map, and maybe use that as an intermediate before rendering with the tile map.
Follow my progress on Twitter
or in this thread Archer Devlog
B
40
S
17
G
17
Posts: 991
Reputation: 12,654

Post » Thu Mar 16, 2017 2:06 am

The models already are in pretty much normalized coordinants of -1 to 1. Using color to define position probably has way too low of percision to be useful, not to mention it would be slow to constantly need to get the individual components.

That's odd that using only one axis of rotation is that much faster. The rotation math is only done on three objects, one for each axis X,y and z. We could combine the equations together at the expense of being readable.

The zsorting of the points is probably the slow point now. For the tilemap rendering we could instead do a zbuffer instead of sorting and see if that's faster. For the Sprite rendering we could import the normals and transform them too, and then don't display or sort the normals facing away from the camera.

The tilemap object does some typically useful things when you set a tile, such as updating its collision polygons. That probably adds up the way we're using it.

Overall 4000 points is pretty high and we probably can get something that looks good with much fewer. Although we'd want it much faster if at all possible.

I did an animation test with that eagle where all the points lerp between two frames with distorted points. It only lost a few fps.
B
92
S
32
G
109
Posts: 5,291
Reputation: 70,993

Post » Thu Mar 16, 2017 10:27 am

Have an idea that possibly could make it a lot faster. It's a pretty experimental approach to how we generally think of 3D. It would involve restructuring the point data, and have it indexed. I got the idea by looking at the way you get the point positions and the rgb value for those positions. Basically it would work like this...

It's pretty much creating a search algorithm, only getting relevant data from the point cloud, limited to number number of "pixels" in the tilemap.

Every cell of the tilemap just searches for a the color value it want's to show, and maybe we could get that directly from the point cloud if it was indexed. Translations and rotations would be done at Bounding box level for the object, so we don't need to reposition points individually.

For a quick indexing test. You mentioned the data i pretty normalzed already, so we create 50 steps between -1 and 1. If we take the point cloud data, populate a 50x50x50 array with the average color of every point in each "cell". so if there is any point with the value 0,0,0 we would place the rgb value of that point in the dead center of the array. if a cell has no value, it means transparent, if has a value, it would render to the tilemap.

If we can have some kind of bounding box representing the array data that we could rotate & transform A simple search from the each individual cell of the tile map looking at that bounding box, could get the indexed rgb rgb value of the cell it's looking at. For example. tilemap 25,25 is has the array cell # 26,25,12 (we can disregard all cells behind it as it is opaque)in it's view we would know what color to display for that individual pixel. If a tile map pixel is looking has multiple cells in it's view, we could get the average color of these, that way we could have something similar to anti-aliasing as well.

LOL. hopefully you can understand what I'm rambling about. I'm going to do some tests indexing the point cloud data, so we can minimize the data we need to get. Theoretically you could have massive amounts of points, if you can get them quick enough from files on disk with an index, you probably wouldn't even need to load them in to memory.

As long as each pixel know's what he's looking at, he could jump directly to the index point and get the color information from the correct "cell". the tile map cell is basically jumping straight in to "Column, 6, row 9, z 8, and getting the correct rgb value.

Image

Image
Follow my progress on Twitter
or in this thread Archer Devlog
B
40
S
17
G
17
Posts: 991
Reputation: 12,654

Post » Thu Mar 16, 2017 1:27 pm

If we store RGBA in each cell we can get a bit more detail and antialiasing effect like this. We could store more information in this index, like surface direction, normal direction etc etc, but RGBA should do for now.

Image

Pic 1. If the ball fills only one tile, we can get the rgba value for the ball at index level 0. that's the average color and coverage of the entire ball.
Pic 2. If the ball fills 2x2 tiles. we would get a semitransparent red shade from from each cell in index level 1.
Pic 3. If the ball fills 8x8 tiles, we get the the rgba value from each cell in, index level 3.

The only problem so far, is how we translate or rotate the object. Ideally we would rotate/translate a bounding box (or the index), instead of shifting all the points and values in the array creating a new index every tick.
Follow my progress on Twitter
or in this thread Archer Devlog
B
40
S
17
G
17
Posts: 991
Reputation: 12,654

Post » Thu Mar 16, 2017 6:38 pm

@R0j0hound

Testing the indexing right now, and it seems to be working. We could potentially use an unlimited number of points in the point cloud. It doesn't really matter... it would take longer to build the index though, but once the index is built, we never really touch the points.

Level 0 index. the average color and coverage of the shape. This is only used if the entire object fit in one "pixel" area.
level 1 index. 2x2x2 array used when object fits in a 2x2 pixel area, and so on.....
level 2 index. 4x4x4 array
level 3 index. 8x8x8 array
level 4 index. 16x16x16 array.
level 5 index. 32x32x32 array. This is the maximum I've tested so far, and looks great on a 32x32 tilemap.
you could go as high as your native screen resolution. 1920x1920x1920 for example. Ideally we could crop the away unused whitespace in the array so there's less area to search.

Building the indexes is the easy part. Preferably we would have these prebuilt in a custom file, as the point cloud data is irrelevant once the indexes are built.

I still have to figure out how to rotate the index. I'm an artist not a coder, so i can easily visualize what I'm trying to accomplish, but hard to do the actual syntax for it.

Will share a capx once I'm done with the testing of building indexes.

Although so far it seems performance is not based on how many points in the cloud (we could use millions) but rather the efficiency of the search algorithm (how fast per pixel we can get the rgb value from the index) and the actual render resolution.

50x50 would be pretty fast, but 1200x1200 would be slower, unless we can optimize the search heavily.
Follow my progress on Twitter
or in this thread Archer Devlog
B
40
S
17
G
17
Posts: 991
Reputation: 12,654

Post » Thu Mar 16, 2017 8:44 pm

That sounds similar to a SVO (sparse voxel octree) which is commonly used for rendering/storing voxels. Here's a link with some code to find the intersection of a ray and the octree that I may study a bit more later.
http://stackoverflow.com/questions/1022 ... algorithms

Right now we're just transforming all the points and basically rendering all of them. Next would be to just use a uniform 3d grid of voxels or a SVO and cast a ray for every pixel we want to display. Ray casting on a uniform grid could be done with a line drawing algorithm like dda. I'm uncertain it will be faster than what we're doing now, due to the overhead of events adding up and sometimes providing no gain. It may be interesting to try that approach, as it also would eliminate the holes on the model.
B
92
S
32
G
109
Posts: 5,291
Reputation: 70,993

PreviousNext

Return to Game Development, Design & Ideas

Who is online

Users browsing this forum: No registered users and 2 guests