PDA

View Full Version : Problem creating a Mesh + Displacement Shader



boehmi
01-19-2011, 04:23 AM
Hi there... i hope you guys can help me out ;)

i want to dynamically create a quadratic mesh of triangles with a given mesh width and the number of rectangels per side
after that i want to use a displacement shader to "transform" a texture into height differences (y-axis) to create a kind of terrain from a height map jpeg file.
But i'm getting crazy results and i don't know if my vertex/texture-coord-creation algorithm or my shader program is wrong...

Vertex Coord Creation:
triangleNew is the array for the whole mesh
just 2 loops to build the mesh from the lower left corner to the upper right corner linewise


for(var i = 0;i<rectsPerSide;i++) {
for(var j = 0;j<rectsPerSide;j++) {
var base = i*18*(rectsPerSide)+j*18;
// p1.x
triangleNew.vertices[base+0] = j*(rectWidth)-width/2; // -width/2 = centering the mid point of the mesh to (0,0,0)
// p1.y
triangleNew.vertices[base+1] = 0;
// p1.z
triangleNew.vertices[base+2] = -i*(rectWidth)+width/2;
// p2.x
triangleNew.vertices[base+3] = j*(rectWidth)+rectWidth-width/2;
// p2.y
triangleNew.vertices[base+4] = 0;
// p2.z
triangleNew.vertices[base+5] = -i*(rectWidth)+width/2;
// p3.x
triangleNew.vertices[base+6] = j*(rectWidth)+rectWidth-width/2;
// p3.y
triangleNew.vertices[base+7] = 0;
// p3.z
triangleNew.vertices[base+8] = -i*(rectWidth)-rectWidth+width/2;
// p4.x
triangleNew.vertices[base+9] = j*(rectWidth)-width/2;
// p4.y
triangleNew.vertices[base+10] = 0;
// p4.z
triangleNew.vertices[base+11] = -i*(rectWidth)+width/2;
// p5.x
triangleNew.vertices[base+12] = j*(rectWidth)-width/2;
// p5.y
triangleNew.vertices[base+13] = 0;
// p5.z
triangleNew.vertices[base+14] =-i*(rectWidth)-rectWidth+width/2;
// p6.x
triangleNew.vertices[base+15] = j*(rectWidth)+rectWidth-width/2;
// p6.y
triangleNew.vertices[base+16] = 0;
// p6.z
triangleNew.vertices[base+17] = -i*(rectWidth)-rectWidth+width/2;
}
}


Texture Coord Creation:


for(var i = 0;i<rectsPerSide;i++) {
for(var j = 0;j<rectsPerSide;j++) {
var base = i*12*(rectsPerSide)+j*12;
// p1.x
triangleNew.textureCoords[base+0] = j*(1/rectsPerSide);
// p1.y
triangleNew.textureCoords[base+1] = 1-i*(1/rectsPerSide);
// p2.x
triangleNew.textureCoords[base+2] = j*(1/rectsPerSide)+1/rectsPerSide;
// p2.y
triangleNew.textureCoords[base+3] = 1-i*(1/rectsPerSide);
// p3.x
triangleNew.textureCoords[base+4] = j*(1/rectsPerSide)+1/rectsPerSide;
// p3.y
triangleNew.textureCoords[base+5] = 1-(i*(1/rectsPerSide)+1/rectsPerSide);
// p4.x
triangleNew.textureCoords[base+6] = j*(1/rectsPerSide);
// p4.y
triangleNew.textureCoords[base+7] = 1-i*(1/rectsPerSide);
// p5.x
triangleNew.textureCoords[base+8] = j*(1/rectsPerSide);
// p5.y
triangleNew.textureCoords[base+9] = 1-(i*(1/rectsPerSide)+1/rectsPerSide);
// p6.x
triangleNew.textureCoords[base+10] = j*(1/rectsPerSide)+1/rectsPerSide;
// p6.y
triangleNew.textureCoords[base+11] =1- (i*(1/rectsPerSide)+1/rectsPerSide);
}
}


Vertex Shader:
It should just shift the y-coord of the vertex by the doubled value of the green-channel of the current texel


attribute vec3 aVertexPosition;
attribute vec3 aNormals;
attribute vec2 aTextureCoord;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
uniform mat4 uNMatrix;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
void main(void)
{
vec4 tex = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_Position = uPMatrix * uMVMatrix * (vec4(aVertexPosition,1.0) + vec4(0.0, tex[1]*2.0, 0.0 ,0.0));
vTextureCoord = aTextureCoord;
}


Fragment Shader:
just for completeness... this one works fine!
the texture is mapped without any errors


varying vec2 vTextureCoord;
uniform sampler2D sampler;
void main(void)
{
gl_FragColor = texture2D(sampler, vec2(vTextureCoord.s, vTextureCoord.t));
}

In the attachements you can find the results for meshwidth=10 and rectsPerSide=2 (and one example with 40)
the height map is a diagonal color gradient from red to green, so the red corner should be lower than the green corner
When i do not replace the y-coord and just keep the mesh flat, everything looks good so far, but with the replacement it's just chaotic ;)
When i just draw the vertices without connecting them to triangles/lines you can see, that vertices with the same color have differtent y-values... how can that be ?

the generated vertex buffer:


-5,0,5,
0,0,5,
0,0,0,

-5,0,5,
-5,0,0,
0,0,0,

0,0,5,
5,0,5,
5,0,0,

0,0,5,
0,0,0,
5,0,0,

-5,0,0,
0,0,0,
0,0,-5,

-5,0,0,
-5,0,-5,
0,0,-5,

0,0,0,
5,0,0,
5,0,-5,

0,0,0,
0,0,-5,
5,0,-5


and the texture coords


0,1,
0.5,1,
0.5,0.5,

0,1,
0,0.5,
0.5,0.5,

0.5,1,
1,1,
1,0.5,

0.5,1,
0.5,0.5,
1,0.5,

0,0.5,
0.5,0.5,
0.5,0,

0,0.5,
0,0,
0.5,0,

0.5,0.5,
1,0.5,
1,0,

0.5,0.5,
0.5,0,
1,0

david_f_knight
01-19-2011, 10:38 AM
It's much easier to use the OpenGL Tessellation shader stages to implement what you describe. [I don't check this forum often anymore, so I can't provide specific help. But basically, what you have described that you want to do is an ideal application of the Tessellation shader stages that were introduced in OpenGL 4.0 .]

boehmi
01-20-2011, 01:31 AM
I have to use OpenGL ES 2.0 (WebGL) ;)