|
| 1 | +using GeometryBasics, LinearAlgebra, Trace, BenchmarkTools |
| 2 | +using ImageShow |
| 3 | +using Makie |
| 4 | +include("./../src/gpu-support.jl") |
| 5 | + |
| 6 | +LowSphere(radius, contact=Point3f(0)) = Sphere(contact .+ Point3f(0, 0, radius), radius) |
| 7 | + |
| 8 | +function tmesh(prim, material) |
| 9 | + |
| 10 | + prim = prim isa Sphere ? Tesselation(prim, 64) : prim |
| 11 | + mesh = normal_mesh(prim) |
| 12 | + m = Trace.create_triangle_mesh(mesh) |
| 13 | + return Trace.GeometricPrimitive(m, material) |
| 14 | +end |
| 15 | + |
| 16 | +material_red = Trace.MatteMaterial( |
| 17 | + Trace.ConstantTexture(Trace.RGBSpectrum(0.796f0, 0.235f0, 0.2f0)), |
| 18 | + Trace.ConstantTexture(0.0f0), |
| 19 | +) |
| 20 | + |
| 21 | +begin |
| 22 | + s1 = tmesh(LowSphere(0.5f0), material_red) |
| 23 | + s2 = tmesh(LowSphere(0.3f0, Point3f(0.5, 0.5, 0)), material_red) |
| 24 | + s3 = tmesh(LowSphere(0.3f0, Point3f(-0.5, 0.5, 0)), material_red) |
| 25 | + s4 = tmesh(LowSphere(0.4f0, Point3f(0, 1.0, 0)), material_red) |
| 26 | + |
| 27 | + ground = tmesh(Rect3f(Vec3f(-5, -5, 0), Vec3f(10, 10, 0.01)), material_red) |
| 28 | + back = tmesh(Rect3f(Vec3f(-5, -3, 0), Vec3f(10, 0.01, 10)), material_red) |
| 29 | + l = tmesh(Rect3f(Vec3f(-2, -5, 0), Vec3f(0.01, 10, 10)), material_red) |
| 30 | + r = tmesh(Rect3f(Vec3f(2, -5, 0), Vec3f(0.01, 10, 10)), material_red) |
| 31 | + bvh = Trace.BVHAccel([s1, s2, s3, s4, ground, back, l, r]) |
| 32 | + res = 512 |
| 33 | + resolution = Point2f(res) |
| 34 | + f = Trace.LanczosSincFilter(Point2f(1.0f0), 3.0f0) |
| 35 | + film = Trace.Film(resolution, |
| 36 | + Trace.Bounds2(Point2f(0.0f0), Point2f(1.0f0)), |
| 37 | + f, 1.0f0, 1.0f0, |
| 38 | + "shadows_sppm_res.png", |
| 39 | + ) |
| 40 | + screen_window = Trace.Bounds2(Point2f(-1), Point2f(1)) |
| 41 | + cam = Trace.PerspectiveCamera( |
| 42 | + Trace.look_at(Point3f(0, 4, 2), Point3f(0, -4, -1), Vec3f(0, 0, 1)), |
| 43 | + screen_window, 0.0f0, 1.0f0, 0.0f0, 1.0f6, 45.0f0, film, |
| 44 | + ) |
| 45 | + lights = ( |
| 46 | + # Trace.PointLight(Vec3f(0, -1, 2), Trace.RGBSpectrum(22.0f0)), |
| 47 | + Trace.PointLight(Vec3f(0, 0, 2), Trace.RGBSpectrum(10.0f0)), |
| 48 | + Trace.PointLight(Vec3f(0, 3, 3), Trace.RGBSpectrum(25.0f0)), |
| 49 | + ) |
| 50 | + img = zeros(RGBf, res, res) |
| 51 | +end |
| 52 | + |
| 53 | +@inline function get_camera_sample(p_raster::Point2) |
| 54 | + |
| 55 | + p_film = p_raster .+ rand(Point2f) |
| 56 | + p_lens = rand(Point2f) |
| 57 | + Trace.CameraSample(p_film, p_lens, rand(Float32)) |
| 58 | +end |
| 59 | + |
| 60 | +using KernelAbstractions.Extras.LoopInfo: @unroll |
| 61 | + |
| 62 | +function simple_shading(bvh, shape, ray, si, l, depth, max_depth, lights) |
| 63 | + core = si.core |
| 64 | + n = si.shading.n |
| 65 | + wo = core.wo |
| 66 | + # Compute scattering functions for surface interaction. |
| 67 | + si = Trace.compute_differentials(si, ray) |
| 68 | + mat = Trace.get_material(bvh, shape) |
| 69 | + if mat.type === Trace.NO_MATERIAL |
| 70 | + return l |
| 71 | + end |
| 72 | + bsdf = mat(si, false, Trace.Radiance) |
| 73 | + # Compute emitted light if ray hit an area light source. |
| 74 | + l += Trace.le(si, wo) |
| 75 | + # Add contribution of each light source. |
| 76 | + @unroll for light in lights |
| 77 | + sampled_li, wi, pdf, vt = Trace.sample_li( |
| 78 | + light, core, rand(Point2f), |
| 79 | + ) |
| 80 | + (Trace.is_black(sampled_li) || pdf ≈ 0.0f0) && continue |
| 81 | + f = bsdf(wo, wi) |
| 82 | + if !Trace.is_black(f) && !Trace.intersect_p(bvh, Trace.spawn_ray(vt.p0, vt.p1)) |
| 83 | + l += f * sampled_li * abs(wi ⋅ n) / pdf |
| 84 | + end |
| 85 | + end |
| 86 | + # if depth + 1 <= max_depth |
| 87 | + # # Trace rays for specular reflection & refraction. |
| 88 | + # l += specular_reflect(bsdf, i, ray, si, scene, depth) |
| 89 | + # l += specular_transmit(bsdf, i, ray, si, scene, depth) |
| 90 | + # end |
| 91 | + return l |
| 92 | +end |
| 93 | + |
| 94 | + |
| 95 | +@inline function trace_pixel(camera, bvh, xy, lights) |
| 96 | + pixel = Point2f(Tuple(xy)) |
| 97 | + camera_sample = get_camera_sample(pixel) |
| 98 | + ray, ω = Trace.generate_ray_differential(camera, camera_sample) |
| 99 | + l = Trace.RGBSpectrum(0.0f0) |
| 100 | + if ω > 0.0f0 |
| 101 | + hit, shape, si = Trace.intersect!(bvh, ray) |
| 102 | + if hit |
| 103 | + l = simple_shading(bvh, shape, ray, si, l, 1, 8, lights) |
| 104 | + end |
| 105 | + end |
| 106 | + return RGBf(l.c...) |
| 107 | +end |
| 108 | + |
| 109 | +using KernelAbstractions |
| 110 | +import KernelAbstractions as KA |
| 111 | + |
| 112 | + |
| 113 | +@kernel function ka_trace_image!(img, camera, bvh, lights) |
| 114 | + idx = @index(Global, Linear) |
| 115 | + if checkbounds(Bool, img, idx) |
| 116 | + xy = Tuple(divrem(idx, size(img, 1))) |
| 117 | + @inbounds img[idx] = trace_pixel(camera, bvh, xy, lights) |
| 118 | + end |
| 119 | +end |
| 120 | + |
| 121 | +function launch_trace_image_ir!(img, camera, bvh, lights) |
| 122 | + backend = KA.get_backend(img) |
| 123 | + kernel! = ka_trace_image!(backend) |
| 124 | + open("test2.ir", "w") do io |
| 125 | + CUDA.@device_code_llvm io begin |
| 126 | + kernel!(img, camera, bvh, lights, ndrange=size(img), workgroupsize=(16, 16)) |
| 127 | + end |
| 128 | + end |
| 129 | + AMDGPU.synchronize(; stop_hostcalls=false) |
| 130 | + return img |
| 131 | +end |
| 132 | +function launch_trace_image!(img, camera, bvh, lights) |
| 133 | + backend = KA.get_backend(img) |
| 134 | + kernel! = ka_trace_image!(backend) |
| 135 | + kernel!(img, camera, bvh, lights, ndrange=size(img), workgroupsize=(16, 16)) |
| 136 | + KA.synchronize(backend) |
| 137 | + return img |
| 138 | +end |
| 139 | +# using AMDGPU |
| 140 | +# ArrayType = ROCArray |
| 141 | +using CUDA |
| 142 | +ArrayType = CuArray |
| 143 | +preserve = [] |
| 144 | +gpu_bvh = to_gpu(ArrayType, bvh; preserve=preserve); |
| 145 | +gpu_img = ArrayType(zeros(RGBf, res, res)); |
| 146 | +# launch_trace_image!(img, cam, bvh, lights); |
| 147 | +# @btime launch_trace_image!(img, cam, bvh, lights); |
| 148 | +# @btime launch_trace_image!(gpu_img, cam, gpu_bvh, lights); |
| 149 | +launch_trace_image!(gpu_img, cam, gpu_bvh, lights); |
0 commit comments