我是金属新手。我们可以在单个应用程序中创建多少个 MTLRenderpassdescriptor(任意限制)?
我想要三个 MTLRenderpassdescriptor 是否可能。一我需要根据手指位置绘制四边形。这就像离屏渲染。将会有纹理输出。
我想将输出纹理传递给另一个渲染通道描述符来处理它的颜色,这也类似于离屏渲染。这里将提供新的输出纹理
我想向屏幕呈现新的输出纹理。是否可以 ?当我创建三个渲染通道描述符时,只有两个可用。
第一次离屏渲染效果很好
let renderPass = MTLRenderPassDescriptor()
renderPass.colorAttachments[0].texture = ssTexture
renderPass.colorAttachments[0].loadAction = .clear
renderPass.colorAttachments[0].clearColor = MTLClearColorMake( 0.0, 0.0, 0.0, 0.0)
renderPass.colorAttachments[0].storeAction = .store
let commandBuffer = commandQueue.makeCommandBuffer()
var commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPass)
for scene in scenesTool{
scene.render(commandEncoder: commandEncoder!)
}
commandEncoder?.endEncoding()
Run Code Online (Sandbox Code Playgroud)
此渲染通道描述符在调试中也不可用。
let renderPassWC = MTLRenderPassDescriptor()
renderPassWC.colorAttachments[0].texture = ssCurrentTexture
renderPassWC.colorAttachments[0].loadAction = .clear
renderPassWC.colorAttachments[0].clearColor = MTLClearColorMake( 0.0, 0.0, 0.0, 0.0)
renderPassWC.colorAttachments[0].storeAction = .store
let commandBufferWC = commandQueue.makeCommandBuffer()
let commandEncoderWC = commandBufferWC?.makeRenderCommandEncoder(descriptor: renderPassWC)
for scene in scenesWCTool{ …Run Code Online (Sandbox Code Playgroud) fragment half4 fragmen_shader_test(WaterColorCloudOut params[[stage_in]],
texture2d<float , access::sample>cloud1 [[texture(0)]],
texture2d<half, access::sample> cloud2 [[texture(1)]],
texture2d<half, access::sample> cloud3 [[texture(2)]]
)
{
constexpr sampler defaultSampler;
float4 color1;
if(params.index == 0){
color1= float4(cloud1.sample(defaultSampler, float2(params.textureCoordinates))) * params.color ;
}
else if(params.index == 1){
color1= float4(cloud2.sample(defaultSampler, float2(params.textureCoordinates))) * params.color ;
} else{
color1= float4(cloud3.sample(defaultSampler, float2(params.textureCoordinates))) * params.color ;
}
return half4(color1);
}
Run Code Online (Sandbox Code Playgroud)
这里我使用了三个纹理,因为 If-else 条件的性能随着时间的推移而下降。我觉得如果我将纹理数组发送到着色器,则无需执行 if else 语句。在CPU中我有三个MTLTexture。如何将三个纹理绑定到一个数组并将其传递给着色器。
在CPU端我创建了三个纹理并创建了一个MTLTexture数组
var textureArray:[MTLTexture] = []
Run Code Online (Sandbox Code Playgroud)
然后我将纹理附加到该数组。在 MTLRenderCommandEncoder 中
let myRange: CountableRange = 0..<2
commandEncoder.setFragmentTextures(textureArray, range: myRange)
Run Code Online (Sandbox Code Playgroud)
在着色器中
texture2d_array<float , …Run Code Online (Sandbox Code Playgroud) 我正在向我的金属内核和着色器函数传递一个参数结构。我找不到任何指定使用哪些 Swift 数据类型来匹配 Metal 中的数据类型的地方。
我已经尽力猜测在 Swift 端使用什么数据类型,但我在结构中定义变量的顺序似乎非常挑剔。这让我相信他们没有对齐。
例如,以下是我在 Metal 中使用的数据类型:
struct ComputeParameters {
bool yesNo;
int count;
float scale;
float2 point;
float4 color;
};
Run Code Online (Sandbox Code Playgroud)
这是我在 Swift 中对应的结构:
struct ComputeParameters {
var yesNo: Bool = false
var count: Int32 = 0
var scale: Float32 = 1.0
var point: float2 = float2(0.0, 0.0)
var color: float4 = float4(0.0, 0.0, 0.0, 1.0)
}
Run Code Online (Sandbox Code Playgroud)
这是我从上面使用的数据类型表。
Metal _________ Swift
bool Bool
int Int32
float Float32
float2 float2
float4 float4
Run Code Online (Sandbox Code Playgroud)
那些是正确的吗?有没有记录参数数据类型的地方?
我想在应用程序退出活动状态后立即将 MTKView(或 GLKView/CAEAGLLayer)的内容设置为黑色。将其设置为透明颜色(例如黑色)并显示它的最快且最可靠的方法是什么?
我正在尝试使用 CoreImage & Metal 处理一系列 UIImages 并显示它们。我的问题是如果我的 gcd 块很忙,我想删除传入的图像。我如何实现这个 GCD 队列,我如何定义队列的最大缓冲区大小?
在金属着色器下,为什么这两行的工作原理不同:
float b = (color.rgb * float3(1,1.1,0.9)).x;
Run Code Online (Sandbox Code Playgroud)
和
float b = dot(color.rgb, float3(1,1.1,0.9));
Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的 iPhone SE 上运行我的金属程序。
我为threadsPerThreadGroup和threadsPerGrid大小尝试了很多数字,所有这些都给了我这个错误: TLValidateFeatureSupport:3539: failed assertion `Dispatch Threads with Non-Uniform Threadgroup Size is only supported on MTLGPUFamilyApple4 and later.'
这是我的代码。
var threadsPerThreadGroup: MTLSize
var threadsPerGrid: MTLSize
computeCommandEncoder.setComputePipelineState(updateShader)
let w = updateShader.threadExecutionWidth
threadsPerThreadGroup = MTLSize(width: w, height: 1, depth: 1)
threadsPerGrid = MTLSize(width: Int(constants.bufferLength), height: 1, depth: 1)
if(frames % 2 == 0) {
computeCommandEncoder.setBuffer(buffer1, offset: 0, index: 0)
computeCommandEncoder.setBuffer(buffer2, offset: 0, index: 1)
} else {
computeCommandEncoder.setBuffer(buffer2, offset: 0, index: 0)
computeCommandEncoder.setBuffer(buffer1, offset: 0, index: 1)
}
computeCommandEncoder.setBytes(&constants, …Run Code Online (Sandbox Code Playgroud) 我刚刚创建了一个 Metal 模板并稍微更改了代码。我用 Minecraft 16x16 青金石矿石纹理切换了默认颜色图,但由于某种原因,它们在低分辨率时会变得模糊。我正在尝试实现像素化的 Minecraft 外观,因此想知道如何禁用这种模糊/过滤。
有没有办法加载/呈现资产而不产生这种模糊?这是我的加载资产函数:
class func loadTexture(device: MTLDevice, textureName: String) throws -> MTLTexture {
/// Load texture data with optimal parameters for sampling
return try MTKTextureLoader(device: device).newTexture(name: textureName, scaleFactor: 1.0, bundle: nil, options: [
MTKTextureLoader.Option.textureUsage: NSNumber(value: MTLTextureUsage.shaderRead.rawValue),
MTKTextureLoader.Option.textureStorageMode: NSNumber(value: MTLStorageMode.`private`.rawValue)
])
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的模糊立方体的屏幕截图: