2014-11-02 48 views
1

我試圖用手動填充1D紋理並將該紋理傳遞給計算着色器(這些是我想通過代碼設置的2個像素,它們不代表任何圖像)。手動設置金屬1D紋理

由於金屬的例子目前量小,所有的例子我能找到對付2D紋理通過轉換加載UIImage原始字節的數據,而是創建一個虛擬UIImage載入紋理感覺就像一個黑客對我來說。

這是「幼稚」的方式,我開始用 -

... 
var manualTextureData: [Float] = [ 1.0, 0.0, 0.0, 1.0, 
            0.0, 0.0, 1.0, 1.0 ]; 
let region: MTLRegion = MTLRegionMake1D(0, textureDescriptor.width); 
myTexture.replaceRegion(region, mipmapLevel: 0, withBytes: &manualTextureData, bytesPerRow: 0); 

但金屬不着色器(它得到一個空的紋理,除了第一個值)識別這些值。

我很快意識到浮點數組可能必須轉換爲字節數組(例如UInt8),但無法找到將[Float]轉換爲[UInt8]的方法。

我考慮的另一種可能的選擇是使用一個CVPixelBuffer對象,但這也感覺就像解決問題的方法。

那麼最好的解決方法是什麼?

在此先感謝。

  • 請注意,我不熟悉Objective-C的,所以我不知道用CVPixelBuffer/UIImage是否是誇大了一些東西,應該是直接的。

回答

0

如果你想要一個浮點紋理bytesPerRow應該爲寬度乘以4,因爲float的大小爲4個字節。金屬複製記憶並且不關心價值。這是你的任務;-)

喜歡的東西:

myTexture.replaceRegion(region, mipmapLevel: 0, withBytes: &manualTextureData, bytesPerRow: manualTextureData.count * sizeof(Float)); 
+0

金屬規範規定1D紋理(只)需要bytesPerRow設置爲0 :-) – Aquatic 2014-11-05 06:13:20

0

我看不出有任何理由讓你使用1D紋理傳遞數據。相反,我只想傳遞一個緩衝區。就像這樣:

var dataBuffer:MTLBuffer? = device.newBufferWithBytes(&manualTextureData, length: sizeOf(manualTextureData), options: MTLResourceOptions.OptionCPUCacheModeDefault) 

然後你把它掛到您的renderCommandEncoder這樣的:

renderCommandEncoder.setFragmentBuffer(dataBuffer, offset: 0, atIndex: 1)//Note that if you want this buffer to be passed to you vertex shader you should use setVertexBuffer 

然後在你的着色器,你應該這樣const device float* bufferPassed [[ buffer(1) ]]

添加參數,然後使用它像這樣,在您的着色器實現中:

float firstFloat = bufferPassed[0]; 

T他的意志將完成工作。

+0

感謝。是的 - 我知道緩衝區,我已經在很多其他地方使用過它們。 儘可能在緩衝區上使用1D貼圖有什麼好處? 我以爲他們可能會使用相同的硬件。 1D紋理應該包含一個預先計算的顏色齶,我的所有內核都需要從輸入中讀取。雖然緩衝區可以在這裏使用,但我認爲紋理會更加優化,因爲只有顏色參數很重要。 – Aquatic 2014-11-05 06:07:07

0

沒有真正回答你的問題,但你可以在你的金屬着色器中定義一個數組,而不是將值作爲紋理傳遞。

喜歡的東西:

constant float manualData[8] = { 1.0, 0.0, 0.0, 1.0, 
           0.0, 0.0, 1.0, 1.0 }; 

vertex float4 world_vertex(unsigned int vid[[vertex_id]], ...) { 
    int manualIndex = vid % 8; 
    float manualValue = manualData[manualIndex]; 
    // something deep and meaningful here... 
    return float4(manualValue); 
} 
0

請原諒簡潔的回覆,但你會發現它有用看看我的實驗用斯威夫特和金屬。我在Swift中創建了一個粒子系統,它作爲粒子結構的一維數組傳遞給Metal計算着色器。通過使用posix_memalign,我可以消除在Metal和Swift之間傳遞數組所導致的瓶頸。

我這個博客廣泛:http://flexmonkey.blogspot.co.uk/search/label/Metal

我希望這有助於。

西蒙