我正在使用Microsoft的光线追踪软件实现示例。其实这个例子是关于多线程的,但是吸引我的是3D渲染算法。
这是方法。如果是尾递归,我可以很容易地做到这一点,但我还不能在这里做到。
using System.Numerics;
private const int maxDepth = 6;
private Vector3 TraceRay(Ray ray, Scene scene, int depth)
{
(SceneObject obj, float distance) = ClosestIntersection(ray, scene);
if (obj is null)
return Vector3.Zero;
Vector3 pos = distance * ray.Direction + ray.Start;
Vector3 normal = obj.Normal(pos);
Vector3 reflectDir = Vector3.Reflect(ray.Direction, normal);
Vector3 color = GetNaturalColor(obj, pos, normal, reflectDir, scene);
if (depth >= maxDepth)
return color;
// типы = float Vector3
return color + obj.Surface.Reflect(pos) * obj.Surface.Diffuse(pos) * TraceRay(new Ray(pos, reflectDir), scene, depth + 1);
}
初始调用:
Vector3 color = TraceRay(new Ray(camera.Pos, GetPoint(x, y, camera)), scene, 0);
是否可以在不分配额外内存的情况下进行线性优化?或者有一个选择,但这样它至少会更快一点。
我不会展示从这里调用的方法和我的数据结构,它们不会影响问题的本质。但如果你需要 - 写,我会补充这个问题。
这里是光束。
readonly ref struct Ray
{
public readonly Vector3 Start;
public readonly Vector3 Direction;
public Ray(Vector3 start, Vector3 direction)
{
Start = start;
Direction = direction;
}
}
顺便说一句,我推导出这样的像素颜色公式
c0 + r0 * (c1 + r1 * (c2 + r2 * (c3 + r3 * (c4 + r4 * (c5 + r5 * (c6))))))
cN
- 与照明相关的物体颜色
rN
- 反射系数
N
- 迭代
总的来说,不出所料,没有发现任何魔法。
我们设法摆脱了递归,但内存分配......在堆栈上。:)
性能略有提高,几乎在测量误差范围内。但我还没有想出更好的办法。