It is currently Sat Aug 22, 2020 4:26 am


All times are UTC




Post new topic Reply to topic  [ 15 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Tue Sep 23, 2014 11:58 am 

Joined: Thu Oct 06, 2011 2:26 pm
Posts: 46
Location: Berlin
Hey,

I just tried to switch to the most recent version of PolyVox to see if it would give any performance boost, especially in the mesh extraction.
But instead of gains all of it takes 30% longer and introduces completely unrequired faces.

Here is a picture of how it looked with a ~1 year old version of PolyVox:
Image
Notice how mesh generation takes 2.5 seconds.

And here is a picture showing the same with the current version:
Image
And another one viewed from the sides:
Link
Notice how mesh generation goes up to 3.7 seconds.

As you can see, the correct geometry is still there. But in addition to that, a large bunch of unasked for faces that span from one end of the region to the other end.
And as this was not the case before, I figure there is either a bug in the mesh extraction or I do something wrong.

Here is the code I use to create the mesh - still based on the old Ogre PolyVox tutorial, mostly, except the extraction part:
Code:
void
TerrainCreator::applyVoxelsToMesh(Ogre::ManualObject* p_manualMesh)
{
// Oh. My. God. Template horror...no wonder all examples with this use auto.
// No auto on my watch, though.
#define DecodedType PolyVox::Mesh<PolyVox::Vertex<MeshType::VertexType::DataType>, MeshType::IndexType>
#define MeshType PolyVox::Mesh<PolyVox::MarchingCubesVertex<PolyVox::SimpleVolume<BYTE>::VoxelType > >
   
    // Extract and decode mesh
    MeshType mesh = PolyVox::extractMarchingCubesMesh(_voxelVolume, _voxelVolume->getEnclosingRegion());

    DecodedType decodedMesh = PolyVox::decodeMesh(mesh);

    p_manualMesh->begin("SimpleTexture", Ogre::RenderOperation::OT_TRIANGLE_LIST);
    {
        const std::vector<PolyVox::Vertex<MeshType::VertexType::DataType> >& vecVertices
            = decodedMesh.getVertices();
        const std::vector<uint32_t>& vecIndices = decodedMesh.getIndices();

        PolyVox::Vector3DFloat v3dFinalVertexPos;
        for(unsigned int index = 0; index < vecIndices.size(); ++index)
        {
            const PolyVox::Vertex<MeshType::VertexType::DataType>& vertex
            = vecVertices[vecIndices[index]];
            const PolyVox::Vector3DFloat& v3dVertexPos = vertex.position;
            const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.normal;
            v3dFinalVertexPos = v3dVertexPos -
                    PolyVox::Vector3DFloat(_width >> 1, _height >> 1, _depth >> 1);

            p_manualMesh->position( v3dFinalVertexPos.getX(),
                                    v3dFinalVertexPos.getY(),
                                    v3dFinalVertexPos.getZ());
            p_manualMesh->normal(   v3dVertexNormal.getX(),
                                    v3dVertexNormal.getY(),
                                    v3dVertexNormal.getZ());
            p_manualMesh->textureCoord( v3dFinalVertexPos.getX() / 4.0f,
                                        v3dFinalVertexPos.getY() / 4.0f,
                                        v3dFinalVertexPos.getZ() / 4.0f);
        }
    }
    p_manualMesh->end();
}

_________________
My site! - Have a look :)
Also on Twitter - with more ketchup


Last edited by TheSHEEEP on Tue Sep 23, 2014 12:50 pm, edited 1 time in total.

Top
Offline Profile  
Reply with quote  
 Post subject: Re: Ogre + SimpleVolume + new mesh extraction = not working
PostPosted: Tue Sep 23, 2014 12:49 pm 

Joined: Thu Oct 06, 2011 2:26 pm
Posts: 46
Location: Berlin
Another thing I noticed which I do not want to open up a new thread for is that reading Voxels seems to be significantly slower.

Here is the a part of the code that I use to smooth the voxel field before extracting the mesh:
Code:
curVal = (   curVal +
   _voxelVolume->getVoxelAt(x-1, y + 1, z) +
   _voxelVolume->getVoxelAt(x,   y + 1, z-1) +
   _voxelVolume->getVoxelAt(x+1, y + 1, z) +
   _voxelVolume->getVoxelAt(x,   y + 1, z+1) +
   _voxelVolume->getVoxelAt(x-1, y - 1, z) +
   _voxelVolume->getVoxelAt(x,   y - 1, z-1) +
   _voxelVolume->getVoxelAt(x+1, y - 1, z) +
   _voxelVolume->getVoxelAt(x,   y - 1, z+1)) / 9;

The rest is basically looping over the voxels to find those I want to smooth.
And of course, setting to the new value afterwards. Lots of getVoxelAt() calls, far fewer setVoxalAt() calls. Works rather well.

But as you may have noticed from the (hard to read) log stuff, this also became twice as slow using the new PolyVox.
At first I thought that this was just the "day form" of Windows (as Windows sometimes decides to just be slower some days), but I just checked it and the difference really is only in new vs. old PolyVox.

I find this to be a rather significant slowdown. Seems like the new PolyVox stores its data much less CPU cache friendly in a SimpleVolume. At least that would be my explanation.

_________________
My site! - Have a look :)
Also on Twitter - with more ketchup


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Tue Sep 23, 2014 9:21 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Ok, so let's look at the 'correctness' issue first. One significant difference is that you need a MarchingCubesController (or DefaultMarchingCubesController) for your voxel type. What VoxelType are you using? For primitive types the DefaultMarchingCubesController should be fine (and maybe with MaterialDensity88, etc, haven't tested those in a while).

Have you got only a single volume in the scene, or are your using multiple volumes placed next to each other? PolyVox has added 'wraps modes' when accessing the volume which could affect the value returned on borders.

Lastly, perhaps you can test with just a simple shape such as a sphere or something, and maybe using a single region (or was that a single region?)? What if you shrink the region so that it doesn't actually cover the whole of the area you want to extract - does that fix the artifacts?

As for the performance, well it is hard to make a comparison while the output is different. But the performance could indeed be lower for a couple of reasons:

  • If you really have the latest version then SimpleVolume is removed, and is simply a typedef to the new PagedVolume (you should have seen a message about this during compilation). PagedVolume is indeed slower than the old SimpleVolume beause the blocks are stored in a map rather than than with direct pointers. This is basically a memory/performance tradeoff, but you can use RawVolume if your volumes are just a few million voxels. Read more here: viewtopic.php?p=4523#p4523
  • I believe the support for wrap modes has some significant overhead though I haven't yet looked into it properly. They were added to make the volume resampling for LOD better/easier but I'm not certain they are needed. I need to do more research here.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Wed Sep 24, 2014 8:21 am 

Joined: Thu Oct 06, 2011 2:26 pm
Posts: 46
Location: Berlin
I will try some of your suggestions, but let me first describe what I am actually doing:

Basically, I "misuse" PolyVox as a tool to create a mesh out of a 3D noise field. That's it. No paging, no LOD, nothing. Or rather, all of that we will be doing ourselves, as we just need the mesh and no voxel manipulation will happen at runtime (hence we need no voxel logic at runtime, a mesh is enough).
I also use only one a single volume.

Oh, and I indeed did not see the compiler warnings. I have many libraries that spawn warnings I can do nothing about, so I tend to ignore those if they do not come from my own files.

What I just tried is this:
Code:
//Extract and decode mesh
PolyVox::Region region = _voxelVolume->getEnclosingRegion();
region.shrink(30);
MeshType mesh = PolyVox::extractMarchingCubesMesh(_voxelVolume, region);

30 is 10% of the whole region. With that value, the error is gone.
So I tried with more values. From 15 on, things start to improve slightly, but all errors seem to be gone only from 25. So it is kind of a threshold.

Of course, we do not want to cut off almost 10% of our regions ;)

I will now try another controller...
Edit: Okay, it seems the default controller already is the marching cubes one, so not sure what I should change there.

Edit 2:
Okay, I replaced my SimpleVolume with a RawVolume. The result was a significant speedup, faster even than the old version using SimpleVolume. I also did the smoothing of the noise field directly on that field, not after I transferred it to the RawVolume. No idea why I did not do it like that to begin with.

So I think the performance problem is solved using RawVolume. If I understood everything, it should be better suited to our case anyway, right? We use the volume once to create a mesh, then delete it.

Edit 3:
What I tried next is using different wrap modes. Border is the default and you know the result.
Clamp produces exactly the same erroneous faces as Border.
Both AssumeValid and Validate crash during the process, with Validate producing the following error:
Quote:
Position is outside valid region


Edit 4:
I tried to get creative and thought "Well, if shrinking works, why not make the volume too big to begin with, then shrink the extracted region down to the correct size?!". So I created the RawVolume at 330x330x330, then shrunk the extracted region to be 300x300x300. Didn't work, same problem :(
It seems one really has to cut pieces of the actual region filled with noise values.

I am now officially out of ideas. My best bet now would be reverting to the old PolyVox and using RawVolume there for the speedup. But I would really love to test if the new extraction is faster in my case.

_________________
My site! - Have a look :)
Also on Twitter - with more ketchup


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Thu Sep 25, 2014 8:40 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
TheSHEEEP wrote:
So I created the RawVolume at 330x330x330, then shrunk the extracted region to be 300x300x300. Didn't work, same problem :(


Ah, right, I'm pretty sure I know the problem now. I hadn't realised your region was so large, and this is a problem because of the new way in which we encode vertex positions. Basically we use 1 byte for the integer position and one byte for the fractional position. This means each component of the position can only have the range 0-255, and if it is greater than this then the vertex will basically 'wrap around' causing streaks across your volume.

Many people are using PolyVox in dynamic environments, and so they keep the region size small to allow fast updates. Hence I didn't really worry about the 256 limit (though I should at least have added an assert - sorry about that). It was a bad assumption though as clearly there are people who are using such large regions in specific use-cases.

Short term, the only way you can work around this is to extract multiple smaller regions and then combine them. This is messy though. Also, now that I understand the problem I think you probably are seeing the 'true' performance, and apparently it is slower for you than it was before. This is probably due to the wrap modes, as mentioned before. Overall, your best option might be to go back to the last stable release.

Long term, we should find a way to fix this. The encoding of vertex positions should probably be made optional, but I have to find an elegant way to do this. The performance problems from the wrap modes should also be addressed (or the feature should be removed) but this has to happen anyway as it's also affecting Cubiquity.

Really sorry for these problems but thanks for bringing the issue to our attention.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Thu Sep 25, 2014 9:32 am 

Joined: Thu Oct 06, 2011 2:26 pm
Posts: 46
Location: Berlin
I see the problem.

Is there a way to get the latest stable version with the improvements made to the Array class? It seems that it is quite significant.

I tried to manually merge and cherry-pick around, but could not get it to work.

_________________
My site! - Have a look :)
Also on Twitter - with more ketchup


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Thu Sep 25, 2014 11:11 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
TheSHEEEP wrote:
Is there a way to get the latest stable version with the improvements made to the Array class? It seems that it is quite significant.


The new Array class is much simpler than the old one - it's just a single small header file. I would try renaming the class to 'ArrayNew' or something (also the typedefs), and then adding it to your old project. Then you can selectively replace instances of the old class with the new class, while leaving most of it untouched (I think). There's only a couple of instances you would need to replace in the surface extractor.

Also, remember that the acess syntax has changed. The new class uses (x,y,z) rather than [x][y][z].


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Fri Sep 26, 2014 9:05 am 

Joined: Thu Oct 06, 2011 2:26 pm
Posts: 46
Location: Berlin
Yes, that worked well, thank you.

I hope you can can change the new version so that it works for arbitrarily sized regions :)
If the optimization for < 255 sized regions is that good, I would actually suggest making an extra class for that plus a generic class for arbitrary sizes.

_________________
My site! - Have a look :)
Also on Twitter - with more ketchup


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Fri Sep 26, 2014 1:30 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Great, I'm glad it works! I've logged the size-limitation issue here: https://bitbucket.org/volumesoffun/poly ... ted-to-256


Top
Offline Profile  
Reply with quote  
 Post subject: Re: SimpleVolume + new mesh extraction = broken & slow
PostPosted: Tue Dec 16, 2014 1:44 pm 

Joined: Thu Oct 06, 2011 2:26 pm
Posts: 46
Location: Berlin
I just wanted to ask if anything has changed about this problem.
We will next decide on the version of PolyVox to use for our final project.

We can just use our "custom" version, no problem, but if this is resolved by now, we could switch to an official version.

_________________
My site! - Have a look :)
Also on Twitter - with more ketchup


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net