【问题标题】:Does Metal support anything like glDepthRange()?Metal 是否支持 glDepthRange() 之类的东西?
【发布时间】:2020-12-27 22:01:44
【问题描述】:

我正在编写一些绘制天空盒的金属代码。我希望顶点着色器输出的深度始终为 1,但当然,我也希望将顶点绘制在正确的位置。

在 OpenGL 中,您可以使用 glDepthRange(1,1) 在这种情况下将深度始终写为 1.0。我在 Metal 中没有看到类似的东西。这样的事情存在吗?如果没有,是否有另一种方法可以始终从顶点着色器输出 1.0 作为深度?

我想要完成的是先绘制风景,然后绘制天空盒以避免过度绘制。如果我只是将输出顶点的 z 分量设置为 1.0,那么几何图形显然不会正确绘制。我在这里有什么选择?

【问题讨论】:

    标签: metal vertex-shader depth-buffer


    【解决方案1】:

    看起来您可以大致指定片段着色器输出(返回值)格式:

    struct MyFragmentOutput {
        // color attachment 0
        float4 color_att [[color(0)]];
        // depth attachment
        float depth_att [[depth(depth_argument)]]
    }
    

    如 Metal Shading Language Specification (https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf) 的第 88 页上的“片段函数输出属性”部分所示。看起来anydepth_argument 的工作值(更多信息请参见此处:In metal how to clear the depth buffer or the stencil buffer?

    然后您将片段着色器设置为使用该格式

    fragment MyFragmentOutput interestingShaderFragment
    // instead of: fragment float4 interestingShaderFragment
    

    最后只需写入片段着色器中的深度缓冲区:

    MyFragmentOutput out;
    out.color_att = float(rgb_color_here, 1.0);
    out.depth_att = 1.0;
    return out;
    

    经过测试,效果很好。

    【讨论】:

    • 在片段着色器中写出来为时已晚。如果深度计算在已绘制对象的后面,我不需要调用片段着色器。
    • 然后我会查看early_fragment_tests(在同一个文档中稍早一点,〜上一页),不太精通,但听起来可能是您需要的。或者调用discard_fragment(); 作为片段着色器中的第一件事(如果in.position.z > depth_treshhold)可能很有用。
    • 感谢指点!这听起来确实像我需要的。但是,除了几句话说它存在于金属着色语言规范中之外,我找不到任何关于它如何工作的信息。我会继续挖掘,但如果您知道任何示例,将不胜感激。
    • 抱歉,我知道的不多,我想我也没有时间去挖掘了。
    猜你喜欢
    • 2011-08-11
    • 2021-06-10
    • 2013-08-09
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多