Problem creating a Triangle Mesh + Displacement Shader

Started by
6 comments, last by boehmi 13 years, 3 months ago
Hi there, this is my first post and 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
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 ;)

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
Advertisement
Can you try isolating the problem by removing the texture values from the height calculation. Try making the y-coordinate the value of x+z instead. If that works as expected, then the texture coordinate calculations could be off.
gl_Position = uPMatrix * uMVMatrix * (vec4(aVertexPosition,1.0) + vec4(0.0, tex[1]*2.0, 0.0 ,0.0));


Could you also post a screenshot of numOfTiles > 2 for y = 0.

Thanks
ok here are the 2 images with 40 rectsPerSide
i also added another image with another height map... there you can see that it works a little bit ;) but the rectangles still have a wrong orientation

i think there is a problem with texture mapping to vertices, that are used by more multiple rectangles and thus are contained more than once in the vertice array/buffer..?

ok here are the 2 images with 40 rectsPerSide
i also added another image with another height map... there you can see that it works a little bit ;) but the rectangles still have a wrong orientation

i think there is a problem with texture mapping to vertices, that are used by more multiple rectangles and thus are contained more than once in the vertice array/buffer..?


The vertices still look a bit odd, but I've been over the calculations a few times and it looks right.

Anyway, your triangles' orientation may have a bit to do with it. You are drawing one triangle CCW and the other CW

You can try switching p5 and p6 in both your vertex generation and your texture coord generation and see if it helps.

// 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;


to

// p5.x
triangleNew.vertices[base+12] = j*(rectWidth)+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)-width/2;
// p6.y
triangleNew.vertices[base+16] = 0;
// p6.z
triangleNew.vertices[base+17] = -i*(rectWidth)-rectWidth+width/2;
Didn't help :(
i'm now trying to define every vertice only once and create the triangles dynamically with an index-buffer... but my brain already hurts^^
Okay.. that worked <img src="http://public.gamedev.net/public/style_emoticons/default/smile.gif" class="bbc_emoticon" alt=":)"><br>i used an index buffer and gl.drawElements instead of drawArrays<br>

Okay.. that worked :)


Great! Good to hear! Good luck!
Yes it looked good, but now i have another problem...

the displacement is displaced xD.. means the "hills" are not exactly where the green coloured vertices are
but the more rectangles i use, the better it gets

shader code is the same

vertice creation
for(var i = 0;i<rectsPerSide+1;i++) {
for(var j = 0;j<rectsPerSide+1;j++) {
var base = i*(rectsPerSide+1)*3+(j*3);
// p1.x
triangleNew.vertices[base+0] = j*(rectWidth)-width/2;
// p1.y
triangleNew.vertices[base+1] = 0;
// p1.z
triangleNew.vertices[base+2] = -i*(rectWidth)+width/2;
}
}


tex coords:

for(var i = 0;i<rectsPerSide+1;i++) {
for(var j = 0;j<rectsPerSide+1;j++) {
var base = i*(rectsPerSide+1)*2+(j*2);
// p1.x
triangleNew.textureCoords[base+0] = j*(1/rectsPerSide);
// p1.y
triangleNew.textureCoords[base+1] = 1-i*(1/rectsPerSide);
}
}


indices:

var index = 0;
for(var i = 0;i<rectsPerSide;i++) {
for(var j = 0;j<rectsPerSide;j++) {
var base = i*(rectsPerSide+1)+j;

triangleNew.indices[index++] = base;
triangleNew.indices[index++] = base+1;
triangleNew.indices[index++] = base+2+rectsPerSide;

triangleNew.indices[index++] = base;
triangleNew.indices[index++] = base+1+rectsPerSide;
triangleNew.indices[index++] = base+2+rectsPerSide;
}
}


See these examples with 4, 10 and 40 rectsPerSide:

This topic is closed to new replies.

Advertisement