如何在directx12中使用高度图来渲染不同纹理的不同地形?

时间:2017-03-13 13:32:43

标签: graphics directx directx-11 directx-12

terrain demo

bool TerrainDemo::ReadRawFile(std::string filePath)
{
    std::ifstream inFile;
    inFile.open(filePath.c_str(), std::ios::binary);
    inFile.seekg(0, std::ios::end);
    std::vector<BYTE> inData(inFile.tellg());
    inFile.seekg(std::ios::beg);
    inFile.read((char*)&inData[0], inData.size());
    inFile.close();

    m_heightInfos.resize(inData.size());
    for (unsigned int i = 0; i < inData.size(); ++i)
    {
        m_heightInfos[i] = inData[i];
    }

    return true;
}


bool TerrainDemo::InitTerrain(float width, float height, UINT m, UINT n,     float scale)
{
    m_cellsPerRow = m;
    m_cellsPerCol = n;
    m_verticesPerRow = m + 1;
    m_verticesPerCol = n + 1;
    m_numsVertices = m_verticesPerRow*m_verticesPerCol;
    m_width = width;
    m_height = height;
    m_heightScale = scale;

for (auto& item : m_heightInfos)
{
    item *= m_heightScale;
}

float oX = -width * 0.5f;
float oZ = height * 0.5f;
//每一格坐标变化
float dx = width / m;
float dz = height / n;

m_vertices.resize(m_numsVertices);


for (UINT i = 0; i < m_verticesPerCol; ++i)
{
    float tempZ = oZ - dz * i;
    for (UINT j = 0; j < m_verticesPerRow; ++j)
    {
        UINT index = m_verticesPerRow * i + j;
        m_vertices[index].Pos.x = oX + dx * j;
        m_vertices[index].Pos.y = m_heightInfos[index];
        m_vertices[index].Pos.z = tempZ;
        m_vertices[index].TexC = XMFLOAT2(dx*i, dx*j);                      
    }
}



UINT nIndices = m * n * 6;
m_indices.resize(nIndices);
UINT tmp = 0;
for (UINT i = 0; i < n; ++i)
{
    for (UINT j = 0; j < m; ++j)
    {
        m_indices[tmp] = i * m_verticesPerRow + j;
        m_indices[tmp + 1] = i * m_verticesPerRow + j + 1;
        m_indices[tmp + 2] = (i + 1) * m_verticesPerRow + j;

        XMFLOAT3 temp;
        ComputeNomal(m_vertices[m_indices[tmp]], m_vertices[m_indices[tmp + 1]],
            m_vertices[m_indices[tmp + 2]], temp);
        m_vertices[m_indices[tmp]].Normal = temp;
        m_vertices[m_indices[tmp + 1]].Normal = temp;
        m_vertices[m_indices[tmp + 2]].Normal = temp;


        m_indices[tmp + 3] = i * m_verticesPerRow + j + 1;
        m_indices[tmp + 4] = (i + 1) * m_verticesPerRow + j + 1;
        m_indices[tmp + 5] = (i + 1) * m_verticesPerRow + j;

        ComputeNomal(m_vertices[m_indices[tmp + 3]], m_vertices[m_indices[tmp + 4]],
            m_vertices[m_indices[tmp + 5]], temp);
        m_vertices[m_indices[tmp + 3]].Normal = temp;
        m_vertices[m_indices[tmp + 4]].Normal = temp;
        m_vertices[m_indices[tmp + 5]].Normal = temp;

        tmp += 6;
    }


}

return true;

}

void TerrainDemo::ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal)
{
XMFLOAT3 f1(v2.Pos.x - v1.Pos.x, v2.Pos.y - v1.Pos.y, v2.Pos.z - v1.Pos.z);
XMFLOAT3 f2(v3.Pos.x - v1.Pos.x, v3.Pos.y - v1.Pos.y, v3.Pos.z - v1.Pos.z);
XMVECTOR vec1 = XMLoadFloat3(&f1);
XMVECTOR vec2 = XMLoadFloat3(&f2);
XMVECTOR temp = XMVector3Normalize(XMVector3Cross(vec1, vec2));
XMStoreFloat3(&normal, temp);
}

作为图片,我通过分析高度图来渲染地形,但只使用一个纹理。图中不同的高度代表不同的地形,如道路,草地,水等。如何使用不同的纹理来渲染不同的地形?我必须计算地形不同部分的顶点和索引吗? 有些部分是不规则的,如何计算它们的索引?在着色器中执行此操作是否可以,以及如何操作?

0 个答案:

没有答案