Jasoco's 3D Engine Thread: Go to Page 6 Please!

Showcase your libraries, tools and other projects that help your fellow love users.
pekka
Party member
Posts: 206
Joined: Thu Jan 07, 2010 6:48 am
Location: Oulu, Finland
Contact:

Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE

Post by pekka »

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.
User avatar
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

Post by Jasoco »

I tried that too and it didn't work well at all.

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
If you have any example, I'd love to see it.
pekka
Party member
Posts: 206
Joined: Thu Jan 07, 2010 6:48 am
Location: Oulu, Finland
Contact:

Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE

Post by pekka »

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)
I think this should be as follows.

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)
Here is my Lua function and an example below with data pulled from the data file by hand.

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
I tried it with the first poly in the data file. It has point indices 0 1 and 17, which have these values:

Code: Select all

	14.369 11.0421 -0.369
	13.284 11.0421 -5.864
	18.819 -3.9579 -8.219
Interacting with my code in the Lua interpreter, I got these values this time:

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
> 
These values correspond with the values in the file quite well this time. I believe I made an error entering some data earlier, when I reported my values were slightly off.

The file has this.

Code: Select all

0.9133 0.3653 -0.1803
You should note that in many graphics libraries the convention is to have normals for vertices, and not triangle faces as in this program (and file format). This method does not apply to them, of course.

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
I called my cross product function as follows.

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)
I hope this helped.
User avatar
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

Post by Jasoco »

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?
Image

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 154 times
pekka
Party member
Posts: 206
Joined: Thu Jan 07, 2010 6:48 am
Location: Oulu, Finland
Contact:

Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE

Post by pekka »

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

Code: Select all

  -- line 14
  light = {x = 100,y = 100,z = 100,intensity = 0.5}
and normalize the light vector before calculating the dot product

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))
instead of

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))
Finally, I changed how the light affects the polygon color to this

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
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.)
Attachments
3D.love
Jasoco's love file with some changes to main.lua
(9.42 KiB) Downloaded 149 times
User avatar
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

Post by Jasoco »

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.
User avatar
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

Post by Jasoco »

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.
User avatar
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

Post by Jasoco »

Needs optimization, but I have a prototype for a Star Fox style flight level...

Image

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.
pekka
Party member
Posts: 206
Joined: Thu Jan 07, 2010 6:48 am
Location: Oulu, Finland
Contact:

Re: Jasoco's 3D Model Extravaganza.. NOTHING IS "NORMAL" ANYMORE

Post by pekka »

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.
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.

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.
User avatar
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

Post by Jasoco »

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.
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests