I've been writing a raycaster since 2 days ago. I am using a simple and fast algorithm for detecting walls using rays. It's C btw. My question is: what check should I use to detect what face of the wall did the ray hit? I've been thinking about checking if the ray Y component is larger than the ray X component, and that would mean that I've hit the left and right faces. Right? I'm not really sure. Full code here:
double rayAngle, wallX, wallY, rayX, rayY, h, distance, lineHeight, lineOffset, cameraAngle, shadeDistance;
for (double ray = 0; ray < FOV * RAY_PER_DEG; ray++) // we want to raycast FOV * RAYS_PER_DEG rays
{
rayAngle = playerAngle + TO_RADIANS(ray / RAY_PER_DEG - FOV / 2); // set the ray angle derived from the ray index
wallX = playerX; // set current wall coordinates to player's
wallY = playerY; //
rayY = sin(rayAngle) * DISTANCE_COEFFICIENT; // use vector decomposition to determine X and Y components of the ray
rayX = cos(rayAngle) * DISTANCE_COEFFICIENT; //
for(distance = 0; distance < MAX_DISTANCE; distance++) // check for ray collision
{
wallX = wallX + rayX; // increase wall coordinates
wallY = wallY + rayY;
if (wallX < mapWidth && wallY < mapHeight && // check for wall boundaries
wallX >= 0 && wallY >= 0 &&
mapWalls[(int)wallY * mapHeight + (int)wallX]) // check for wall to be present
{
break;
}
}
// fisheye compensation
cameraAngle = playerAngle - rayAngle; // determine the camera angle
WRAP_AROUND_RADIANS(cameraAngle);
distance = distance * cos(cameraAngle); // adjust distance by x component of camera angle
lineHeight = WALL_HEIGHT * MAX_WALL_HEIGHT / distance;
lineOffset = WALL_HEIGHT - lineHeight/2; // move the line at middle
// draw the ray on the map
shadeDistance = 1 / distance;
glLineWidth(1 / RESOLUTION);
glBegin(GL_LINES);
glColor3f(shadeDistance * SHADE_COEFFICIENT, 0, 0); // wall
glVertex2f(ray / RESOLUTION, lineHeight + lineOffset);
glVertex2f(ray / RESOLUTION, lineOffset);
glColor3f(0, shadeDistance * SHADE_COEFFICIENT, 0); // floor
glVertex2f(ray / RESOLUTION, lineOffset);
glVertex2f(ray / RESOLUTION, 0);
glEnd();
}
https://pastebin.com/BsNYvXPf Feel free to tell me anything about the code. Edit: I have to know this to implement texture mapping.
Represent ray in parametric coordinates
x = x0 + dx * t
y = y0 + dy * t
In your case dx=cos(rayAngle), dy=sin(rayAngle)
, and (dx,dy)
is unit direction vector.
Check intersections with vertical and horizontal line
x0 + dx * t1 = wallX
y0 + dy * t2 = wallY
get t1, t2
t1 = (wallX - x0) / dx
t2 = (wallY - y0) / dy
and smaller value from t1,t2
tells us what wall will be met first.
increase wall coordinates
- do walls move?