Minecraft clone, how to handle grass block colours

I’m working on a Minecraft clone at the moment as a way to learn more about procedural generation. I’ve got infinite generation going, Chunks that are generating a single mesh each from an array of Block data, the textures being handled from a texture atlas, and then some. As it is now I’m using actual Minecraft textures as placeholders, and what I’m looking to achieve is a similar result of grass/leaves/etc changing colours depending on the type of biome they’re in. I’m not worried about the biomes yet, I’m currently stuck on actually just changing the colour.

Looking at the textures used for grass by Minecraft shows:

  1. grass_top - Which is a greyscaled top face texture of grass
  2. grass_side - A side face coloured showcasing dirt, and a bit of grass at the top
  3. grass_side_overlay - The same as the previous texture, but the dirt is removed, and the image is greyscaled like the grass_top

And playing around with the standard shader, I created two extra textures for testing purposes:

  1. grass_side_overlay_mask - Purely to test a bit, and block out the main texture
  2. grass_side_overlay_red - Used to represent what a grass block could look like with a differnt colour later on

Any white seen in the textures is transparent.

alt text

What I have now which is a temparary solution I setup earlier prior to wanting to work on having different coloured grass/leaves/etc, is the side face always being grass_side, and the top being coloued in with a modified version of standard shader that allows vertex colour. Obviously this wouldn’t be applicable since it would leave bits of dirt on the faces having grass_side as a texture with some discolouration.

I’ve thought of trying to overlay a secondary texture like the name of Minecrafts texture suggests, but that doesn’t seem possible without modifying standard shader, nor am I entirely sure that would work or be optimal considering my textures come from a texture atlas.

So I’m wondering what kind of approaches can be looked at to solve this problem, and what might be considered the best, or most optimal way of achieving this result. I’m also wondering if there is a way this can be done without modifying standard shader.

Some more informaton to get a better idea of what I’m doing.

As I said, I have Chunks being generated, and each chunk contains single mesh generated from an array of Block data. Chunks being 16x16x16.

An example of what a chunk looks like:

alt text

I’ve been playing around with the standard shader a bit to see how the UV Set works, and see if I could get it to show in some way to see if they were actually working. From what I can tell, the UV1 only get’s used - even if you select it - if you’re using a _DetailAlbedoMap since in the standard shader the texcoords of UV1 relate to the Detail Albedo. So I set Detail Albedo to be the same texture - My Texture Atlas - to check if it was using the UV1.

private void _Render ()
{
    if (Instance == null)
    {
        Instance = new GameObject("Chunk [" + position.ToVector3().ToString() + "]",
                                  typeof(MeshCollider),
                                  typeof(MeshFilter),
                                  typeof(MeshRenderer));
        Instance.transform.position = position.ToVector3();
        Instance.GetComponent<Renderer>().material = Resources.Load<Material>("_Materials/Chunk");
        Instance.GetComponent<Renderer>().material.mainTexture = TextureAtlas.GetAtlas();
        Instance.transform.SetParent(WorldManager.Instance.ChunksContainer.transform);
    }

    Mesh mesh = _Chunkmesh.ToMesh();
    Instance.transform.GetComponent<MeshCollider>().sharedMesh = mesh;
    Instance.transform.GetComponent<MeshFilter>().sharedMesh = mesh;
    //Instance.transform.GetComponent<Renderer>().material.SetTexture("_DetailMask", TextureAtlas.GetAtlas());
    Instance.transform.GetComponent<Renderer>().material.SetTexture("_DetailAlbedoMap", TextureAtlas.GetAtlas());
}

and here’s what it looks like with the grass_side_overly_mask:

alt text

Right now all my blocks secondary uvs are being set to the same cooridnates for testing purposes:

public virtual Vector2[] MaskPosition (Direction direction)
{
    return TextureAtlas.GetCoordinate("grass_side_overlay_mask").ToUvMap();
}

Then I wanted to see what would happen if I put the red overlay on it:

alt text

As you can see, weirdly enough it leaves some pixels of the face black which shouldn’t be, at least not from any reason I can understand. But lastly, I put the actual grass_side_overlay as the UV1 as the texcoords, and somehow I got something almost identical to the grass_side_overlay_mask:

alt text

I recognize that if I put a texture with pure transparancy in the Detail Mask that the parts blacked out in the above image would then be revealed. To me this suggests that if the shader had a way to attribute a colour to the Detail Albedo, then only the Detail Albedo would be affected by that colour, while still being overlayed. While the Main Texture would still keep it’s own colour. Would this be correct? And if so, would this be an appropriate solution?

If it is, I’d definitely look into it despite the need of modifying the standard shader. But I’d still also like to know if there was other ways of solving this problem, and as said above, what would be best, or optimal. Again, I’d personally like to avoid modifying the standard shader, but if it can’t be done without doing so, I’d be resolved to do so. Any suggestions are welcome, and thanks in advance for any help provided.

I’m not sure if this is the answer you’re looking for, but you can modify the ‘tint’ of an instance of a material: material.color. This only affects the instance of the material so you can change it individually for each block.

Not sure if that’s what you wanted, but I hope it helps!