- AVS Troubleshooting
- Two raytracing problems
Archive: Two raytracing problems
skupers
29th June 2003 13:19 UTC
Two raytracing problems
I've been trying to do some more advanced raytracing and I have two questions. The code can be found in the sections under each question.
---------------
Question 1: I tried making a hyperboloid from one piece using the formule x^2+y^2-z^2=1. So far no problems, but I wanted to view it from the outside. This means the point of origin must lie outside the object with the equation x^2+y^2-z^2=1. I thought that that would be pretty easy to do by changing to the origin coördinates {ox,oy,oz} to {0,2,0} and then I could find out later how to make sure that the position of origin is relative to the rotation angles in such a way that the camera always look at the object.
But after I changed {ox,oy,oz} to {0,2,0} (you can do this changing the following line:
Frame:
ox=0;oy=0;oz=0;
to
Frame
ox=0;oy=2;oz=0;
The view isn't like the object I intended at all. What have I done wrong?
The code of the dynmov:
init
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05
frame
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=0;oy=0;oz=0;
c1=ox*ox+oy*oy-oz*oz-1;
beat
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;
point
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
a1=x3d*x3d+y2d*y2d-z3d*z3d;b1=2*(x3d*ox+y2d*oy-z3d*oz);
ki=sqrt(b1*b1-4*a1*c1)/(2*a1);
k1=-b1/(2*a1)+ki;
k2=-b1/(2*a1)-ki;
k=min(k1,k2);
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=abs(atan2(ix,iy))/pi*2;y=iz*3;
alpha=1.3-abs(iz)/2;
---------------
Question 2: I wanted to do a triangular tunnel by defining three planes with the following formulas:
-x+y=2
x+y=2
y=-sqrt(2)
This should give you a triangle tunnel, but instead I get something very strange. There are three planes, which will form a triangle when extended, but on and around the places where the triangle sides should meet, there are some strange planes that go to infinity. Making the k1, k2 and k3 absolute solves the problem, but gives you a six-sided tunnel. I want a three-sided one.
I think the problem has to do with the -infinity outcomes for k1, k2 and k3, but I can't get rid of those without making the tunnel six-sided. The code of the dynmov:
init
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05
frame
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=0;oy=0;oz=0;
beat
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;
point
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy)/(y2d-x3d);
k2=(2-ox-oy)/(y2d+x3d);
k3=(-sqrt(2)-oy)/y2d;
k=min(k1,min(k2,k3));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=ix;y=iz;
alpha=1.3-abs(iz)*0.5;
13373571
29th June 2003 14:21 UTC
For the second problem:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy)/(y2d-x3d);
k1=if(below(k1,0),5000,k1);
k2=(2-ox-oy)/(y2d+x3d);
k2=if(below(k2,0),5000,k2);
k3=(-sqrt(2)-oy)/y2d;
k3=if(below(k3,0),5000,k3);
k=min(k1,min(k2,k3));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=ix;y=iz;
alpha=1.3-abs(iz)*0.5;
Min takes the lowest value, so if k2=-100 and k3=-50, your math would choose k2. I changed the code so it (essentially) takes the number with the lowest positive value, but does not use that number's absolute value. At leat I think that's what I did... It kinda don't look right to me
I haven't worked on the first problem much, but i'll try to figgure it out...
edit: put that code in per point.
edit2: Man i'm dumb... All I did was get rid of all negative k1,k2,and k3 values, I dunno what I was talking about above...
skupers
29th June 2003 15:14 UTC
Wow, great, thanks a lot, I now see what I did wrong. 13373571, you'll get a word of thank when I finish my dynmov tetrahedron ;).
13373571
29th June 2003 17:51 UTC
In the first one, you use
ki=sqrt(b1*b1-4*a1*c1)/(2*a1);
k1=-b1/(2*a1)+ki;
k2=-b1/(2*a1)-ki;
k=min(k1,k2);
... This has the same problem as the second one... if k1=-13373571 and k2=13373571, you will render the negative value... I don't know if that's your only problem though, I haven't tested because I'm sick of winamp crashing every five minutes... It's enough to make me want to try winamp 2.
And by the way, I *think* you can use
ki=sqrt(b1*b1-4*a1*c1)/(2*a1);
k=-b1/(2*a1)-ki;
k=if(below(k,0),-b1/(2*a1)+ki,k);
and then blend out negative ks...
Wow, great, thanks a lot, I now see what I did wrong. 13373571, you'll get a word of thank when I finish my dynmov tetrahedron .
Yeesh, even thinking about a DM tetrahedron makes my head hurt :D especially if you're going to be viewing it from outside...
edit: Wow I use a lot of ...s, I need to try to stop doing that
shreyas_potnis
30th June 2003 06:03 UTC
13373571, the dm master after UnConeD :D (btw, do you have a nick or something? feels funny to call you 13373571)
13373571
30th June 2003 08:35 UTC
Some people have called me "I.P. Address" and "Numbers"...
You can say "leet" or 1337 or any variation thereof. Or just smack your keypad randomly and use the number that comes up.
uNDefineD
30th June 2003 14:38 UTC
Looks like LeetEsti to me. ;)
[Ishan]
30th June 2003 16:50 UTC
yeah, i thought of that too!
sidd
30th June 2003 17:10 UTC
i always thought it was leetest1
like "leetest one".
thanks for the advise though 14234563780, from now on i shall call you 0142387134610..
skupers
30th June 2003 19:05 UTC
I made a DM tetraeder. I made it using the following formules for the sides:
x+y+z=2
-x+y+z=2
y+z=-sqrt(2)
z=-sqrt(2)
The code for that dynmov is the following:
init:
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05;
frame:
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=0;oy=0;oz=0;
beat:
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;
pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
k1=if(below(k1,0),5000,k1);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
k2=if(below(k2,0),5000,k2);
k3=(-sqrt(2)-oz)/z3d;
k3=if(below(k3,0),5000,k3);
k4=(-sqrt(2)-oy-oz)/(y2d-z3d);
k4=if(below(k4,0),5000,k4);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1.3-abs(iz)*0.5;
But when I try to view that from the outside, it doesn't look like a tetraeder. The sides 'continue'. It looks like when you see a cube from the outside with all the sides extended infinitely. Using max() instead of min() doesn't work. If you do that, it gets all infinity. I think you have to determine the lines where two planes meet and then use an if()-function to choose min() when inside those lines and to use max() when outside those lines.
I did figure out how to make the camera always point at the center of the object, after looking at UnConeD's WaterCube code. Instead of getting the origin {ox,oy,oz} from the rotation angles {rx,ry,rz}, you determine the rotation angles from the origin. You can do this with atan2(). An example is the following code, which you can paste in the frame section of the dynmov above.
frame:
o=o+or;or=(or*19+oc)*0.05;
ox=sin(o)*3;oy=cos(o)*3;oz=0;
rz=atan2(ox,oy);
rx=atan2(oy,oz);
ry=0;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
Since oz=0, there's no need to calculate ry.
13373571
1st July 2003 01:09 UTC
But when I try to view that from the outside, it doesn't look like a tetraeder. The sides 'continue'. It looks like when you see a cube from the outside with all the sides extended infinitely. Using max() instead of min() doesn't work. If you do that, it gets all infinity.
The reason we were setting the k values to 5000 was because we were using min and there isn't much chance that 5000 will be the minimum value. But when using max, we want the negative values to stay negative so that they aren't selected for rendering.
I think you have to determine the lines where two planes meet and then use an if()-function to choose min() when inside those lines and to use max() when outside those lines.
Lines don't have insides. And we already know how to get the tetrahedron to work from inside the tetrahedron. Please be precise when describing ideas, otherwise it's hard for my puny brain to comprehend. And if you have problems putting your idea into words, it will be even harder for you to put it into code. This isn't just nitpicking, I honestly have no clue what you're saying.
No, I haven't fixed your tetrahedron, I told you earlier that even thinking about a dm tetrahedron made my head hurt, didn't I? It's more complex than a cube... :(
Let's just wait for UCD to look at this.
Edit: And no, six lines that intersect at the four corners of a tetrahedron don't have insides either.
skupers
1st July 2003 08:34 UTC
I meant the pieces of the planes that are inside and outside those lines.
nixa
1st July 2003 09:07 UTC
You can also make the camera view the orgin by using :
frame:
rx=rx+bx;ry=ry+by;rz=rz+bz;
sx=sin(rx);sy=sin(ry);sz=sin(rz);
cx=cos(rx);cy=cos(ry);cz=cos(rz);
ox=cy*distance;oy=cz*sy*distance;oz=-sz*sy*distance;
beat:
bx=(rand(201)*0.01-1)*sp;by=(rand(201)*0.01-1)*sp;bz=(rand(201)*0.01-1)*sp;
point:
dx=sx*x+cx*y;dy2=cx*x-sx*y;
dz=sy+cy*dx;dx=cy-sy*dx;
dy=sz*dy2+cz*dz;dz=cz*dy2-sz*dz;
...
....
And the rotation will stay random
13373571
1st July 2003 11:25 UTC
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(below(ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy-oz)/(y2d-z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
It's supposed to calculate ix,iy,and iz for each plane and then if these coordinates are beyond the bounds of the triangle that each plane is going to be "cut" into, it sets k for that plane to be an arbitrary large number (1337). When this is done for all of the planes, we should have the four triangles that make up the tetrahedron. Then supposedly the closest triangle (found with min) should be the proper one.
Unfortunately, it don't work. :(
anybody know why?
skupers
1st July 2003 14:11 UTC
The idea seems to be right, but like you said, it doesn't work. My guess is that the way you decide if the coordinates are outside the bounds of the triangle are somehow flawed. The sides of plane z=-sqrt(2) (k3) lie on -ix+iy+iz=2, ix+iy+iz=2, iy+iz=-sqrt(2) and ofcourse z=-sqrt(2), because that the plane itself. Yet you test for -ix+iy+iz=2, ix+iy+iz=2 and iz=-sqrt(2), but not for iy+iz=-sqrt(2). Was that meant like this and if so, why?
I think we should try to solve this first so that when you view the tetraeder from the inside, it's look normal. Then, if we did it correct, moving the origin outside the object, using nixa's code, would give us a nice DM tetraeder.
13373571
1st July 2003 14:52 UTC
...... look carefully at each of the triangle cutter-upper lines. For each plane, I tested its intersection with the other three, but not its intersection with itself because that would've been just a tad redundant...
I just realized my error though... I had thought that earlier when you were listing the planes, you were putting them in order. I guess that was a kinda dumb assumption. Anyways, the fix after that is still a tad glitchy, here is the latest attempt:
pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(below(ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy-oz)/(y2d-z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);
At least we have triangles now... sorta
UnConeD
1st July 2003 16:41 UTC
skupers: this is wrong:
rz=atan2(ox,oy);
rx=atan2(oy,oz);
The problem with your hyperboloid is twofold:
- you're not discarding points behind the camera (k<0)
- you're not discarding points where there is no intersection (b^2-4*a*c < 0 for the quadratic equation).
I won't bother with the tetrahedron, too much trouble :P. Essentially you just raytrace all the front-facing planes, clip all intersectionpoints with the correct triangle and then min the remaining points. A good source for a fast triangle/line intersection test should be the 3D rendering scene. Try flipcode or something.
skupers
1st July 2003 18:21 UTC
you're not discarding points where there is no intersection (b^2-4*a*c < 0 for the quadratic equation).
Right, I forgot that sqrt( a ) is in AVS the same as sqrt( |a| ) (try x=i*2-1;y=sqrt(i); in a SSC to see this).
So, this seems to be a good version of the hyperboloid from one space:
init:
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05;
frame:
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=cy*3;oy=cz*sy*3;oz=-sz*sy*3;
c1=ox*ox+oy*oy-oz*oz-1;
beat:
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;
pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
a1=x3d*x3d+y2d*y2d-z3d*z3d;b1=2*(x3d*ox+y2d*oy-z3d*oz);
d1=b1*b1-4*a1*c1;
k1=if(below(d1,0),50000,(-b1+sqrt(d1))/(2*a1));
k1=if(below(k1,0),50000,k1);
k2=if(below(d1,0),50000,(-b1-sqrt(d1))/(2*a1));
k2=if(below(k2,0),50000,k2);
k=min(k1,k2);
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=abs(atan2(ix,iy))/pi*2;y=iz*3;
alpha=2/k-abs(iz)/6/k;
It's really cool and looks kinda like a wormhole ;).
13373571
1st July 2003 18:21 UTC
Essentially you just raytrace all the front-facing planes
Uhh, what's wrong with doing the back-facing planes too? It's easier and we're going to be doing min() on k anyways...
I now have a fairly tetrahedral shape going on having fixed a few more obvious stupid errors (not all of which were mine for a change :p I actually looked at skuper's code) but one of the points of the tetrahedron always manages to stretch to infinity and both oy and oz seem to be changing the same value.
The problem isn't with the triangle cutting stuff, that's working great, it's somethin about how dx,dy,dz, and/or ox,oy,oz are being used, they don't do what they're supposed to and I don't see why.
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(above(k1,0)*below(ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(above(k2,0)*below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(above(k3,0)*below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iy+iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy-oz)/(y2d+z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(above(k4,0)*below(-ix+iy+iz,2)*above(iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);
skupers
1st July 2003 22:59 UTC
Yeah, it at least looks like a tetraeder now, but I don't know why on of the points goes to infinity. It seems to me z1=-sqrt(2) is the bottom plane. I'll look into it further tommorrow, it's 0:05 AM in the Netherlands now ;).
I now have a fairly tetrahedral shape going on having fixed a few more obvious stupid errors (not all of which were mine for a change I actually looked at skuper's code)
Maybe you could tell me some of those errors, so I don't end up repeating them.
Do you mean oy and oz change per pixel? If so, that isn't happening. You can check that by adding x=x1*oy;y=y1*oz; to the end of the dynmov. They only change per frame (they're ofcourse supposed to do this), not per pixel.
BTW, are you a university student like UnConeD and Jheriko, 1337?
13373571
2nd July 2003 01:27 UTC
Maybe you could tell me some of those errors, so I don't end up repeating them.
but.... they were obvious and I'm lazy. Just remember the old adage that "When describing many planes, you are likely to switch subtraction and addition once or twice."
If you set everything to zero (the d's and the o's) and then add small increments to oy and then set it back to zero and do the same with oz, they seem to cause the same changes if I remember correctly.
BTW, are you a university student like UnConeD and Jheriko, 1337?
No :D I'm entering junior year in high school.
UnConeD
2nd July 2003 02:26 UTC
1337: there's nothing wrong with raytracing the backfacing points, but if you can avoid it easily, it's another optimization staring you in the face.
For example for quadrics... the solutions to the equation are something like (-b-sqrt(d))/2a and (-b+sqrt(d))/2a. Because of the way the equation is written down, one of them is always the frontfacing point, and the other is always the backfacing point. If you never switch between inside/outside, then you can always use the same point.
And in Watercube I only raytrace 3 planes rather than 6 because only 3 are ever visible at once.
sidd
2nd July 2003 04:14 UTC
with the tetrahedron: its practiaclally impossible to perform any intelegent back-face culling in avs, due to lack of decent control structures.
When you are veiwing it from the exterior, you cant just use max or min, or comninations of both, because you are dealling with infinite planes. Imagine that there is one face of the tertrahedron dirctly flat to the camera (x,y plane), this plane will never shine as the max or min k value becaue the angled planes adjacent to stretch out to infinity, and therfore go infront of it.
To get it to work properly, you would either have to write a backface culling line for each individual plane, or write a limiter for each plane, so that when it reaches the boundries of a particular face, it starts drawin the next plane.
It might be easier to do one DM for each face.
(ucd) Essentially you just raytrace all the front-facing planes, clip all intersectionpoints with the correct triangle
How do you go about clipping the intersection point?
13373571
2nd July 2003 06:08 UTC
1337: there's nothing wrong with raytracing the backfacing points, but if you can avoid it easily, it's another optimization staring you in the face.
For example for quadrics... the solutions to the equation are something like (-b-sqrt(d))/2a and (-b+sqrt(d))/2a. Because of the way the equation is written down, one of them is always the frontfacing point, and the other is always the backfacing point. If you never switch between inside/outside, then you can always use the same point.
Yes, I know that (-b-sqrt(d))/2a always gives the lowest k value in a quadratic because 2a and sqrt(d) are always positive. But with a tetrahedron, I see no easy trick to determine weather you are looking at the front or the back of the plane. The only way would be to figure out the relationships between ox,oy, and oz based on each plane's formula that signify weather the camera is "behind" the plane or in front of it, and after that, due to the funky if statements, I only think it would speed it up a little. Cubes are a rare exception: the formulas for their planes are simple and you can use just three planes and shift their distance back and forth to fake 6 planes ( (distance-ox)/dx ). In other words: Skupers can do it if he wants the speed, I don't feel like it.
siddhartha: one DM for each face would require that each DM has knowledge of the locations of the other faces... and each point has to calculate four identical rotations. slow as hell and hard to code, methinks. And you can use min once you've cut the planes into triangles like we've been doing in the last few examples.
shreyas_potnis
2nd July 2003 09:34 UTC
my eight sided dm :)
i understand, there is an extra rotation on the z axis, which i had made for a purpose, but it is not meant to be here and i am not interested in changing it now.
init:
pi=acos(-1)
frame:
t=t+.001+ti*.1;ti=ti*.9;
ox=cos(t)*.6*sin(t*.76+t);
oy=cos(t*.76+1)*.9;
oz=sin(t-1)*cos(t);
rx=0.1+atan2(ox,sqr(oy)+sqr(oz));
ry=atan2(ox,oz);
rz=-atan2(oz,sqr(ox)+sqr(oy));
sx=sin(rx);sy=sin(ry);sz=sin(rz);
cx=cos(rx);cy=cos(ry);cz=cos(rz);
af=max(h,w)/min(h,w);
cz1=cos(-pi/4);sz1=sin(-pi/4);
beat:
ti=.4
point:
y=if(above(h,w),y*af,y);x=if(above(w,h),x*af,x);
dx1=x*cz-y*sz;
dy1=x*sz+y*cz;
dy2=dy1*cx-sx;
dz2=dy1*sx+cx;
dx3=dx1*cy-dz2*sy;
dz2=dx1*sy+dz2*cy;
dx1=dx3*cz1-dy2*sz1;
dy1=dx3*sz1+dy2*cz1;
dx3=dx1;dy2=dy1;
k1=(1-oy-ox)/(dy2+dx3);
k1=if(below(k1,0),(-1-oy-ox)/(dy2+dx3),k1);
k3=(1-oy)/dy2;
k3=if(below(k3,0),(-1-oy)/dy2,k3);
k4=(1-ox)/dx3;
k4=if(below(k4,0),(-1-ox)/dx3,k4);
k5=(2-oz)/dz2;
k5=if(below(k5,0),(-2-oz)/dz2,k5);
k=min(min(k1,k5),min(k4,k3));
x=k*dx3-ox;
y=k*dz2-oz;
x=if(equal(k,k4),k*dy2-oy,x);
y=if(equal(k,k5),k*dy2-oz,y);
13373571
2nd July 2003 09:52 UTC
that's great, although it doesn't render from the outside and doesn't help at all with the tetrahedron :rolleyes:
nice work :D
sidd
2nd July 2003 10:46 UTC
And you can use min once you've cut the planes into triangles like we've been doing in the last few examples.
true that.. Sorry, i stopped looking at the examples with scrutiny after the first couple. :D
shreyas_potnis
2nd July 2003 13:41 UTC
hehe, this thread turned into a code book :D
btw. this shape is a hedron now, isnt it?
i dont know exactly what a hedron is, leave alone a tetrahedron.
13373571
2nd July 2003 14:22 UTC
i dont know exactly what a hedron is, leave alone a tetrahedron.
Then
look it up.
Skupers: You ARE absolutely sure that the four planes you posted earlier form a tetrahedron, right? Because it seems to me that they form a triangle tunnel with a plane intersecting it... and it seems to me that that's what AVS is rendering... and it seems to me that improper planes is the only way to explain what AVS is doing.
skupers
2nd July 2003 15:29 UTC
I'm almost certain. I made a image to explain how I got the formulas. It's attached.
13373571
3rd July 2003 04:57 UTC
wouldn't adding z on all 3 planes make all 3 planes slope downwards?
Zevensoft
3rd July 2003 06:22 UTC
A tetrahedron is a four sided 3D object with all faces being triangles. You people are talking about a triangular prism.
sidd
3rd July 2003 06:46 UTC
:D
13373571
3rd July 2003 07:11 UTC
A tetrahedron is a four sided 3D object with all faces being triangles. You people are talking about a triangular prism.
Zevensoft, we've been talking about taking four planes, cutting them into triangles, and fitting the triangles together. At least that's what I've been talking about ever since skupers said "tetrahedron". We made a triangular tunnel/prism a good while back. WTF do you mean we've been talking about a triangular prism?
skupers
3rd July 2003 07:49 UTC
Originally posted by 13373571
wouldn't adding z on all 3 planes make all 3 planes slope downwards?
No, there's a plane z1=-1 to cut the tunnel. At z1=1, using x1+y1=1-z1 gives you x1+y1=0. And if there was something wrong with these formulas, wouldn't we have noticed earlier? Viewing from the outside gives you a tetrahedron.
13373571
3rd July 2003 07:57 UTC
Viewing from the outside gives you a tetrahedron.
No it doesn't, that's the problem, remember? It gives us a triangular prism that stretches infinitely in one diagonal direction and is cut by the plane z=-sqrt(2).
Edit:
Here, i just fixed it.
Pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(above(k1,0)*below(ix+iy+iz,2)*above(iy,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(above(k2,0)*below(-ix+iy+iz,2)*above(iy,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(above(k3,0)*below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iy,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy)/(y2d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(above(k4,0)*below(-ix+iy+iz,2)*above(iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);
I changed the plane z+y=-sqrt(2) into the plane y=-sqrt(2). That's what was wrong, you had the wrong plane. Blargh.
skupers
3rd July 2003 16:24 UTC
Then, it should be y-z=-sqrt(2), not y=-sqrt(2). Sorry for my stupid mistake. :(
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(above(k1,0)*below(ix+iy+iz,2)*above(iy-iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(above(k2,0)*below(-ix+iy+iz,2)*above(iy-iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(above(k3,0)*below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iy-iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy+oz)/(y2d-z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(above(k4,0)*below(-ix+iy+iz,2)*above(iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);
This should work.
13373571
3rd July 2003 17:27 UTC
Sorry for my stupid mistake. :(
No problem, everybody screws stuff like that up occasionally.
I was just getting irritated because I couldn't get something to work even though it seemed so clear that it should've been working.