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/FlamboyantConcernedHypsilophodonLighting following the camera:
https://gfycat.com/SickRequiredAsianelephantLighting from above and normal debugging:
https://gfycat.com/ArtisticVerifiableGreendarnerdragonflyC++ 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.