【发布时间】:2018-06-12 09:26:21
【问题描述】:
我有一个 1080x1920 像素的纹理。我正在尝试在纵横比不同的MTKView 上渲染它。 (即 iPad/iPhone X 全屏)。
这就是我为MTKView 渲染纹理的方式:
private func render(_ texture: MTLTexture, withCommandBuffer commandBuffer: MTLCommandBuffer, device: MTLDevice) {
guard let currentRenderPassDescriptor = metalView?.currentRenderPassDescriptor,
let currentDrawable = metalView?.currentDrawable,
let renderPipelineState = renderPipelineState,
let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: currentRenderPassDescriptor) else {
semaphore.signal()
return
}
encoder.pushDebugGroup("RenderFrame")
encoder.setRenderPipelineState(renderPipelineState)
encoder.setFragmentTexture(texture, index: 0)
encoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1)
encoder.popDebugGroup()
encoder.endEncoding()
// Called after the command buffer is scheduled
commandBuffer.addScheduledHandler { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.didRender(texture: texture)
strongSelf.semaphore.signal()
}
commandBuffer.present(currentDrawable)
commandBuffer.commit()
}
我希望纹理在UIView 上呈现为.scaleAspectFill,我正在尝试学习Metal,所以我不确定我应该在哪里寻找这个(.metal 文件,管道、视图本身、编码器等)
谢谢!
编辑:这是着色器代码:
#include <metal_stdlib> using namespace metal;
typedef struct {
float4 renderedCoordinate [[position]];
float2 textureCoordinate; } TextureMappingVertex;
vertex TextureMappingVertex mapTexture(unsigned int vertex_id [[ vertex_id ]]) {
float4x4 renderedCoordinates = float4x4(float4( -1.0, -1.0, 0.0, 1.0 ),
float4( 1.0, -1.0, 0.0, 1.0 ),
float4( -1.0, 1.0, 0.0, 1.0 ),
float4( 1.0, 1.0, 0.0, 1.0 ));
float4x2 textureCoordinates = float4x2(float2( 0.0, 1.0 ),
float2( 1.0, 1.0 ),
float2( 0.0, 0.0 ),
float2( 1.0, 0.0 ));
TextureMappingVertex outVertex;
outVertex.renderedCoordinate = renderedCoordinates[vertex_id];
outVertex.textureCoordinate = textureCoordinates[vertex_id];
return outVertex; }
fragment half4 displayTexture(TextureMappingVertex mappingVertex [[ stage_in ]],texture2d<float, access::sample> texture [[ texture(0) ]]) {
constexpr sampler s(address::clamp_to_edge, filter::linear);
return half4(texture.sample(s, mappingVertex.textureCoordinate));
}
【问题讨论】:
-
我已经通过几种不同的方式完成了这项工作,要么在 CPU 上生成顶点位置/纹理坐标并将它们传递给顶点着色器,要么在顶点着色器中即时生成它们本身。你能分享一下你目前拥有的着色器代码吗?
-
我用着色器代码更新了帖子。这东西对我来说仍然有点神秘。我最终做了什么,因为纹理的大小是静态的,我动态计算
metal view以正确调整自身大小以保持纹理的方面......我知道这不是应该这样做的,但我是卡住了。