Swift Metal Shader Issue

问题描述 投票:-1回答:1

我一直在努力使以下用opengl编写的着色器能够以金属化的速度工作:https://github.com/gl-transitions/gl-transitions/blob/master/transitions/SimpleZoom.glsl我在着色器函数中使用内核方法,以下是所得视频的一个输出帧。Image frame during zoom

我也编写了其他一些着色器,这些着色器也能成功工作,但是在此着色器上停留了5个多小时。

swift opengl shader metal
1个回答
0
投票

在转换此着色器时,我尝试保持尽可能接近原始材质的精神和结构。但是,由于GLSL和MSL之间存在显着差异,因此我不得不采取一些自由措施:

  • 假定制服和其他全局变量以constant缓冲区的形式到达
  • 将参数从片段着色器传递到实用程序功能,而不是将其作为全局变量访问

话虽如此,这是我最好的尝试,它可以实现您所需的缩放效果的Metal着色器:

struct VertexIn {
    float2 position  [[attribute(0)]];
    float2 texCoords [[attribute(1)]];
};

struct VertexOut {
    float4 position [[position]];
    float2 texCoords;
};

float4 getColor(texture2d<float, access::sample> tex2d, float2 uv) {
    constexpr sampler sampler2d(coord::normalized,
                                address::clamp_to_edge,
                                filter::linear,
                                mip_filter::linear);

    return tex2d.sample(sampler2d, float2(uv.x, 1.0f - uv.y));
}

float2 zoom(float2 uv, float amount) {
    return 0.5f + ((uv - 0.5f) * (1.0f - amount));
}

float4 transition (texture2d<float, access::sample> fromTexture,
                   texture2d<float, access::sample> toTexture,
                   float nQuick,
                   float progress,
                   float2 uv)
{
    float4 fromColor = getColor(fromTexture, zoom(uv, smoothstep(0.0f, nQuick, progress)));
    float4 toColor = getColor(toTexture, uv);
    return mix(fromColor, toColor, smoothstep(nQuick - 0.2f, 1.0f, progress));
}

vertex VertexOut textured_vertex(VertexIn in [[stage_in]]) {
    VertexOut out;
    out.position = float4(in.position, 0.0f, 1.0f);
    out.texCoords = in.texCoords;
    return out;
}

fragment float4 zoomed_textured_fragment(VertexOut in [[stage_in]],
                                         constant float& zoom_quickness [[buffer(0)]],
                                         constant float& progress       [[buffer(1)]],
                                         texture2d<float, access::sample> fromTexture [[texture(0)]],
                                         texture2d<float, access::sample> toTexture   [[texture(1)]])
{
    float nQuick = clamp(zoom_quickness, 0.2 , 1.0);
    return transition(fromTexture, toTexture, nQuick, progress, in.texCoords);
}

您似乎已经具有渲染代码,所以我只需要注意,我使用以下Swift代码将参数作为单独的常量缓冲区传递:

var zoomSpeed: Float = 0.5
renderCommandEncoder.setFragmentBytes(&zoomSpeed, length: MemoryLayout<Float>.size, index: 0)

renderCommandEncoder.setFragmentBytes(&progress, length: MemoryLayout<Float>.size, index: 1)

其中progress是随时间变化以执行缩放动画的Float变量。

© www.soinside.com 2019 - 2024. All rights reserved.