# Strange Bug in Projected-Grid Rendering

This topic is 829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello.

I have been attempting to implement a projected grid to test out some water related code I have written. In order to do this I implemented the projected grid created by Eric Bruneton in his ocean water/lighting paper (http://www-ljk.imag.fr/Publications/Basilic/com.lmc.publi.PUBLI_Article@125fe8a8322_1ac3379/article.pdf). I have essentially completed the implementation aside for one odd bug that remains unsolved. Whenever the pitch of the camera increases to above some angle, dependent on how the "horizon" of the grid is computed, the grid becomes to draw degenerate triangles and it seems like a projection problem but I can't really tell what about this angle causes the grid to spasm so severely. The code for grid generation is implemented as follows:

void generate_mesh(float camera_theta)
{
if (grid_vbo_size != 0) {
glDeleteVertexArrays(1, &grid_vao);
glDeleteBuffers(1, &grid_vbo);
glDeleteBuffers(1, &grid_ibo);
}
glGenVertexArrays(1, &grid_vao);
glBindVertexArray(grid_vao);
glGenBuffers(1, &grid_vbo);
glBindBuffer(GL_ARRAY_BUFFER, grid_vbo);
//was horizon = tan(camera_theta / 180 * M_PI);
float horizon = tan(45 / 180.0 * M_PI);
float s = std::min(1.1f, 0.5f + horizon * 0.50f);
std::cout << s << std::endl;
float vmargin = 0.1;
float hmargin = 0.1;
int size = int(ceil(HEIGHT * (s + vmargin) / grid_size) + 5) * int(ceil(WIDTH * (1.0 + 2.0 * hmargin) / grid_size) + 5);
glm::vec4 *data = new glm::vec4[int(ceil(HEIGHT * (s + vmargin) / grid_size) + 5) * int(ceil(WIDTH * (1.0 + 2.0 * hmargin) / grid_size) + 5)];
int n = 0;
int nx = 0;
for (float j = HEIGHT * s - 0.1; j > -HEIGHT * vmargin - grid_size; j -= grid_size) {
nx = 0;
for (float i = -WIDTH * hmargin; i < WIDTH * (1.0 + hmargin) + grid_size; i += grid_size) {
data[n++] = glm::vec4(-1.0 + 2.0 * i / WIDTH, -1.0 + 2.0 * j / HEIGHT, 0.0, 1.0);
nx++;
}
}
glBufferData(GL_ARRAY_BUFFER, n * 16, data, GL_STATIC_DRAW);
delete[] data;
glGenBuffers(1, &grid_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid_ibo);
grid_vbo_size = 0;
GLuint *indices = new GLuint[6 * int(ceil(HEIGHT * (s + vmargin) / grid_size) + 4) * int(ceil(WIDTH * (1.0 + 2.0 * hmargin) / grid_size) + 4)];
int nj = 0;
for (float j = HEIGHT * s - 0.1; j > -HEIGHT * vmargin; j -= grid_size) {
int ni = 0;
for (float i = -WIDTH * hmargin; i < WIDTH * (1.0 + hmargin); i += grid_size) {
indices[grid_vbo_size++] = ni + ((nj + 1) * nx);
indices[grid_vbo_size++] = (ni + 1) + ((nj + 1) * nx);
indices[grid_vbo_size++] = (ni + 1) + (nj * nx);
indices[grid_vbo_size++] = (ni + 1) + (nj * nx);
indices[grid_vbo_size++] = ni + ((nj + 1) * nx);
indices[grid_vbo_size++] = ni + nj * nx;
ni++;
}
nj++;
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER, grid_vbo_size * sizeof(GLuint), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 4 * sizeof(GL_FLOAT), (GLvoid *)0);
glEnableVertexAttribArray(0);
delete[] indices;
glBindVertexArray(0);
}


As I mentioned above the following line:

float horizon = tan(45 / 180.0 * M_PI);


affects the angle at which the grid begins to become warped. In Bruneton's original code this angle was set to be the pitch of the camera but this still presents the bug (and other undesirable behavior.) The matrices used to project the grid are simply my standard projection and view matrices (along with their inverts) and seem to be set up correctly as they projected various other geometry as expected.

The actual grid is transformed like so in a shader:

vec2 ocean_pos(vec4 vertex)
{
vec3 camera_dir = normalize((screen_to_camera * vertex).xyz);
vec3 world_dir = (camera_to_world * vec4(camera_dir, 0.0)).xyz;
//was t = -world_camera.z / world_dir.z;
float t = -world_camera.y / world_dir.y;
return world_camera.xz + t * world_dir.xz;
}
void main()
{
vec2 u = ocean_pos(position);
float s = sin(u.x) * cos(u.y);
color = vec3(s);
gl_Position = world_to_screen * vec4(u.x, s, u.y, 1.0);
} 

where world_to_screen = perspective matrix * view matrix, screen_to_camera = inverse perspective matrix, camera_to_world = inverse of view matrix, and world_camera is the position of the camera in world space.

In order to illustrate the problem further here is a screenshot of the grid with the camera pointed just under the problem angle:

[attachment=33137:angle_problem2.png]

And then when the camera is moved just above the angle:

[attachment=33138:angle_problem3.png]

Filled in:

[attachment=33139:angle_problem.png]

(the grid is being offset by sine functions to emphasize the bug but it is present in non offset grids.)

Has anyone who has implemented this encountered similar problems? Does anyone see if it's obvious why applying the aforementioned transformation would so warp a grid when the view is of a certain angle?

Edited by multifractal

##### Share on other sites

Looks like the top row of vertices has bad positions.  It's getting clipped in the first screenshot, so it doesn't show.  My guess is the bad positions come from bad indices and the bad indices come from an off-by-one error when generating indices (probably on the loop bounds).

##### Share on other sites

In the second image there you can definitely see that some of the indices are incorrect because there is lines going straight through the model in a lot of places. I'd re-check your indices and the way they are being calculated.

##### Share on other sites

Looks like the top row of vertices has bad positions.  It's getting clipped in the first screenshot, so it doesn't show.  My guess is the bad positions come from bad indices and the bad indices come from an off-by-one error when generating indices (probably on the loop bounds).

In the second image there you can definitely see that some of the indices are incorrect because there is lines going straight through the model in a lot of places. I'd re-check your indices and the way they are being calculated.

I too thought the indices were the problem but I tried drawing the vertices without doing all of the projections and no problem was seen with the polygon construction:

[attachment=33167:angle_problem4.png]

this mesh is created with the same indices and vertices that the projected grid in the original post uses.

##### Share on other sites

Looks like the top row of vertices has bad positions.  It's getting clipped in the first screenshot, so it doesn't show.  My guess is the bad positions come from bad indices and the bad indices come from an off-by-one error when generating indices (probably on the loop bounds).

In the second image there you can definitely see that some of the indices are incorrect because there is lines going straight through the model in a lot of places. I'd re-check your indices and the way they are being calculated.

I too thought the indices were the problem but I tried drawing the vertices without doing all of the projections and no problem was seen with the polygon construction:

this mesh is created with the same indices and vertices that the projected grid in the original post uses.

I feel like the code you wrote is too messy to easily debug it and picture what is going on here.

##### Share on other sites

I feel like the code you wrote is too messy to easily debug it and picture what is going on here.

Can I clear something up for you then? Do you not understand the bounds of the loop?

##### Share on other sites

Maybe it's division by zero or near zero in ocean_pos()

##### Share on other sites

Maybe it's division by zero or near zero in ocean_pos()

Wow, a quick test of that yielded the attached image. Upside down, but with the problem resolved. Thanks for your help!

[attachment=33184:Screenshot 2016-09-07 04.59.37.png]

EDIT: In the case that anyone is interested in the fix:

the glitch happens whenever 'world_dir.y'  from

float t = -ocean_camera_pos.y / world_dir.y;
return ocean_camera_pos.xz + (t) * world_dir.xz;



became positive making 't' become negative. Setting the variable like:

float t = -ocean_camera_pos.y / (min(world_dir.y, -0.001));


generally resolves the problem.

Edited by multifractal

1. 1
2. 2
3. 3
Rutin
16
4. 4
5. 5

• 11
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633723
• Total Posts
3013541
×