So awesome news, i did it.
I’m making this post to mark my question as answered and to help anyone out that is making something similar to this.
My english isnt great so ill try to provide as much clear information as possible, if anyone wants more details about anything regarding this post or similar, feel free to ask.
I have made (rather updated) a custom shadergraph to handle uvs and textures while respecting the 8 vertex based cube logic and the flat shading thats part of that.
This group of nodes:
returns a normal that is calculated from triangles, which always face the correct direction on a cube, not vertices (by default) who are “smoothed” because they have multiple triangles using them.
Putting that group of nodes into Normal World Space, makes the 8vertex cube flat shaded
Using only that, and inputing a texture > sample texture > into base color, makes a flat shaded cube with 8 vertices, but the texture is completely off, its stretched.
My cubes have their uvs calculated through a script based on their faceDirection, but because uvs are vertex based in Unitys mesh class, you cant properly give each of the 6 faces a seperate uv, because a vertex has to face 3 directions, it cant.
What i can do however, is give the left right, front and back face their uvs and store that in the XY of uv0 and give the top and bottom face their own uvs and store that in the ZW of uv0
switch (cFaceIndex)
{
case 0: // back
uvs[cVertexIndex + 0] = new float4(0, 0, 0, 0);
uvs[cVertexIndex + 1] = new float4(1, 0, 1, 0);
uvs[cVertexIndex + 2] = new float4(1, 1, 1, 0);
uvs[cVertexIndex + 3] = new float4(0, 1, 0, 0);
addedVertices = 4;
break;
case 1: // front
uvs[cVertexIndex + 4] = new float4(1, 0, 1, 0);
uvs[cVertexIndex + 5] = new float4(0, 0, 1, 1);
uvs[cVertexIndex + 6] = new float4(0, 1, 1, 1);
uvs[cVertexIndex + 7] = new float4(1, 1, 0, 1);
addedVertices = 8;
break;
case 2: // right
uvs[cVertexIndex + 1] = new float4(1, 0, 1, 0);
uvs[cVertexIndex + 2] = new float4(1, 1, 1, 0);
uvs[cVertexIndex + 5] = new float4(0, 0, 1, 1);
uvs[cVertexIndex + 6] = new float4(0, 1, 1, 1);
addedVertices = 7;
break;
case 3: // left
uvs[cVertexIndex + 0] = new float4(0, 0, 0, 0);
uvs[cVertexIndex + 3] = new float4(0, 1, 0, 0);
uvs[cVertexIndex + 4] = new float4(1, 0, 0, 1);
uvs[cVertexIndex + 7] = new float4(1, 1, 0, 1);
addedVertices = 8;
break;
case 4: // top
uvs[cVertexIndex + 2] = new float4(1, 1, 1, 0);
uvs[cVertexIndex + 3] = new float4(0, 1, 0, 0);
uvs[cVertexIndex + 6] = new float4(0, 1, 1, 1);
uvs[cVertexIndex + 7] = new float4(1, 1, 0, 1);
addedVertices = 8;
break;
case 5: // bottom
uvs[cVertexIndex + 0] = new float4(0, 0, 0, 0);
uvs[cVertexIndex + 1] = new float4(1, 0, 1, 0);
uvs[cVertexIndex + 4] = new float4(1, 0, 0, 1);
uvs[cVertexIndex + 5] = new float4(0, 0, 1, 1);
addedVertices = 6;
break;
}
I have a little more code going on, but this part makes uvs per face, and it knows what face its dealing with, faces facing right get the uvs for the right, left left, etc.
the X and Y coords are for the left, right, front and back faces, the Z and W coords are for the top and bottom faces, the shadergraph will do the rest of the math to fit the texture accordingly.
Im working with 1 giant texture png, that contains XtimesX T shaped textures, all containing 6 squares, for each of the faces of a cube, each T shape is 1 texture and the giant texture png (called a textureAtlas) is always as wide as long.
atlasSize is the length (and width) of the textureAtlas
This part creates with the help of textureIndex (stored in the first coord of uv1) the offset for the tiling and offset node, so the correct texture is used (according to “textureIndex”)
tiling is 1 fourth divided by atlas size, so 1 T texture is selected
“Zoom In” adds an offset to center the texture on the textureAtlas to the format of 1 T texture, which is then offsetted to the asked texture by textureIndex
I set the “textureIndexs” in the same script as above:
for (int i = 0; i < addedVertices; i++)
{
textureData[cVertexIndex + i] = new float2(textureIndexs[cubeIndex], 0);
}
Then the uv handling:
Uv0 X and Y is used for left, right, front and back and is Inputted into a branch node for each of the faces (6)
Each face has a Dot product check, to see if the current face (triangle actually) is that face (eg left checks if triangles normal is (-1, 0, 0), if true
Add Uv for that triangle + 1block offset to the left, to get left face of T texture and go through a bunch of Add nodes and then Into the Uv of the sample texture
Up and bottom faces use Uv0 Z and W instead of X and Y
My attempted explanation is probably very, very useless, but if anyone asks a specific question about something, a script to share, idk, ill try to explain it better
heres the shader (convert filetype to .shadergraph before adding to unity, i could only send .txt files), have fun
Flat Shader.txt (291.5 KB)