Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (115)
games submitted by our members
Games in WIP (562)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Normalizing normals of an indexed vertex array does not seem to work  (Read 1136 times)
0 Members and 1 Guest are viewing this topic.
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Posted 2013-03-17 11:16:24 »

Hello, im trying to render some simple map using the VBO and Shader.
Im trying to fix this annoying stoff for an few days now, but i cant seem to fix it.
Does anyone have suggestions?

VBO Code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
    public void Draw(){       
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, pointbufferid);
        bindBufferData();
       
        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexbufferid);
        if(update){  glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexbuferdata, type); }

       
       
        glVertexPointer(3, GL_FLOAT, stride, 0); // float at index 0
       glNormalPointer(GL_FLOAT, stride, 12);
        glTexCoordPointer(2, GL_FLOAT, stride, 24); // float at index 6
       
        //glEnableVertexAttribArray(attrib);
       //glVertexAttribPointer(attrib, 4, GL_UNSIGNED_BYTE, false, stride, 32);

        glDrawElements(GL_TRIANGLES, indexsize, GL_UNSIGNED_INT, 0);
       
       
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

       
        //glDisableVertexAttribArray(attrib);
       glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       
        update = false;
    }


Calculating normals for Vertex points:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
    private void calcNormals(){
        normal = new Vector3f(1,1,1);
       
        for(TriangleIndice f : faces){
            Vector3f.add(normal, f.getNormal(), normal);
        }
     
        normal.normalise();
        //System.out.println(normal.x + " x " + normal.y + " x " + normal.z);
   }


Shader (just simple lightning):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
varying vec3 normal, lightDir, eyeVec;
varying vec3 pos;

uniform vec3 lightpos;

vec4 color, c;

void main()
{  
    vec3 N = normalize(normal);
    vec3 L = normalize(lightDir);
   float lambertTerm = dot(N,L);

   float val = clamp(lambertTerm, 0, 1);
   c = vec4(val, val, val, 1);
   
   

    gl_FragColor = vec4(c.xyz, 1.0);
}


Result:


As visible, the normals are kinda messed up at some places.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2013-03-17 11:43:20 »

Actually that is correct. The visual artifacts are the result of triangles not being curved surfaces.

Interpolating the normals (and even renormalizing it) is not enough, if you look at the actual normals per vertex of the triangle. The normals in the corners of your triangle are simply too different to produce an accurate continuous 'surface'.

You can work around this issue by increasing the density of height-samples (in rough areas), or using a normalmap with significantly higher resolution than your geometry heightmap.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #2 - Posted 2013-03-17 11:47:30 »

Last but not least:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
    private void calcNormals(){
-        normal = new Vector3f(1,1,1);
+        normal = new Vector3f(0,0,0);
       
        for(TriangleIndice f : faces){
            Vector3f.add(normal, f.getNormal(), normal);
        }
     
        normal.normalise();
        //System.out.println(normal.x + " x " + normal.y + " x " + normal.z);
   }

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #3 - Posted 2013-03-17 11:50:52 »

Thank you, but i think im already doing this, the maxheight is 5000.

With this function im generating points:
1  
2  
3  
4  
5  
6  
7  
    private TrianglePoint getTrianglePoint(int xoffset, int zoffset){
        float px = (x+xoffset)*16;
        float pz = (z+zoffset)*16;
       
        //Vector3f position, Vector2f Texture
       return new TrianglePoint(new Vector3f(px, (float)height[xoffset*size+zoffset] / 150f, pz), new Vector2f(px / (float)size, pz / (float)size));
    }


*The fix you posted did not do much:
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #4 - Posted 2013-03-17 11:52:55 »

Just increase the density of your heightmap, and you'll see the problem is fixed - just like I suggested.

As this is probably too heavy on the geometry side, I suggested normalmaps to fake it.


*The fix you posted did not do much:
It fixed a bug. Thanks for the gratitude.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #5 - Posted 2013-03-17 11:57:08 »

Thank you, the problem is clear, i guess using vertex normals wont work so well with this rotation.
(small changes are not very visible, big ones get glitched.
Im going to follow your advise for normal maps.
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #6 - Posted 2013-03-17 11:59:25 »

Just increase the density of your heightmap, and you'll see the problem is fixed - just like I suggested.

As this is probably too heavy on the geometry side, I suggested normalmaps to fake it.


*The fix you posted did not do much:
It fixed a bug. Thanks for the gratitude.

Im gratefull for your help.
I was just talking about the problem iself, and i already sayd thanks in the post, so i thought twice is a little to much Smiley
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #7 - Posted 2013-03-17 12:07:45 »

Thank you, but i think im already doing this, the maxheight is 5000.
You can't be doing that already. The problem is that 'max height' doesn't influence 'roughness' in a meaningful way. In the end you want curvy slopes, and one way or another you'll have to create accurate normals for them, so there's no way around providing high resolution geometry - whether that translates into a higher vertex count (either for the full map, or for problematic regions) or a normalmap is up to you, but there is no way to 'fix' this problem with 'max height' or any other mathematical corrections in the current setup.

Imagine trying to render normals for a sphere, where you sample 8 points (they form a cube). You'll never get the normals to look right, because the 'samples' and the accompanying normals are not accurate enough to create smooth (interpolated) normals. The more samples points you throw at it, the better the quality of the interpolated normals (and therefore shading) becomes.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #8 - Posted 2013-03-17 18:16:44 »

Thanks, i understand.
Now im trying to get some normals from my height map, but it gets really messed up:

Top image is the heightmap, bottom image are the calculated normals from this texture.
Does ayone knos why it does get so messed up?




Shader code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
   vec2 size = vec2(2.0,0.0);
   float NORMAL_OFF = (1.0 / 256.0);
   vec3 offset = vec3(-NORMAL_OFF, 0, NORMAL_OFF);

   float s11 = texture2D(Texture0, gl_TexCoord[0].xy).x;
    float s21 = texture2D(Texture0, gl_TexCoord[0].xy + offset.zy).x;
    float s12 = texture2D(Texture0, gl_TexCoord[0].xy + offset.yz).x;
    vec3 va = normalize( vec3(offset.z, 0.0, s21 - s11) );
   vec3 vb = normalize( vec3(0.0, offset.z, s12 - s11) );
   
   vec3 N = normalize( cross(va, vb) );
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #9 - Posted 2013-03-17 18:23:45 »

Scale s11, s21 and s12 way down, so that they make sense relative to NORMAL_OFF.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #10 - Posted 2013-03-17 20:44:04 »

I think my whole code was off, even scaling the values did not change much.
I found some c++ code to create normals really nicely, so i just took this and ported it to glsl.
Thansk for your help Riven Cheesy

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
float getHeightMap(int xoff, int yoff){
   return texture2D(Texture0, gl_TexCoord[0].xy + vec2(NORMAL_OFF * xoff, NORMAL_OFF * yoff)).x;
}

vec3 CalculateNormal()
{
            // Value from trial & error.
           // Seems to work fine for the scales we are dealing with.
           float strength = 4;
 
            float tl = getHeightMap(-1, -1);
            float l = getHeightMap(-1, 0);
            float bl = getHeightMap(-1, 1);
            float b = getHeightMap(0, 1);
            float br = getHeightMap(1, 1);
            float r = getHeightMap(1, 0);
            float tr = getHeightMap(1, -1);
            float t = getHeightMap(0, -1);
 
            // Compute dx using Sobel:
           //           -1 0 1
           //           -2 0 2
           //           -1 0 1
           float dX = tr + 2 * r + br - tl - 2 * l - bl;
 
            // Compute dy using Sobel:
           //           -1 -2 -1
           //            0  0  0
           //            1  2  1
           float dY = bl + 2 * b + br - tl - 2 * t - tr;
 
            vec3 N = normalize(vec3(dX, dY, 1.0f / strength));
 
    return N;
}
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

radar3301 (10 views)
2014-09-21 23:33:17

BurntPizza (28 views)
2014-09-21 02:42:18

BurntPizza (18 views)
2014-09-21 01:30:30

moogie (20 views)
2014-09-21 00:26:15

UprightPath (27 views)
2014-09-20 20:14:06

BurntPizza (29 views)
2014-09-19 03:14:18

Dwinin (46 views)
2014-09-12 09:08:26

Norakomi (74 views)
2014-09-10 13:57:51

TehJavaDev (102 views)
2014-09-10 06:39:09

Tekkerue (50 views)
2014-09-09 02:24:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!