correct order of face drawing
#1
Posted 18 March 2006 - 09:26 PM
http://www.geocities...k/engine3d.html
It works well apart from occasionally faces that should be drawn behind are drawn in front. At the moment I'm calculating the distance of the center of the face from the camera. This sometimes produces incorrect results when faces are close together and if faces are different sizes. I'm assuming the faces are not actually intersecting.
Is there a way I can work out the exact order? I've tried thinking of ways envolving all the vertices around the face but nothing I can think of is full-proof.
Please help if you know the answer.
Thanks
Peter Bone
#3
Posted 19 March 2006 - 10:15 AM
#4
Posted 19 March 2006 - 06:28 PM
#5
Posted 23 March 2006 - 04:21 PM
Here's the program I'm working on.
http://atlas.walagat...rbone/rubix.zip
It's the internal faces overlapping the external faces as a layer rotates that's the problem - set the rotation speed to lowest in properties.
#6
Posted 23 March 2006 - 10:00 PM
peterbone said:
Use a sorting algorithm, silly! If polygon A is in front of B, and B is in front of C, then A is in front of C. So you can use quicksort or whatever and it will work fine.
#7
Posted 23 March 2006 - 10:06 PM
#8
Posted 23 March 2006 - 10:06 PM
If you start to have significant overdraw the z-test can actually speed things up.
#9
Posted 23 March 2006 - 10:07 PM
We had to sort polys on the ps1 (that's a 30Mhz CPU) and it was never much of a deal.
#10
Posted 24 March 2006 - 09:04 AM
But if you really want to take this renderer to a whole new performance level you should use assembly. I'm rendering some scenes originally meant for hardware rendering at 640x480 at 30 FPS or more... That's how powerful modern CPUs really are when using MMX/SSE instructions and the most advanced optimizations.
If you're not so concerned about performance, then just don't be concerned about it at all and use a good z-buffer implementation. In my experience it's always best to use the same techniques used by graphics hardware when in doubt. They really use poweful algorithms that are not so bad for software rendering either.
#11
Posted 24 March 2006 - 10:36 AM
Thanks Nick, but I think I'll skip the z buffer for now - I think the polygon sorting method will be faster since I don't know how to write assembly. Are you the same Nick that helped me several times before? You told me I needed to do sub pixel accuracy and several other things. Thanks.
So no-one's got a link for the modified painters algorithm that explains in more detail? I'll try to find something in my university library.
So what did you think of my rubik's cube simulator? It was confusing to make but very satisfying. If anyone wants the Delphi code I'll send it to you.
#12
Posted 24 March 2006 - 06:21 PM
ZFar := 987;
ZNear := 813;
a := (zFar + zNear) / (zFar - zNear);
b := 2 * zFar * zNear / (zNear - zFar);
Depth := Trunc((a + b / ViewPoint.Z) * High(Integer));
What's wrong with that? a + b / ViewPoint.Z should normalize it between -1 and 1 so multiplying by the largest possible integer (32bit) value should normalize in the range of the integer but it seems to be overflowing the integer. I got those equations from wikipedia but it doesn't show how they're derived.
#13
Posted 24 March 2006 - 08:27 PM
znear := some small value
zFar := some very large value
Max_z_value_in_buffer = largest value representable in your zbuffer.
z: z of current pixel, should to be >= znear and <= zfar
zbufferval = Max_z_value_in_buffer * (z-znear)/ (zfar-znear)
#14
Posted 26 March 2006 - 06:09 PM
#15
Posted 27 March 2006 - 11:20 AM
I know I shouldn't worry about optimization so much when it's already fast enough but I can't help the feeling that it could always be slightly faster!
Here's my line rasterizing code. Got any speed ups?
scanpointer := @Scanlines[y][ScanStart]; depthpointer := @DepthBuf[y][ScanStart]; for x := ScanStart to ScanEnd do begin if D > depthpointer^ then begin Scanpointer^ := RGB; depthpointer^ := D; end; Inc(scanpointer); Inc(depthpointer); Inc(D, Ddx); end;Also, what's the best way to clear my z buffer? It's a 2d dynamic array. I've seen reference to using MemSet but Delphi doesn't seem to have that. At the moment I'm using optimized rasterizing code.
#16
Posted 27 March 2006 - 01:13 PM
peterbone said:
This is exactly what a homogeneous projection matrix does in Direct3D (or OpenGL):
[w 0 0 0] [0 h 0 0] [0 0 Q 1] [0 0 -Q*Zn 0] with Q = Zf / (Zf - Zn)You can see that A = -Q*Zn and B = Q. Also note how we get w = z in the last column. Now the nicest thing about having this in matrix form is that you can multiply it with the model and view transform matrices, and get the whole transformation from model space to clip space in just one matrix!
Quote
Quote
Quote
...
Looks optimized to me, but allow me to use it to clarify my point. If your compiler is any good, that code executes in 10 clock cycles per pixel. With a low-end 1 GHz CPU, 640x480 screen and crazy 10x overdraw, that still gives us over 300 FPS! For that rubix game, 10 FPS should be plenty... So you can see there is lots of extra processor power you can so something more useful with than drawing extra frames. I'm thinking about a shiny rubix cube reflecting the environment. :worthy:
To get there, you'll need many extra features like diffuse lighting, texture mapping and alpha blending. If you try to optimize everything from the start, you will end up with spaghetti code that becomes unmanageable and you will either end up rewriting everything several times or just never finish it. If on the other hand you forget about optimizations for a while, this can be achieved in a couple weeks tops. And if it's not fast enough it will only take a day to optimize the real bottlenecks with only a fraction of your code made less manageable.
But even if you're not interested in a shiny rubix, I hope it's clear now that any optimization at this point is a waste of time. There is absolutely no reason to make it faster than it already is.
And if you're really still interested in a direct answer: Yes it can be optimized, by using assembly with MMX instructions. But it should be clear by now that this would make the code totally unmanageable at this point. You need to go in the other direction, even if that means less optimizations, because it doesn't matter.
Quote
#17
Posted 27 March 2006 - 02:55 PM
That Depth equation is fixed point integer. It doesn't overflow because the the z values are always > about 800 or something.
I want my programs to work on slow computers too. On my 2GHz pc it uses up over 50% of the processor when on full screen.
I think I'll give the shiny cube a miss but it does have diffuse lighting. Maybe you didn't notice because the difference in intensity isn't much.
I'm clearing my colour buffer using the windows fillrect routine since it's a bitmap. It's slightly faster than anything I can write. Maybe I'll make my z-buffer a 32 bit bitmap too.
Thanks for all your help and someone should correct wikipedia or add to it to make those equations make sense.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users












