저는 금속으로 라이브 필터를 적용 할 때 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에 접근하고있어,
코드 :
I는 텍스처 배열에 추가하고있어 3,691,363,210struct 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;
}
텍스쳐는 I 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 클래스는 수정왔다.
메소드 추가가 이렇게됩니다.
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
}
그리고 임이
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);
메서드에서 세 번째 매개 변수는 무엇입니까? 나는 그것을 색인으로 사용하고 임의의 텍스쳐를 가져 오기 위해 임의의 색인을 주었다. 맞습니까?
편집 2 :
나는 마지막으로 수 제안을 구현하고 나는 다른 인코더를 구현하고 나는 ACV
부정적인 필터와 함께 다음과 같은 화면을 가지고 전에 endEncoding
방법을 사용하여 결과를 얻었다.
누군가 나를 제안 할 수 있습니까?
감사합니다.
''constant array, 5> texture_array [[texture (1)]]'을 사용했지만'Uknown type array' 오류가 발생했습니다. 사실 나는 그것을 전에 사용하려고했지만'texture2d_array'를 사용하게하는 같은 오류가 발생했습니다. 왜 이것이이 오류를 내고 있는지 제안 해 주시겠습니까? 컴파일러 때문인가요? 그리고 한 가지 더, 텍스처를'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'를 기대하기 때문에. 그럼 나 한테 제안 해 줄래? –