提问人:Moldytzu 提问时间:10/26/2023 更新时间:10/26/2023 访问量:67
如何在光线投射器游戏引擎中检测光线撞到墙上的哪一侧?
How can I detect what side the ray has hit a wall in a raycaster game engine?
问:
从 2 天前开始,我一直在写光线投射器。我正在使用一种简单而快速的算法来使用射线检测墙壁。顺便说一句,这是 C。我的问题是:我应该使用什么检查来检测光线击中了墙壁的哪个面?我一直在考虑检查光线 Y 分量是否大于光线 X 分量,这意味着我已经击中了左右面。右?我不太确定。 完整代码在这里:
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请随时告诉我有关代码的任何信息。 编辑:我必须知道这一点才能实现纹理映射。
答:
1赞
MBo
10/26/2023
#1
以参数坐标表示射线
x = x0 + dx * t
y = y0 + dy * t
在你的例子中,并且是单位方向向量。dx=cos(rayAngle), dy=sin(rayAngle)
(dx,dy)
检查垂直线和水平线的交叉点
x0 + dx * t1 = wallX
y0 + dy * t2 = wallY
获取 T1、T2
t1 = (wallX - x0) / dx
t2 = (wallY - y0) / dy
而较小的值 from 告诉我们将首先遇到什么墙。t1,t2
increase wall coordinates
- 墙壁会移动吗?
评论
0赞
Moldytzu
10/26/2023
关于前 2 个方程,我真正应该对 t 使用什么?
0赞
MBo
10/26/2023
它只是参数。它在光线的开头为 0,并沿光线递增。参数 t=1 对应于距起点 1 的点,依此类推。
0赞
Moldytzu
10/26/2023
所以 x 和 y 将是最终的光线坐标,x0 和 y0 将是初始坐标(在我的情况下是玩家的),对吧?
0赞
MBo
10/26/2023
x 和 y 是每个参数(如函数)的当前坐标。 - 是的,玩家坐标x(t),y(t)
x0, y0
0赞
Moldytzu
10/26/2023
我更新了代码,它在某种程度上有效(它非常弯曲,并且在墙壁旁边有奇怪的伪影,而且播放器背面的墙壁甚至没有渲染)pastebin.com/XFyn0r0x imgur.com/a/q6CidC5(为什么 imgur 认为我的屏幕截图很辣?
评论