3D graphics using arrays?

Discuss game development design and post your game ideas

Post » Tue Sep 06, 2016 3:27 pm

I was playing around (experimenting) with arrays a bit to see if i could use arrays to render an object in 3D a 64x64 array holding rgb info in each cell.

Kind of like this example here done in excel.
https://www.youtube.com/watch?v=XeXISSrIaJA

I can get the stuff to render, but maybe someone has some good idea to get started creating the motion? How would you go about doing something similar in C2?

And would it be possible to read data from an 3D file. Like an obj, or any other format to populate the array?

Any thoughts?

This link Explains how it's done, but for me it's incomprehensible.
http://www.gamasutra.com/view/feature/3 ... ry_3d_.php
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 945
Reputation: 12,212

Post » Wed Mar 08, 2017 2:54 pm

I did a simple vector 3D grid floor, red lines on a black background (very 80s style!) when I was just messing around a few months ago.
.
I used the simple version formula right at the bottom of the wiki 3D projection page (under diagram).
https://en.wikipedia.org/wiki/3D_projection

It worked very well.

To do what you want to do you would have to implement the orthographic (or even the perspective) projection maths with all the rotation stuff on the same wiki page. Im not sure if it would be done with just points or would be better with points and lines .

Also this covers the basic 3D but does not cover occlusion so will be just see-through wireframe models.

but yes definitely you could do it directly in the construct 2 editor probably even without any custom js.

I would love to try but I just don't have the time these days....barely have 2 hours on a weekend to work on Construct 2 stuff so I have to be disciplined with what I get into.

actually importing models though that is a whole different ball game!
...
B
42
S
21
G
7
Posts: 260
Reputation: 7,683

Post » Wed Mar 08, 2017 4:55 pm

You can find more info about that sort of thing by an Internet search of "software rasterizer." The aticle you linked only gives a general overview from what I see.

You said you came up with a way to display the array as pixels so I'll leave that subject for now.

The simplest thing to draw is points. Basically you just have a list of 3d points that project to 2d like the link in the second post and just set the nearest pixel to the color.
Lines can be done by stepping from one projected point to another with something like "bresenham's line algorithm."

Animation is done by clearing the array and doing something like a 3d rotation on the points before projecting them to 2d. So just clear, move points, project to 2d, and repeat. It's hard to make it fast though.

The obj file format is a text format so it'll be easier to parse than something else. Tokenat() can be used to do this. Basically look at one line at a time and see what the line starts with. If it starts with "v" it's followed by 3 numbers seperated by spaces that is a 3D point. If it starts with "f" it's a face and it's followed by indexes of the points that make up the points. Lines can be found from pairs of points of the face. That's the basics of it. There is other info you can parse if you need it.

Here's a tutorial that goes in depth on how to make a software rasterizer that may be useful:
https://github.com/ssloy/tinyrenderer/w ... -Bresenham’s-Line-Drawing-Algorithm
B
91
S
31
G
103
Posts: 5,241
Reputation: 67,768

Post » Mon Mar 13, 2017 9:48 pm

@tunepunk
I had some fun trying my hand at implementing some of that stuff. My events are mostly clean and as readable as possible, although it's at the point where a lot of it needs to be refactored and cleaned up. It is mostly organized so maybe you'll find it useful.
https://dl.dropboxusercontent.com/u/542 ... rizer.capx

What it does is fairly straight forward.

1
The object file is loaded so we have a list of 3d points and a list of faces which list indices of the points.

2
The points are moved around, or in the capx rotated around in 3d.
Rotation
The rotation math to rotate on the xy plane is this:
newx = x*cos(ang)-y*sin(ang)
newy = y*cos(ang)+x*sin(ang)
It's basically the same for xz or yz rotations. Just change the x,y variables.
Changing the amount of rotation every frame can be used for animation.
Translation
Next after rotating the points around we need to move the points away from 0,0,0 which is the viewer position. So for example we want the object center to be five units in front of the viewer you could do this:
newz = z+5
This is important to do before the perspective transform because things get distorted near 0 and we shouldn't be able to see points with z<0 or behind the camera.
Perspective
Perspective is really simple, it's just multiplying x,y by a scale number and dividing by z:
perspectiveX= x*scale/z
perspectiveY= y*scale/z
final transformation to screen position
This is basically changing the center from 0,0 to the center of the screen.
screenx = x+320
screeny = y+240

3
Now that the points are transformed we next want to draw points and lines and perhaps polygons. There are a few ways that come to mind.
Using sprites
Sprites could be created at the transformed xy position and lines could be done by stretching sprites from one point to another. Polygons could be done with some madness with triangle sprites but that's not straightforward.
Using the canvas plugin
You can plot points, draw lines and draw polygons fairly easy. The antialiased lines may not be what you want. Also the paster plugin can be used for textured polygons but that's a different topic.
Using a tilemap
The tilemap can be thought of as an array and it removes the step needed to convert the array to something visual. One color is simple but if you look at the capx it shows a way to do a spectrum of colors, well 4096 to be exact. It takes red,green and blue components in the range of 0 to 15 and converts it to a tile number.


Line drawing
This is done by lerping from the one point to the other and drawing the inbetween points. Look the "plot line" function in the capx, it's fairly simple.
polygon drawing
This took me a bit to wrap my head around. I tried two methods to draw triangles.
The first one is fairly simple to understand. First you find the bounding box that contains the all three points of the triangle, then you loop over every pixel in that bounding box and see if that pixel is inside the polygon. Unfortunately the math looks a bit hairy.
The second method is a scanline method which is faster. It involves sorting the three points by y and then lerping along the edges to get the x positions at every y. It has less hairy math but isn't the simplest to understand either.


Performance on the monkey model is about 4-6 fps and I don't think a whole lot of extra performance for this can be squeezed out of the events. This sort of thing is always pretty slow which is why the rasterization is usually all done by the gpu. It can be made faster if most of it was done in javascript, and the events were only used to issue commands. 60fps should be possible with the events ported directly over, but js isn't pleasant to work with imo.
B
91
S
31
G
103
Posts: 5,241
Reputation: 67,768

Post » Mon Mar 13, 2017 11:47 pm

That's pretty awesome @R0j0hound ...u got a lot further than me on that. It's quite amazing it worked that well.

I was just going to try a new approach as well trying out rendering point cloud data just for fun, but currently stuck since I didn't find any good (free) software to convert some model to point cloud data yet, as in this case I thing it would be faster than drawing polygon data. Not a very dense point cloud but a bit bloated points to fill the gaps between them.
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 945
Reputation: 12,212

Post » Tue Mar 14, 2017 6:35 am

Look here:
http://www.meshlabjs.net/
Load your 3d model in obj format and search for "Poisson Disk Sampling". You could then export it back out to a obj file. The only catch is color/texture isn't used. I think an orthogonal render of the model could be used to sample the colors.

Another idea could be to convert the mesh to voxels. There's a command line utility poly2vox that looks like it supports a few formats. The voxel formats would need to be decoded though.
B
91
S
31
G
103
Posts: 5,241
Reputation: 67,768

Post » Tue Mar 14, 2017 9:55 am

@R0j0hound Yeah voxel data would do the trick.

Just theorizing here of a possible way, maybe you have some input.
But wonder if there's any raw format or a way to convert it to JSON or something, easily readable by construct. Basically what you would need is only XYZ position for each voxel (point), and maybe color information for each point. (Rgb)

For each voxel, you then draw or place a 1x1 pixel sprite on screen.

I got the idea from here, which I'm sort of trying to back-engineer now.
https://www.youtube.com/watch?v=00gAbgBu8R4

Just to start simple. Imagine you have a screen resolution of 50x50 or pixels, for each pixel you want to cast a ray forward. If they ray hit something in 3D space (a point in the point cloud or the average color of a group of points) you render that pixel, in the correct color.

Image

I'm just curious to try out the voxel/point cloud approach also, to see if it would render faster, since you don't have to draw triangles. Just getting the RGBA info from a point in 3D.
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 945
Reputation: 12,212

Post » Tue Mar 14, 2017 6:27 pm

You may be able to do that with meshlab or cloudcompare, but there's probably a more direct way to do it.

I found this:
http://www.danielgm.net/cc/forum/viewto ... f=9&t=2322
So with cloudcompare you can load a mesh and get a point cloud of the surface. I think a file format like ply would help here since it can be in text.

Here's the test. I took the model in blender and created a uv for it and baked a texture to it, then after a little fanagling I managed to get the exported obj file to include the image with it. Then I followed the guide in the link above to sample points on the 3d model. I used 2000 points since that seemed reasonable, then I exported with the ply file format since that stores vertex colors.
https://dl.dropboxusercontent.com/u/542 ... zer_3.capx

It works and is slightly faster but the object has to be drawn smaller to hide the gaps. I also disabled the perspective transform since that caused even more gaps.
B
91
S
31
G
103
Posts: 5,241
Reputation: 67,768

Post » Tue Mar 14, 2017 10:13 pm

Impressive @R0j0hound u basically made both a mesh and voxel renderer in 50 events.

Took a look at your example and tried to identify what was so heavy on the cpu. Draw calls seemed very small, so it must be updating the rotation every tick. None the less it's a very cool example of what can be done with a bit of brute force and Vaseline.

My main goal with the experiment was just to see if it worked and clearly you have proven that it does. Very nice example indeed. I really liked the use of Tile map object to draw the pixels. Clever.
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 945
Reputation: 12,212

Post » Wed Mar 15, 2017 12:59 am

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.
B
91
S
31
G
103
Posts: 5,241
Reputation: 67,768

Next

Return to Game Development, Design & Ideas

Who is online

Users browsing this forum: No registered users and 1 guest