I ended up generating a blending map at runtime based off the previously-generated heightmap. Here is the heightmap I have generated from my geometry:

Here is the blending map that gets generated from the heightmap (everything not black is actually transparent):

Just in case someone might find such a thing useful, here’s my code (I’m sure it’s wildly inefficient):
function CreateHeightmap()
{
var heightmap : Texture2D = new Texture2D(textureResolution, textureResolution);
var origin : Vector3 = Vector3(0.0, 0.0, 0.0);
var heightmapArray :Color[] = new Color[textureResolution * textureResolution];
var uvs1 = mesh.uv;
var uv_x : int = 0;
var uv_y : int = 0;
var topLeftCornerPos : int = 0;
var topRightCornerPos : int = 0;
var currentPos : int = 0;
var cpcX : int = 0;
var cpcY : int = 0;
var thisDistance : float = 0.0;
var thisColorValue : float = 0.0;
var thisColor : Color = Color.black;
var boxHeight : int = (size * 2) + 1;
// draw a gradient on each vertex position in UV space whose whiteness
// corresponds to its vertex's distance from the center of the globe
for (i = 0; i < mesh.vertices.Length; i++)
{
uv_x = Mathf.RoundToInt(uvs1[i].x * textureResolution);
uv_y = Mathf.RoundToInt(uvs1[i].y * textureResolution);
var height : float = (Vector3.Distance(origin, mesh.vertices[i]));
if (height > 1)
{
height = (height - 1) * 20;
if (height > 1) height = 1;
}
else
{
// ocean pixel, we don't care
height = 0;
}
var arrayPos : int = ((uv_y - 1) * textureResolution) + uv_x;
// define a square in which to paint the gradient
topLeftCornerPos = arrayPos - size - (textureResolution * size);
topRightCornerPos = arrayPos + size - (textureResolution * size);
for (var q = topLeftCornerPos; q < topRightCornerPos; q++)
{
for (var k = 1; k < boxHeight; k++)
{
currentPos = q + (k * textureResolution);
if (currentPos < textureResolution * textureResolution)
{
// calculate this pixel's distance from
// the center of the gradient
cpcX = currentPos % textureResolution;
cpcY = Mathf.Floor(currentPos / textureResolution);
// calculate raw distance
thisDistance = Vector2.Distance(Vector2(cpcX, cpcY), Vector2(uv_x, uv_y));
// translate distance to be 0 - 1
thisDistance = (1 - (thisDistance / boxHeight));
if (thisDistance > 1) thisDistance = 1;
thisColorValue = (thisDistance * height) / (boxHeight / 4);
thisColor = Color(thisColorValue, thisColorValue, thisColorValue);
heightmapArray[currentPos] = thisColor + heightmapArray[currentPos];
}
}
}
}
heightmap.SetPixels(heightmapArray, 0);
heightmap.Apply();
// write the heightmap to a file for perusal
var bytes = heightmap.EncodeToPNG();
File.WriteAllBytes(Application.dataPath + "/../Assets/Dynamics/heightmap.png", bytes);
return heightmapArray;
}
function CreateBlendingMap(heightmapArray : Color[])
{
var blendingMap : Texture2D = new Texture2D(textureResolution, textureResolution);
var blendingMapArray : Color[] = new Color[textureResolution * textureResolution];
var heightmapValue : float = 0.0;
for (var i=0; i < blendingMapArray.length; i++)
{
// grab the red component of this pixel
heightmapValue = heightmapArray[i].r;
blendingMapArray[i] = DetermineBlendedPixelColorValue(heightmapValue);
}
// write the blendingMap to disk for perusal
blendingMap.SetPixels(blendingMapArray, 0);
blendingMap.Apply();
bytes = blendingMap.EncodeToPNG();
File.WriteAllBytes(Application.dataPath + "/../Assets/Dynamics/blendingMap.png", bytes);
}
function DetermineBlendedPixelColorValue(height: float)
{
// don't go through this song-and-dance for water
if (height < 0.00){return Color.red;}
// not water, figure out what color to use for the blending map
var range : float = (1.0 / 7);
var currentMod : float = 0.0;
var currentColor : Color = Color(0,0,0,0);
// dirt
currentMod = (range - Mathf.Abs(height)) / range;
if (currentMod > 0)
{
currentColor = currentColor + (Color(1,0,0,0) * currentMod);
}
// grass
currentMod = (range - Mathf.Abs(height - 0.15)) / range;
if (currentMod > 0)
{
currentColor += (Color(0,1,0,0) * currentMod);
}
// more grass
currentMod = (range - Mathf.Abs(height - 0.30)) / range;
if (currentMod > 0)
{
currentColor += (Color(0,1,0,0) * currentMod);
}
// even more grass
currentMod = (range - Mathf.Abs(height - 0.45)) / range;
if (currentMod > 0)
{
currentColor += (Color(0,1,0,0) * currentMod);
}
//rocks
currentMod = (range - Mathf.Abs(height - 0.60)) / range;
if (currentMod > 0)
{
currentColor += (Color(0,0,1,0) * currentMod);
}
// more rocks
currentMod = (range - Mathf.Abs(height - 0.75)) / range;
if (currentMod > 0)
{
currentColor += (Color(0,0,1,0) * currentMod);
}
// mountain
currentMod = (range - Mathf.Abs(height - 0.90)) / range;
if (currentMod > 0)
{
currentColor += (Color.black * currentMod);
}
// fix for mountains to make it black
if (height >= 0.9)
{
currentColor = Color.black;
}
return currentColor;
}