【问题标题】:Custom Variable Declarations Using Metal With Scene Kit Shader Modifiers使用带有场景工具包着色器修改器的 Metal 自定义变量声明
【发布时间】:2019-12-18 09:44:09
【问题描述】:

我很难将制服传递给 Scene Kit 的着色器修改器。这在使用 OpenGL 时似乎可以正常工作,但在使用 Metal 时却不行。

我之前成功使用过 SCNProgram,但想利用 SceneKit 的 tessellator 而不是设置计算着色器来进行 tessellation。

但我想使用我已经用 Metal 编写的代码,而不是使用 OpenGL。

遗憾的是,关于如何做到这一点的例子并不多。 这个 Swift Playground 说明了如何在 OpenGL 中很好地做到这一点。

https://github.com/markpmlim/Twister/blob/master/Twister.playground/Contents.swift

//Geometry - Metal will translate the OpenGL code.
let geometryShaderModifier =
"uniform float twistFactor;\n" +
"mat4 rotationAroundX(float angle) {\n" +
"return mat4(1.0,    0.0,         0.0,        0.0,\n" +
"            0.0,    cos(angle), -sin(angle), 0.0,\n" +
"            0.0,    sin(angle),  cos(angle), 0.0,\n" +
"            0.0,    0.0,         0.0,        1.0);\n" +
"}\n" +
"#pragma body\n" +
"float rotationAngle = _geometry.position.x * twistFactor;\n" +
"mat4 rotationMatrix = rotationAroundX(rotationAngle);\n" +
"_geometry.position *= rotationMatrix;\n" +
"vec4 twistedNormal = vec4(_geometry.normal, 1.0) * rotationMatrix;\n" +
"_geometry.normal   = twistedNormal.xyz;\n"

但是当我将它更改为 Metal 时它不起作用:

let geometryShaderModifier =
"#pragma arguments \n" +
"float twistFactor;\n" +
"float4x4 rotationAroundX(float angle) {\n" +
"return float4x4(1.0,    0.0,         0.0,        0.0,\n" +
"                0.0,    cos(angle), -sin(angle), 0.0,\n" +
"                0.0,    sin(angle),  cos(angle), 0.0,\n" +
"                0.0,    0.0,         0.0,        1.0);\n" +
"}\n" +
"#pragma body\n" +
"float rotationAngle = _geometry.position.x * twistFactor;\n" +
"float4x4 rotationMatrix = rotationAroundX(rotationAngle);\n" +
"_geometry.position *= rotationMatrix;\n" +
"float4 twistedNormal = float4(_geometry.normal, 1.0) * rotationMatrix;\n" +
"_geometry.normal   = twistedNormal.xyz;\n"

这就是我提供值的方式,使用键值编码:

 // The uniform "twistFactor" must be assigned a value.
 torus.setValue(1.0, forKey: "twistFactor")

我想我可以切换回使用 OpenGL 来解决这个问题,但有点令人沮丧的是,Apple 的着色器修改器文档中的前几行很难开始工作。

// For Metal, a pragma directive and one custom variable on each line:
#pragma arguments
float intensity;

我在不同的论坛上看到过各种帖子,它们都有相同的基本问题,如果他们能为此提供更清晰的文档,那就太好了。

我收到以下错误消息:

program_source:2566:50:错误:使用未声明的标识符“twistFactor”

提前感谢您的帮助!

【问题讨论】:

    标签: shader scenekit metal modifier


    【解决方案1】:

    您可以使用 #pragma declaration 标记来帮助 SceneKit 区分着色器修饰符参数和本地函数:

    let geometryShaderModifier =
        "#pragma arguments\n" +
         "float twistFactor;\n" +
         "#pragma declaration\n" + // HERE
         "float4x4 rotationAroundX(float angle) {\n" +
         "return float4x4(1.0,    0.0,         0.0,        0.0,\n" +
         "                0.0,    cos(angle), -sin(angle), 0.0,\n" +
         "                0.0,    sin(angle),  cos(angle), 0.0,\n" +
         "                0.0,    0.0,         0.0,        1.0);\n" +
         "}\n" +
         "#pragma body\n" +
         "float rotationAngle = _geometry.position.x * twistFactor;\n" +
         "float4x4 rotationMatrix = rotationAroundX(rotationAngle);\n" +
         "_geometry.position *= rotationMatrix;\n" +
         "float4 twistedNormal = float4(_geometry.normal, 1.0) * rotationMatrix;\n" +
         "_geometry.normal   = twistedNormal.xyz;\n"
    

    【讨论】:

    • 我无法添加赞成票,因为我对 Stack Overflow 的评价不够高,但这解决了它!干杯!
    猜你喜欢
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2015-07-09
    • 2018-01-09
    • 2016-08-17
    • 2020-02-28
    相关资源
    最近更新 更多