| |
Scout
Registered: Dec 2002 Posts: 1570 |
3D projection on the C=64 (or...how do I divide?)
Hi!
After 12 years I picked up coding again on the C=64.
What I want to make is a simple 3D starfield.
I know something about 3D programming, so that's no issue.
The only thing I stumbled on is how to implement 3D projection (X1=X/Z) and especially the dividing part of it.
How can I implement this on the C=64?
Any hints, tips?
Thanx!
R.
(Asm on the PC is so much easier ;-) |
|
| |
Perff Administrator
Posts: 1680 |
One of the methods I have used the most when dividing (and multiplying) in assembler is using logarithm.
I use the fact that:
x/y = e^(log x - log y)
You have one table containing values of log(x), and another table of e^x
When you want to divide the content of the X-reg with the Y-reg you do:
sec
lda logtable,x
sbc logtable,y
tax
lda exptable,x
That's it! :)
(You must of course take care of overflows etc.)
One downside using this is that the result is not 100% accurate, but it's fast and you can also use it for multiplying. (do an add instead of sbc) |
| |
Scout
Registered: Dec 2002 Posts: 1570 |
Hey!
Now that's what I call a great solution!
Cheers!
R. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
if you have enough memory you can also have everything precalculated :) but there is no better way to divide on c64 thats sure.. :)
|
| |
CreaMD
Registered: Dec 2001 Posts: 3057 |
Cool stuff.
Roman |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
the lacking accuracy of this approach is not to be ignored with 3d code. i might add that the best accuracy with this algorithm can be achieved by using the binary logarithm, but i guess you've already taken that one.
for more accuracy, the best thing is a plain binary division routine that calculates one bit of the result per loop pass, being as exact as you want it to be.
if you never coded such a thing, wait for some future issue of one of the disk mags where there are further chapters of my tutorial on maths in assembler published. i don't want to get into further detail here but i can send you sample routines or the chapter of that tutorial in german language, as i did not translate it to english yet. |
| |
Scout
Registered: Dec 2002 Posts: 1570 |
Quote: the lacking accuracy of this approach is not to be ignored with 3d code. i might add that the best accuracy with this algorithm can be achieved by using the binary logarithm, but i guess you've already taken that one.
for more accuracy, the best thing is a plain binary division routine that calculates one bit of the result per loop pass, being as exact as you want it to be.
if you never coded such a thing, wait for some future issue of one of the disk mags where there are further chapters of my tutorial on maths in assembler published. i don't want to get into further detail here but i can send you sample routines or the chapter of that tutorial in german language, as i did not translate it to english yet.
Hi
I appreciate if you could send those routines/info.
It's no problem if the text is in German coz I can read it a bit (I'm dutch).
Thanx.
R.
|
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
I have always precalculated everything => no need for division and other nasty realtime stuff :)
But if I'm going to make something in realtime one day, Perffs algorithm seems pretty smart... But if it's inaccurate how about this:
x/y = x*(1/y)
Then you just need a table of 1/x and to do a multiply. The latter can be done with this algorithm...
Let f(x) = x^2 / 4.
Then a*b = f(a+b) - f(a-b)
So with a table of squares/4 and 1/x you should be able to divide using adc and sbc. |
| |
Nightlord Account closed
Registered: Jan 2003 Posts: 131 |
cruzer:
i have thought of division using your approach but i ran into a problem that 1/x table starts to get inacurate for large x values. besides the f(a+b) and f(a-b) also becomes troublesome. since now typical a values are decimals and typical b values are fixed point reals between 0 and 1
i have the feeling that this should be fixable by playing with the tables but couldn't figure out how? so how do you handle these issues.
thanx in advance |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Nightlord: Do you need to divide by large numbers when doing 3d projections?
Any division routine on c64 is bound to be inaccurate or slow, so I guess you'll have to live with some inaccuracy. Then the trick is to make it just accurate enough to suit your particular need.
But as I said, I always precalculate everything, so I haven't got any experience with implementing a division routine myself.
And btw, I think Perff's routine looks smarter than mine. |
| |
SIDWAVE Account closed
Registered: Apr 2002 Posts: 2238 |
If you only want to make a 3D starfield end nothing else, just do like the game DELTA.
set a sprite and give it a different X position every rasterline.
The sprite is just made of a single vertical line in 1 color.
Do different sinus tables for each sprite, and it will look quite real to you.
|
... 25 posts hidden. Click here to view all posts.... |
Previous - 1 | 2 | 3 | 4 - Next |