簡體   English   中英

在金屬中手動設置1D紋理

[英]Manually set a 1D Texture in Metal

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

由於目前僅有少量的Metal示例,我可以找到所有示例,這些示例都涉及2D紋理 ,該2D紋理通過將已加載的UIImage轉換為原始字節數據來加載紋理,但是創建虛擬UIImage對我來說就像是hack。

這是我開始的“天真”方式-

...
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);

但是Metal無法在着色器中識別這些值(除第一個值外,它將獲得空紋理)。

我很快意識到Float數組可能必須轉換為字節數組(例如UInt8 ),但是也找不到從[Float]轉換為[UInt8]方法。

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

那么解決這個問題的正確方法是什么?

提前致謝。

  • 請注意,我對Objective-C並不熟悉,因此我不確定使用CVPixelBuffer / UIImage是否會因為某些簡單的事情而被誇大。

如果要浮動紋理,則bytesPerRow應為寬度的4倍,因為浮動的大小為4個字節。 Metal復制內存,而不關心值。 那是你的任務;-)

就像是:

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

我看不出有任何理由使用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) ]]參數const device float* bufferPassed [[ buffer(1) ]]

然后在着色器實現中像這樣使用它:

float firstFloat = bufferPassed[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);
}

請原諒簡短的答復,但您可能會發現查看我對Swift和Metal的實驗很有用。 我已經在Swift中創建了一個粒子系統,該系統作為粒子結構的一維數組傳遞到Metal計算着色器。 通過使用posix_memalign,我可以消除在Metal和Swift之間傳遞數組引起的瓶頸。

我已經在此廣泛地寫過博客: http : //flexmonkey.blogspot.co.uk/search/label/Metal

我希望這有幫助。

西蒙

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM