how to have 2 materials on a procedural mesh

is it possible to have two materials on one mesh made through code (a flat plane), and can I determine the material based on height? eg:

 if (vert.y > grass)
{
//then set material to grass;
}
else
//set material to dirt

Well you have the wrong picture of what a material is. A material is not somehow assigned to a mesh. It’s actually the other way round. A material is a tool that is used to render a mesh. It’s essentially a shader / GPU program combined with configuration data like textures, normal maps and other data like a tint color. From the GPU point of view you start with a material. So the shader is loaded into the pipeline, the static uniform parameters are set and then a draw call is issued where the GPU is told to render a given mesh with the currently loaded shader program.

While it is possible with Unity’s MeshRenderer to specify multiple materials, those are used for the different submeshes that are defined in the Mesh class. Submeshes in a mesh can share the same vertices, but have seperate triangle / index buffers which define the actual triangles / faces. A mesh with multiple submeshes are essentially seperate meshes which are just defined within the same class. Since different materials apply to the different submeshes, each submesh is rendered seperately. So while you could split your mesh into several submeshes and use a different material for each submesh, you can not get any kind of blending between them. So you get a hard edge between the two submeshes / materials.

If you’re looking for blending between different textures, you need a single material where you can blend between different textures / colors within the shader. A good example is Unity’s terrain shader. It uses a splatmap to blend between different terrain textures. The 3 color channels and the alpha channel of the splatmap is used as a mask by the shader to blend the different textures together. So the red channel may define how much weight the first texture has and the blue channel may correspond to the second texture. When you “paint” with a terrain texture in Unity’s terrain editor, you actually paint onto the splatmap.

Of course you can differentiate between different textures in the shader based on the height of a fragment or based on other vertex attributes. A commonly used channel is the color channel.

Here’s an example shader that does blend between two textures based on a global blend setting. This is useful for something like a night / day version and you slowly change the blend variable when the time changes. So it does not blend on a per vertex / fragment basis. However instead of using that global “blend” variable you could use the fragments y position in relation to a reference value.