随机分形地形生成算法-D3D12实现

/// 创建随机地形
void Terrain::BulidRandomTerrain(float height, UINT seed)
{
	srand(seed);		// 随机数发生器
	struct Quad			// 定义待处理的正方形结构
	{
		UINT index;		// 左上角顶点索引
		UINT length;	// 边长

		Quad(UINT i, UINT len) {
			index = i;
			length = len;
		}
	};
	float aspect = height / (float)mSize;
	std::queue qQuad;		// 待处理正方形队列
	Quad quad(0, mSize - 1);
	qQuad.push(quad);

	while (!qQuad.empty())
	{
		Quad currQuad = qQuad.front();
		qQuad.pop();
		float maxH = currQuad.length * aspect;	// 当前点最大高度
		// 正方形阶段
		int a = currQuad.index;					// 左上角
		int b = a + currQuad.length;			// 右上角
		int c = a + currQuad.length * mSize;		// 左下角
		int d = c + currQuad.length;			// 右下角
		int m = a + mSize * currQuad.length / 2 + currQuad.length / 2;	// 中心
		Vertices[m].Pos.y = (Vertices[a].Pos.y + Vertices[b].Pos.y +
			Vertices[c].Pos.y + Vertices[d].Pos.y) / 4.0 + MathHelper::RandF(-maxH / 2.0, maxH);

		// 菱形阶段
		int e = a + currQuad.length / 2;		// 上中点
		int f = c + currQuad.length / 2;		// 下中点
		int g = m - currQuad.length / 2;		// 左中点
		int h = m + currQuad.length / 2;		// 右中点
		Vertices[e].Pos.y = (Vertices[a].Pos.y + Vertices[b].Pos.y +
			Vertices[m].Pos.y + Vertices[m].Pos.y) / 4.0 + MathHelper::RandF(-maxH / 2.0, maxH);
		Vertices[f].Pos.y = (Vertices[c].Pos.y + Vertices[d].Pos.y +
			Vertices[m].Pos.y + Vertices[m].Pos.y) / 4.0 + MathHelper::RandF(-maxH / 2.0, maxH);
		Vertices[g].Pos.y = (Vertices[a].Pos.y + Vertices[c].Pos.y +
			Vertices[m].Pos.y + Vertices[m].Pos.y) / 4.0 + MathHelper::RandF(-maxH / 2.0, maxH);
		Vertices[h].Pos.y = (Vertices[b].Pos.y + Vertices[d].Pos.y +
			Vertices[m].Pos.y + Vertices[m].Pos.y) / 4.0 + MathHelper::RandF(-maxH / 2.0, maxH);

		int new_length = currQuad.length / 2;
		// 如果新边长大于1(即还可再分),则加入新的正方形入队
		if (new_length > 1) {
			qQuad.push(Quad(a, new_length));
			qQuad.push(Quad(e, new_length));
			qQuad.push(Quad(g, new_length));
			qQuad.push(Quad(m, new_length));
		}
	}

	setTerrainNormal();
	//setTerrainTex();
}

/// 计算地形法线
void Terrain::setTerrainNormal() {
	UINT triCount = GetIndices16().size() / 3;		// 三角形数量

	for (UINT i = 0; i < triCount; i++) {
		// 三角形的顶点索引
		UINT i0 = GetIndices16()[i * 3 + 0];
		UINT i1 = GetIndices16()[i * 3 + 1];
		UINT i2 = GetIndices16()[i * 3 + 2];

		// 三角形的顶点
		auto v0 = Vertices[i0];
		auto v1 = Vertices[i1];
		auto v2 = Vertices[i2];

		// 三角形两条边的向量
		XMVECTOR vec0 = DirectX::XMLoadFloat3(&v0.Pos) - DirectX::XMLoadFloat3(&v1.Pos);
		XMVECTOR vec1 = DirectX::XMLoadFloat3(&v1.Pos) - DirectX::XMLoadFloat3(&v2.Pos);
		XMVECTOR normal = XMVector3Cross(vec0, vec1);

		// 累加三角形共享顶点的法向量
		XMStoreFloat3(&Vertices[i0].Normal, DirectX::XMLoadFloat3(&Vertices[i0].Normal) + normal);
		XMStoreFloat3(&Vertices[i1].Normal, DirectX::XMLoadFloat3(&Vertices[i1].Normal) + normal);
		XMStoreFloat3(&Vertices[i2].Normal, DirectX::XMLoadFloat3(&Vertices[i2].Normal) + normal);

	}

	// 将所有法线归一化
	for (UINT i = 0; i < Vertices.size(); i++) {
		XMStoreFloat3(&Vertices[i].Normal, XMVector3Normalize(DirectX::XMLoadFloat3(&Vertices[i].Normal)));
	}
}

 

你可能感兴趣的:(随机分形地形生成算法-D3D12实现)