I use a z=f(x,y)
function to generate a surface, and now I can draw the surface in OpenGL.
Please see the image shot below, the surface's color is depends on the Z
value of the vertex, the higher it is, the more red it has.
Here is the function I used to generate the vertex:
int g_N = 30;
float f(float x, float y, float tx = 0);
float f(float x, float y, float tx)
{
// conver the value to [0, 1]
x = x/g_N;
y = y/g_N;
// use any curve function you want
float dx = x-0.5;
float dy = y-0.5;
float r = sqrt(dx*dx + dy*dy);
return sin((r+tx)*8.0f*3.141526f) * 5.0f;
}
I just create a (X,Y)
grid from (0,0)
to (29,29)
, so each (X,Y)
pair can has a value Z.
Then I have generate a lot of triangles. Each rectangle will be divided to two triangles, and I add the vertex and the index to the VBO, and finally use the shader to draw the triangles, thus make the surface. I used the method mentioned here: Create a grid in OpenGL to got the triangles from the grid.
Here is the surface shader I use to make the surface's color depends on the Z value of the vertex.
#version 330 core
uniform float ZL;
uniform float ZH;
out vec3 color;
in vec3 pos;
// https://stackoverflow.com/questions/7706339/grayscale-to-red-green-blue-matlab-jet-color-scale
vec3 jet(float t)
{
return clamp(vec3(1.5) - abs(4.0 * vec3(t) + vec3(-3, -2, -1)), vec3(0), vec3(1));
}
void main()
{
float param = (pos.z - ZL) / (ZH - ZL);
color = jet(param);
}
As you can see, the result image is not smooth as I expected, see the arrows on the image shots. So, how to make the surface more smooth?
I know I can generate the normal vector of each vertex, by using this methods from wikipedia: 1.1 Calculating a surface normal, it just needs to calculate the partial derivative on X
and Y
axis, but I'm not sure using normal vector will make the surface smoother, and how to do that? Do I need to tweak the shader? Thanks.
EDIT: Maybe, there are some already OpenGL related library to generate those vertex and make smooth surface? I think this is a very common need.