2017-02-19 29 views
2

最近,我在玩SceneKit,我找到了colorGrading屬性。該文檔說初始化3D類型的金屬質感

The contents value for this material property must be a 3D color lookup table, or a 2D texture image that represents such a table arranged in a horizontal strip.

和3D顏色查找表可以從金屬紋理中讀取。

You can provide data in this cubic format as a Metal texture with the type3D texture type.

那麼如何設置scnCamera.colorGrading.contents屬性。

回答

3

創建3D紋理與創建2D紋理非常相似,前提是您的緩衝區包含適當佈局的圖像數據。我假設你已經有了。以下是如何創建本身的質感,將數據複製到它,並將它設置爲顏色分級質地:

var dim = 16 

var values: UnsafeMutablePointer<Float> = ... // alloc and populate 3D array of pixels 

let textureDescriptor = MTLTextureDescriptor() 
textureDescriptor.textureType = .type3D 
textureDescriptor.pixelFormat = .rgba32Float 
textureDescriptor.width = dim 
textureDescriptor.height = dim 
textureDescriptor.depth = dim 
textureDescriptor.usage = .shaderRead 

let texture = device.makeTexture(descriptor: textureDescriptor) 

texture.replace(region: MTLRegionMake3D(0, 0, 0, dim, dim, dim), 
       mipmapLevel:0, 
       slice:0, 
       withBytes:values, 
       bytesPerRow:dim * MemoryLayout<Float>.size * 4, 
       bytesPerImage:dim * dim * MemoryLayout<Float>.size * 4) 

camera.colorGrading.contents = texture 

編輯

這裏有一個完整的解析器會變成一個.cube等文件轉換成MTLTexture適合於具有這種性質使用:

import Metal 

class AdobeLUTParser { 

    static func texture(withContentsOf url: URL, device: MTLDevice) -> MTLTexture? { 

     let lutString = try! NSString(contentsOf: url, encoding: String.Encoding.utf8.rawValue) 

     let lines = lutString.components(separatedBy: "\r\n") as [NSString] 

     var dim = 2 

     var values: UnsafeMutablePointer<Float>? = nil 
     var index = 0 

     for line in lines { 

      if line.length == 0 { continue; } // skip blanks 

      let firstChar = line.character(at: 0) 

      if firstChar < 58 /*':'*/ { 
       if values == nil { 
        print("Error: Got data before size in LUT") 
        break; 
       } 

       let numbers = line.components(separatedBy: " ") as [NSString] 
       if numbers.count == 3 { 
        let r = numbers[0].floatValue 
        let g = numbers[1].floatValue 
        let b = numbers[2].floatValue 
        let a = Float(1) 

        values![index * 4 + 0] = r 
        values![index * 4 + 1] = g 
        values![index * 4 + 2] = b 
        values![index * 4 + 3] = a 

        index += 1 
       } 
      } else { 
       if line.hasPrefix("LUT_3D_SIZE") { 
        let sizeString = line.components(separatedBy: " ")[1] as NSString 
        dim = Int(sizeString.intValue) 
        if dim < 2 || dim > 512 { 
         print("Error: insane LUT size: \(dim)") 
        } 
        let rawPointer = malloc(dim * dim * dim * 4 * MemoryLayout<Float>.size) 
        values = rawPointer!.bindMemory(to: Float.self, capacity: dim * dim * dim * 4) 
       } else if line.hasPrefix("LUT_1D_SIZE") { 
        print("Error: 1D LUTs not supported") 
        break 
       } 
      } 
     } 

     if values == nil { 
      print("Did not parse LUT successfully") 
      return nil 
     } 

     let textureDescriptor = MTLTextureDescriptor() 
     textureDescriptor.textureType = .type3D 
     textureDescriptor.pixelFormat = .rgba32Float 
     textureDescriptor.width = dim 
     textureDescriptor.height = dim 
     textureDescriptor.depth = dim 
     textureDescriptor.usage = .shaderRead 

     let texture = device.makeTexture(descriptor: textureDescriptor) 

     texture.replace(region: MTLRegionMake3D(0, 0, 0, dim, dim, dim), 
         mipmapLevel:0, 
         slice:0, 
         withBytes:values!, 
         bytesPerRow:dim * MemoryLayout<Float>.size * 4, 
         bytesPerImage:dim * dim * MemoryLayout<Float>.size * 4) 

     return texture 
    } 
} 

用法:

let mtlDevice = MTLCreateSystemDefaultDevice() 

let lutURL = Bundle.main.url(forResource: "MyGradingTexture", withExtension: "cube") 

let lutTexture = AdobeLUTParser.texture(withContentsOf: lutURL!, device: mtlDevice!) 

camera.colorGrading.contents = lutTexture 
+0

哦,不...醫生說有兩種方法來設置這個屬性。一個是給出一個方形圖像,一個是3D顏色查找表。我搜索3D顏色查找表並下載一些.cube文件。我想如果我可以將這些文件設置爲這個colorGrading。但醫生說應該使用金屬。我不準確地知道如何去做。 – HaoDong

+0

我總是得到錯誤'錯誤:在LUT的大小之前得到數據 沒有成功解析LUT' – HaoDong

+0

這裏是文件'https:// pan.baidu.com/s/1bp27u0n' – HaoDong