Terrain mapping - more earthquake when closer to ground

Started by
35 comments, last by Green_Baron 4 years, 7 months ago

The book you have spends a chapter on coordinate precision and render relative to eye (pp. 155ff.) and has exsample code in C#/GLSL but that is easily transferable. I could not explain it better (or shorter :-)) I have tried it out (it works), but with a different LOD algorithm than the examples in book (no chunked LOD or clipmapping because too CPU intensive). In my take on LOD of a height map only the bounding boxes of the nodes to render this frame have actual world coordinates, the terrain itself has no mesh except for a single one the size of a single node, which is passed around and sized accordingly in the vertex shader.

You find my blog entry here. Code fragments included. And the example code of the book's authors on github.

The matrices need not have double precision ! Only the view matrix has large numbers in the translation column which are stripped off before being passed into the shader. The matrices are applied in the vertex shader after the camera position (which is double) has been deducted from the world positions (which are doubles), leaving handsome float numbers behind. So, only world positions (depending on your LOD algorithm) and the camera position need double precision.

Btw., it took me several weeks to figure it out, so don't be too frustrated if it takes some time ? Experiment with a huge subdivided icosphere/planet /whatever before applying it to your lod'ed terrain !

Edit:  @TeaTreeTim has solved much of this long ago with other approaches ...

Advertisement

Ok, I now found your blog after I searched for that. Thanks.  I will work on new LOD method to replace my old code that use trigonometry for LOD determination, etc.

1 minute ago, Sword7 said:

Ok, I now found your blog after I searched for that. Thanks.  I will work on new LOD method to replace my old code that use trigonometry for LOD determination, etc.

One problem at a time .... ?

If you're still at it, i have a correction to what i wrote above.

I am playing around with this a bit and have observed some jerking. This was due to my model-view matrix being just float. Better have it as double on the CPU, and after stripping it from the translation column, cast it to float before transmitting it to the shader. The rest of the matrix (rotation) are just small numbers that fit perfectly in float.

OpenGlobe has even the perspective matrices as doubles, but as long as the depth of field fits into a float that would not necessarily be necessary.

Still interested in other solutions !

Ok, I studied my 3D Engine Design for Virtual Globes book.  I tried to implemented RTE method with DSFUN90 but it did not work.  Also I implemented vertices with error difference.  I saw nothing when I cleared translation parts of matrix. When I leave matrix unchanged, planet re-appeared but still jitters when very close.  I searched for some solution but can't find any solution so far.   My codes (CPU side and GPU side) is:


prm.dmProj  = glm::perspective(glm::radians(DOFS_DEFAULT_FOV), double(gl.getWidth()) / double(gl.getHeight()), DDIST_NEAR, DDIST_FAR);
prm.dmView  = glm::transpose(glm::toMat4(prm.crot));

vec3f_t gCamerah, gCameral;

convertDoubleToTwoFloats(prm.obj.cpos, gCamerah, gCameral);

prm.dmWorld = prm.dmView * glm::translate(glm::transpose(prm.obj.orot), prm.obj.cpos);

prm.dmWorld[3].x = 0;
prm.dmWorld[3].y = 0;
prm.dmWorld[3].z = 0;

prm.mvp = mat4f_t(prm.dmProj * prm.dmWorld);

uint32_t mvpLoc = glGetUniformLocation(pgm->getID(), "mvp");
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(prm.mvp));

uint32_t chLoc = glGetUniformLocation(pgm->getID(), "gCamerah");
glUniformMatrix4fv(chLoc, 1, GL_FALSE, glm::value_ptr(gCamerah));
uint32_t clLoc = glGetUniformLocation(pgm->getID(), "gCameral");
glUniformMatrix4fv(clLoc, 1, GL_FALSE, glm::value_ptr(gCameral));

#version 420

// vertex buffer objects
//layout (location=0) in vec3 vPosition;
layout (location=0) in vec3 vPositionh;
layout (location=1) in vec3 vPositionl;
layout (location=2) in vec3 vNormal;
//layout (location=2) in vec3 vColor;
layout (location=3) in vec2 vTexCoord;

//uniform mat4 gView;  // Projection * View
//uniform mat4 gWorld; // World space
uniform mat4 mvp;

uniform vec3 gCamerah;
uniform vec3 gCameral;

out vec4 myColor;
out vec2 texCoord;

void main()
{
    vec3 t1 = vPositionl - gCameral;
    vec3 e = t1 - vPositionl;
    vec3 t2 = ((-gCameral - e) + (vPositionl - (t1 - e))) +
        vPositionh - gCamerah;
    vec3 hdiff = t1 + t2;
    vec3 ldiff = t2 - (hdiff - t1);

//    gl_Position = gView * gWorld * vec4(hdiff + ldiff, 1.0);
    gl_Position = mvp * vec4(hdiff + ldiff, 1.0);
    myColor = vec4(0.7, 0.7, 0.7, 1.0); // vec4(vColor, 1.0);
    texCoord = vTexCoord;
}

 

I must admit that rendering rte was the reason why i dropped glm and brewed my own math lib, because it does conversions and coercions silently through all sorts of converting constructors and cast operators that in the end i didn't know what type my data, if at all, had.

Question: where do you strip the model view matrix from the translation part ?

18 minutes ago, Green_Baron said:

I must admit that rendering rte was the reason why i dropped glm and brewed my own math lib, because it does conversions and coercions silently through all sorts of converting constructors and cast operators that in the end i didn't know what type my data, if at all, had.

Question: where do you strip the model view matrix from the translation part ?

Perhaps I will try Eigen instead but I plan to develop my own math library.  Look at my code above.  I cleared forth row of matrix for translation since matrix was already transposed.  I noticed that camera position is part of translation area of MV matrix according to debugging printout of matrix.

Why do you transpose ?

Just now, Green_Baron said:

Why do you transpose ?

Without transpose, I tried to move but it move oppositely and more confusing. With transpose, I move around correctly.

Something is borked. You should not have to transpose. Also, if it was reallyreallyreally necessary (which i doubt), i wouldn't bother the CPU with it but have OpenGL do it when reading the uniform data (see glUnformMatrix* ).

This topic is closed to new replies.

Advertisement