Jasoco's 3D Engine Thread: Go to Page 6 Please!
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
If I read your code correctly, you are calculating the cross product from the point coordinates of the triangles. You should instead calculate them from the coordinates of the vectors you get from subtracting the triangles' corner coordinates. These are the edge vectors of the triangle.
You can pick any two edges of the triangle for this, as long as they are not the same. You may get the negation of the normal vector that the format uses if you pick a different order to do the calculations in, but you can easily see if that happens by comparing the expected values with the ones you get.
Actually, it seems the values I got from some experiments differ slightly from the NORM values in the model file. The difference is on the order of a few hundreths of a coordinate unit.
So, to sum up: You have three points defining a triangle--p1 p2 and p3. Calculate the vectors (p2-p1) and (p3-p1) and do their cross product. That is the normal you are looking for. Or if it is not, then using them in the order (p3-p1) and (p2-p1) should be.
You can pick any two edges of the triangle for this, as long as they are not the same. You may get the negation of the normal vector that the format uses if you pick a different order to do the calculations in, but you can easily see if that happens by comparing the expected values with the ones you get.
Actually, it seems the values I got from some experiments differ slightly from the NORM values in the model file. The difference is on the order of a few hundreths of a coordinate unit.
So, to sum up: You have three points defining a triangle--p1 p2 and p3. Calculate the vectors (p2-p1) and (p3-p1) and do their cross product. That is the normal you are looking for. Or if it is not, then using them in the order (p3-p1) and (p2-p1) should be.
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
I tried that too and it didn't work well at all.
If you have any example, I'd love to see it.
Code: Select all
if calcNorm then
local nx, ny, nz, com, nf, x1, x2, x3, y1, y2, y3, z1, z2, z3
for i, p in pairs(poly) do
x1 = points[p.p1].x
y1 = points[p.p1].y
z1 = points[p.p1].z
x2 = points[p.p2].x
y2 = points[p.p2].y
z2 = points[p.p2].z
x3 = points[p.p3].x
y3 = points[p.p3].y
z3 = points[p.p3].z
nx = (y2-y1)*(z3-z1) - (z2-z1)*(y3-y1)
ny = (z2-z1)*(x3-x1) - (y2-y1)*(z3-z1)
nz = (x2-x1)*(y3-y1) - (x2-x1)*(x3-x1)
com = (nx * nx) + (ny * ny) + (nz * nz)
nf = math.sqrt(com)
nx = nx / nf
ny = ny / nf
nz = nz / nf
p.nx = nx
p.ny = ny
p.nz = nz
...
end
end
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
I think this should be as follows.Jasoco wrote:Code: Select all
nx = (y2-y1)*(z3-z1) - (z2-z1)*(y3-y1) ny = (z2-z1)*(x3-x1) - (y2-y1)*(z3-z1) nz = (x2-x1)*(y3-y1) - (x2-x1)*(x3-x1)
Code: Select all
nx = (y2-y1)*(z3-z1) - (z2-z1)*(y3-y1)
ny = (z2-z1)*(x3-x1) - (x2-x1)*(z3-z1)
nz = (x2-x1)*(y3-y1) - (y2-y1)*(x3-x1)
Code: Select all
-- calculate the cross product from three points
function cross3p(x1, y1, z1, x2, y2, z2, x3, y3, z3)
-- calculate the two vectors
a1, a2, a3 = x3-x1, y3-y1, z3-z1
b1, b2, b3 = x2-x1, y2-y1, z2-z1
-- cross product
n1 = a2*b3 - a3*b2
n2 = a3*b1 - a1*b3
n3 = a1*b2 - a2*b1
-- normalization constant
nl = math.sqrt(n1^2 + n2^2 + n3^2)
return n1/nl, n2/nl, n3/nl
end
Code: Select all
14.369 11.0421 -0.369
13.284 11.0421 -5.864
18.819 -3.9579 -8.219
Code: Select all
Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require 'cross'
> print (cross3p(14.369, 11.0421, -0.369, 13.284, 11.0421, -5.864, 18.819, -3.9579, -8.219))
0.91325633509108 0.36530253403643 -0.1803244992855
>
The file has this.
Code: Select all
0.9133 0.3653 -0.1803
Does my code help you get them all right now? I am testing my code more carefully, and will post an update a bit later.
LATER EDIT: I tested whether the values my cross product function gives ever differ significantly from the ones Jasoco's code reads from the file. The following test was never true in the whole file.
Code: Select all
if math.abs(poly[i].nx - nx) >= 0.001 or
math.abs(poly[i].ny - ny) >= 0.001 or
math.abs(poly[i].nz - nz) >= 0.001 then
Code: Select all
nx, ny, nz = cross3p(points[p.p1].x, points[p.p1].y, points[p.p1].z,
points[p.p2].x, points[p.p2].y, points[p.p2].z,
points[p.p3].x, points[p.p3].y, points[p.p3].z)
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
I get the same data, but the model looks really bad. All the faces are bright colored except a few random ones on the spout, handle and lid knob.
Is this what you see?
Alternatively, I don't think StarFox had real-time shading. I think all its polygon faces were pre-colored. If I use this as an engine for a game, I could just go that route. Pre-calculate the color based on their angles or something. It's not like I'd need shading in a SF clone.
Though I still want to get it working right for other purposes.
Edit: Uploaded new download
Is this what you see?
Alternatively, I don't think StarFox had real-time shading. I think all its polygon faces were pre-colored. If I use this as an engine for a game, I could just go that route. Pre-calculate the color based on their angles or something. It's not like I'd need shading in a SF clone.
Though I still want to get it working right for other purposes.
Edit: Uploaded new download
- Attachments
-
- 3D.love
- Normals using code above
- (9.38 KiB) Downloaded 155 times
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
The normals my code are so close numerically to the normals in the file that the problem must be in the shading code. I didn't have the time to work it out in detail, but I found out that the result is much better if I change the light location
and normalize the light vector before calculating the dot product
instead of
Finally, I changed how the light affects the polygon color to this
I must repeat this is not something I put a lot of thought into. I should review how to do proper lighting calculations from my computer graphics book before suggesting anything as remotely correct or useful. However, I can't really find the time to do this properly now. My contributions to the LÖVE 3D programming will have to stop here. Perhaps I can return to this topic later, but I cannot promise anything yet.
All I can say that the result from these changes looked somewhat better than the previous one. I've also attached a love file with the changes I suggested above in it, in case I messed them up somehow. (I really should have used the magical diff program, but I was too hasty. Sorry.)
Code: Select all
-- line 14
light = {x = 100,y = 100,z = 100,intensity = 0.5}
Code: Select all
-- in love.draw
local lx, ly, lz = light.x - p.cx, light.y - p.cy, light.z - p.cz
local ln = math.sqrt(lx*lx+ly*ly+lz*lz)
fDot = -(((lx/ln) * p.nx) + ((ly/ln) * p.ny) + ((lz/ln) * p.nz))
Code: Select all
-- I removed this
fDot = -(((light.x - p.cx) * p.nx) + ((light.y - p.cy) * p.ny) + ((light.z - p.cz) * p.nz))
Code: Select all
-- in love.draw again
-- removed the use of ambient light here, just used a simple additive light model
r = r + p.c[1] * plight
g = g + p.c[2] * plight
b = b + p.c[3] * plight
All I can say that the result from these changes looked somewhat better than the previous one. I've also attached a love file with the changes I suggested above in it, in case I messed them up somehow. (I really should have used the magical diff program, but I was too hasty. Sorry.)
- Attachments
-
- 3D.love
- Jasoco's love file with some changes to main.lua
- (9.42 KiB) Downloaded 150 times
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
Thank you! I think you might have done it. I did comparisons between the included Normals and the pre-calculated ones with your new code and they look almost exactly alike. I think you might have fixed it. Thanks! I'll do some more testing when I go to lunch.
Now I just need to get people making their own 3D models to import into the project so we can see what we can do with this.
I'm going to implement a system for adding points (vertices) and triangles (faces) yourself as the program is running so you can see your results in real-time later.
I just wish this could do clipping. In that when two triangles merge, they clip each other so you don't get flickering, instead it looks ike they're attached. It would help with the spout and handle where they meet the pot.
Now I just need to get people making their own 3D models to import into the project so we can see what we can do with this.
I'm going to implement a system for adding points (vertices) and triangles (faces) yourself as the program is running so you can see your results in real-time later.
I just wish this could do clipping. In that when two triangles merge, they clip each other so you don't get flickering, instead it looks ike they're attached. It would help with the spout and handle where they meet the pot.
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
Doing a little work on this thing. I've noticed for some reason my light source is not working right. For instance, the X, Y and Z of the light are the opposite of where the light actually shines. i.e., the triangles facing the light are dark, and the ones facing away are bright. What? Weird. Why? So strange.
I have also devised a way to load multiple "j3d" files into the scene with offsets so you could basically create an empty world, then load parts in one at a time and place them where you want them. Also scale them before placing them. Though right now it doesn't let you rotate them but I will get that working. Should be easy. I have enough experience with math.sin(), math.cos() etc to do that.
Still working on making it a space shooter like StarFox. Should be easy. But I might need to use sprites for now. For the enemies and such.
Edit: Some observations. Seems the maximum number of triangles I can render comfortably without slowdown is 500 or so. When creating a world for an on-rails shooter, I won't and shouldn't create triangles that will never be seen. In StarFox for example, the first level, Corneria, was created mostly from cubes. I am almost certain they saved rendering time and space by only creating sides that will be seen from the player's POV. Along the side of the level you would see many boxes. Those boxes probably only had front, top and one or two sides rendered. The back and bottom and possibly furthest sides were not even in memory. I tried this method by removing the bottom and back from my cubes and cut down my triangle count significantly. I should play through the first level of SF again and see if I can estimate how many world polygons there are and see if my engine could render that well.
I have also devised a way to load multiple "j3d" files into the scene with offsets so you could basically create an empty world, then load parts in one at a time and place them where you want them. Also scale them before placing them. Though right now it doesn't let you rotate them but I will get that working. Should be easy. I have enough experience with math.sin(), math.cos() etc to do that.
Still working on making it a space shooter like StarFox. Should be easy. But I might need to use sprites for now. For the enemies and such.
Edit: Some observations. Seems the maximum number of triangles I can render comfortably without slowdown is 500 or so. When creating a world for an on-rails shooter, I won't and shouldn't create triangles that will never be seen. In StarFox for example, the first level, Corneria, was created mostly from cubes. I am almost certain they saved rendering time and space by only creating sides that will be seen from the player's POV. Along the side of the level you would see many boxes. Those boxes probably only had front, top and one or two sides rendered. The back and bottom and possibly furthest sides were not even in memory. I tried this method by removing the bottom and back from my cubes and cut down my triangle count significantly. I should play through the first level of SF again and see if I can estimate how many world polygons there are and see if my engine could render that well.
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
Needs optimization, but I have a prototype for a Star Fox style flight level...
Unfortunately it likes to run at 20-30FPS. Which is still better than Star Fox which I believe ran at 15FPS. Still. I'll have to figure out how to insert the points and triangles into a table when they are needed and remove them when they aren't anymore.
When it starts, the camera is up in the air pointing down, like a cherry picker it swoops down and tilts to follow the (Not designed or created yet) player ship.
Still buggy though.
Unfortunately it likes to run at 20-30FPS. Which is still better than Star Fox which I believe ran at 15FPS. Still. I'll have to figure out how to insert the points and triangles into a table when they are needed and remove them when they aren't anymore.
When it starts, the camera is up in the air pointing down, like a cherry picker it swoops down and tilts to follow the (Not designed or created yet) player ship.
Still buggy though.
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
It's a sign error, or so it looks to me. The part where we calculate the dot product with surface normals and light vectors (into fDot variable) is to blame, and adding or removing one unary minus should help.Jasoco wrote:Doing a little work on this thing. I've noticed for some reason my light source is not working right. For instance, the X, Y and Z of the light are the opposite of where the light actually shines. i.e., the triangles facing the light are dark, and the ones facing away are bright. What? Weird. Why? So strange.
You can do the lighting calculations in a cheaper way by not having a point light, which necessitates all those vector calculations to work out what is its direction relative to the triangles center, but using a precomputed light vector. This simulates a distant light source by having all the light hit the triangles from the same direction.
Try various normalized vectors for use with the triangle normals in the part where you calculate fDot and see if it makes the drawing noticeably faster. You may also try caching the light calculation results for objects that don't move relative to the light source, in case it turns out the lighting calculations are taking upa significant amount of time.
Edit: Changed one word. Helpfully in bold now
Last edited by pekka on Tue Mar 16, 2010 6:51 pm, edited 1 time in total.
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE
Well, aren't you the one who re-did my Normals and Dot stuff?
It's running a little slow, I think for my Star Fox clone I will probably have to disable certain things, like how I removed unseen vertices and triangles from the cubes lining the side of the map. And since I really don't need a live light source I'd just shade the polygons myself to have darker sides to give the illusion of lighting. Also back faces no longer need to be calculated when there are no back faces to be seen so I can turn that off too.
But I'd keep that stuff in tact for people who still want to use it as a 3D model viewer. Right now it's two projects in one. And funny, it started as a way to make a cool attractive rotating logo for my Zelda clone engine.
I'm still trying to figure out how to rotate just a set of points independently of the rest of the model. Right now the rotation is done by actually rotating the whole "world". The objects are still stationary. If I can figure out the calculations needed to rotate a whole set of vertices independently, it would be perfect. Especially since it would mean I could have my ship tilt and barrel-roll, or nose dive.
It's running a little slow, I think for my Star Fox clone I will probably have to disable certain things, like how I removed unseen vertices and triangles from the cubes lining the side of the map. And since I really don't need a live light source I'd just shade the polygons myself to have darker sides to give the illusion of lighting. Also back faces no longer need to be calculated when there are no back faces to be seen so I can turn that off too.
But I'd keep that stuff in tact for people who still want to use it as a 3D model viewer. Right now it's two projects in one. And funny, it started as a way to make a cool attractive rotating logo for my Zelda clone engine.
I'm still trying to figure out how to rotate just a set of points independently of the rest of the model. Right now the rotation is done by actually rotating the whole "world". The objects are still stationary. If I can figure out the calculations needed to rotate a whole set of vertices independently, it would be perfect. Especially since it would mean I could have my ship tilt and barrel-roll, or nose dive.
Who is online
Users browsing this forum: No registered users and 1 guest