• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
CryoGenesis

Voxel Rendering (OpenGL) +1 for help

15 posts in this topic

Hello thar. I have written a voxel engine in java (using openGL) which is pretty good. There is one downside. The FPS. The engine only checks to to render blocks in your view distance and only renders blocks that you see. It doesn't even render the faces you don't see. The way the blocks are render is just by using active rendering. This keeps a steady 30FPS with a view distance of a mere 30 blocks infront of the player. I tried to speed the rendering up with Vertex buffer objects but the game uses up WAAAAAYY too much RAM (2.9G to be precise). I then made only 1 Vertex buffer object and just translated it for each cube. This put the RAM to normal levels but the FPS dropped to around 4 - 9 FPS... I then switched to display lists and made just one display list that would be translated for each cube to keep ram to a minimum. Again, 6 - 11 FPS.
Do you know of any ways to render lots of cubes at minimum ram and high FPS? I know minecraft does it relatively well and that uses OpenGl?
0

Share this post


Link to post
Share on other sites
[quote name='larspensjo' timestamp='1345399024' post='4971164']
How many faces (triangles) do you show?

The following is a world at 160 blocks viewing distance. With a low budget graphics card, it renders at about 30 FPS with 250000 triangles and 500 draw calls in full widescreen mode. If is based on VBOs.

You say that you use far too much memory. How much data do you have per vertex? I use the following per vertex:
[source lang="cpp"]struct VertexDataf {
glm::vec3 fNormal;
glm::vec2 fTexture;
glm::vec3 fVertex;
float fIntensity; // Pre computed The light intensity of this vertex
float fAmbient;
};
[/source]
I use back face culling to skip faces I can see.

Using only one vertex buffer object for one block means you need to change the transformation matrix for every block. This is probably very expensive, with one draw call for every block. Please explain about the data structures you used for the VBOs, and maybe we can identify why it is too much RAM.

[attachment=10777:blocks.jpeg]
[/quote]
Well I changed it so only the voxels that are active have their VBOs initialized and that brought the Ram usage down to a gig or so.
The voxels are drawn using quads and the VBO objects have 72 floats representing each vertex for each face so even though there are only 8 vertexes for a cube I have to do it for each face so it's basically 3(spacial coordiantes)*4(vertexes per face)*6(faces) = 72. Although, I'm not sure if there is a way round that or not. I'm not sure why the static VBO was taking up so much FPS.

At the moment I'm only using 1 chunk. The chunk is 128*128*128 but only a 10th of that is active due to the terrain generation being at a low level.
Is there a way to only have 8 vertexes in a VBO and draw cubes from that? Edited by CryoGenesis
0

Share this post


Link to post
Share on other sites
[quote name='CryoGenesis' timestamp='1345397605' post='4971158']
I then made only 1 Vertex buffer object and just translated it for each cube.
[/quote]

Are you saying that you have a draw call for each cube? If possible, batch your cubes into as few draw calls as possible. If they all use the same shader, then you would only need to batch on differing textures...but you could batch even harder than that by using a 3D texture and selecting an appropriate texture from within it based upon some parameter. You lose the ability to specify things like your model matrix in a standard uniform, but you could potentially just index in to a uniform buffer object...otherwise just repeat that data on each vertex.

At that point, you're basically replicating [url="http://www.opengl.org/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml"]instanced rendering[/url]...which may be the natural next step.
2

Share this post


Link to post
Share on other sites
[quote name='CryoGenesis' timestamp='1345400661' post='4971171']
At the moment I'm only using 1 chunk. The chunk is 128*128*128 but only a 10th of that is active due to the terrain generation being at a low level.
Is there a way to only have 8 vertexes in a VBO and draw cubes from that?
[/quote]
That would sure save a lot of memory, but I don't know how to make it efficient. Maybe using a geometry shader to generate vertices. Having one draw call for every block, with an updated model matrix every time, is not feasible.
I am using chunks of 32x32x32 blocks, but I can't say that 128 is wrong. In my case, network transfer speed is important, and too big chunks would be inefficient. When drawing at 160 blocks viewing distance, I need at most 130 chunks, at about. That makes 32x32x32x130=4 million possible cubes.
A disadvantage with too big chunks is that the chance increase that some part of it is visible, forcing you to draw all of it. The disadvantage of too small chunks is that there will be very many draw operations, which can become inefficient. Maybe 128 is a little too big? I think 32 is a good compromise, still leading to long enough lists of triangles to be efficient.
There is one way to save vertex data space. If your chunks are 128 in width, you can represent cube addresses in a byte (instead of a 32-bit float). That would reduce the memory with a factor of 4. You then need to have the shader translate the byte number to a world position coordinate (which is just what it does anyway).
1

Share this post


Link to post
Share on other sites
[quote name='larspensjo' timestamp='1345407835' post='4971202']
[quote name='CryoGenesis' timestamp='1345400661' post='4971171']
At the moment I'm only using 1 chunk. The chunk is 128*128*128 but only a 10th of that is active due to the terrain generation being at a low level.
Is there a way to only have 8 vertexes in a VBO and draw cubes from that?
[/quote]
That would sure save a lot of memory, but I don't know how to make it efficient. Maybe using a geometry shader to generate vertices. Having one draw call for every block, with an updated model matrix every time, is not feasible.
I am using chunks of 32x32x32 blocks, but I can't say that 128 is wrong. In my case, network transfer speed is important, and too big chunks would be inefficient. When drawing at 160 blocks viewing distance, I need at most 130 chunks, at about. That makes 32x32x32x130=4 million possible cubes.
A disadvantage with too big chunks is that the chance increase that some part of it is visible, forcing you to draw all of it. The disadvantage of too small chunks is that there will be very many draw operations, which can become inefficient. Maybe 128 is a little too big? I think 32 is a good compromise, still leading to long enough lists of triangles to be efficient.
There is one way to save vertex data space. If your chunks are 128 in width, you can represent cube addresses in a byte (instead of a 32-bit float). That would reduce the memory with a factor of 4. You then need to have the shader translate the byte number to a world position coordinate (which is just what it does anyway).
[/quote]
Hey thanks, the reason the world size is 128 is just because of engine testing. I'm not looking to make the game multiplayer either.
I like the idea of having the blocks only hold a byte.
Each block holds 96 bits for its position so only having 24 bits would be a hell of a good Idea.
The blocks also hold 3 integers with their voxel positions in. I could just scrap those and use the byte position instead.
Although this brings down the memory usage I expect that the VBOs would bring it straight back up again. Each block holds a VBO with a ridiculous amount of floats. I tried converting it to display lists but it didn't give me any increase in fps. It decreased the fps instead.
Might have a look at the minecraft source code and see how that voxel engine draws the cubes.
Still, thanks for the idea!
0

Share this post


Link to post
Share on other sites
[quote name='CryoGenesis' timestamp='1345408701' post='4971210']
Each block holds a VBO with a ridiculous amount of floats.
[/quote]
Actually, the VBOs can be encoded as byte integers also. I know it works, because that is the way I did it originally.

I had to go for floats eventually, because my terrain is sent through a smoothing filter (see same scene with smoothing below).
[attachment=10785:blocks1.jpeg]
0

Share this post


Link to post
Share on other sites
[quote name='larspensjo' timestamp='1345411919' post='4971231']
[quote name='CryoGenesis' timestamp='1345408701' post='4971210']
Each block holds a VBO with a ridiculous amount of floats.
[/quote]
Actually, the VBOs can be encoded as byte integers also. I know it works, because that is the way I did it originally.

I had to go for floats eventually, because my terrain is sent through a smoothing filter (see same scene with smoothing below).
[attachment=10785:blocks1.jpeg]
[/quote]

I turned the positions etc to bytes. It only saved around 50k of memory in exchange for some bugs. I changed it back to floats just so the code is clean.
How did you manage to render that much with VBOs?
0

Share this post


Link to post
Share on other sites
[quote name='CryoGenesis' timestamp='1345413155' post='4971237']
[quote name='larspensjo' timestamp='1345411919' post='4971231']
[quote name='CryoGenesis' timestamp='1345408701' post='4971210']
Each block holds a VBO with a ridiculous amount of floats.
[/quote]
Actually, the VBOs can be encoded as byte integers also. I know it works, because that is the way I did it originally.

I had to go for floats eventually, because my terrain is sent through a smoothing filter (see same scene with smoothing below).
[attachment=10785:blocks1.jpeg]
[/quote]

I turned the positions etc to bytes. It only saved around 50k of memory in exchange for some bugs. I changed it back to floats just so the code is clean.
How did you manage to render that much with VBOs?
[/quote]

Oh and also good job on that. It looks really good.
0

Share this post


Link to post
Share on other sites
Wait, each block holds a vbo, as in you have a vbo for each cube? You should pretty much have as few vbos as you can. In your case, that could pretty much be one. As in, you input your data once - or when it changes - and only render using a single glDrawArrays (or similar) call per frame. Or divide into slightly smaller blocks of multiple cubes (which you might be doing, your description wasn't too clear about that) and call it for every N³ block of cubes, still not for every cube. You might also want to draw with index lists, though that might not be a good idea if you want to have per-face normal information. Which is not absolutely necessary, but makes lighting a bit easier.

Also, if you only have a few vbos, they don't take RAM pretty much at all, only VRAM. And assuming you use vec3 for every position, normal and texture coordinate and also use a baked float for ambient occlusion or whatever, you'll be doing 40 bytes per vertex and 960 bytes per cube. With 200MB of VRAM, that gives you over 200k cubes (a lot more in usual situations if you cull the underground faces) to play with, which ought to be more than enough.
0

Share this post


Link to post
Share on other sites
[quote name='powly k' timestamp='1345416381' post='4971257']
Wait, each block holds a vbo, as in you have a vbo for each cube? You should pretty much have as few vbos as you can. In your case, that could pretty much be one. As in, you input your data once - or when it changes - and only render using a single glDrawArrays (or similar) call per frame. Or divide into slightly smaller blocks of multiple cubes (which you might be doing, your description wasn't too clear about that) and call it for every N³ block of cubes, still not for every cube. You might also want to draw with index lists, though that might not be a good idea if you want to have per-face normal information. Which is not absolutely necessary, but makes lighting a bit easier.

Also, if you only have a few vbos, they don't take RAM pretty much at all, only VRAM. And assuming you use vec3 for every position, normal and texture coordinate and also use a baked float for ambient occlusion or whatever, you'll be doing 40 bytes per vertex and 960 bytes per cube. With 200MB of VRAM, that gives you over 200k cubes (a lot more in usual situations if you cull the underground faces) to play with, which ought to be more than enough.
[/quote]
I tried to use one static vbo for the cubes and just translate the cube for each draw. It lagged the game like hell. I'm looking to get around (32*32*32)*5 cubes in the Ram. This is all the cubes in the current chunk and all the cubes in the adjacent chunks. When you move to the next chunk all the data is saved and whatever chunks havent been loaded or generated are generated.
The problem is the VBO takes in vertexes for each face. Thats 72 float variables stored for EACH cube. Not to mention Texture coordinates. When I ran this last time on a 128*128*128 chunk it managed to run fast but it took up around 2Gigs of Ram.
0

Share this post


Link to post
Share on other sites
You're doing Vertex Arrays (VA) instead of Vertex Buffer Objects (VBO) if your index count makes your RAM usage go up. (Or you're developing on a laptop with shared memory, which would be very, very sad.)

I'm also interested in how you got it to take over 2 GBs of whatever memory it takes. If you go the very unoptimized route and store everything (underground, air, all the cubes there are) in your VBO, you'd still have only 32x32x32x5x72x4 bytes = 47 185 920 bytes - under 50 MBs. If you optimize it a bit and only store and show the ground layer, you'll probably be looking at a few megabytes of data.

EDIT: Ah, you got the >2GB with 128³, which would still result in around 600MB by my calculations. I wonder what's going wrong here.. Edited by powly k
0

Share this post


Link to post
Share on other sites
Ah yes I'm using a laptop with 256mb of dedicated VRAM. The laptop itself is pretty good. it runs on a 2.4Ghz dual core AMD with a Radeon HD graphics card. My laptop isn't a High end gaming laptop but it should be able to run anything that I make by myself.
On startup only the active blocks have VBOs when you add a block to the world it initializes its VBO.
I think one of the main reasons of the 2g memory usage was that I was doing 128*128*(some random number between 5 and 20) blocks that all had a VBO that held 72 float variables.
It's very in-efficient and I'm trying to find out how to have VBOs with only 8 floats for the vertexes.
0

Share this post


Link to post
Share on other sites
[quote name='CryoGenesis' timestamp='1345420858' post='4971272']
It's very in-efficient and I'm trying to find out how to have VBOs with only 8 floats for the vertexes.
[/quote]

Well, if you want to take that idea to the extreme...you can get away with 1 float per voxel if you use a geometry shader, but I can't speak to the speed or plausibility of that. You could also apply the same idea by sending your 8 floats through, and then using the geometry shader to generate whatever else you need. And finally, you can try sending 8 floats plus an integer index buffer. Edited by nox_pp
0

Share this post


Link to post
Share on other sites
I'm still concerned about the amount of your VBOs, so when you say you have 128x128x5~20 blocks, they're all in the same VBO, right?
0

Share this post


Link to post
Share on other sites
The chunk size is 128*128*128 and each one has its own VBO. Only the blocks that are generated at startup get a vbo and the rest aren't rendered until they are added.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0