Help Calculating UV for Heightmap from Vertex Coordinates

I currently have a terrain mesh that I’m successfully rendering, generated from digital elevation data. Now I need to render a line over that terrain such that the line is “draped” over the contours of the terrain.

My approach has been to render the full height and width of the terrain to a heightmap texture using an orthographic projection. Then, when I’m drawing the line, I can sample the heightmap for the correct height.

My problem is I’m having difficulty calculating the correct UV coordinates to look up the height in the texture. My line will have height variations, but they are all over the place and do not follow the terrain in the slightest. Often going into the terrain itself.

Currently I’m calculating the UV coordinates in the vertex shader for the line. I’ve tried using a separate UV buffer as well but I get the same results.

Here is my vertex shader where I’m calculating the UV and interpolating the height stored in the red channel.

#version 120

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

attribute vec2 Vertex;

uniform sampler2D terraintexture;

void main()
{
  vec2 pos;

  // Map vertex to -1 -> 1 range
  pos.x = (Vertex.x) / (HalfSquareSize);
  pos.y = (Vertex.y) / (HalfSquareSize);

  // Then convert to 0 -> 1 for texture
  pos += 1.0;
  pos /= 2.0;

  vec4 tex = texture2D(terraintexture, pos);

  // Convert 0 -> 1 back to MinHeight -> MaxHeight
  float altitude = (tex.r * (2 * MaxHeight)) - MaxHeight;

  // Apply model with vertex at 0 height
  vec4 x = Model * vec4(Vertex.x, 0.0, Vertex.y,  1.0);

  // Apply our offset
  x.y += altitude;

  gl_Position =  Projection * View * x;
}

I’ve thought that maybe my heightmap and terrain mesh were possibly rotated differently, but I’ve tried rotating the heightmap multiple ways with no results. Any help is greatly appreciated, thank you.

Yeah, that’s not going to work very well. Even if you implement this correctly, interpolation of the position from the heighmap will not match up with the depth buffer from the terrain very well. So sometimes the terrain will be in front of the line.

A better approach would be to redraw the terrain with a projected texture of a line. This would be a transparent overlay for the terrain; outside of the line, the alpha is zero.

The simplest solution is to render the terrain again (or at least each triangle which the line touches) with the line as a texture

If want to rendering the line with GL_LINE_STRIP or GL_LINES, it needs to be aligned to the actual triangle mesh which is being rendered, not to the terrain which the triangle mesh approximates. Even then, to avoid depth fighting you’ll either need glDepthFunc(GL_LEQUAL) and possibly glPolygonOffset, or elevate the line slightly above the triangle mesh.

If the “line” is a polyline (rather than a single line segment), each existing vertex needs to be forced to be co-planar to the triangle in which it lies. And you need to add a vertex whenever the line crosses a triangle edge, with that vertex lying on the triangle edge.

Thank you all for the responses. One thing I forgot to add in my original post that is that the line will be offset from the terrain by a couple hundred feet, so the line following the contour of the terrain exactly isn’t a concern. It is okay if the line has larger segments than that of the terrain, However with that said I still can’t have the line going in to the terrain at all.