FroggestSpirit
 Joined: Mar 2013
Posts: 79
|
 |
Posted on: July 07, 2014, 04:39:59 PM |
|
|
For quite a while, I have been drawing only the face normals of the 3D models in Project Collidascope. This gives the game a very flat and jagged look. I started looking into calculating vertex normals, and smoothing the whole thing out. The basic idea was to calculate all the face normals, and add them to the vertices that make up that face, that way it averages the normals of the connecting faces. I'm not sure if I missed something, but the code does not seem to be working. Here is the code I used to generate the normals: http://pastebin.com/raw.php?i=Hc8Nb7YEThe function normal works, as it's from the kingspace engine, and returns the normal as rx, ry and rz EDIT: if push comes to shove, I can always have the normals pre-calculated and saved to the model, but I figured it will become easier to be able to calculate them during runtime if I have objects morphing and moving around
|
|
|
TheExDeus
 Joined: Apr 2008
Posts: 1,860
|
 |
Reply #1 Posted on: July 07, 2014, 04:58:28 PM |
|
|
The code I used in the water demo was this: http://pastebin.com/zV4gXtQgThe normal code alone is this: //Normal calculation normals = ds_grid_create(3,ds_grid_width(heights)*ds_grid_height(heights)); ds_grid_clear(normals,0.0); for(int i = 0; i < ds_list_size(indicies)-2; i += 1) { if (i%2){ index1 = ds_list_find_value(indicies,i+1); index2 = ds_list_find_value(indicies,i); index3 = ds_list_find_value(indicies,i+2); }else{ index1 = ds_list_find_value(indicies,i); index2 = ds_list_find_value(indicies,i+1); index3 = ds_list_find_value(indicies,i+2); } x1 = ds_grid_get(vertices,0,index1); y1 = ds_grid_get(vertices,1,index1); z1 = ds_grid_get(vertices,2,index1); x2 = ds_grid_get(vertices,0,index2); y2 = ds_grid_get(vertices,1,index2); z2 = ds_grid_get(vertices,2,index2); x3 = ds_grid_get(vertices,0,index3); y3 = ds_grid_get(vertices,1,index3); z3 = ds_grid_get(vertices,2,index3); //Get vector nx1 = x3 - x1, ny1 = y3 - y1, nz1 = z3 - z1; nx2 = x2 - x1, ny2 = y2 - y1, nz2 = z2 - z1; //Cross cx = ny2 * nz1 - nz2 * ny1; cy = nz2 * nx1 - nx2 * nz1; cz = nx2 * ny1 - ny2 * nx1; //Normalize L = sqrt(cx * cx + cy * cy + cz * cz); cx /= L; cy /= L; cz /= L; ds_grid_add(normals,0,index1,cx); ds_grid_add(normals,1,index2,cy); ds_grid_add(normals,2,index3,cz); } for(int i = 0; i < ds_grid_height(normals); ++i) { //Normalize total L = sqrt(ds_grid_get(normals,0,i) * ds_grid_get(normals,0,i) + ds_grid_get(normals,1,i) * ds_grid_get(normals,1,i) + ds_grid_get(normals,2,i) * ds_grid_get(normals,2,i)); ds_grid_set(normals,0,i,ds_grid_get(normals,0,i)/L); ds_grid_set(normals,1,i,ds_grid_get(normals,1,i)/L); ds_grid_set(normals,2,i,ds_grid_get(normals,2,i)/L); }The calculation part is quite verbose, as I cannot use classed in EDL. But the idea is that I use indices to make triangles, and normals are then calculated for these triangles. The normals are all added up, so any vertex that is part of a triangle gets a smoother normal, which is what you described. QuoteEDIT: if push comes to shove, I can always have the normals pre-calculated and saved to the model, but I figured it will become easier to be able to calculate them during runtime if I have objects morphing and moving around It won't be possible to calculate them per-frame anyway. So just add them to the model or calculate at start. edit: Also, that is about the same code that was previously in ENIGMA and Robert removed.
|
|
|