【发布时间】:2020-07-25 01:42:18
【问题描述】:
我正在尝试使用带有 SCNTechnique 的 Metal 片段着色器来根据顶点 Y 世界位置修改片段颜色。
到目前为止我的理解
SCNTechnique 可以配置一系列渲染通道。渲染通道允许注入顶点和片段着色器。这些着色器是用 Metal 编写的。 Metal Shading Language Specification 描述了这两个支持的输入/输出。 每个正在渲染的顶点都会调用顶点着色器。我们可以将额外的信息从顶点着色器传递给片段着色器(如 3D 空间中的位置,请参阅MSLS section 5.2)。 片段着色器最接近一个像素,如果有多个三角形“符合”该像素的条件,则可以将其称为单个“像素”的倍数。 (通常)在片段着色之后,如果一个片段未能通过深度或模板测试,它可能会被丢弃。
我的尝试
这是我尝试的。 (我希望它能够说明我缺乏理解的地方)。
struct VertexOut {
float4 position [[position]];
};
vertex VertexOut innerVertexShader(VertexIn in [[stage_in]]) {
VertexOut out;
out.position = in.position;
return out;
};
fragment half4 innerFragmentShader(VertexOut in [[stage_in]],
half4 color [[color(0)]]) {
half4 output;
output = color; // test to see if getting rendered color works
output.g = in.position.y; // test to see if getting y works
return output;
}
这些着色器在 SCNTechnique 字典中被引用。
[
"passes": [
"innerPass: [
"draw": "DRAW_NODE",
"node": "inner",
"metalVertexShader": "innerVertexShader",
"metalFragmentShader": "innerFragmentShader"
]
],
"sequence": ["innerPass"],
"symbols": [:],
"targets": [:],
]
// ...
let technique = SCNTechnique(dictionary: techniqueDictionary)
这将执行以下操作:该技术被正确实例化并附加到场景中(因为它会影响渲染)。但它似乎没有将相机变换或节点位置变换应用于顶点。而是将每个节点呈现为从 (0,0,1) 位置 (0,0,0) 处查看。颜色不对。如果我从 SCNTechnique 中删除着色器,每个渲染都像我预期的那样。
如何利用常规的 SceneKit 行为(相机变换等),并且仅根据片段的 y 世界位置修改颜色输出?我希望这需要在片段级别上发生,使用在顶点着色器中以某种方式获得的世界位置。我搜索了诸如“金属基本顶点着色器”之类的东西,但一无所获。 我见过着色器like this,但我确信我应该能够依赖 SceneKit 渲染来处理光照、PBR 材质、相机变换等内容。此时我觉得每当我搜索一些金属主题时,我都会结束在尚未成功将我的理解提升到一个新水平的相同网站上。因此,我们也感谢任何新的/额外的资源。
背景
在过去的两个月里,我一直在开发自己的游戏项目,它使用 SceneKit 作为主要的图形框架。我已经转向 SCNTechnique 和 Metal 着色器来获得自定义效果。尤其是最后两个让我非常头疼,因为缺乏示例代码/文档/运行时反馈。 因此,我考虑过迁移到 Unity/Unreal 甚至完全取消这个项目。但是因为我很固执,也因为我真的不想将我的 Swift 代码移植到 C#/C++,所以我还没有放弃 SceneKit。
【问题讨论】:
-
如果你想重用大部分 SceneKit 的默认渲染,也许着色器修改器是比技术更好的工具。你有一个你想要达到的目标的视觉例子吗?
标签: scenekit metal fragment-shader scntechnique