Javier-Garzo / Marching-cubes-on-Unity-3D

Terrain voxel engine with the use of Marching Cubes implemented in Unity 2020.3.17f1 (LTS).
MIT License
332 stars 43 forks source link

How to apply texture to the whole chunk? #6

Closed Somshekardsi closed 3 years ago

Somshekardsi commented 3 years ago

Hi,

How to apply texture to the whole chunk same as the right part of the picture?

The left part of the picture is current texturing.

Capture (2)

Javier-Garzo commented 3 years ago

The idea to achieve the second image is split the textures UV in 16x16 (total number voxel of area) using only the texturation code.

For this implementation you need change two functions("Execute" and "CalculateVertex" ) inside the script "BuildChunkJob". I write this modification of the code:

Code ``` /// /// Called when run the job. /// public void Execute() { for (int y = 0; y < Constants.MAX_HEIGHT; y++)//height { for (int z = 1; z < Constants.CHUNK_SIZE + 1; z++)//column, start at 1, because Z axis is inverted and need -1 as offset { for (int x = 0; x < Constants.CHUNK_SIZE; x++)//line { NativeArray cube = new NativeArray(8,Allocator.Temp); int mat = Constants.NUMBER_MATERIALS; cube[0] = CalculateVertexChunk(x, y, z, ref mat); cube[1] = CalculateVertexChunk(x + 1, y, z, ref mat); cube[2] = CalculateVertexChunk(x + 1, y, z - 1, ref mat); cube[3] = CalculateVertexChunk(x, y, z - 1, ref mat); cube[4] = CalculateVertexChunk(x, y + 1, z, ref mat); cube[5] = CalculateVertexChunk(x + 1, y + 1, z, ref mat); cube[6] = CalculateVertexChunk(x + 1, y + 1, z - 1, ref mat); cube[7] = CalculateVertexChunk(x, y + 1, z - 1, ref mat); CalculateVertex(cube, mat, x,z-1); } } } } /// /// Calculate the vertices of the voxels, get the vertices of the triangulation table and his position in the world. Also check materials of that vertex (UV position). /// public void CalculateVertex(NativeArray cube, int colorVert, int xPos, int zPos) { //Values above isoLevel are inside the figure, value of 0 means that the cube is entirely inside of the figure. int cubeindex = 0; if (cube[0].w < isoLevel) cubeindex |= 1; if (cube[1].w < isoLevel) cubeindex |= 2; if (cube[2].w < isoLevel) cubeindex |= 4; if (cube[3].w < isoLevel) cubeindex |= 8; if (cube[4].w < isoLevel) cubeindex |= 16; if (cube[5].w < isoLevel) cubeindex |= 32; if (cube[6].w < isoLevel) cubeindex |= 64; if (cube[7].w < isoLevel) cubeindex |= 128; for (int i = cubeindex * 16; jobTriTable[i] != -1; i++) { int v1 = jobCornerIndexAFromEdge[jobTriTable[i]]; int v2 = jobCornerIndexBFromEdge[jobTriTable[i]]; if (interpolate) vertex.Add(interporlateVertex(cube[v1], cube[v2])); else vertex.Add(midlePointVertex(cube[v1], cube[v2])); const float uvOffset = 0.0001f; //Small offset for avoid pick pixels of other textures //TEXTURIZATION CODE: NEED REWORKING FOR CORRECT WORKING, now have problems with the directions of the uv if (i % 6 == 0) uv.Add(new float2(Constants.MATERIAL_SIZE * (colorVert % Constants.MATERIAL_FOR_ROW) + Constants.MATERIAL_SIZE *(xPos+1)/Constants.CHUNK_SIZE - uvOffset, 1 - Constants.MATERIAL_SIZE * Mathf.Floor(colorVert / Constants.MATERIAL_FOR_ROW) - Constants.MATERIAL_SIZE * zPos / Constants.CHUNK_SIZE - uvOffset)); else if (i % 6 == 1) uv.Add(new float2(Constants.MATERIAL_SIZE * (colorVert % Constants.MATERIAL_FOR_ROW) + Constants.MATERIAL_SIZE * (xPos + 1) / Constants.CHUNK_SIZE - uvOffset, 1 - Constants.MATERIAL_SIZE * Mathf.Floor(colorVert / Constants.MATERIAL_FOR_ROW) - Constants.MATERIAL_SIZE * (zPos+1) / Constants.CHUNK_SIZE + uvOffset)); else if (i % 6 == 2) uv.Add(new float2(Constants.MATERIAL_SIZE * (colorVert % Constants.MATERIAL_FOR_ROW) + Constants.MATERIAL_SIZE * xPos / Constants.CHUNK_SIZE + uvOffset, 1 - Constants.MATERIAL_SIZE * Mathf.Floor(colorVert / Constants.MATERIAL_FOR_ROW) - Constants.MATERIAL_SIZE * zPos / Constants.CHUNK_SIZE - uvOffset)); else if (i % 6 == 3) uv.Add(new float2(Constants.MATERIAL_SIZE * (colorVert % Constants.MATERIAL_FOR_ROW) + Constants.MATERIAL_SIZE * (xPos + 1) / Constants.CHUNK_SIZE - uvOffset, 1 - Constants.MATERIAL_SIZE * Mathf.Floor(colorVert / Constants.MATERIAL_FOR_ROW) - Constants.MATERIAL_SIZE * (zPos + 1) / Constants.CHUNK_SIZE + uvOffset)); else if (i % 6 == 4) uv.Add(new float2(Constants.MATERIAL_SIZE * (colorVert % Constants.MATERIAL_FOR_ROW) + Constants.MATERIAL_SIZE * xPos / Constants.CHUNK_SIZE + uvOffset, 1 - Constants.MATERIAL_SIZE * Mathf.Floor(colorVert / Constants.MATERIAL_FOR_ROW) - Constants.MATERIAL_SIZE * (zPos + 1) / Constants.CHUNK_SIZE + uvOffset)); else if (i % 6 == 5) uv.Add(new float2(Constants.MATERIAL_SIZE * (colorVert % Constants.MATERIAL_FOR_ROW ) + Constants.MATERIAL_SIZE * xPos / Constants.CHUNK_SIZE + uvOffset, 1 - Constants.MATERIAL_SIZE * Mathf.Floor(colorVert / Constants.MATERIAL_FOR_ROW) - Constants.MATERIAL_SIZE * zPos / Constants.CHUNK_SIZE - uvOffset) ); } } ```

However the texturization of the voxels presents problems with interpolation (voxels with don't fill his full area) and problems of orientation (incorrect uv direction in the voxels), because the texturization code need improvements. You can see other problems related here: https://github.com/Javier-Garzo/Marching-cubes-on-Unity-3D/issues/5.



Some result that i archieve with the code modification: image

if you increase the variable "uvOffset ", you can get that low resolution style: const float uvOffset = 0.01f;

image

Somshekardsi commented 3 years ago

Thank you, @Javier-Garzo for your helpful response. I'll try.