Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Continuing my exploration of raycasting, I am very confused about how the correction of the fisheye effect works.

Looking at the screenshot below from the tutorial at permadi.com, the way I understand the cause of the fisheye effect is that the rays that are cast are distances from the player, rather than the distances perpendicular to the screen (or camera plane) which is what really needs to be displayed. The distance perpendicular to the screen then, in my world, should simply be the distance of Y coordinates (Py - Dy) assuming that the player is facing straight upwards.

enter image description here



Continuing the tutorial, this is exactly how it seems to be according to the below screenshot. From my point of view, the "distorted distance" below is the same as the distance PD calculated above, and what's labelled the "correct distance" below should be the same as Py - Dy. Yet, this clearly isn't the case according to the tutorial. My question is, WHY is this not the same? How could it not be? What am I understanding and visualizing wrong here?

enter image description here


UPDATE: Here's another perspective. The tutorial at lodev.org has another way of handling the fisheye effect which confuses me in the same way. This one relies on distance vectors more than angles and calculates the perpendicular distance to the wall according to the below formulas where mapX is the position of the player, rayPosX is the position of the wall that has been hit by a ray, and rayDirX is the direction of the ray (along with its Y counterparts of course). (1-stepX)/2 is simply a way of adding 1 if the ray is on the left side of the field of view. By the same logic as in the above tutorial, the perpendicular distance is simply mapX - rayPosX in my world. Why does rayDirX need to be divided to it?

//Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
if (side == 0)
      perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
else
      perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
share|improve this question
    
"Yet, this clearly isn't the case according to the tutorial." What makes you say this? It appears to be the case and doesn't appear to be contradicted by the tutorial. –  MaulingMonkey Dec 10 '12 at 2:59
    
Because the tutorial continues with "Thus to remove the viewing distortion, the resulting distance obtained from equations in Figure 17 must be multiplied by cos(BETA)." Figure 17 being the first screenshot in my question. You're supposed to do this rather than just simply taking Py - Dy. –  mattboy Dec 10 '12 at 3:15
    
I think you might be reading a little too much into the wording. If you can calculate Py - Dy directly, that's entirely an option. With 'traditional' GPU rasterizeration systems for example, you're typically transforming everything into camera space, making Py - Dy trivial to calculate. Those transformations typically involve a 4x4 matrix built up from other matricies which happen to involve cos(θ) sin(θ) terms. On the other hand if you're not already in camera space and aren't planning on transforming everything to it and your camera isn't axis aligned, how do you calculate Py-Dy (in 3D)? –  MaulingMonkey Dec 10 '12 at 6:01
    
Py and Dy are already calculated and known at this point in the tutorial. In fact you can't calculate the distance in figure 17 without them. Why does the figure 17 distance need to be calculated at all when Py-Dy is (supposedly) always the correct length in the end? –  mattboy Dec 10 '12 at 7:23
    
I just added another example to the question from a different tutorial. –  mattboy Dec 10 '12 at 7:42
add comment

1 Answer

up vote 1 down vote accepted

I understand it well enough now. What I described in the question only applies when facing perfectly upwards/downwards or to the left/right. When the player faces any other direction than this however, you of course have to convert the X or Y distance to the larger, real perpendicular distance of the camera plane, hence the additions to the formulas. I knew it was simple!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.