2
\$\begingroup\$

I am making a game in c++ with opengl and glm and was working on my terrain when this happend :

enter image description here

as it appears it is renderering just the way i planned it, but my question was, how do i make it appear so that the their are not as many shadows? i have no idea of how i can fix this.

Here is the normal code:

        glm::vec3 calculateNormal(int x, int z) {
            float heightL = getHeight(x - 1, z);
            float heightR = getHeight(x + 1, z);
            float heightD = getHeight(x, z - 1);
            float heightU = getHeight(x, z + 1);
            glm::vec3 normal(heightL - heightR, 2.0f, heightD - heightU);
            glm::vec3 result = glm::normalize(normal);
            return result;
        }

and here is the terrain normal generation code

for (int i = 0; i < vertex_count; i++) {
                for (int j = 0; j < vertex_count; j++) {

                    float height = getHeight(j, i);

                    vert[vertexPointer * 3] = (float)j / ((float)vertex_count - 1) * size;
                    vert[vertexPointer * 3 + 1] = height;
                    vert[vertexPointer * 3 + 2] = (float)i / ((float)vertex_count - 1) * size;

                    glm::vec3 normal = calculateNormal(j, i);

                    norm[vertexPointer * 3] = normal.x;
                    norm[vertexPointer * 3 + 1] = normal.y;
                    norm[vertexPointer * 3 + 2] = normal.z;
                    ...

here is the terrain generation code

float getNoise(int x, int z) {
            int seed = x + z + (std::rand() % (0 - 15));
            return seed * 2.0f - 1.0f;
        }

        float generateheight(int x, int z) {
            return getIntoplatedNoise(x/16.0f, z/ 16.0f);
        }

        float getSmoothNoise(int x, int z) {
            float corners = (getNoise(x - 1, z - 1) + getNoise(x + 1, z - 1) + getNoise(x - 1, z + 1) + getNoise(x + 1, z + 1)) / 16.0f;
            float sides = (getNoise(x - 1, z) + getNoise(x + 1, z) + getNoise(x, z - 1) + getNoise(x, z + 1)) / 8.0f;
            float center = getNoise(x, z) / 4.0f;
            return corners + sides + center;

        }

        float getIntoplatedNoise(float x, float z) {
            int intX = (int)x;
            int intZ = (int)z;
            float fracX = x - intX;
            float fracZ = z - intZ;

            float v1 = getSmoothNoise(intX, intZ);
            float v2 = getSmoothNoise(intX + 1, intZ);
            float v3 = getSmoothNoise(intX, intZ + 1);
            float v4 = getSmoothNoise(intX + 1, intZ + 1);

            float i1 = interplate(v1, v2, fracX);
            float i2 = interplate(v3, v4, fracX);
            return interplate(i1, i2, fracZ);
        }

        float interplate(float a, float b, float blend) {
            double theta = blend * M_PI;
            float f = ((float) 1.0f - cos(theta)) * 0.5f;
            return a * (1.0f - f) + b * f;
        }

        float getHeight(int x, int z) {
            return generateheight(x, z);
        }

Thank you very much for you time

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

It seems each time you call getHeight(x,z) you get different results, regardless of whether the (x,z) is the same or not, so the generated normals don't match the terrain surface.

Normals will match the actual terrain if you compute them from the generated terrain, and not from what getHeight returns. However, it makes sense to also fix getHeight so it always returns the same value for the same input point. As a tip, take a look at Perlin Noise.

https://en.wikipedia.org/wiki/Perlin_noise

\$\endgroup\$
5
  • \$\begingroup\$ To be more specific, your problem is that getNoise(x,z) is returning a value based upon std::rand(). \$\endgroup\$ May 4, 2016 at 3:20
  • \$\begingroup\$ @TrevorPowell ok so i have to use controlled-random number generation like simplex noise \$\endgroup\$ May 4, 2016 at 3:49
  • \$\begingroup\$ @Gato ok so now i have an impementation of perlin noise and have a understanding of it. how would i implement it in my terrain? \$\endgroup\$ May 4, 2016 at 3:57
  • \$\begingroup\$ @TheRealBigfoot429 Try replacing the getIntoplatedNoise with the the Perlin noise. You might need some scaling/shifting of the coordinates or the generated values. \$\endgroup\$
    – Gato
    May 4, 2016 at 4:00
  • 1
    \$\begingroup\$ @Gato your a genious! thank you very much for this help once again! \$\endgroup\$ May 4, 2016 at 4:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .