2-7 创建颜色混合区域

  在上一章我们完成了地图单元自身颜色区域的构建,但是并没有在颜色上进行修正。这一章中我们要创建颜色混合区域,并让颜色混合区域和地图单元区域都显示正确的颜色。

  通过观察上图可以发现,颜色混合区域是V1、V2、V3、V4这四个顶点所组成的一个四边形区域,也就是两个三角面片组成了这个颜色混合区域。在HexMesh.cs中添加一个三角面片的方法和一个为颜色混合区域顶点添加颜色的方法。代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55


/// <summary>
/// 为每个三角面片的3个顶点赋颜色值
/// </summary>
/// <param name="color">三角面片顶点的颜色信息</param>
private void AddTriangleColor(Color color)
{
colors.Add(color);
colors.Add(color);
colors.Add(color);
}

/// <summary>
/// 创建颜色混合区域的三角面片定点信息和索引,这个区域是一个四边形,所以有4个顶点
/// </summary>
/// <param name="v1">三角面片第一个顶点位置信息</param>
/// <param name="v2">三角面片第二个顶点位置信息</param>
/// <param name="v3">三角面片第三个顶点位置信息</param>
/// <param name="v4">三角面片第四个顶点位置信息</param>
private void AddQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4)
{
//获取当前vertices链表中已经录入的数量
int vertexIndex = vertices.Count;

//在vertices链表中添加新增的顶点位置信息
vertices.Add(v1);
vertices.Add(v2);
vertices.Add(v3);
vertices.Add(v4);

//在triangles链表中添加新增顶点信息的索引
//两个三角面片组成了颜色混合区域,分别为:V1V3V2 和 V2V3V4
triangles.Add(vertexIndex);
triangles.Add(vertexIndex + 2);
triangles.Add(vertexIndex + 1);
triangles.Add(vertexIndex + 1);
triangles.Add(vertexIndex + 2);
triangles.Add(vertexIndex + 3);
}

/// <summary>
/// 为四边形颜色混合区域的每个顶点赋值颜色
/// </summary>
/// <param name="c1">第一个顶点的颜色信息</param>
/// <param name="c2">第二个顶点的颜色信息</param>
/// <param name="c3">第三个顶点的颜色信息</param>
/// <param name="c4">第四个顶点的颜色信息</param>
private void AddQuadColor(Color c1, Color c2, Color c3, Color c4)
{
colors.Add(c1);
colors.Add(c2);
colors.Add(c3);
colors.Add(c4);
}

  因为将地图单元和颜色混合区域分开了,接下来需要修改private void Triangulate(HexDirection direction, HexCell cell)方法中的一部分代码,分别构建地图单元自身三角面片和颜色混合区域的面片。并为每个顶点赋值相应的颜色。代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33


private void Triangulate(HexDirection direction, HexCell cell)
{


//这两个Vector3变量,是新的cell自身颜色区域中,两个新的顶点信息,其每个顶点距离cell中心为75%外接圆半径
Vector3 v1 = center + HexMetrics.GetFirstSolidCorner(direction);
Vector3 v2 = center + HexMetrics.GetSecondSolidCorner(direction);

//这两个Vector3变量,是原本构成cell一个三角面片的其中两个顶点位置。现在是颜色混合区域的两个顶点位置。
Vector3 v3 = center + HexMetrics.GetFirstCorner(direction);
Vector3 v4 = center + HexMetrics.GetSecondCorner(direction);

//使用声明的新变量,替换之前计算得出的结果
AddTriangle(center, v1, v2);

//将计算好的颜色混合区域定点位置信息,添加到添加到链表中
AddQuad(v1, v2, v3, v4);



//这里为cell的三角面片每个顶点赋值颜色,因为cell自身不再参与颜色混合,所以只有自身颜色
AddTriangleColor(cell.color);

//为颜色混合区域的4个顶点分别赋值颜色
//其中v1 v2是cell自身颜色,v3 v4是混合后的颜色
AddQuadColor(
cell.color,
cell.color,
(cell.color + prevNeighbor.color + neighbor.color) / 3.0f,
(cell.color + nextNeighbor.color + neighbor.color) / 3.0f
);

  创建了颜色混合区域之后,在视觉效果上有了比较大的提升,现在地图单元既能保持自己的颜色不会被干扰,同时还有专门的颜色混合区域来进行与相邻地图单元的颜色混合。但是我们仔细观察运行结果,还是会发现一些问题,例如当三个相邻切互相颜色不同的地图单元互相进行颜色混合的时候,颜色混合区域会互相干扰,产生一种类似于“溢色”的感觉。在接下来的章节中,我们会进一步拆分颜色混合区域,来解决这个问题。

Github代码