[MetalKit]14-Ray-tracing-in-a-Swift-playground5射线追踪5
本系列文章是對 metalkit.org 上面MetalKit內容的全面翻譯和學習.
MetalKit系統文章目錄
讓我們繼續上周的工作完成ray tracer射線追蹤器.現在我們知道如何生成不同材料的球體,也知道了如何從不同角度來觀察它們,讓我們再看看如何生成更多的球體.
在pixel.swift中創建一個random_scene() 方法:
func random_scene() -> Hitable_list {var objects = [Hitable]()objects.append(Sphere(c: float3(0, -1000, 0), r: 1000, m: Lambertian(albedo: float3(0.5, 0.5, 0.5))))for a in -2..<3 {for b in -2..<3 {let materialChoice = drand48()let center = float3(Float(a) + 0.9 * Float(drand48()), 0.2, Float(b) + 0.9 * Float(drand48()))if length(center - float3(4, 0.2, 0)) > 0.9 {if materialChoice < 0.8 { // diffuselet albedo = float3(Float(drand48()) * Float(drand48()), Float(drand48()) * Float(drand48()), Float(drand48()) * Float(drand48()))objects.append(Sphere(c: center, r: 0.2, m: Lambertian(albedo: albedo)))} else if materialChoice < 0.95 { // metallet albedo = float3(0.5 * (1 + Float(drand48())), 0.5 * (1 + Float(drand48())), 0.5 * (1 + Float(drand48())))objects.append(Sphere(c: center, r: 0.2, m: Metal(albedo: albedo, fuzz: Float(0.5 * drand48()))))} else { // glassobjects.append(Sphere(c: center, r: 0.2, m: Dielectric()))}}}}objects.append(Sphere(c: float3(0, 0.7, 0), r: 0.7, m: Dielectric()))objects.append(Sphere(c: float3(-3, 0.7, 0), r: 0.7, m: Lambertian(albedo: float3(0.4, 0.2, 0.1))))objects.append(Sphere(c: float3(3, 0.7, 0), r: 0.7, m: Metal(albedo: float3(0.7, 0.6, 0.5), fuzz: 0.0)))return Hitable_list(list: objects) } 復制代碼這個方法生成了25個小球體,并用隨機值給它們賦上不同材料,lambertian, metal 或glass.然后把這些球體添加到一個列表里,作為返回值.我們還添加一個大球體,還有我們初始的3個小球體.
然后在imageFromPixels() 方法里,我們將以前添加球體的代碼:
var objects = [Hitable]() var object = Sphere(c: float3(0, -100.5, -1), r: 100, m: Lambertian(albedo: float3(0.7, 0.23, 0.12))) objects.append(object) object = Sphere(c: float3(1, 0, -1), r: 0.5, m: Metal(albedo: float3(0.8, 0.6, 0.2), fuzz: 0.1)) objects.append(object) object = Sphere(c: float3(-1, 0, -1), r: 0.5, m: Dielectric()) objects.append(object) object = Sphere(c: float3(-1, 0, -1), r: -0.49, m: Dielectric()) objects.append(object) object = Sphere(c: float3(0, 0, -1), r: 0.5, m: Lambertian(albedo: float3(0.24, 0.5, 0.15))) objects.append(object) let world = Hitable_list(list: objects) 復制代碼替換為一行,創建隨機場景:
let world = random_scene() 復制代碼一般情況下,現在我會告訴你可以渲染場景了,但是我從?hyperjeff那里學到了一點加速的方法,可以讓我們更快得到更好的質量的圖片.還是在imageFromPixels() 方法里,將外層循環的第一行:
for i in 0..<width { 復制代碼替換為下面的代碼:
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) dispatch_apply(width, queue) { i in 復制代碼通過使用GCD多線程,渲染速度提高了3倍!在playground主頁面中,看看新生成的圖像:
這張圖片創建參數是:ns=50,球體產生器范圍 -7..<7,圖片分辨率800 x 400.整個渲染花費752秒,如果你想要快一些,5秒渲染的話,我建議使用參數:ns=10,球體產生器范圍 -2..<3,圖片分辨率400 x 200. 源代碼source code?已發布在Github上.
下次見!
總結
以上是生活随笔為你收集整理的[MetalKit]14-Ray-tracing-in-a-Swift-playground5射线追踪5的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态规划实现斐波那契数列求解
- 下一篇: 【Compiling Swift sou