关于OpenGL的光线追踪,有几个问题。

7

我需要进行一种有限的光线追踪。我不需要反射。我只需要根据像素经过物体的方式以及折射来改变像素的颜色。我也只需要测试光线与球体和圆盘之间的相交情况,不需要其他。

以下是我的着色器中的主要功能:

void main(void)
{
    Ray ray;
    ray.origin=vec3(0.5,0.5,.75);

    ray.direction=vec3(gl_FragCoord.x/width,gl_FragCoord.y/height,-gl_FragCoord.z)-ray.origin;
    ray.direction=normalize(ray.direction);

    gl_FragColor=trace(ray);
}

我的第一个问题与光线的起源有关。我该如何获取它的位置?目前,我只是随便调整,直到看起来正确,但如果我改变屏幕的宽度或高度,我必须再次尝试调整。

我的第二个问题是关于光线和圆盘之间的交点。我首先检查光线是否与平面相交,然后检查交点是否在圆盘半径内。 我的代码如下:

float intersectPlane(Ray ray,vec3 point,vec3 normal)
{
    return dot(point-ray.origin,normal)/dot(ray.direction,normal);
}
...

det=intersectPlane(ray,bodies[count].position,vec3(0,0,1));
if(det>0)
{
        if(distance(det*ray.direction,bodies[count].position)<=bodies[count].radius) 
        {
            return vec4(1.0,0.0,0.0,1.0);
        }
}

问题在于,如果bodies[count].radius小于或等于射线起点的z位置,则什么也不会显示出来。因此,
if(det>0)
{
        if(distance(det*ray.direction,bodies[count].position)<=.76) 
        {
            return vec4(1.0,0.0,0.0,1.0);
        }
}

使用实际半径会导致没有结果,而使用可见的磁盘半径则会有结果。

3个回答

3

关于您的第二个问题:不要使用距离,而要使用平方距离。这样可以加快处理速度,并且我认为它可能会解决您的问题。


1
  1. 光线的起点取决于您,但我建议您指定起点,使得像素位置大致等距离于起点和物体之间。

  2. 注意光线的方向,也就是您想要看到的物体必须在相机前方。(发射的光线必须击中物体。)


1
射线与平面的交点计算方法如下:
dist = dot( plane_origin - ray.origin, plane_NV ) / dot( ray.direction, plane_NV );
plane_isect = ray.origin + ray.direction * dist;

您的函数intersectPlane正确计算了光线到平面交点处的距离,但在将其与圆盘中心进行比较之前,您没有计算交点。

要测试交点是否在半径内,请执行以下操作:

vec3 plane_isect = ray.origin + det * ray.direction;
if ( distance( plane_isect, bodies[count].position ) <= bodies[count].radius ) 

将您的代码适应为以下形式:
det = intersectPlane( ray, bodies[count].position, vec3(0,0,1) );
if ( det>0 )
{
    vec3 plane_isect = ray.origin + det * ray.direction;
    if ( distance( plane_isect, bodies[count].position ) <= bodies[count].radius ) 
    {
        return vec4(1.0,0.0,0.0,1.0);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接