I've never done transparency before. I've dealt with it in extremes (either opaque or completely transparent) but never anything in between. Because of that, I definitely had my work cut out for me this week. I posted in the forums, as well as on a couple of other places, looking for advice in simplifications I could make to the normal process of just sorting all transparent faces.
What I ended coming up with was two things: I can limit the sorting two 8 different options (+x+y+z, -x+y+z, +x-y+z, +x+y-z, -x-y+z, -x+y-z, +x-y-z, -x-y-z), and I can sort only within chunks, since my chunks are already being sorted for rendering. The first option requires one calculation of an index, making distance calculations and such unnecessary and computationally expensive compared to an index calculation, and the other makes it easy to sort in parallel -- pushing these tasks to the thread pool during the pre-render stage.
Creating this algorithm, I noticed the effects of it didn't work well with greedy meshing! That wasn't a good thing....what ended up happening was the sorting didn't take into account that some faces extend a decent distance, and that issue unfortunately led to the failure of this simplified method. The method assumes every face is its own, and isn't merged with other faces around it. Instead (for now), I am keeping the per-chunk sorting, but depth sorting using a distance vector form the player to the face. The structure is shown below:[code=:0]typedef struct INDEXARRAY { //pointer to actual data in VBO (CPU side) unsigned int* _indices; int _length;} INDEXARRAY;typedef struct TRANSPARENTFACE { // Indices for a face are in groups // of 6 -- from _indexStart to // _indexStart + 3, inclusive. unsigned int _indexStart; // hopefully center-point will work fine // for sorting! If not, I can expand here // for something that works better. With // greedy meshing, I can also limit the // extent faces merge to try and help too. float _x, _y, _z;} TRANSPARENTFACE;class TransparentMesh : public Mesh {private:protected: INDEXARRAY _indexArray; std::vector _transparentFaces;public: void addTransparentFace(unsigned int firstIndex, float x, float y, float z); void setIndices(std::unique_ptr &&ind); void sort(Camera& cam);};
My current meshing strategy requires the following strategy:[code=:0]// 1. std::vector for each thing (position, index, color, normal, lighting, etc.)//2. get Type* and copy into VertexBuffer (stores in a Buffer class, // much like nio.Buffer in Java)//3. Sends unique ptr of VertexBuffer to the Mesh instance (passing ownership,// and you can still get the data with get() functions).
From there, the [font='courier new']TransparentMesh[/font] class overrides the virtual method [font='courier new']setIndices[/font] to make sure to extract the indices and store the pointer to the array in the [font='courier new']_indexArray[/font] variable. Now when sorting occurs, at the end of the method, it marks the mesh and the indices VertexBuffer for updating during the rendering method! It's a little hack-y, but it works for now.
Also, the mesher needs to call the [font='courier new']addFace()[/font] method to add the face information used in sorting. This is useful and allows for users to decide when/how/if they want to sort faces, meaning they only use the method when they do want to sort faces. Since this is a voxel engine, i doubt this code will be touched much anyways, but I'll come back to it later when/if it presents an issue.
At this point I haven't written the depth-sorting by distance yet since school started this week, but I should have time after I finish my homework to get it finished, and hopefully get to more stuff this week, like terrain generation (in the works already!) as well as the beginnings of something new...? I'll have to see what I want to do next!
Until Next Time,
ST
Edit: I wanted to ask something about that surface merge. Don't you get cracks (T-junctions) ? I remember a discussion about this at 0fps.
Anyway, interesting development.