Archive: raytraced sine-cosine landscape using whittaker/newton-raphson


30th January 2004 08:53 UTC

raytraced sine-cosine landscape using whittaker/newton-raphson
Dude!
One week ago I was still, enviously, looking at all those real-3d DMs and didn't even know what all those dx, oz and k stuff meant. Today I'm presenting my first 100% self made DM with raytracing.
It might be nothing special to all you elite math-aces out there, but to me it's special because it's the first sine-cosine landscape I've ever seen in a DM, and it's mine(sorry, but I feel so smart)! I've still got some questions about it, but I will start with the code.
I've seen the formula somewhere at school and didn't what it is, so I "took" it home.
Here it is:
z = sin(x)*cos(y)
Quite easy, but I was unable to solve it for "k" and so I tried to aproximate it. With the methods I've seen in this forum (UnConeD your'e so pow(skilled,infinite)) I even managed it.

Here's the DM code (newton-raphson):
All checkboxes set to active.

init:
------
dov=4;
------

frame:
-----------------------------------------------------------------------
t=gettime(0);
ox=sin(t+t); oy=sin(t); oz=sin(t*.5)+5;
rx=ox*.5; ry=oy*.5; rz=oz;
sx=sin(rx); cx=cos(rx); sy=sin(ry); cy=cos(ry); sz=sin(rz); cz=cos(rz);
-----------------------------------------------------------------------

beat:
----------
(is empty)
----------

pixel:
--------------------------------------------------------------------------------------------------
dx=sin(r)*d; dy=-cos(r)*d;
dx1=dx*cz-dy*sz; dy1=dx*sz+dy*cz; dy=dy1*cx-sx; dz1=dy1*sx+cx; dx=dx1*cy-dz1*sy; dz=dx1*sy+dz1*cy;
six=sin(dx+ox); cix=cos(dy+oy);
k=k-(six*cix-dz-oz)/(-dx*cix*dy*six-dz); six=sin(dx*k+ox); cix=cos(dy*k+oy);
k=k-(six*cix-dz*k-oz)/(-dx*cix*dy*six-dz); six=sin(dx*k+ox); cix=cos(dy*k+oy);
k=k-(six*cix-dz*k-oz)/(-dx*cix*dy*six-dz); six=sin(dx*k+ox); cix=cos(dy*k+oy);
k=k-(six*cix-dz*k-oz)/(-dx*cix*dy*six-dz); six=sin(dx*k+ox); cix=cos(dy*k+oy);
k=k-(six*cix-dz*k-oz)/(-dx*cix*dy*six-dz); six=sin(dx*k+ox); cix=cos(dy*k+oy);
ix=dx*k+ox; iy=dy*k+oy; iz=dz*k+oz;
x=ix; y=iy;
alpha=dov*2-sqrt(ix*ix+iy*iy+iz*iz); alpha=if(below(alpha,0),0,if(above(alpha,1),1,alpha));
--------------------------------------------------------------------------------------------------

As you will see, the result is quite ugly and the fogging also gets messed up. Even with twenty steps it didn't look better.
So I tried it with the whittaker method (thx to UnConeD again).

DM code (whittaker):
All checkboxes set to active, again.

init:
------
dov=4;
------

frame:
-----------------------------------------------------------------------
t=gettime(0);
ox=sin(t+t); oy=sin(t); oz=sin(t*.5)+5;
rx=ox*.5; ry=oy*.5; rz=oz;
sx=sin(rx); cx=cos(rx); sy=sin(ry); cy=cos(ry); sz=sin(rz); cz=cos(rz);
-----------------------------------------------------------------------

beat:
----------
(is empty)
----------

pixel:
--------------------------------------------------------------------------------------------------
dx=sin(r)*d; dy=-cos(r)*d;
dx1=dx*cz-dy*sz; dy1=dx*sz+dy*cz; dy=dy1*cx-sx; dz1=dy1*sx+cx; dx=dx1*cy-dz1*sy; dz=dx1*sy+dz1*cy;
k=k+(sin(dx+ox)*cos(dy+oy)-dz-oz);
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz);
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz);
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz);
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz);
ix=dx*k+ox; iy=dy*k+oy; iz=dz*k+oz;
x=ix; y=iy;
alpha=dov*2-sqrt(ix*ix+iy*iy+iz*iz); alpha=if(below(alpha,0),0,if(above(alpha,1),1,alpha));
--------------------------------------------------------------------------------------------------

Looks way better, hu?

Ok, that was the code. As you might have seen (switch of blending), in the distance everything get's messed up.
So here's my first question:
Is there a way to solve the equation for "k"?
If yes, please tell me how.
I've been thinking about refraction stuff, but I've had nothing to use it on, now I have.
I'm sure I can figure out, with trying around a bit, how to do this (I know the basics). But I really have no idea of how to calculate the normal vectors of a point on that landscape (maybe I have, but I'm not sure about it, plus it's pretty late now so I don't have time to think about it), so can someone tell me how to do this?

Well, that's it. Now it's your turn, tell me how you like the DM, or answer my questions, or do both.
Thank 'n see y'all.


30th January 2004 12:30 UTC

Not bad at all...

For the normal/gradient, just use (-***8706;z/***8706;x, -***8706;z/***8706;y, 1). (***8706; = partial derivative)

Oh and my flag preset was in fact a "sine/cosine landscape" really. So you're not first, sorry :rolleyes:.

Equations with sine are usually tricky to solve: a ray that is not to steep will have multiple intersections anyway (some rays even infinite), so you're better off doing it numerically.

By the way, maybe you should try starting by raytracing the plane that touches the tops of the bumps: this is a good starting value for 'k' and could speed up the code and allow for higher gridsize (and less uglyness in the distance).


30th January 2004 13:33 UTC

UnConeD:"Oh and my flag preset was in fact a "sine/cosine landscape" really. So you're not first, sorry"
Me:"Damned!"
UnConeD:"By the way, maybe you should try starting by raytracing the plane that touches the tops of the bumps"
Me:"I will try that, but my understanding of raytracing is still a bit :down: so could you please explain to me why this makes it faster."
Well, thanks for your help.
btw: I've now seen all your packs, (:mad: <- want's to be you) and the final whack was just inhuman. I bet it wont take long until someone will make games using AVS. I've read about a wolfenstein preset, you've made. Can I download it somewhere?
'Nuf questions, I hope the final whack wasn't your last pack. Cya.


30th January 2004 18:40 UTC

Why a plane would speed it up: for plain whittaker raytracing, you usually start with k=0 or some other small value.
If you start by raytracing the plane which touches the tops of the bumps, you will already be close to the intersection point, and you will probably need less iterations.
Raytracing a plane is quite fast (well compared to sines/cosine anyway).

Depending on which side your camera is on, you'll need to raytrace z=1 or z=-1:


z = 1
<=> k*dz+oz = 1
<=> k = (1-oz)/dz


Once you have that, you probably need less whittaker iterations. By the way, you never reset your 'k' so in fact you're iterating progressively from gridpoint to gridpoint (which might be better or worse, depending on the camera angle).

You can get the wolfenstein preset here, but it's just Elevation with different texturing (Elevation was derived from WolfenAVStein).

30th January 2004 20:53 UTC

and don't forget about alpha optimiz.:

alpha=min(1,max(0,dov*2-sqrt(ix*ix+iy*iy+iz*iz)));


31st January 2004 00:43 UTC

Uhh where did your Whittaker constant go by the way?

pixel:
--------------------------------------------------------------------------------------------------
dx=sin(r)*d; dy=-cos(r)*d;
dx1=dx*cz-dy*sz; dy1=dx*sz+dy*cz; dy=dy1*cx-sx; dz1=dy1*sx+cx; dx=dx1*cy-dz1*sy; dz=dx1*sy+dz1*cy;
wh=.5;
k=k+(sin(dx+ox)*cos(dy+oy)-dz-oz)*wh;
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz)*wh;
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz)*wh;
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz)*wh;
k=k+(sin(dx*k+ox)*cos(dy*k+oy)-dz*k-oz)*wh;
ix=dx*k+ox; iy=dy*k+oy; iz=dz*k+oz;
x=ix; y=iy;
alpha=dov*2-sqrt(ix*ix+iy*iy+iz*iz); alpha=if(below(alpha,0),0,if(above(alpha,1),1,alpha));
--------------------------------------------------------------------------------------------------

If you add that constant you'll notice the texture on the edges doesn't distort nearly as much because it makes the approximation more exact. And yeah go with the initial plane approximation like UnConeD said. You might be interested in looking at my Adapt preset. The post should still be in this forum down on the list. That uses whittaker iteration as well. Thats another direction to take this idea.

Oh and it kinda sounds like you haven't dealt with functions of more than one variable before... I'm all for refraction but you might come across one problem if you try and complicate the equation. If you make the equation too complicated it's gonna be a pain to get the partial derivatives (or just REALLY LONG). Just a friendly word of warning. I ran into that problem anyways...