簡體   English   中英

如何在 OpenGL 中使用 Perlin Noise 生成程序地形?

[英]How to generate procedural terrain with Perlin Noise in OpenGL?

我需要在 OpenGL 中使用 Noise(使用 Perlin 噪聲)生成程序地形。 每次應用程序運行新地形時,都需要使用新種子生成。 (不要使用外部庫。)在為噪聲地形創建類時是否需要方法/要求。 我需要調用哪些函數/計算以及調用順序?

PS:我使用 Visual Studio 2019。

// Copy the array data into a float array, and scale and offset the heights.
    mHeightmap.resize(NumRows * NumCols, 0);
    for( int i = 0; i < NumRows * NumCols; ++i)
    {
        mHeightmap[i] = (float)in[i] * HeightScale;
    }

// A height for each vertex
{
    std::vector<unsigned char> in(NumRows * NumCols);

    // Open the file.
    std::ifstream inFile;
    inFile.open(heightmapName.c_str(), std::ios_base::binary);

    if (inFile)
    {
        // Read the RAW bytes.
        inFile.read((char*)&in[0], (std::streamsize)in.size());

        // Done with file.
        inFile.close();
    }

    // Copy the array data into a float array, and scale and offset the heights.
    mHeightmap.resize(NumRows * NumCols, 0);
    for( int i = 0; i < NumRows * NumCols; ++i)
    {
        mHeightmap[i] = (float)in[i] * HeightScale;
    }

void Terrain::CreateVAO()
{
    std::vector<GLfloat> vertices;
    vertices.reserve(NumCols * NumRows * 8);
    

    float invTwoDX = 1.0f / (2.0f * CellSpacing);
    float invTwoDZ = 1.0f / (2.0f * CellSpacing);

    //vertices 
    for ( int z = 0; z < NumRows; z++)
    {
        for ( int x = 0; x < NumCols; x++)
        {
            
            //vertex data
            int i = z * NumCols + x;
            vertices.push_back((float)x*CellSpacing);
            vertices.push_back(mHeightmap[i]);
            vertices.push_back((float)z * CellSpacing);

            //normal data

            glm::vec3 _N = { 0.0f,1.0f, 0.0f };

            if(z >= 1 && z < NumRows -1 && x >= 1 && z < NumCols - 1)
            { 
                float t = mHeightmap[(z - 1) * NumCols + x];
                float b = mHeightmap[(z + 1) * NumCols + x];
                float l = mHeightmap[z * NumCols + x - 1];
                float r = mHeightmap[z * NumCols + x + 1];

                glm::vec3 tanZ(0.0f, (b - t) * invTwoDZ, 1.0f);
                glm::vec3 tanX(1.0f, (r - l) * invTwoDX, 0.0f);

                glm::vec3 _C, _N;
                _C = glm::cross(tanZ, tanX);
                _N = glm::normalize(_C);

                
            }
            
            vertices.push_back(_N.x);
            vertices.push_back(_N.y);
            vertices.push_back(_N.z);


            vertices.push_back((float)x);
            vertices.push_back((float)z);


        }
    }
    

    std::vector<GLuint> indices;
    vertices.reserve((NumCols-1)*(NumRows -1)*6);
    //indices
    for ( int z = 0; z < NumRows-1; z++)
    {
        for ( int x = 0; x < NumCols-1; x++)
        {
            GLint a = z * NumCols + x;
            GLint b = (z +1) * NumCols + x;
            GLint c = z * NumCols + (x+1);
            GLint d = (z+1) * NumCols + (x+1);

            indices.push_back(c);
            indices.push_back(a);
            indices.push_back(b);

            indices.push_back(c);
            indices.push_back(b);
            indices.push_back(d);
        
        }
    }
    indexcount = indices.size();


    GLuint VBO, EBO;


    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);

    glVertexAttribPointer(
        0,
        3,
        GL_FLOAT,
        GL_FALSE,
        8 * sizeof(GLfloat), //Strude of the single vertex(pos)
        (GLvoid*)0); //Offset from beginning of Vertex
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(
        1,
        3,
        GL_FLOAT,
        GL_FALSE,
        8 * sizeof(GLfloat), //Strude of the single vertex(pos+color)
        (GLvoid*)(3 * sizeof(GLfloat))); //Offset from beginning of Vertex
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(
        2,
        2, //2 float component for coordinates
        GL_FLOAT,
        GL_FALSE,
        8 * sizeof(GLfloat), //Strude of the single vertex(pos+color+texture)
        (GLvoid*)(6 * sizeof(GLfloat)));//Offset from beginning of Vertex
    glEnableVertexAttribArray(2);

我不確定我是否在您的代碼中看到使用了 Perlin 噪聲。 試試這個輕量級、易於集成的庫: https : //github.com/Auburn/FastNoise ,其中包含 Perlin 和大量其他有用的東西,如可視化工具。 用法和noise.GetNoise((float)x, (float)y);一樣簡單noise.GetNoise((float)x, (float)y); 你可以插入你的高度功能

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM