繁体   English   中英

使用 Apple 的 Metal 示例对我自己的 Shader 进行离屏渲染不起作用

[英]Offscreen rendering of my own Shader with Apple's Metal sample doesn't work

苹果示例程序

https://developer.apple.com/documentation/metal/customizing_render_pass_setup

我正在考虑制作 Swift 并使用我自己的 Shader 进行离屏渲染。 Swift 转换本身没有问题。 当我在那里编写以下单色着色器时,我能够毫无问题地将其输出到屏幕上。

fragment float4 simpleFragmentShader(VertexOut vertexIn [[stage_in]] {
    return float4(1.0, 0.0, 0.0, 1.0);
}

但是,如果您使用以下阴影,屏幕会立即变黑,您将无法正常输出。 这个着色器在普通的 Metal 代码中工作得很好,但它在上面的示例环境中不起作用。 在上面的示例代码中使用这样的Shader时,是否可以在不更改示例代码或Shader中的某处使用它?

vertex VertexOut simpleVertexShader(constant float4 *positions [[buffer(0)]],
 uint vid [[ vertex_id ]]) {
    
    VertexOut out;
    
    out.pos = positions[vid];
    
    return out;
}


fragment float4 simpleFragmentShader(VertexOut vertexIn [[stage_in]],
                                     constant float2 &resolution [[buffer(0)]]) {

    float2 resolution0 = float2(resolution[0], resolution[1]);
    float2 p = (vertexIn.pos.xy * 2.0 - resolution0) / min(resolution0.x, resolution0.y);

    return float4(p, 0.0, 1.0);
    
}

在此处输入图片说明

图像是为了成功。

分辨率等基本描述没有问题。

renderEncoder.setFragmentBuffer(resolutionBuffer, offset: 0, index: 0)

添加最终渲染的Shader。

vertex VertexTextureOut textureVertexShader(constant float4 *positions [[buffer(0)]],
                                            constant float2 *texcoord [[buffer(1)]],
                                            uint vid [[ vertex_id ]]) {
    
    VertexTextureOut out;
    
    out.pos = positions[vid];
    out.texcoord = texcoord[vid];
    
    return out;
}

fragment float4 textureFragmentShader(VertexTextureOut vertexIn [[stage_in]],
                                     texture2d<float> renderTargetTexture [[texture(0)]]) {
    
    constexpr sampler simpleSampler;

    // Sample data from the texture.
    float4 colorSample = renderTargetTexture.sample(simpleSampler, vertexIn.texcoord);

    // Return the color sample as the final color.
    return colorSample;
}

问题是“in.texcoord.xy”已经在使用标准化坐标,所以它们已经在 0.0-1.0 的范围内

这有效:

float2 p = (in.texcoord.xy) ;
return float4(p, 0.0, 1.0);

更新:使用您的示例项目和:

float2 p = (vertexIn.pos.xy) / min(resolution0.x, resolution0.y);
return float4(p, 0.0, 1.0);

我得到这些似乎正确的结果:

在此处输入图片说明

更新 2:示例项目 2 对我来说崩溃了。 我不得不注释掉这两行(Renderer.swift 的第 63 和 65 行:

//textureDescriptor.textureType = .type2DMultisample
//textureDescriptor.sampleCount = 4

这让我进入了部分黑屏。 接下来我将 Shaders.metal 的第 29 行更改为:

float2 p = (vertexIn.pos.xy) / min(resolution0.x, resolution0.y);

这给了我预期的结果:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM