Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (778)
Games in Android Showcase (231)
games submitted by our members
Games in WIP (856)
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  
  [Solved] Per Vertex Normal Calculation Does not Work  (Read 630 times)
0 Members and 1 Guest are viewing this topic.
Offline mudlee

Junior Devvie


Medals: 6
Exp: 5 years



« Posted 2018-02-19 10:33:26 »

Hi all.

I'm stuck with calculating per vertex normals. I've checked this http://www.java-gaming.org/topics/reopened-calculating-normal-vectors/33838/view.html, but got no new information.
I render two objects (see screenshot), the cube is exported from blender and the other one is constructed manually from code. As you see, the blender cube is OK. Also, if I create the same object from blender and export it with normals, it's also OK.

So I think, something wrong with my manual code. Screenshot: https://drive.google.com/open?id=1hsAFJMJSH9atgcxQNe6o_YyzXqgr2NYh

How triangles constructed: https://drive.google.com/open?id=1YrF6IiHIg9ieNZ1Us9pvKsCp-a4Z6lcm

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  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
float[] vertices = new float[]{
                0, 0, 0,
                0, 0, 1,
                1, 0, 1,
                1, 0.5f, 0,
                //1,0.5f,0,
                //1,0,1,
                2, 0, 1,
                2, 0, 0
        };

        int[] indices = new int[]{
                1, 2, 0,
                2, 3, 0,

                2, 5, 3,
                2, 4, 5
        };

        float[] normals=new float[vertices.length];
        int normalsIndex=0;

        Vector3f[] triangleVertices=new Vector3f[3];
        for (int i=0;i<indices.length;i++){
            int index=indices[i];
            Vector3f vertexPos=new Vector3f(
                    vertices[index*3],
                    vertices[index*3+1],
                    vertices[index*3+2]
            );

            if(i%3==0){
                triangleVertices[0]=vertexPos;
            }
            else if(i%3==1){
                triangleVertices[1]=vertexPos;
            }
            else if(i%3==2){
                triangleVertices[2]=vertexPos;
                // Nf = (↑B - ↑A) × (↑C - ↑A)
                Vector3f normal=triangleVertices[1].sub(triangleVertices[0]).cross(triangleVertices[2].sub(triangleVertices[0]));
                normal.normalize();
                normals[normalsIndex++]=normal.x;
                normals[normalsIndex++]=normal.y;
                normals[normalsIndex++]=normal.z;
            }
        }
Offline KaiHH

JGO Kernel


Medals: 650



« Reply #1 - Posted 2018-02-19 21:40:53 »

What you are doing is called "per face" normals. Sure, normals are always assigned to vertices, but you want each vertex of the same face/triangle to have the same normal direction. Therefore, you cannot use indices like you did, because vertices with the same position cannot share the same normal anymore, since the normal depends on the face/triangle that vertex is part of.
That means, we have to duplicate multiple uses of the same vertex position and compute a face normal for all the vertices of the current triangle.
Try this (based on this code, not tested):
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  
/*
 * We have to duplicate same vertex positions
 * because they need multiple normals depending
 * on which face/triangle they are part of.
 */

float[] vertices = new float[] {
  0.0f, 0.0f, 1.0f, // 1
  1.0f, 0.0f, 1.0f, // 2
  0.0f, 0.0f, 0.0f, // 0
  1.0f, 0.0f, 1.0f, // 2
  1.0f, 0.5f, 0.0f, // 3
  0.0f, 0.0f, 0.0f, // 0
  1.0f, 0.0f, 1.0f, // 2
  2.0f, 0.0f, 0.0f, // 5
  1.0f, 0.5f, 0.0f, // 3
  1.0f, 0.0f, 1.0f, // 2
  2.0f, 0.0f, 1.0f, // 4
  2.0f, 0.0f, 0.0f  // 5
};
/*
 * Compute per face normals.
 */

float[] normals = new float[vertices.length];
for (int i = 0; i < vertices.length; i += 3*3) { // <- 3*3 = one triangle/face per iteration
  Vector3f v0 = new Vector3f(vertices[i + 0], vertices[i + 1], vertices[i + 2]);
  Vector3f v1 = new Vector3f(vertices[i + 3], vertices[i + 4], vertices[i + 5]);
  Vector3f v2 = new Vector3f(vertices[i + 6], vertices[i + 7], vertices[i + 8]);
  Vector3f n = v1.sub(v0).cross(v2.sub(v0)).normalize();
  // Assign that normal to all vertices of the current triangle/face
  for (int j = 0; j < 3; j++) {
    normals[i + 3*j + 0] = n.x;
    normals[i + 3*j + 1] = n.y;
    normals[i + 3*j + 2] = n.z;
  }
}
Offline mudlee

Junior Devvie


Medals: 6
Exp: 5 years



« Reply #2 - Posted 2018-02-20 12:55:10 »

Yeah, it works! Thanks for your help!
Pages: [1]
  ignore  |  Print  
 
 

 
hadezbladez (358 views)
2018-11-16 13:46:03

hadezbladez (191 views)
2018-11-16 13:41:33

hadezbladez (361 views)
2018-11-16 13:35:35

hadezbladez (90 views)
2018-11-16 13:32:03

EgonOlsen (2191 views)
2018-06-10 19:43:48

EgonOlsen (2226 views)
2018-06-10 19:43:44

EgonOlsen (1384 views)
2018-06-10 19:43:20

DesertCoockie (2022 views)
2018-05-13 18:23:11

nelsongames (1674 views)
2018-04-24 18:15:36

nelsongames (2312 views)
2018-04-24 18:14:32
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
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!