patternjavaMinor
Voxel Engine optimization
Viewed 0 times
enginevoxeloptimization
Problem
I am writing custom voxel engine in Java with JME3, but it is very slow, for simplicity I am rendering cubes instead of faces, also border detection messes up output mesh (doesn't draw cubes on chunk edges).
I would be very thankful if someone with more skill looked into it.
I have included all the code so you won't miss anything.
You could have a look at
You can find rest of the code here:
http://pastebin.com/7S90L1Bd
I would be very thankful if someone with more skill looked into it.
I have included all the code so you won't miss anything.
You could have a look at
CubicalMeshificator and improve on it, lets say by making only necessary faces not whole cubes.You can find rest of the code here:
http://pastebin.com/7S90L1Bd
CubicalMeshificator (extracts mesh from voxel data)public class CubicalMeshificator {
private static LinkedList verticesPosition = new LinkedList();
private static LinkedList verticesNormal = new LinkedList();
private static LinkedList verticesUV = new LinkedList();
private static LinkedList indices = new LinkedList();
public static Mesh createMesh(Voxel [][][] voxels, Vector3f size, float voxelSize) {
for(int x = 0; x = 0 && x+1 = 0 && y+1 = 0 && z+1 list)
{
IntBuffer buff = BufferUtils.createIntBuffer(list.size());
buff.clear();
for (Integer e : list) {
buff.put(e.intValue());
}
buff.flip();
return buff;
}
}Solution
Profiling
The first thing I would do when I have performance problems is profile the code, to see where the problem is. Profiling is not hard to do, most IDEs come with tools that can do it. There really isn't a need to optimize code that isn't responsible for performance problems, especially because faster code often is less readable.
Most of the things I mention further down might decrease the readability of your code, and you should profile all of them, because it's hard to say what will actually help and what will not, because it's hard to predict what the compiler will optimize, etc.
You will get better profiling results if you extract some code to its own function, eg the code that adds indices, the code that adds vertices, the code that creates the actual mesh, etc. If your worried about the additional overhead because of the function calls, you can remove them after you profiled the code.
Unnecessary Checks in Loop
You perform some checks more often then necessary. When you have three nested loops, checks that only involve the outer loop can be moved to that loop, so they are checked less often and you avoid going through the inner loops. You shoudn't overdo this though, because the extra variables might cause performance loss, and will lead to harder to read code.
For example, you have this check in the inner-most loop:
[*] well, maybe; the compiler might optimize the difference away
Unnecessary Operations in Loop
You also have some operations which you perform quite a lot of times, for example
Unnecessary Function calls
Function calls aren't free, so in performance critical code it might be a good idea to avoid calling the same function a bunch of times. You could for example try to save the result of
Data Structure Transformations
You perform a lot of transformations from one data structure to another. For example,
Misc
The first thing I would do when I have performance problems is profile the code, to see where the problem is. Profiling is not hard to do, most IDEs come with tools that can do it. There really isn't a need to optimize code that isn't responsible for performance problems, especially because faster code often is less readable.
Most of the things I mention further down might decrease the readability of your code, and you should profile all of them, because it's hard to say what will actually help and what will not, because it's hard to predict what the compiler will optimize, etc.
You will get better profiling results if you extract some code to its own function, eg the code that adds indices, the code that adds vertices, the code that creates the actual mesh, etc. If your worried about the additional overhead because of the function calls, you can remove them after you profiled the code.
Unnecessary Checks in Loop
You perform some checks more often then necessary. When you have three nested loops, checks that only involve the outer loop can be moved to that loop, so they are checked less often and you avoid going through the inner loops. You shoudn't overdo this though, because the extra variables might cause performance loss, and will lead to harder to read code.
For example, you have this check in the inner-most loop:
if(x-1 >= 0 && x+1 = 0 to x > 0 which is faster[*] and a lot clearer. You could also negate the expression and use continue if you think that this will lead to too deply nested code.[*] well, maybe; the compiler might optimize the difference away
Unnecessary Operations in Loop
You also have some operations which you perform quite a lot of times, for example
x*voxelSize. You could extract that to directly inside the x loop as well.Unnecessary Function calls
Function calls aren't free, so in performance critical code it might be a good idea to avoid calling the same function a bunch of times. You could for example try to save the result of
verticesPosition.size() in a local variable.Data Structure Transformations
You perform a lot of transformations from one data structure to another. For example,
verticesPosition is a linked list, which you then transform to an array, which is then transformed to a float buffer. Try to reduce the amount of different data structures you use.Misc
- always use curly brackets, even around one-line statements. Your first
ifstatement is hard to read without it, and in case you later add another block of code, this can very easily lead to bugs.
- at the very least, use correct indentation; wrong indentation makes this even more confusing.
- you could also combine the two if-statements.
Code Snippets
for(int x = 0; x < size.x; x++) {
if (x > 0 && x < size.x - 1) {
for(int y = 0; y < size.y; y++) {
for(int z = 0; z < size.z; z++) {
[...]
}
}
}Context
StackExchange Code Review Q#90243, answer score: 5
Revisions (0)
No revisions yet.