英文:
Is there a more efficient way to do raycasting?
问题
以下是您要翻译的部分:
这里有个故事。我想学习图形编程,但发现OpenGL的语法很难,所以我在.Net C#中创建了一个渲染器,将图像保存到位图中。我找不到关于如何进行光线投射(raycasting)的信息,因此我想出了自己的方法,通过在循环中将一个点从相机移动到近平面上的某一点,然后继续移动直到它击中某物或到达远平面。以下是代码的简化片段:
// 遍历近平面上的每个点,根据分辨率进行划分
for (int y = 0; y < nearPlanePoints.GetLength(1); y++)
{
for (int x = 0; x < nearPlanePoints.GetLength(0); x++)
{
bool doBreak = false;
// 获取从相机指向近平面上当前像素的方向
Vector3 rayDirection = new Vector3(nearPlanePoints[x,y], nearPlane).Normalized;
// 移动点,每次移动rayStep距离,直到达到远平面
for (float z = 0; z <= farPlane; z+=rayStep)
{
Vector3 point = position + rayDirection * z;
// 检查与“场景”中对象的碰撞(由于我使用半径,我只能渲染球体)
for (int i = 0; i < sceneObjects.Length; i++)
{
if (Vector3.Distance(point, sceneObjects[i].position) <= sceneObjects[i].radius)
{
// 当碰撞时,将相应像素的颜色设置为对象的颜色
renderedImage[(y * Program.image_width) + x] = sceneObjects[i].color;
// 不再继续搜索碰撞
doBreak = true;
break;
}
}
if (doBreak)
break;
else
// 如果搜索结束没有碰撞,将相应像素的颜色设置为预定义的背景颜色
renderedImage[(y * Program.image_width) + x] = backgroundColor;
}
}
}
return renderedImage;
问题在于,当远平面非常远并且不与任何物体碰撞时,光线投射会变得明显较慢,这让我相信可能有更高效的光线投射方法。当然,它在CPU上运行也会变慢,但我无法使用任何.Net GPU API(只能使用.Net提供的默认命名空间),所以无法改变这一点。
如果您可以指导我找到答案的网站,或者任何可以在这个旅程中帮助我的网站,那将不胜感激!
我一直在努力谷歌如何做事,但更多时候我找不到任何信息,只能自己想出解决方案,因此我的方法可能非常低效。非常感谢您的理解。
提前感谢您的任何回答!
英文:
Here's the story. I wanted to get into graphics programming, but found OpenGL's syntax hard, so I made a renderer in .Net C# that saves the image into a bitmap. I couldn't find any information on how to do raycasting, so I came up with my own way to do it, where I move a point with a for loop from the camera towards a point on the nearplane and beyond until it either hits something, or it reaches the far plane. Here's a simplified snippet of the code
// Go through every point on the near plane, divided by the resolution
for (int y = 0; y < nearPlanePoints.GetLength(1); y++)
{
for (int x = 0; x < nearPlanePoints.GetLength(0); x++)
{
bool doBreak = false;
// Get the direction from the camera towards the current pixel on the near plane
Vector3 rayDirection = new Vector3(nearPlanePoints[x,y], nearPlane).Normalized;
// Move the point by rayStep ammount until reaching the far plane
for (float z = 0; z <= farPlane; z+=rayStep)
{
Vector3 point = position + rayDirection * z;
// Check for collision with object in the "scene" (since I use radius, I can only render spheres)
for (int i = 0; i < sceneObjects.Length; i++)
{
if (Vector3.Distance(point, sceneObjects[i].position) <= sceneObjects[i].radius)
{
// When collides, paint the corresponding pixel to the color of the object
renderedImage[(y * Program.image_width) + x] = sceneObjects[i].color;
// Don't continue to search for collision
doBreak = true;
break;
}
}
if (doBreak)
break;
else
// If the search ended without a collision, paint the corresponding pixel to a predefined background color
renderedImage[(y * Program.image_width) + x] = backgroundColor;
}
}
}
return renderedImage;
The thing is, the raycasts get significantly slower when the far plane is really far and it doesn't collide with anything, leading me to believe that there might be a more efficient way to do raycasting. Of course, the fact that it runs on the CPU also makes it slower, however I am unable to use any of the .Net GPU APIs (I can only use the default namespaces offered by .Net), so that cannot be helped.
If you could direct me to a website where I can find an answer, or just any website that might help me with this journey in general, that would be greatly appreciated!
I've been trying my best to Google how I should do things, but more often than not, I couldn't find anything and I had to come up with a solution myself, so my methods may be incredibly inefficient. Thank you for understanding.
Thank you in advance for any answers!
答案1
得分: 0
我找到的有效方法受到一种叫做“射线行进”的技术的启发,在这种方法中,你找到最近的物体(在我的情况下是一个点减去它的半径),获取射线点与这个物体之间的距离,然后向前移动这么多距离,然后重复。
英文:
What I've found to work was inspired by a technique called ray marching, where you find the closest object (in my case a point minus it's radius), get the distance between the ray's point and this object, and move that much forward, then repeat.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论