私はmetalでのライブフィルタのアプリケーションにtexture2d_arrayを使用しようとしています。しかし、私は適切な結果を得ていません。 Class MetalTextureArray
:metalのtexture2d_array配列の使い方は?
イムは、このようなテクスチャ配列、
コードを作成します。
class MetalTextureArray {
private(set) var arrayTexture: MTLTexture
private var width: Int
private var height: Int
init(_ width: Int, _ height: Int, _ arrayLength: Int, _ device: MTLDevice) {
self.width = width
self.height = height
let textureDescriptor = MTLTextureDescriptor()
textureDescriptor.textureType = .type2DArray
textureDescriptor.pixelFormat = .bgra8Unorm
textureDescriptor.width = width
textureDescriptor.height = height
textureDescriptor.arrayLength = arrayLength
arrayTexture = device.makeTexture(descriptor: textureDescriptor)
}
func append(_ texture: MTLTexture) -> Bool {
if let bytes = texture.buffer?.contents() {
let region = MTLRegion(origin: MTLOrigin(x: 0, y: 0, z: 0), size: MTLSize(width: width, height: height, depth: 1))
arrayTexture.replace(region: region, mipmapLevel: 0, withBytes: bytes, bytesPerRow: texture.bufferBytesPerRow)
return true
}
return false
}
}
イムエンコーディングこのようなrenderEncoderにこのテクスチャ、
コード:
let textureArray = MetalTextureArray.init(firstTexture!.width, firstTexture!.height, colorTextures.count, device)
_ = textureArray.append(colorTextures[0].texture)
_ = textureArray.append(colorTextures[1].texture)
_ = textureArray.append(colorTextures[2].texture)
_ = textureArray.append(colorTextures[3].texture)
_ = textureArray.append(colorTextures[4].texture)
renderEncoder.setFragmentTexture(textureArray.arrayTexture, at: 1)
は最後に、私はこのようなフラグメントシェーダでtexture2d_arrayにアクセスしています、
コード:
私はテクスチャ配列に追加していますstruct RasterizerData {
float4 clipSpacePosition [[position]];
float2 textureCoordinate;
};
multipleShader(RasterizerData in [[stage_in]],
texture2d<half> colorTexture [[ texture(0) ]],
texture2d_array<half> texture2D [[ texture(1) ]])
{
constexpr sampler textureSampler (mag_filter::linear,
min_filter::linear,
s_address::repeat,
t_address::repeat,
r_address::repeat);
// Sample the texture and return the color to colorSample
half4 colorSample = colorTexture.sample (textureSampler, in.textureCoordinate);
float4 outputColor;
half red = texture2D.sample(textureSampler, in.textureCoordinate, 2).r;
half green = texture2D.sample(textureSampler, in.textureCoordinate, 2).g;
half blue = texture2D.sample(textureSampler, in.textureCoordinate, 2).b;
outputColor = float4(colorSample.r * red, colorSample.g * green, colorSample.b * blue, colorSample.a);
// We return the color of the texture
return outputColor;
}
テクスチャは、私が2として最後の引数を与えたこのコードhalf red = texture2D.sample(textureSampler, in.textureCoordinate, 2).r;
ではサイズ256 * 1
であるACV曲線ファイルから抽出されたテクスチャですので、私はそれをアクセスするテクスチャのインデックスと考えました。しかし、私はそれが何を意味するのか分からない。
しかし、これらのすべてを行った後、私は黒い画面を取得しています。私は他のフラグメントシェーダを持っていて、それらのすべてがうまく動作しています。しかし、このフラグメントシェイダーのために私は黒い画面を表示しています。私はこのコードのために考えるhalf blue = texture2D.sample(textureSampler, in.textureCoordinate, 2).b
私はすべての赤、緑、青の値の0
を得ています。
編集1:
としては、私は質感とまだ結果をコピーするためにblitcommandEncoderを使用し提案しました。私のコードをここに
、
マイMetalTextureArrayクラスは修正を歩んできました。
メソッドappendはこのようになります。
func append(_ texture: MTLTexture) -> Bool {
self.blitCommandEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSize(width: texture.width, height: texture.height, depth: 1), to: self.arrayTexture, destinationSlice: count, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0))
count += 1
return true
}
とIM私のシェーダコードは、この
let textureArray = MetalTextureArray.init(256, 1, colorTextures.count, device, blitCommandEncoder: blitcommandEncoder)
for (index, filter) in colorTextures!.enumerated() {
_ = textureArray.append(colorTextures[index].texture)
}
renderEncoder.setFragmentTexture(textureArray.arrayTexture, at: 1)
のようなテクスチャを追加それでも私は黒い画面を取得し、この
multipleShader(RasterizerData in [[stage_in]],
texture2d<half> colorTexture [[ texture(0) ]],
texture2d_array<float> textureArray [[texture(1)]],
const device struct SliceDataSource &sliceData [[ buffer(2) ]])
{
constexpr sampler textureSampler (mag_filter::linear,
min_filter::linear);
// Sample the texture and return the color to colorSample
half4 colorSample = colorTexture.sample (textureSampler, in.textureCoordinate);
float4 outputColor = float4(0,0,0,0);
int slice = 1;
float red = textureArray.sample(textureSampler, in.textureCoordinate, slice).r;
float blue = textureArray.sample(textureSampler, in.textureCoordinate, slice).b;
float green = textureArray.sample(textureSampler, in.textureCoordinate, slice).g;
outputColor = float4(colorSample.r * red, colorSample.g * green, colorSample.b * blue, colorSample.a);
// We return the color of the texture
return outputColor;
}
のようになります。
textureArray.sample(textureSampler, in.textureCoordinate, slice);
メソッドでは、3番目のパラメータは何ですか。私はそれをインデックスとして使っていましたが、ランダムなテクスチャを取得するためにランダムなインデックスをいくつか与えました。それが正しいか?
編集2:別のエンコーダが実装され、IはACV
負フィルターで次の画面を持っている前
提案を実現するために、私が最後にできると私はendEncoding
方法を使用して結果を得ました。
誰かが私に示唆することができます。
ありがとうございました。
'constant array,5> texture_array [[texture(1)]]'を使用しましたが、 'Uknown type array'というエラーが発生しています。実際に私は以前にそれを使用しようとしましたが、同じエラーが発生し、 'texture2d_array'を使用する必要がありました。なぜこのエラーを出すのか、私にお勧めできますか?それはコンパイラのためですか?もう1つのことは、テクスチャを 'UnsafeMutablePointer'に変換する方法を知ることができますか? –
どのSDKとデプロイメントターゲットを使用していますか?ターゲットのビルド設定については、Metal言語のリビジョンは何ですか?テクスチャ配列は、GPUファミリ3以上(およびmacOS 10.13+)のiOS 10以降でのみ使用できます。テクスチャを 'UnsafeMutablePointer'にどこで変換したいですか? 'setFragmentTextures()'を考えているなら、Swift配列やテクスチャを渡すだけで、自動的に変換が行われます。 –
私はiOS 9をサポートしようとしています。だから、私のフラグメントシェーダーの内部にテクスチャのような配列を使用することは可能です。そして、私は 'arrayTexture.replace(region:region、mipmapLevel:0、slice:4、withBytes:bytes、bytesPerRow:texture.bufferBytesPerRow、bytesPerImage:texture.bufferBytesPerRow * textureのメソッドで' UnsafeMutablePointer'にテクスチャを変換したいと思います。 .height) 'withBytesパラメータは' UnsafeMutablePointer'を期待するためです。だから、私に示唆することができます。 –