It is currently Sat Aug 22, 2020 3:36 am


All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Irrlicht procedural mesh and lighting problem.
PostPosted: Mon Jul 24, 2017 6:30 am 

Joined: Fri Jul 21, 2017 6:11 am
Posts: 5
Hello and thanks for any help in advance!

I'm playing around with PolyVox and Irrlicht where I'm generating a mesh using information from Polyvox, I then convert this information into an Irrlicht mesh. The problem I'm having is with lighting. It is hard to describe the problem, so I'll just show you it:

Lighting from a single direction (above): https://gfycat.com/FlamboyantConcernedHypsilophodon

Lighting following the camera: https://gfycat.com/SickRequiredAsianelephant

Lighting from above and normal debugging: https://gfycat.com/ArtisticVerifiableGreendarnerdragonfly

C++ code:

Here's where the PolyVox volume is made:
Code:
irr::scene::IMeshSceneNode* ChunkManager::LoadChunkBlock(int x_c, int y_c, int z_c){

   
            PolyvoxIrrlichtUtils poly_object;
            SimpleVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(Common::BLOCKS_PER_CHUNK, Common::BLOCKS_PER_CHUNK, Common::BLOCKS_PER_CHUNK)));

            FastNoise n;
//            n.SetFrequency(0.005f);
//            n.SetFractalGain(0.5f);
            n.SetFractalOctaves(2);
//            n.SetFractalLacunarity(2);
//            n.SetNoiseType(FastNoise::NoiseType::WhiteNoise);
           
           
            for (int z = 0; z < volData.getDepth(); z++)
            {
                for (int y = 0; y < volData.getHeight(); y++)
                {
                    for (int x = 0; x < volData.getWidth(); x++)
                    {
                       
                        uint8_t uVoxelValue = (y+((volData.getHeight()-1)*y_c)) + n.GetValueFractal((x+((volData.getWidth()-1)*x_c))*2+5, (y+((volData.getHeight()-1)*y_c))*2+3, (z+((volData.getDepth()-1)*z_c))*2+0.6) * 40;

                        //Wrte the voxel value into the volume
                        volData.setVoxelAt(x, y, z, uVoxelValue);
                       
                    }
                }
            }


            PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> PlanetMesh;
            PolyVox::MarchingCubesSurfaceExtractor< PolyVox::SimpleVolume<uint8_t> > surfaceExtractor(&volData, volData.getEnclosingRegion(), &PlanetMesh);
            surfaceExtractor.execute();



            irr::scene::IMeshSceneNode* planet_mesh_node = Common::irrScene->addMeshSceneNode(poly_object.convertPolyMesh(PlanetMesh), 0);



            planet_mesh_node->setMaterialFlag(video::EMF_LIGHTING, true);
            planet_mesh_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, false);
            planet_mesh_node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
            planet_mesh_node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, false );
            planet_mesh_node->setMaterialFlag(video::EMF_BACK_FACE_CULLING, true);

           

            planet_mesh_node->setScale(core::vector3df(Common::CHUNK_NODE_SCALE, Common::CHUNK_NODE_SCALE, Common::CHUNK_NODE_SCALE));

           
            float step_x = (Common::BLOCKS_PER_CHUNK * planet_mesh_node->getScale().X) * x_c;
            float step_y = (Common::BLOCKS_PER_CHUNK * planet_mesh_node->getScale().Y) * y_c;
            float step_z = (Common::BLOCKS_PER_CHUNK * planet_mesh_node->getScale().Z) * z_c;
           
            planet_mesh_node->setPosition(vector3df(step_x, step_y, step_z));
           
            planet_mesh_node->getMesh()->setDirty();
            planet_mesh_node->getMesh()->getMeshBuffer(0)->recalculateBoundingBox();
           
           
            //planet_mesh_node->setDebugDataVisible(irr::scene::EDS_NORMALS);
           
           
            return planet_mesh_node;
}




Here's where the PolyVox volume is converted into an Irrlicht mesh:
Code:
irr::scene::SMesh* PolyvoxIrrlichtUtils::convertPolyMesh(const PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal>& meshPoly) {
   //irr::scene::SMeshBuffer* buffer =new irr::scene::SMeshBuffer();
   irr::scene::IDynamicMeshBuffer* buffer =new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_32BIT);
 
   const std::vector<uint32_t>& indices = meshPoly.getIndices();
   const std::vector<PolyVox::PositionMaterialNormal>& vertices = meshPoly.getVertices();

   
   
   buffer->getIndexBuffer().set_used(indices.size());
   for (size_t i = 0; i < indices.size(); ++i) {
       buffer->getIndexBuffer().setValue(i, indices[i]);
   }
 

   buffer->getVertexBuffer().set_used(vertices.size());
   for (size_t i = 0; i < vertices.size(); ++i) {
       const PolyVox::Vector3DFloat& position = vertices[i].getPosition();
       const PolyVox::Vector3DFloat& normal = vertices[i].getNormal();
       buffer->getVertexBuffer()[i].Pos.X = position.getX();
       buffer->getVertexBuffer()[i].Pos.Y = position.getY();
       buffer->getVertexBuffer()[i].Pos.Z = position.getZ();
       buffer->getVertexBuffer()[i].Normal.X = normal.getX();
       buffer->getVertexBuffer()[i].Normal.Y = normal.getY();
       buffer->getVertexBuffer()[i].Normal.Z = normal.getZ();
       buffer->getVertexBuffer()[i].Color = irr::video::SColor(25,185,25,255); //Purple
       
       //buffer->getVertexBuffer()[i].Color = irr::video::SColor(217,255,9,255);
   }
 
   // Recalculate bounding box
   buffer->recalculateBoundingBox();
   
   //Create mesh
   irr::scene::SMesh* mesh = new irr::scene::SMesh;
   mesh->addMeshBuffer(buffer);
   buffer->drop();
 
   mesh->recalculateBoundingBox();
   return mesh;
}


As you can see, on the edge of each mesh there are black triangles that stay black until the direction of the light changes in a way to light them up. I'm looking to fix this. Also, I'm going for a flat-shaded style, so the general look is not the problem, just the edges.

I'm thinking it is something to do with the normals but I'm not sure what it is exactly. I'm not sure if this is something that has to do with PolyVox and the normals it generates or if it is something on my part.

I don't plan on using textures, just vertex colors.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Irrlicht procedural mesh and lighting problem.
PostPosted: Tue Jul 25, 2017 11:44 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Hi, thanks for your interest in PolyVox. From reading your code it appears that your scene consists of multiple small volumes rather than a single large one. In general this is not how you should use PolyVox and it will cause problems with the normals because normals are calculated by looking at adjacent voxels (which don't exist at the edge of the volume). Have a read here:

http://www.volumesoffun.com/polyvox/doc ... l/FAQ.html

Things are slightly different in your case because it looks like you are generating the volume procedurally. I would recommend you look at the 'Paging' example and observe the way it generates data on demand from a Perlin noise function.

However, even if you get the normals generating correctly, they are per-vertex normals intended for smooth shading. You will not get the right result (though it might look OK) if you use them for flat-shading (this is a general computer graphics issue, not a PolyVox one). The conventional approach is to split the triangles up so that they do not share any vertices and then give all the vertices of a given triangle the same normal. However, this significantly increases the amount of data.

An alternative may be to compute the normals via derivative operations in shader code, in which case you can completely ignore (and discard) the ones PolyVox gives you. See here under 'Normal Calculation for Cubic Meshes' (the same principle could be applied to Marching Cubes meshes).

http://www.volumesoffun.com/polyvox/doc ... bic-meshes

However, this does require some reasonable knowledge of shader programming knowledge.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Irrlicht procedural mesh and lighting problem.
PostPosted: Wed Jul 26, 2017 2:44 am 

Joined: Fri Jul 21, 2017 6:11 am
Posts: 5
David Williams wrote:
Hi, thanks for your interest in PolyVox. From reading your code it appears that your scene consists of multiple small volumes rather than a single large one. In general this is not how you should use PolyVox and it will cause problems with the normals because normals are calculated by looking at adjacent voxels (which don't exist at the edge of the volume). Have a read here:

http://www.volumesoffun.com/polyvox/doc ... l/FAQ.html

Things are slightly different in your case because it looks like you are generating the volume procedurally. I would recommend you look at the 'Paging' example and observe the way it generates data on demand from a Perlin noise function.

However, even if you get the normals generating correctly, they are per-vertex normals intended for smooth shading. You will not get the right result (though it might look OK) if you use them for flat-shading (this is a general computer graphics issue, not a PolyVox one). The conventional approach is to split the triangles up so that they do not share any vertices and then give all the vertices of a given triangle the same normal. However, this significantly increases the amount of data.

An alternative may be to compute the normals via derivative operations in shader code, in which case you can completely ignore (and discard) the ones PolyVox gives you. See here under 'Normal Calculation for Cubic Meshes' (the same principle could be applied to Marching Cubes meshes).

http://www.volumesoffun.com/polyvox/doc ... bic-meshes

However, this does require some reasonable knowledge of shader programming knowledge.


Wow! Thanks for the help. You are right about my code generating multiple small volumes. I'm generating volumes in chunks, which then get converted into a mesh. The reason for the chunks is that the player is supposed to be able to walk any direction infinitely (or until floating-point issues occur).

I might end up rearranging the normals for flat shading, but the way it looks now is actually pretty ok for my needs. Using the information you gave me I should be able to figure out a way to fix the normals.

Thanks!


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Irrlicht procedural mesh and lighting problem.
PostPosted: Wed Jul 26, 2017 7:02 am 

Joined: Fri Jul 21, 2017 6:11 am
Posts: 5
I was doing some googling and it seems that using a LargeVolume might make more sense. I'll just have to look through the documentation on how to use it.

If you have any better ideas on how to implement an infinite terrain system let me know, please. From the research I did around the forums it seems many people have tried what I'm doing currently, but there was never any comments saying if they got it to work.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Irrlicht procedural mesh and lighting problem.
PostPosted: Wed Jul 26, 2017 2:35 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Devy wrote:
I was doing some googling and it seems that using a LargeVolume might make more sense.


LargeVolume is in PolyVox 0.2.1 which is actually quite old now, though we haven't made another release since. I'd recommend you try the latest version of the PolyVox code in the develop branch. This has PagedVolume instead of LargeVolume though many of the principles are similar.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Irrlicht procedural mesh and lighting problem.
PostPosted: Thu Jul 27, 2017 5:06 am 

Joined: Fri Jul 21, 2017 6:11 am
Posts: 5
David Williams wrote:
Devy wrote:
I was doing some googling and it seems that using a LargeVolume might make more sense.


LargeVolume is in PolyVox 0.2.1 which is actually quite old now, though we haven't made another release since. I'd recommend you try the latest version of the PolyVox code in the develop branch. This has PagedVolume instead of LargeVolume though many of the principles are similar.


Alright, I see what you mean when you said to look at the paging example. I look into that more. I upgraded the version of PolyVox that I was using to the one you linked. Thank you!


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 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