Я пишу raytracer на F # и пытаюсь использовать многопоточность на этапе выборки Монте-Карло.
Однако, когда я запускаю свой код с асинхронным вариантом, программа никогда не возвращается и работает бесконечно.
Мой код В настоящее время:
let rec rayTrace previousTraceDepth ((ray : Ray) , (accEmitted : Color) , (accScatter :Color)) =
if previousTraceDepth > maxTraceDepth
then
accEmitted + backgroundColor*accScatter
else
let newTraceDepth = previousTraceDepth + 1us
let (realSolution,t,surface) = findClosestIntersection ray surfaces
let surfaceGeometry : Hitable = surface.Geometry
if surfaceGeometry.IntersectionAcceptable realSolution t 1.0f (PointForRay ray t)
then
let emittedShading = surface.Emitted
let e = accEmitted + accScatter*emittedShading
let mcSamples = surface.SampleCount
//Synchronous
// let mutable totalShading = e/surface.MCNormalization
// for _ in 1..mcSamples do
// let (doesRayContribute,outRay,cosOfIncidence) = surface.Scatter ray t ((int)newTraceDepth)
// let shading = surface.BRDF*cosOfIncidence / (surface.PDF*surface.MCNormalization)
// let s = accScatter*shading
// totalShading <- totalShading + (rayTrace newTraceDepth (outRay , e , s))
// totalShading
let eMCAdjusted = e / surface.MCNormalization
let shadingSamplesAsync =
[|
for _ in 1..mcSamples -> async {
let (doesRayContribute,outRay,cosOfIncidence) = surface.Scatter ray t ((int)newTraceDepth)
let shading = surface.BRDF*cosOfIncidence / (surface.PDF*surface.MCNormalization)
let s = accScatter*shading
return rayTrace newTraceDepth (outRay,e,s)
}|]
if Array.isEmpty shadingSamplesAsync then
e
else
let shadingSamplesSync = shadingSamplesAsync |> Async.Parallel |> Async.RunSynchronously
Array.sumBy (fun x -> eMCAdjusted + x) shadingSamplesSync
else
accEmitted + backgroundColor*accScatter
Как сделать этот метод асинхронным рекурсивным?