• 12
• 12
• 9
• 10
• 13

# Planet rendering [was: Stupid GLSL question(vertex positioning)]

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

## Recommended Posts

I have a sphere with a heightmap aligned to it so that the middle of it just touches the sphere. Now I want to pull the vertices down to the sphere surface, which should be simple, but I keep failing! It just keeps being flat or otherwise disappearing or swirling around, depending on what I try. I suspect what I'm doing wong is related to me not really knowing what to do the with the 4D vectors... The sphere is centered at the origin.
uniform float radius; // sphere radius

void main() {
float height = gl_Vertex.y; // get heightmap value from vertex before transformation
vec4 pos = gl_ModelViewMatrix * gl_Vertex; // this places the heightmap onto the sphere

// if this line is removed the heightmap is positioned just fine on the sphere
// only it's not fitted to the surface, which is what I intend
pos.xyz = normalize(pos.xyz) * (radius + height);

gl_Position = gl_ProjectionMatrix * pos;
}


[Edited by - robinei on May 12, 2007 4:02:24 PM]

##### Share on other sites
You're going to get a lot of distortion using a stereographic projection, especially if you're normalizing the vector that contains height in the Y-component. The best way to do this would to either generate the vertexes so they already approximate the surface of the sphere, or to use a smarter projection. I also notice you're subtracting 'center' from 'pos', the latter which is in view-space by that point, and the former which I'm guessing you left in world-space. That's probably another source of error.

What I would do is map linear distances on the plane to spherical distances, and then convert those to spherical coordinates. Off the top of my head, it might look something like this:
// Map into sphere-space by subtracting centervec2 offset = (gl_Vertex.xz / gl_Vertex.w) - center.xy;float len = length(offset);float theta = 0.0f;float phi = 0.0f; // atan returns undefined results if both parameters are 0, so be safeif(len > 0.00001){   theta = len / radius;   phi = atan(offset.y, offset.x);} float cos_t = cos(theta);float sin_t = sin(theta);float cos_p = cos(phi);float sin_p = sin(phi); // Move back into world space by adding center and mutiplying by adjusted radiusvec3 worldPos = (radius + gl_Vertex.y) * vec3(cos_p * sin_t, cos_t, sin_p * sin_t) + center;gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(worldPos.x, worldPos.y, worldPos.z, 1.0f);

Keep in mind that even though this will spherically map the vertexes, the fragments will still be interpolated linearly, so the terrain triangles will be underneath the surface of the imaginary sphere. Increasing tessellation will minimize this effect.

##### Share on other sites
That worked wonders!

Now I just have to figure out how to sample the heightmap. I'm going to use the wavelet-based ECW-format that lets me do decompression of regions of interest at the detail level I need.

Now these map projections dedicate as big an area for lines around the earth near the poles as they do near the equator, so it seems to me I have to do wider and less detailed samples nearer to the poles.

Are there any good resources for these kind of things? I plan to write about it for a university project next semester, possibly forming a basis for my thesis. Right now I was just trying to implement something quick and dirty to get some ideas, but I need to study some material before really getting started.