[osg-users] [osgDEM] calculate height above ellipsoid in vertex shader

28 views
Skip to first unread message

Sebastian Messerschmidt

unread,
Dec 4, 2013, 8:23:12 AM12/4/13
to OpenSceneGraph Users
Hi,

I have a osgDEM produced geocentric database.
I looked into the geometryTechnique implementation to see if I somehow
can access the height of the vertices above the ellipsoid in the vertex
shader.
Unfortunately I don't have any idea how to calculate this from the give
matrices. Is this information somehow available at all?
My plan is to overwrite some of the functionality in the
geometryTechnique to pass the appropriate matrices to the shader.
Anyone having an idea?


_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Sebastian Messerschmidt

unread,
Dec 5, 2013, 8:06:40 AM12/5/13
to OpenSceneGraph Users
Hi,

I managed to get the local heights.
After realizing, that the osg_ViewMatrix * gl_ModelViewMatrix will bring
me into world space I was able to use a XYZ_to_latlonheight function in
the vertex shader.
There is only one catch with this: precision. It seems that the float
matrices will simply cut away to much precision so I get massive flickering.
Anyone any idea how to solve, improve this? In the end I simply want to
draw a water surface where the height of the geometry is below a certain
threshold. My problem here are the fragment where the height is almost
equal to the threshold.

I also tried to move the LLH-calculation to the fragment shader, but it
didn't help.

example:

vertex-shader:

out vec3 lat_lon_height;

vec3 XYZ_to_llh(vec3 ws_pos)
{
//from osgEarth
float X = xyz.x;
float Y = xyz.y;
float Z = xyz.z;
float _radiusEquator = 6378137.0;
float _radiusPolar = 6356752.3142;
float flattening = (_radiusEquator-_radiusPolar)/_radiusEquator;
float _eccentricitySquared = 2*flattening - flattening*flattening;
float p = sqrt(X*X + Y*Y);
float theta = atan(Z*_radiusEquator , (p*_radiusPolar));
float eDashSquared = (_radiusEquator*_radiusEquator -
_radiusPolar*_radiusPolar)/(_radiusPolar*_radiusPolar);
float sin_theta = sin(theta);
float cos_theta = cos(theta);

float latitude = atan( (Z +
eDashSquared*_radiusPolar*sin_theta*sin_theta*sin_theta), (p -
_eccentricitySquared*_radiusEquator*cos_theta*cos_theta*cos_theta) );
float longitude = atan(Y,X);
float sin_latitude = sin(latitude);
float N = _radiusEquator / sqrt( 1.0 -
_eccentricitySquared*sin_latitude*sin_latitude);
float height = p/cos(latitude) - N;
return vec3(longitude, latitude, height);
}

void main()
{
vec3 ws_pos = osg_ViewMatrix * osg_ModelViewMatrix * gl_Vertex;
llh = XYZ_to_llh(ws_pos);
...
}

fragment:

void main()
{
if (llh.z < 10.0)
{
gl_FragColor = vec4(1,0,0,1);
}
else
{
gl_FragColor = color;

Wojciech Lewandowski

unread,
Dec 5, 2013, 11:49:15 AM12/5/13
to OpenSceneGraph Users
Hi Sebastian,

Perhaps your GPU can use doubles ? Many of them can these days. You may also try to refactor the code to use pairs of floats (as base and offset) which in theory may be almost as precise as double. It may be however very tricky for such non-linear math as geographic projections...

Cheers,
Wojtek


2013/12/5 Sebastian Messerschmidt <sebastian.m...@gmx.de>

    }
}


Sebastian Messerschmidt

unread,
Dec 5, 2013, 11:55:55 AM12/5/13
to OpenSceneGraph Users
HI Wojciech,


Hi Sebastian,

Perhaps your GPU can use doubles ? Many of them can these days. You may also try to refactor the code to use pairs of floats (as base and offset) which in theory may be almost as precise as double. It may be however very tricky for such non-linear math as geographic projections...
I've tried. Unfortunately the trigonometric functions are not available for double precision. And I'm clueless with the two-float mechanism and trigonometric functions.
Also I guess I would have to push double matrices, and I don't know how OSG is handling them. I can recall Robert explaining that they are indeed pushed as double matrices, so the driver would cut them to float.

cheers
Sebastian


Cheers,
Wojtek


2013/12/5 Sebastian Messerschmidt <sebastian.m...@gmx.de>

    }
}


Wojciech Lewandowski

unread,
Dec 5, 2013, 11:55:59 AM12/5/13
to OpenSceneGraph Users
Hi Sebastian, 

Just an extra thought that came to me. Terrain LOD paging may cause the elevation jumps too. When LODs change meshes get denser or less dense - new vertices show up or excess vertices hide and that may also bring lot of surprises. 

Cheers,
Wojtek






2013/12/5 Wojciech Lewandowski <w.p.lew...@gmail.com>

Sebastian Messerschmidt

unread,
Dec 5, 2013, 12:28:55 PM12/5/13
to OpenSceneGraph Users
Hi Wojciech,
Hi Sebastian, 

Just an extra thought that came to me. Terrain LOD paging may cause the elevation jumps too. When LODs change meshes get denser or less dense - new vertices show up or excess vertices hide and that may also bring lot of surprises.
You're correct. But it seems to happen mostly if get close to the mesh, where the LOD should not change anymore.
Right now I'm trying to live with it. But I'm sure there might be clever tricks to make it nicer ;-)
I'm trying to get some info from the osgEarth guys, they surely know how to handle those floating point beasts.

cheers
Sebastian


Cheers,
Wojtek






2013/12/5 Wojciech Lewandowski <w.p.lew...@gmail.com>


2013/12/5 Sebastian Messerschmidt <sebastian.m...@gmx.de>

    }
}


Trajce Nikolov NICK

unread,
Dec 5, 2013, 12:34:33 PM12/5/13
to OpenSceneGraph Users
Hi Sebastion,

when you deal with geocentric data, the precision is an issue even if it is not on the GPU. The way how TerraVista (you have heard of it, right) was solving this was by introducing a matrix of doubles for the origin or the center of the tile and all the math was then with floats locally to the tile, in other words, all terrain tiles resides in their local floats coordinate system with doubles matrix on top. It is still possible to work with floats this way - that is how I did the geocentric whole earth terrapage - well, Robert pointed me to this trick. My two cents.

Nick 
--
trajce nikolov nick

Sebastian Messerschmidt

unread,
Dec 5, 2013, 1:31:22 PM12/5/13
to OpenSceneGraph Users
Hi Nick,
Hi Sebastion,

when you deal with geocentric data, the precision is an issue even if it is not on the GPU. The way how TerraVista (you have heard of it, right) was solving this was by introducing a matrix of doubles for the origin or the center of the tile and all the math was then with floats locally to the tile, in other words, all terrain tiles resides in their local floats coordinate system with doubles matrix on top. It is still possible to work with floats this way - that is how I did the geocentric whole earth terrapage - well, Robert pointed me to this trick. My two cents.
I'm aware of the concept. In fact this is how OSG renders the geocentric data. The only difference is, that the View and ModelViewMatrices are pulled down to float precision in the shader.
So in the ModelViewMatrix the precision is good, as it is kept double precision all the way through the graph. Essentially view and model matrices are canceling out here.
My problem is the float precision product (ModelView) and ViewInverse to get the ModelMatrix again. *sigh*
Maybe I can install an update callback of some kind to push a float precision ModelMatrix for the terrain tiles and use it directly.
Thank you for the hint anyways :-)


cheers
Sebastain

Robert Osfield

unread,
Dec 6, 2013, 5:43:46 AM12/6/13
to OpenSceneGraph Users
Hi Sebastian,

Personally I'd subclass from osgTerrain::GeometryTechnique and pass a FloatArray as a vertex attrib array or tex coord array and store the heights there.

Robert.


On 4 December 2013 13:23, Sebastian Messerschmidt <sebastian.m...@gmx.de> wrote:
Hi,

I have a osgDEM produced geocentric database.
I looked into the geometryTechnique implementation to see if I somehow can access the height of the vertices above the ellipsoid in the vertex shader.
Unfortunately I don't have any idea how to calculate this from the give matrices. Is this information somehow available at all?
My plan is to overwrite some of the functionality in the geometryTechnique to pass the appropriate matrices to the shader.
Anyone having an idea?


_______________________________________________
osg-users mailing list

Glenn Waldron

unread,
Dec 6, 2013, 7:14:59 AM12/6/13
to OpenSceneGraph Users

Sabastian,
osgEarth does more or less what Robert describes. We encode each vert's height value (and unit vector) in a vertex attribute.

Sebastian Messerschmidt

unread,
Dec 6, 2013, 7:55:54 AM12/6/13
to OpenSceneGraph Users
Am 06.12.2013 13:14, schrieb Glenn Waldron:

Sabastian,
osgEarth does more or less what Robert describes. We encode each vert's height value (and unit vector) in a vertex attribute.


Thank you Glenn. Are the vertices relative to the Ellipsoid?
Or can you point me to the sources where I can check it myself?

cheers
Sebastian
On Dec 6, 2013 5:43 AM, "Robert Osfield" <robert....@gmail.com> wrote:
Hi Sebastian,

Personally I'd subclass from osgTerrain::GeometryTechnique and pass a FloatArray as a vertex attrib array or tex coord array and store the heights there.

Robert.
On 4 December 2013 13:23, Sebastian Messerschmidt <sebastian.m...@gmx.de> wrote:
Hi,

I have a osgDEM produced geocentric database.
I looked into the geometryTechnique implementation to see if I somehow can access the height of the vertices above the ellipsoid in the vertex shader.
Unfortunately I don't have any idea how to calculate this from the give matrices. Is this information somehow available at all?
My plan is to overwrite some of the functionality in the geometryTechnique to pass the appropriate matrices to the shader.
Anyone having an idea?


_______________________________________________
osg-users mailing list

_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Sebastian Messerschmidt

unread,
Dec 6, 2013, 8:00:18 AM12/6/13
to OpenSceneGraph Users
Hi Robert,

Hi Sebastian,

Personally I'd subclass from osgTerrain::GeometryTechnique and pass a FloatArray as a vertex attrib array or tex coord array and store the heights there.
Okay, that would double the data then. I'm a bit nervous about adding more vertex attributes as I already have a lot of data per vertex.
Is there any option where I could pass the ModelMatrix (not the ModelViewMatrix) in a draw callback or something? The thing is that I might need more than simply the height, but probably the complete world-space vertex.
As I wrote before I guess the precision is lost when using the osg_ViewMatrixInverse * ModelVIewMatrix, so moving this calculation to the CPU would help a lot.

Robert.


On 4 December 2013 13:23, Sebastian Messerschmidt <sebastian.m...@gmx.de> wrote:
Hi,

I have a osgDEM produced geocentric database.
I looked into the geometryTechnique implementation to see if I somehow can access the height of the vertices above the ellipsoid in the vertex shader.
Unfortunately I don't have any idea how to calculate this from the give matrices. Is this information somehow available at all?
My plan is to overwrite some of the functionality in the geometryTechnique to pass the appropriate matrices to the shader.
Anyone having an idea?


_______________________________________________
osg-users mailing list

Aurelien Albert

unread,
Dec 6, 2013, 8:05:11 AM12/6/13
to osg-...@lists.openscenegraph.org
Hi,

I'm facing the same problem, and I can't pre-compute vertex attributes on CPU because my vertex are moved by the shader him-self (displacement mapping).

I've tried to use double matrices, but these leads to a lot of compatibility problem.

Since the precision problem is in the "temporary computation" and not in the final result (result values are small and fit well in a 32 bits float) I precompute (on CPU) lot of values in a 2048 (or 4096) pixels wide Texture1D.

In the shader I have only to read in this look-up-table. There are some limitations (linear sampling, max input value in look up table...) but for my problem, it works very well.

Cheers,
Aurelien

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=57581#57581

Glenn Waldron

unread,
Dec 6, 2013, 8:10:23 AM12/6/13
to OpenSceneGraph Users

The heights are relative to the ellipsoid, yes. I can send you a code link when I get back (in on the road atm).

Reply all
Reply to author
Forward
0 new messages