raytraced tunnel

category: general [glöplog]
hi all,
can anyone please point me in the direction of a good raytraced tunnel tutorial, or released source codes.
as i am having great difficulty tracking down any good documentation of this effect myself.

it would be great if i could actualy find a C/C++ or JAVA tutorial.

thanks for all your help

added on the 2007-05-02 09:42:08 by stunna stunna
wasnt that explained in some diskmag couple of years back?
added on the 2007-05-02 09:59:34 by the_Ye-Ti the_Ye-Ti
1. void main(int argc, char *argv[]) // now is C tutorial
2. Tunnel is: x^2+y^2=r^2
3. Ray is: (x,y,z)=(x0,y0,z0)+t*(dx,dy,dz)
4. Solve for t (want positive solution)
5. Get (x,y,z) from ray equation
6. Calc. (u,v) = ( arctan(y/x) , z)
7. Scale (u,v) any way you like
8. Greetings to Drifters
added on the 2007-05-02 10:01:07 by doomdoom doomdoom
doom, thanks but i have the basic premise behind the tunnel working. it seems that when i rotate, my tunnel on the y or x axis the texture warps and distorts.

and i am not sure why. so i was thinking if a scan someone elses code, could help me see where i am going wrong.

the_ye_ti if you could remember the ,ag that would be a great help.
added on the 2007-05-02 10:12:52 by stunna stunna
stunna: it's in Freestyle, but that's in Hungarian... also, the texcoord distort reminds me a bit of my first tunnel - are you able to do a full 360 rotation in it?
added on the 2007-05-02 10:18:00 by Gargaj Gargaj
hint: you will need something like atan2(), not just arctan(). arctan() will show some glitches if you add an offset to the result.
added on the 2007-05-02 10:30:17 by KeyJ KeyJ
gargaj: no i would say that when i hit an angle of 180 degs i start to get texture distortion.
added on the 2007-05-02 10:30:41 by stunna stunna
for(int y=0;y<30;y++){for(int x=0;x<40;x++){
float dx = x-19.5, dy = y-14.5;
float t = sqrt( 100 /( dx*dx+dy*dy+100));
int u = atan2f( dy*t,dx*t )*8/3.14, v = 10*t/2;
putchar( u+v &1 ? '#' : ' ' );
added on the 2007-05-02 10:56:34 by the_Ye-Ti the_Ye-Ti
stunna: rotate your rays and transform your origin!
added on the 2007-05-02 10:58:01 by kusma kusma
the problem you're seeing is that sometimes the texture coordinate interpolation inside of a square isn't giving you the results you expect.

atan2() gives results in the range -pi .. +pi (= -180 .. +180 degrees).

At angle ~180 degrees, you have the following situation:

start of interpolation: 179.5 degrees
end of interpolation: -178.3 degrees

At exactly 180 degrees, the atan2() function has a discontinuity (its value suddenly jumps from +pi to -pi).

If you interpolate from start to end value naïvely, you will interpolate through an interval of 357.8 degrees -- that is, taking the "long way" around the circle. You're taking the long way because you are trying to make a piecewise linear approximation of the atan2() function, without taking the special case of the discontinuity into account.

What you want to do here is to always take the "short way" around the circle. Do that by checking when the delta between the two angle values fall outside the -180 .. +180 degrees interval; if so, add/subtract 360 to either of the angle values until they are max 180 degrees from each other.

In the above example, let's say you want to adjust the end interpolation value. You do:

Code:while (end - start < -180) end += 360; while (end - start > +180) end -= 360;

and in the above example, this will yield an end value of 181.7 degrees, and an interpolation length of 2.3 degrees, which is probably what you desired.
added on the 2007-05-02 11:02:27 by Kalms Kalms
Oh yes, that bloody seam. I've always solved that by mirroring the texture coordinates around the center of the tunnel. The special case that Kalms is describing is the correct fix, but it greatly complicates the data-flow in a "standard" grid-expander as you need to look at neighbor nodes at a level where you still have a concept of the actual geometry. Another fix would be to never allow interpolation of more than half of your texture over one grid-node in either dimension. This has some correctness issues with very down-scaled textures though - but then you already have aliasing issues, so it might not be so bad after all.
added on the 2007-05-02 11:47:22 by kusma kusma
If you're doing the interpolation using integer maths, then you can do the range-reduction fix in the per-square rendering code by sign-extending the texture gradients from the appropriate number of bits to your total word width. (lsl.l #x,dn; asr.l #x,dn where x = 32 - (integer bits used + fractional bits used))
added on the 2007-05-02 12:25:16 by Kalms Kalms
Yes, what kusma said. Use 16-bit integer math if your texture coords are 8.8. That way, 0x0010 - 0xffff = 0x0020 which is what you want.

Avoid arctan(y/x) because of course that glitches when x ~= 0. Since |(x,y)|=r you can safely use either atan2() or:

arctan(y/x) if |x|>|y|
arctan(x/y) otherwise

What you describe as "warping" could be anything of course. A screenshot would help. I'm guessing your problem is with the camera.
added on the 2007-05-02 12:41:18 by doomdoom doomdoom
* 0xfff0
added on the 2007-05-02 12:58:13 by doomdoom doomdoom
doom, i dont have anywhere to upload the screenshots to but i could upload for you the main raytracing loop if that would help.
added on the 2007-05-02 12:59:53 by stunna stunna
Yes, show us the loop.
added on the 2007-05-02 13:34:40 by doomdoom doomdoom
doom, i dont have anywhere to upload the screenshots

There are many free image hosting sites, just choose.
added on the 2007-05-02 15:18:31 by LiraNuna LiraNuna
http://www.scene.org/file.php?file=/mirrors/hornet/code/effects/tunnel/fdtunnel. zip&fileinfo
added on the 2007-05-02 15:35:04 by Tigrou Tigrou
gaffer's tutorial? :P