我自己的 Shader 与 Apple 的 Metal 样本的离屏渲染不起作用
Offscreen rendering of my own Shader with Apple's Metal sample doesn't work
Apple 示例程序
https://developer.apple.com/documentation/metal/customizing_render_pass_setup
我正在考虑制作 Swift 并使用我自己的 Shader 进行离屏渲染。
Swift 转换本身没有问题。
当我在那里写了下面的单色Shader时,我能够毫无问题地将它输出到屏幕上。
fragment float4 simpleFragmentShader(VertexOut vertexIn [[stage_in]] {
return float4(1.0, 0.0, 0.0, 1.0);
}
但是,如果使用下面的Shade,屏幕会立即变黑,无法正常输出。
这个着色器与普通的 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 对我来说崩溃了。我不得不注释掉这两行(Renderer.swift:
的第 63 行和第 65 行
//textureDescriptor.textureType = .type2DMultisample
//textureDescriptor.sampleCount = 4
这让我出现了部分黑屏。接下来我将 Shaders.metal 的第 29 行更改为:
float2 p = (vertexIn.pos.xy) / min(resolution0.x, resolution0.y);
这给了我预期的结果:
Apple 示例程序
https://developer.apple.com/documentation/metal/customizing_render_pass_setup
我正在考虑制作 Swift 并使用我自己的 Shader 进行离屏渲染。 Swift 转换本身没有问题。 当我在那里写了下面的单色Shader时,我能够毫无问题地将它输出到屏幕上。
fragment float4 simpleFragmentShader(VertexOut vertexIn [[stage_in]] {
return float4(1.0, 0.0, 0.0, 1.0);
}
但是,如果使用下面的Shade,屏幕会立即变黑,无法正常输出。 这个着色器与普通的 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 对我来说崩溃了。我不得不注释掉这两行(Renderer.swift:
的第 63 行和第 65 行//textureDescriptor.textureType = .type2DMultisample
//textureDescriptor.sampleCount = 4
这让我出现了部分黑屏。接下来我将 Shaders.metal 的第 29 行更改为:
float2 p = (vertexIn.pos.xy) / min(resolution0.x, resolution0.y);
这给了我预期的结果: