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
ST,
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
ST,
wasnt that explained in some diskmag couple of years back?
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
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
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.
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.
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?
hint: you will need something like atan2(), not just arctan(). arctan() will show some glitches if you add an offset to the result.
gargaj: no i would say that when i hit an angle of 180 degs i start to get texture distortion.
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 ? '#' : ' ' );
}putchar('\n');}
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 ? '#' : ' ' );
}putchar('\n');}
stunna: rotate your rays and transform your origin!
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:
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.
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.
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.
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))
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.
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.
check also here: http://www.programmersheaven.com/download/6273/download.aspx
* 0xfff0
doom, i dont have anywhere to upload the screenshots to but i could upload for you the main raytracing loop if that would help.
Yes, show us the loop.
Quote:
doom, i dont have anywhere to upload the screenshots
There are many free image hosting sites, just choose.
http://www.scene.org/file.php?file=/mirrors/hornet/code/effects/tunnel/fdtunnel.zip&fileinfo
gaffer's tutorial? :P