SceneKit – 不同的混合模式和片段着色问题

Max*_*Max 7 shader blending objective-c ios scenekit

我在其他文章中读到,SceneKit只有两种混合模式,尽管我仍然想知道它们到底是如何工作的以及如何使用它们。

我目前正在尝试使用片段着色器绘制一些抗锯齿圆圈。因此,我想平滑这些圆圈和blur/或fade它们的边缘以使其透明。

使用普通混合模式(不带#transparent),SceneKit 的片段着色器将忽略任何 alpha 值更改,但仍会进行 alpha 混合。Alpha 混合根据材质颜色的 Alpha 值进行。因此,Alpha 混合是可能的,但不能在片段着色器中更改。

为了测试这一点,我使用了一个片段着色器添加,如下所示:

#pragma body
_output.color = vec4(1.0, 1.0, 1.0, 1.0);
Run Code Online (Sandbox Code Playgroud)

这是创建我的圈子的代码:

#define kDefaultCircleColor [UIColor colorWithRed: 0.5 green: 0.0 blue: 0.0 alpha: 0.5]

NSMutableDictionary *shaders = [NSMutableDictionary dictionary];
shaders[SCNShaderModifierEntryPointFragment] = [[NSString alloc] initWithContentsOfURL: [[NSBundle mainBundle] URLForResource: @"test" withExtension: @"shader"] encoding: NSUTF8StringEncoding error: NULL];

MLCircleNode *circNode1 = [MLCircleNode node];
circNode1.radius = 50;
circNode1.position = SCNVector3Make(100, 400, 0);
circNode1.color = kDefaultCircleColor;
circNode1.lineWidth = 15.0;
circNode1.geometry.firstMaterial.shaderModifiers = shaders;
[_baseNode addChildNode: circNode1];

MLCircleNode *circNode2 = [MLCircleNode node];
circNode2.radius = 50;
circNode2.position = SCNVector3Make(125, 400, -1);
circNode2.color = kDefaultCircleColor;
circNode2.lineWidth = 15.0;
circNode2.geometry.firstMaterial.shaderModifiers = shaders;
[_baseNode addChildNode: circNode2];
Run Code Online (Sandbox Code Playgroud)

这就是结果。正如您所看到的,应用了片段着色器的颜色更改,但未应用 alpha 值更改,这会导致透明度为 50% 的白色。

在此输入图像描述

我会通过在着色器中添加 #transparent 来使用透明混合模式来实现所需的效果,但这里我也遇到了一些问题。#transparent混合模式的透明材质的颜色与默认混合模式的透明材质的颜色不同(我猜这是由于使用了(GL_ONE,GL_ONE_MINUS_SRC_ALPHA),但我不确定)。#opaque 混合模式的结果与这两种模式不同。

以下图像之间的区别只是在片段着色器修改器中添加#transparent或添加#opaque:

没有任何添加。

在此输入图像描述

与#transparent

在此输入图像描述

与#opaque

在此输入图像描述

感谢您阅读到目前为止这篇长文章,现在是有趣的部分,问题!

1)第一个例子中的颜色是在哪里计算的?我在片段着色器中设置了颜色 (1.0, 1.0, 1.0, 1.0),但我看到的是 50% alpha 混合的白色,这怎么可能?我想了解这里的着色过程是如何工作的、颜色从何而来以及 alpha 值从何而来,这样我就知道如何有效地使用它。

2) 为什么使用非#transparent 混合和#transparent-blending 时颜色会发生变化?这是否意味着 SceneKit 中有第三种混合模式?

3)如何同时使用两种不同的混合模式?例如,我想要一些节点可以在片段着色器中更改其 alpha 值,因此这些节点将使用#transparent。其他人不应该使用它,但尽管它们应该具有相同的颜色。如何解决这两种混合模式之间的颜色变化?

4) 为了让我的圆的 smoothstep alpha 绘图正常工作,您建议做什么?