I have an issue to find the correct height of walls to make them straight in raycasting rendering.

This is how I calculate the height of the wall which is h_seen:

dist_w = sqrt(pow((w->cam->position.x - w->cam->rays[i].endPoint.x), 2) + pow((w->cam->position.y - w->cam->rays[i].endPoint.y), 2));
distortion = dist_w * tCos(w->cam->fov / 2 - (i * w->cam->fov / WIN_W));
if (distortion)
    h_seen = dist_c * wall_h / distortion;
//printf("h_seen = %f\n", h_seen);
y = cam_h - (h_seen / 2) - 1;

This is a screenshot of the problem enter image description here I have fisheye effect, if i use depth directly

    if (l == 0)
        raytravel.y = w->cam->rays[i].endPoint.y - w->cam->position.y;
        raytravel.x = w->cam->rays[i].endPoint.x - w->cam->position.x;
        depth = raytravel.x * dir.x + raytravel.y * dir.y;
        h_seen = dist_c * wall_h / depth;
        y = cam_h - (h_seen / 2) - 1;
        if (hit == 1)
            while (++y < (cam_h + (h_seen / 2)))
                put_pixel_img(w, WIN_W - i + WIDTH_MM, y + 150, 0xff0000);

enter image description here

// Direction of each ray inside the while loop

if ((hit = intersection(w, l, &dir)))
        w->cam->rays[i].endpoint = w->cam->intersection;
        w->cam->rays[i].endpoint.x = w->cam->position.x + w->cam->raylength * tcos((w->cam->angle + w->cam->fov / 2) - (i * (w->cam->fov / limit)));
        w->cam->rays[i].endpoint.y = w->cam->position.y + w->cam->raylength * tsin((w->cam->angle + w->cam->fov / 2) - (i * (w->cam->fov / limit))); // limit is just the screen width
  • \$\begingroup\$ What data types are each of these variables? Is there a chance you're getting any integer rounding earlier in the computation than you wanted it? \$\endgroup\$ – DMGregory Mar 30 '19 at 19:19
  • \$\begingroup\$ they are doubles and the only int that I use is the pixel to draw! \$\endgroup\$ – Num Lock Mar 30 '19 at 19:27
  • \$\begingroup\$ Can you show us how you're choosing the direction to shoot each ray? \$\endgroup\$ – DMGregory Mar 31 '19 at 13:15
  • \$\begingroup\$ Looks like you're still fanning out your rays by equal angular spacing. Remember I told you in the comments below that this choice is not correct for rendering on a flat screen. It also looks like you might be using the ray direction in your depth calculation, instead of the camera's forward vector (which should not vary from one ray to the next) \$\endgroup\$ – DMGregory Mar 31 '19 at 14:22
  • \$\begingroup\$ Yeah! It was my bad, now the fisheye effect is removed so thank you but the walls are not straight when i look along a wall, you gave me this link gamedev.stackexchange.com/a/156853/39518 but I don't understand your variables forwrd_x, forward_y, right_x and right_y and mostly the way you compute them. \$\endgroup\$ – Num Lock Mar 31 '19 at 14:49

You can simplify your calculation of "distortion," and get rid of some extra trigonometry & divisions, by recognizing that it's actually the depth of the hit point along your camera's forward direction. So, if you keep a unit vector in the direction the camera is facing...

// Vector from the camera to the ray hit using vector subtraction.
rayTravel = w->cam->rays[i].endPoint - w->cam->position;

// Dot product of ray onto camera's unit forward vector.
depth = rayTravel.x * w->cam->forward.x + rayTravel.y * w->cam->forward.y;

// Visible wall height is proportional to true height divided by depth.
h_seen = dist_c * wall_h / depth;

I don't have enough of your raycaster to verify whether this distortion calculation was the source of the problem, but this simplification should at least reduce the surface area for bugs and help narrow down the cause further. ;)

  • \$\begingroup\$ Can I send you my project in DM to verify this ? I have been looking all day to fix this. \$\endgroup\$ – Num Lock Mar 30 '19 at 19:35
  • \$\begingroup\$ No, but if you find you're not getting answers that adequately address your problem, you can update your question to include a Minimal, Complete, Verifiable Example - enough detail for users to be able to reproduce the same effect in their own projects. \$\endgroup\$ – DMGregory Mar 30 '19 at 19:39
  • \$\begingroup\$ @NumLock: From your edit, it looks like you've added the depth value to your distortion calculation. This is incorrect. depth is to be used instead of distortion, as shown in the answer. Note how h_seen is computed directly from dist_c, wall_h, and depth, with no distortion variable at all. \$\endgroup\$ – DMGregory Mar 30 '19 at 20:33
  • \$\begingroup\$ Well! It feels like my understanding of the projection is wrong then? The distortion that i used is to remove the fisheye effect, so that's wrong and how am i supposed to get out the fishbowl? \$\endgroup\$ – Num Lock Mar 30 '19 at 21:00
  • \$\begingroup\$ See this earlier answer about this topic. The short answer is that thinking of your rays as being fired at equal angular increments is usually not what you want. If you're drawing on a flat screen, then the angle between pixels at the edges of the screen as seen from the viewer's eye is actually smaller than the angle between adjacent pixels near the middle of the screen. \$\endgroup\$ – DMGregory Mar 30 '19 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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