【问题标题】:A few questions about ray tracing with opengl关于opengl光线追踪的几个问题
【发布时间】:2011-10-13 18:18:35
【问题描述】:

我需要进行有限形式的光线追踪。我不需要反思。我只需要更改像素的颜色,具体取决于它如何通过对象和折射。我也只需要测试射线与球体和圆盘之间的交叉点,没有别的。

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

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);
        }
}

问题在于,如果 body[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);
        }
}

会产生可见的圆盘,而使用实际半径则不会产生任何结果。

【问题讨论】:

    标签: opengl glsl raytracing


    【解决方案1】:

    关于你的第二个问题:不要使用距离,使用平方距离。它的处理速度更快,我怀疑它可以解决您的问题。

    【讨论】:

      【解决方案2】:
      1. 射线的原点确实取决于您,但我建议您指定原点,使像素位置与原点和对象的距离大致相等。

      2. 注意光线的方向,这意味着您要查看的对象必须在相机前面。 (发出的光线必须击中物体。)

      【讨论】:

        【解决方案3】:

        射线与平面的交点计算如下:

        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);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-03-21
          • 2013-08-27
          • 1970-01-01
          • 1970-01-01
          • 2015-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多