2017-02-19 6 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 

EDIT

ここに.cubeファイルを向けるだろう完全なパーサです

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

ああいいえ...このプロパティを設定する方法は2通りあります。 1つは正方形のイメージを与え、1つは3Dカラールックアップテーブルです。 3Dカラールックアップテーブルを検索し、いくつかの.cubeファイルをダウンロードします。私はこれらのファイルをこのcolorGradingに設定できると思う。しかし医者はメタルを使うべきだと言う。私はそれをする方法を正確に理解していません。 – HaoDong

+0

私はいつもエラー:エラー:LUTのサイズの前にデータを取得しました LUTを正常に解析しなかった場合 – HaoDong

+0

ファイル 'https:// pan.baidu.com/s/1bp27u0n'があります – HaoDong

関連する問題