You're grabbing the generated texture at the wrong time.
Fixed code below:
substance = renderer.material as ProceduralMaterial;
substance.isReadable = true;
// First assign the input texture
substance.SetProceduralTexture("Hexagon_Heights", hexBiomeMap);
// Then rebuild
substance.RebuildTexturesImmediately();
// Then grab the generated texture
substanceTexture = substance.GetGeneratedTexture(substance.GetGeneratedTextures()[0].name);
// Then grab the pixels from the generated texture and apply them to the Texture2D
substanceTexture2D = new Texture2D(substanceTexture.width, substanceTexture.height, TextureFormat.ARGB32, false);
substanceTexture2D.SetPixels32(substanceTexture.GetPixels32(0, 0, substanceTexture.width, substanceTexture.height));
substanceTexture2D.Apply();
Best Regards,
Eric