简体   繁体   English

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

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

Apple sample program苹果示例程序

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

I'm thinking of making Swift and using my own Shader for offscreen rendering.我正在考虑制作 Swift 并使用我自己的 Shader 进行离屏渲染。 Swift conversion itself was done without problems. Swift 转换本身没有问题。 When I wrote the following monochromatic Shader there, I was able to output it to the screen without any problems.当我在那里编写以下单色着色器时,我能够毫无问题地将其输出到屏幕上。

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

However, if you use the following Shade, the screen will turn black immediately and you will not be able to output properly.但是,如果您使用以下阴影,屏幕会立即变黑,您将无法正常输出。 This Shader works fine with normal Metal code, but it just didn't work in the sample environment above.这个着色器在普通的 Metal 代码中工作得很好,但它在上面的示例环境中不起作用。 When using such a Shader in the above sample code, is it possible to use it without changing the sample code or somewhere in the Shader?在上面的示例代码中使用这样的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);
    
}

在此处输入图片说明

The image is for success.图像是为了成功。

There is no problem with basic descriptions such as resolution.分辨率等基本描述没有问题。

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

Addition of Shader of the final rendering.添加最终渲染的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;
}

The issue is that 'in.texcoord.xy' is already using normalized coordinates so they are already in the range on 0.0-1.0问题是“in.texcoord.xy”已经在使用标准化坐标,所以它们已经在 0.0-1.0 的范围内

This works:这有效:

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

Update: using your sample project and:更新:使用您的示例项目和:

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

I get these results which seems correct:我得到这些似乎正确的结果:

在此处输入图片说明

Update 2: The sample project 2 crashes for me.更新 2:示例项目 2 对我来说崩溃了。 I had to comment out these two lines (line 63 and 65 of Renderer.swift:我不得不注释掉这两行(Renderer.swift 的第 63 和 65 行:

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

That got me to a partially black screen.这让我进入了部分黑屏。 Next I changed line 29 of Shaders.metal to:接下来我将 Shaders.metal 的第 29 行更改为:

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

Which gave me expected results:这给了我预期的结果:

在此处输入图片说明

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

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