Question

My code creates a grid of lots of vertices and then displaces them by a random noise value in height in the vertex shader. Moving around using

glTranslated(-camera.x, -camera.y, -camera.z);

works fine, but that would mean you could go until the edge of the grid.

I thought about sending the camera position to the shader, and letting the whole displacement get offset by it. Hence the final vertex shader code:

uniform vec3 camera_position;
varying vec4 position;

void main()
{
    vec3 tmp;
    tmp = gl_Vertex.xyz;
    tmp -= camera_position;
    gl_Vertex.y = snoise(tmp.xz / NOISE_FREQUENCY) * NOISE_SCALING;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    position = gl_Position;
}

EDIT: I fixed a flaw, the vertices themselves should not get horizontally displaced.

For some reason though, when I run this and change camera position, the screen flickers but nothing moves. Vertices are displaced by the noise value correctly, and coloring and everything works, but the displacement doesn't move.

For reference, here is the git repository: https://github.com/Orpheon/Synthworld

What am I doing wrong?

PS: "Flickering" is wrong. It's as if with some positions it doesn't draw anything, and others it draws the normal scene from position 0, so if I move without stopping it flickers. I can stop at a spot where it stays black though, or at one where it stays normal.

Was it helpful?

Solution 2

I managed to fix this bug by using glUniform3fv:

main.c exterp:

// Sync the camera position variable
GLint camera_pos_ptr;
float f[] = {camera.x, camera.y, camera.z};
camera_pos_ptr = glGetUniformLocation(shader_program, "camera_position");
glUniform3fv(camera_pos_ptr, 1, f);

// draw the display list
glCallList(grid);

Vertex shader:

uniform vec3 camera_position;
varying vec4 position;

void main()
{
    vec4 newpos;
    newpos = gl_Vertex;
    newpos.y = (snoise( (newpos.xz + camera_position.xz) / NOISE_FREQUENCY ) * NOISE_SCALING) - camera_position.y;
    gl_Position = gl_ModelViewProjectionMatrix * newpos;
    position = gl_Position;
}

If someone wants to see the complete code, here is the git repository again: https://github.com/Orpheon/Synthworld

OTHER TIPS

gl_Position = ftransform();

That's what you're doing wrong. ftransform does not implicitly take gl_Vertex as a parameter. It simply does exactly what it's supposed to: perform transformation of the vertex position exactly as though this were the fixed-function pipeline. So it uses the value that gl_Vertex had initially.

You need to do proper transformations on this:

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top