| Volumes Of Fun http://www.volumesoffun.com/phpBB3/ |
|
| Trouble with Triplanar Texturing of Multiple Materials http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=375 |
Page 2 of 2 |
| Author: | ker [ Tue Apr 17, 2012 10:54 am ] |
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials |
David Williams wrote: The problem here is that a call to push_back() can cause the size of the vector to exceed its capacity. In this case a larger area of memory is allocated and the contents of the vector are copied accross, so that there is now space to add new elements. However, the references (vertex0, vertex1 and vertex2) are still referring to the old area of memory. This memory gets freed because the vector has moved and the references are now invalid.The easiest solution is to not use references but instead use real variables:Code:const PolyVox::PositionMaterialNormal vertex0 = vertices.at(i0);const PolyVox::PositionMaterialNormal vertex1 = vertices.at(i1);const PolyVox::PositionMaterialNormal vertex2 = vertices.at(i2);Give this a try and see if it works. yes, how very stupid from me... i never thought about that happening... i wonder why it worked on my machine... maybe lots of memory to waste... Quote: One more point - now that I've looked at the code more carefully I can say that it's not doing quite what I would expect. In particular, if a triangle contains three different materials then I would have expected that the triangle gets removed and three new triangles get created (one with each material). However, only one new triangle appears to get created (the size of the index buffer does not change). The wiki code may be using a different technique to me but you can read my approach in Section 3.5.2 of this article: http://books.google.com/books?id=WNfD2u ... &q&f=falseAt any rate, the wiki code is still similar so hopefully you can develop it as needed. yes these approaches differ a lot, i do all merging in the shader... never tested both approaches for efficiency, but yours is probably nicer to the gpu. |
|
| Author: | Eskari [ Tue Apr 17, 2012 11:29 am ] |
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials |
Thank you David and ker for helping me run this error down. Ill look deeper into Davids method on the cpu, though i am a big fan of how concise ker's gpu method is, especially now that i have it running. I will post a copy of my updated implementation later this evening, in case anyone else needs a reference. I'll let you know if i should run across anything else. Thanks again. |
|
| Author: | David Williams [ Tue Apr 17, 2012 12:39 pm ] |
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials |
ker wrote: yes these approaches differ a lot, i do all merging in the shader... never tested both approaches for efficiency, but yours is probably nicer to the gpu. My approach had issues as well though. In particular I have to do additive blending, which means I need to lay a black pass down first. To avoid doing this for all triangles I split the mesh in two (one mesh has only single material triangles and is rendered normally, the other has multi-material triangles and is rendered with blending) so this increases the batch count. I got a working solution but there's probably more research that can be done to find an optimal approach. |
|
| Author: | Eskari [ Sun Apr 22, 2012 1:20 pm ] | ||
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials | ||
I've been trying to tackle a few of the artifacts being generated by the vertex correction code. 1. There is a logic error which causes it to miss one multiple material triangle (we have sorta already discussed this in an earlier post, so no real worries with this one). 2. How is blending over the boundaries between regions achieved? I have been looking through the forums for an example, but have been unable to find a solution. I have broken down my volume into 64x64x64 chunks. A boundary line is created between each region as shown in the attached image. (Thoughts? Suggestions?) As always thank you for your help.
|
|||
| Author: | ker [ Sun Apr 22, 2012 2:42 pm ] |
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials |
is that boundary issue between all regions or only at 0x0x0? if it's a general boundary issue, i believe you have to modify the following three lines Code: float x = vertex_pos.getX(); float y = vertex_pos.getY(); float z = vertex_pos.getZ(); to Code: float x = vertex_pos.getX() + chunk_pos.getX(); float y = vertex_pos.getY() + chunk_pos.getY(); float z = vertex_pos.getZ() + chunk_pos.getZ(); otherwise the texture coordinates start counting at 0x0x0 inside every chunk... i probably did not notice since my textures lined up with the chunks |
|
| Author: | Eskari [ Sat Apr 28, 2012 4:46 pm ] |
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials |
So I have run across another problem which may not be entirely due to applying the Triplanar Texturing codes, but in conjunction with the smooth surface extractor and the smoothRegion function in Filter.inl a material blending error occurs. Attachment: ![]() smoothing.jpg [ 79.57 KiB | Viewed 2713 times ] Shown above, when blending between areas of dirt (material 1) and stone (material 2) a material error occurs and grass (material 0) is shown along the boundaries. In contrast, when just using the smooth surface extractor and no extra smoothing, no error occurs between the boundary of materials: Attachment: ![]() nosmoothing.jpg [ 90.55 KiB | Viewed 2713 times ] This leads me to believe the smoothRegion function is not addressing the interpolation of materials accordingly. I have already made some adjustments to the smoothRegion function to cover interpolation of neighboring materials when a previously empty space is set to a solid, but I am unable to capture this border error correctly. Code: Region croppedRegion = regionToSmooth; uint32_t uArrayWidth = croppedRegion.getUpperCorner().getX() - croppedRegion.getLowerCorner().getX() + 1; uint32_t uArrayHeight = croppedRegion.getUpperCorner().getY() - croppedRegion.getLowerCorner().getY() + 1; uint32_t uArrayDepth = croppedRegion.getUpperCorner().getZ() - croppedRegion.getLowerCorner().getZ() + 1; Array<3, uint16_t> temp(ArraySizes(uArrayWidth)(uArrayHeight)(uArrayDepth)); Array<3, uint16_t> temp2(ArraySizes(uArrayWidth)(uArrayHeight)(uArrayDepth)); int mat; const int numtextures = 10; //Assuming we are using 10 textures for (int32_t z = croppedRegion.getLowerCorner().getZ(); z <= croppedRegion.getUpperCorner().getZ(); z++) { for (int32_t y = croppedRegion.getLowerCorner().getY(); y <= croppedRegion.getUpperCorner().getY(); y++) { for (int32_t x = croppedRegion.getLowerCorner().getX(); x <= croppedRegion.getUpperCorner().getX(); x++) { uint16_t& uDensity = temp[x-croppedRegion.getLowerCorner().getX()][y-croppedRegion.getLowerCorner().getY()][z-croppedRegion.getLowerCorner().getZ()]; uint16_t& uMaterial = temp2[x-croppedRegion.getLowerCorner().getX()][y-croppedRegion.getLowerCorner().getY()][z-croppedRegion.getLowerCorner().getZ()]; int mattemp[10] = {0}; uDensity=0; ////////////Interpolating voxel densities to achieve smoothness//////////// uDensity += volData.getVoxelAt(x-1,y-1,z-1).getDensity(); uDensity += volData.getVoxelAt(x-1,y-1,z-0).getDensity(); uDensity += volData.getVoxelAt(x-1,y-1,z+1).getDensity(); uDensity += volData.getVoxelAt(x-1,y-0,z-1).getDensity(); uDensity += volData.getVoxelAt(x-1,y-0,z-0).getDensity(); uDensity += volData.getVoxelAt(x-1,y-0,z+1).getDensity(); uDensity += volData.getVoxelAt(x-1,y+1,z-1).getDensity(); uDensity += volData.getVoxelAt(x-1,y+1,z-0).getDensity(); uDensity += volData.getVoxelAt(x-1,y+1,z+1).getDensity(); uDensity += volData.getVoxelAt(x-0,y-1,z-1).getDensity(); uDensity += volData.getVoxelAt(x-0,y-1,z-0).getDensity(); uDensity += volData.getVoxelAt(x-0,y-1,z+1).getDensity(); uDensity += volData.getVoxelAt(x-0,y-0,z-1).getDensity(); uDensity += volData.getVoxelAt(x-0,y-0,z-0).getDensity(); uDensity += volData.getVoxelAt(x-0,y-0,z+1).getDensity(); uDensity += volData.getVoxelAt(x-0,y+1,z-1).getDensity(); uDensity += volData.getVoxelAt(x-0,y+1,z-0).getDensity(); uDensity += volData.getVoxelAt(x-0,y+1,z+1).getDensity(); uDensity += volData.getVoxelAt(x+1,y-1,z-1).getDensity(); uDensity += volData.getVoxelAt(x+1,y-1,z-0).getDensity(); uDensity += volData.getVoxelAt(x+1,y-1,z+1).getDensity(); uDensity += volData.getVoxelAt(x+1,y-0,z-1).getDensity(); uDensity += volData.getVoxelAt(x+1,y-0,z-0).getDensity(); uDensity += volData.getVoxelAt(x+1,y-0,z+1).getDensity(); uDensity += volData.getVoxelAt(x+1,y+1,z-1).getDensity(); uDensity += volData.getVoxelAt(x+1,y+1,z-0).getDensity(); uDensity += volData.getVoxelAt(x+1,y+1,z+1).getDensity(); uDensity /= 27; //////////////Material Correction for blank voxels///////////////////// if (volData.getVoxelAt(x,y,z).getMaterial()==0) { mat = volData.getVoxelAt(x-1,y-1,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y-1,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y-1,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y-0,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y-0,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y-0,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y+1,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y+1,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-1,y+1,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y-1,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y-1,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y-1,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y-0,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y-0,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y-0,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y+1,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y+1,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x-0,y+1,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y-1,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y-1,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y-1,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y-0,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y-0,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y-0,z+1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y+1,z-1).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y+1,z-0).getMaterial(); ++mattemp[mat]; mat = volData.getVoxelAt(x+1,y+1,z+1).getMaterial(); ++mattemp[mat]; } //the replacement material is set to the mode of its neighbors. uMaterial = std::distance(mattemp,max_element(mattemp+1,mattemp+numtextures)); } } } for (int32_t z = croppedRegion.getLowerCorner().getZ(); z < croppedRegion.getUpperCorner().getZ(); z++) { for (int32_t y = croppedRegion.getLowerCorner().getY(); y < croppedRegion.getUpperCorner().getY(); y++) { for (int32_t x = croppedRegion.getLowerCorner().getX(); x < croppedRegion.getUpperCorner().getX(); x++) { uint16_t& uDensity = temp[x-croppedRegion.getLowerCorner().getX()][y-croppedRegion.getLowerCorner().getY()][z-croppedRegion.getLowerCorner().getZ()]; uint16_t& uMaterial = temp2[x-croppedRegion.getLowerCorner().getX()][y-croppedRegion.getLowerCorner().getY()][z-croppedRegion.getLowerCorner().getZ()]; MaterialDensityPair44 val = volData.getVoxelAt(x,y,z); val.setDensity(uDensity); //Overwright material if incorrect if (volData.getVoxelAt(x,y,z).getMaterial()==0) { val.setMaterial(uMaterial); } volData.setVoxelAt(x,y,z,val); } } } } } Your thoughts are welcome |
|
| Author: | David Williams [ Sat Apr 28, 2012 10:39 pm ] |
| Post subject: | Re: Trouble with Triplanar Texturing of Multiple Materials |
I'm not sure what the correct solution to this problem is, or even if there is a good solution. Interpolation of material values doesn't really make sense because (for example) materials 1 and 3 should not average to material 2. You may find that one approach is to perform a kind of morphological dilation on the material volume so that the materials expand until there are no voxels with material 0 left (this is OK because the shape of the surface is defined only by the density field). But you can probably find cases where this will fail. Alternatively you could not smooth the volume data at all but to smooth the mesh instead. You'll have other kinds of artifacts to fight then though. |
|
| Page 2 of 2 | All times are UTC |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|