C++光线追踪开发求助:射线与立方体相交功能实现
轴对齐立方体射线相交实现方案
首先明确你的Cube类中,Position作为立方体的中心,Size是各轴向的边长(比如Size.x对应宽度、Size.y对应高度、Size.z对应深度),立方体的轴向边界可通过以下方式计算:
glm::vec3 minBound = Position - Size * 0.5f; glm::vec3 maxBound = Position + Size * 0.5f;
接下来用Slab相交算法实现Intersection函数,这是轴对齐立方体最高效的相交计算方式,代码直接适配你的类结构:
float Cube::Intersection(Ray ray) { // 计算立方体的轴向边界 glm::vec3 minBound = Position - Size * 0.5f; glm::vec3 maxBound = Position + Size * 0.5f; // 计算射线与每个轴平面的t值范围 glm::vec3 tMin = (minBound - ray.Origin) / ray.Direction; glm::vec3 tMax = (maxBound - ray.Origin) / ray.Direction; // 确保tNear是进入平面的t值,tFar是离开平面的t值(处理射线方向为负的情况) glm::vec3 tNear = glm::min(tMin, tMax); glm::vec3 tFar = glm::max(tMin, tMax); // 找到最晚进入的t(射线进入立方体的时间)和最早离开的t(射线离开立方体的时间) float tEnter = glm::max(glm::max(tNear.x, tNear.y), tNear.z); float tExit = glm::min(glm::min(tFar.x, tFar.y), tFar.z); // 相交判断逻辑 // 1. tExit < 0:立方体在射线后方,无交点 // 2. tEnter > tExit:射线未穿过立方体,无交点 // 3. tEnter < 0:射线起点在立方体内,返回0表示命中 if (tExit < 0.0f || tEnter > tExit) { return -1.0f; } else { return tEnter < 0.0f ? 0.0f : tEnter; } }
关键细节说明
- 射线方向为0的情况:glm的除法会自动处理(对应轴的t值会是无穷大/小,后续min/max操作会忽略该轴的影响,相当于射线平行于该轴平面)
- 内部命中逻辑:如果希望射线起点在立方体内时返回-1,可修改返回逻辑为
return (tEnter > 0.0f && tEnter <= tExit) ? tEnter : -1.0f; - 与Sphere类逻辑对齐:返回值为最近的正距离,无交点返回-1
内容的提问来源于stack exchange,提问作者DevStuffz
相关产品推荐
相关产品推荐

