关于opengl光线追踪的几个问题
我需要进行有限形式的光线追踪。我不需要反思。我只需要改变像素的颜色,具体取决于它如何经过对象和折射。我也只需要测试射线与球体和圆盘之间的相交,不需要其他任何东西。
这是我的着色器中的主要功能:
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);
}
}
会产生可见的圆盘,而使用实际半径则不会产生任何结果。
I need to do a limited form of ray tracing. I do not need reflections. I only need to change the color of a pixel, depending on how it passes by an object, and refraction. I also only need to test for intersections between the ray and spheres and disks, nothing else.
This is the main function in my shader:
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);
}
My first question is regarding the origin of the ray. How do I get its location? Right now, I just fiddle around until it looks right, but if I change the width or height of the screen I have to play around until it looks right.
My second question is about the intersection between a ray and a disk. I do this by first checking to see if the ray intersects a plane and then if the intersection point is within the radius of the disk.
My code looks like this
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);
}
}
The problem is that if bodies[count].radius is less than or equal to the z-position of the ray's origin then nothing shows up. So
if(det>0)
{
if(distance(det*ray.direction,bodies[count].position)<=.76)
{
return vec4(1.0,0.0,0.0,1.0);
}
}
results in visible disks, while using the actual radius results in nothing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
关于你的第二个问题:不要使用距离,使用平方距离。它的处理速度更快,我怀疑它可以解决您的问题。
As to your second question: don't use a distance, use a squared distance. It's faster processing, and I suspect it may solve your problem.
光线的原点实际上取决于您,但是我建议您指定原点,以便像素位置与原点和对象的距离大约相等。
请注意光线的方向,这意味着您要查看的物体必须位于相机前面。 (发送的光线必须击中物体。)
Origin of the ray really depends on you however I recommend you to specify the origin point such that the pixel positions are approximately equidistant from the origin and the objects.
Be careful about the direction of the ray meaning that the objects you are trying to see must be in front of the camera. (The rays that are sent must hit the objects.)
射线和平面的交点计算如下:
您的函数 intersectPlane 正确计算了从射线原点到平面交点的距离,但没有计算交点在将其与磁盘中心进行比较之前。
要测试交点是否在半径内,您必须执行以下操作:
像这样调整您的代码:
The intersection point of a ray and a plane is calculated as follows:
Your function
intersectPlane
calculates the distance from the origin of the ray to the intersection point at the plane correctly, but you do not calculate the intersection point before you compare it to the center of the disks.To test if the intersection point is within the radius you have to do the following:
Adapt your code like this: