Ot - 3D voxel engine

I’ll most likely be stopping working on this project as I’ve achieved all the goals I wanted to reach with it in terms of rendering optimizations and algorithms. Thank you to everyone for the feedback! :slight_smile:

Feel free to post further feedback, or ask any questions about the project.

git: https://github.com/mahhov/ot-voxel-engine

5Nw9JopHREc

Vuf5CngovKY

Note about running the code: there are 3 main methods, Engine.main will just run sandbox mode, EditorEngine.main will run just the editor mode, and Client.main will run them both (toggling back and forth via the ‘m’ key).

Sandbox Controls:
w, a, s, d, space, and shift - accelerate ship forward, left, backward, right, up, and down
z, x - zoom camera in and out
move mouse - change camera orientation
p - pause
enter - toggle between free-camera (controlled by mouse movement) and follow-camera (always looks towards your ship)
m - to toggle between sandbox and editor

Editor Controls:
w, a, s, d, space, and shift - to move camera
i, j, k, l, u, o - to change selected direction
1, 2, 3, 4, 0 - to change selected piece (1=hull, 2=rotor/thruster, 3=helium, 4=blade/wing, 0=delete)
mouse move - to change selected location
mouse click - to place selected piece with selected direction at selected location
enter - to reset camera to default location and orientation
\ - to load ship from file
/ - to save ship to file
m - to toggle to sandbox mode and try out your creation! (be sure to save before going to sandbox mode. sandbox mode will load from file, not from whatever is in your editor)


Original Post:

Hello,

Back in 2013, I posted of a 3d engine I had been working on but had to stop due to schoolwork. Well, this Christmas, I began a total fresh remake of the engine; this time focusing on optimizations for extremely vast terrains (rather than dense environments like my previous engine had focused on). My plans are to eventually make it support some kind of pirates battles in the sky game where you create your ships with blocks (kind of like robocraft), though I’m still considering some other ideas as well - if anyone wants to make suggestions, please go ahead :slight_smile:

For drawing, it uses Java.Graphics2D and BufferedImage.

Here’s a quick demo 1 week in.

(if anyone can help if there’s an easy way to shrink the embedded image, thank you)
zip: https://www.dropbox.com/s/k0ju5zp2ijka7wl/ot.jar - outdated
git: https://github.com/mahhov/ot-voxel-engine

SDw4UxfbeQ0

https://s27.postimg.org/xj4gzx9ab/ot_sh.png

This video is private :frowning:

Kev


...

https://s27.postimg.org/xj4gzx9ab/ot_sh.png

Thank you both. The video should be public now.
Here’s another demo showing it in a much larger map

v4VnHYtDSSM

Nice job. I’m curious to see where this goes!

This looks really cool! It kinda reminds me of my ol’ game, Indago (http://www.java-gaming.org/topics/indago-the-search/36948/view.html), haha ;D

Looks cool and I’m interested how it will change in the Future :slight_smile:

i really like the fps on the video :slight_smile:

Joking aside, looks like a cool project!

Thank you all very much for the encouragement! Yes, the fps is pretty low at the moment, but note that I had not finished implementing all the optimization strategies I’d planned, plus that’s a lot more objects on screen than will actually be required. I’m finishing up the final optimization algorithms at the moment and I expect 10-15 fps with that density, map size, and draw distance. I’ll upload another video once I’ve completed the optimizations, maybe with a more toned down density.

I’m sorry but how can you be using Graphics2D for a 3D renderer? :persecutioncomplex:

Hes doing 3D math on the cpu. It’s much slower than using OpenGL or DirectX because those use the graphics card for their calculations.

He’s doing what I’m doing but using java’s polygon rasterization vs. making his own.

Yep pretty much. I’m calculating the screen location, color/shade, order of all the shapes needed to be drawn and just telling some graphics2D instance to drawPolygon / drawString.

I’ve been working on all the optimization algorithms lately, so haven’t had much to show. But I’m pretty much done for now with optimizations, and added support for rotated cubes just to have something new to show.

If anyone’s interested, here’s an generic overview of the optimization steps I take. Feel free to add suggestions.

  1. determine max draw distance (the distance after which even the brightest 1x1x1 object would be too dark / small to be noticeable anyways)
  2. determine the coordinates of the minimum-bounding-axis-aligned-rectangular-prism encompassing the camera field of view.
  3. iterate through these coordinates (left -> center, then right -> center, then center, so we don’t have to worry about draw-order or zbuffering)
  4. for each non-empty coordinate, check if it is within the camera field of view via a simple dot product and distance check (since the minimum bounding rectangular prism is larger than the fov, and since this check is very low-cost)
  5. get the surfaces of that coordinate that have normals facing the camera (again via dot product)
  6. convert the surface coordinates to screen coordinates. As a final check, make sure at least one of the surface’s screen x,y coordinates are within [-.5, .5] and if so, draw it

On top of this, in order to support vast areas, with potentially low-density, the world is divided into chunks, so that chunks aren’t initialized unless they contain at least one surface, and they are skipped over in the drawing algorithm if empty.

The only additional major optimization plan I have, I plan not to update (remove & add) surfaces as they move, unless they are in view. Instead, I’ll “expire” the surface’s old location via some counter, and add “trigger-points” bounding clusters of surfaces which move together so that the actual surfaces are added to the world only if the trigger points are visible.

Here’s a new 30-sec screen-capture.

Oes6N6I4pjs

Shouldn’t it be painfully slower? I’m impressed that you can do that heheh

For a simple use case like this (i.e. no textures, hard shadows, gloss, reflections, etc) the most computationally heavy part with traditional rendering tends to be determining draw order (via z buffering for example). And one of the main trade offs of voxel rendering is that ordering becomes really computationally cheap at the cost of dramatically increasing the number of polygons you have to deal with. But that’s where all these optimization algorithms come in, they all try to minimize the number of “qualified” polygons we have to consider. As for the actual drawing pixels on screen, I’m not sure whether graphics2d instructions still eventually get converted to graphics card instructions or whether they are completed by the CPU, but I do know for my previous rendering project, switching to jogl was only a 10 or so fps gain.

Added ships, i.e. moving cluster of blocks. There’s graphical bug with some surfaces being drawn on top of other surfaces when they shouldn’t be, but I hope to fix that soon.

fsdF4Uid7BM

You don’t have a z-buffer?

Edit: just remembered that you use java2d

Yep, no zbuffer. Just a small update, trailing camera done. Next step, allowing user to control the ship.

2yQoAaePREA

To be honest, your renderer would be faster if you didn’t use Java2D and it would look much better too :stuck_out_tongue:
But I’m not going to force you to do anything, it’s your engine :slight_smile:

Sure, using jogl or lwjgl would make it faster, but it doesn’t really affect the code at all. Maybe later I’ll just swap out Java2d for one of those.

I’ve completed controls; here’s a quick video demonstration. Next step is to make the ship modular, as in built from different pieces such as hull, thruster, helium, etc.

gusWNdKVUiM