我看不到一种明显的方法来改变场景套件节点或几何体的混合功能(glBlendFunc) - 它似乎不是材料的一部分,并且从场景套件中看不是很明显记录它如何组织渲染过程。 我是否需要为只更改GLblending模式的节点创建一个Render委托,或者我是否需要以某种方式设置不同的渲染过程等(从文档中我不知道如何控制渲染过程之类的东西)?
答案 0 :(得分:2)
是!在iOS 9和OS X 10.11(目前处于测试版)中,blendMode
是素材的属性,因此您可以使用加法,乘法或其他方式呈现任何SceneKit内容各种混合。
但是,虽然你仍然支持早期的操作系统版本... iOS 8.x和OS X 10.8到10.10中的SceneKit并不能为混合模式提供API。
您可以通过以下几种方式来解决此问题。
如果在SceneKit绘制之前调用glBlendFunc
和朋友,SceneKit将使用您选择的混合状态进行渲染。诀窍是在适当的时间设置状态以绘制混合内容,并将状态保留为SceneKit期望的未混合内容。
如果您在renderer:willRenderScene:atTime:
中设置了状态并在renderer:didRenderScene:atTime:
中取消设置,则会将混合应用于整个场景。可能不是你想要的。并且您不能仅为要混合的节点使用node renderer delegate,因为SceneKit不会渲染您的节点内容。
如果你能找到一种很好的方法来楔入这些电话,那么它们应该可行。尝试使用自定义程序渲染相关节点,并将您的状态设置为handleBindingOfSymbol:usingBlock:
,也许?
iOS设备中的图形硬件支持在着色器中读取目标片段的颜色值。您可以将此值与要以多种方式编写的颜色组合在一起 - 例如,您可以创建Photoshop-style blend modes。
在SceneKit中,您可以将其与片段着色器修饰符一起使用 - 从gl_LastFragData
读取并写入_output
。这里的例子使用它来做一个简单的添加剂混合。
#pragma transparent
#extension GL_EXT_shader_framebuffer_fetch : require
#pragma body
_output.color = gl_LastFragData[0] + _output.color;
答案 1 :(得分:1)
从经过几个小时的实验我可以看出,无法实际设置用于渲染几何体的混合模式,或控制使用SCNTechnique渲染传递的整体混合模式。
SceneKit似乎只有两种不同的混合模式 - 一种是混合关闭 - 如果它认为材质是不透明的,另一种是#34;透明的"混合模式(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)在考虑材料透明时。如果你想渲染诸如发光之类的东西,这是个坏消息,因为它似乎不可能得到像你想要渲染光束或发光的(GL_ONE,GL_ONE)混合模式。
然而,我发现了一个黑客来解决这个问题并不能让你适当控制混合,但是如果你想要渲染像光束这样的发光物体,它就会起作用:
因为SceneKit使用GL_ONE,GL_ONE_MINUS_SRC_ALPHA混合模式, 所要做的只是渲染你的几何体的alpha通道为0.不幸的是,它并不那么简单,因为默认的SceneKit着色器抛弃alpha通道为0的片段,因此实际上不会渲染任何内容。一个快速而肮脏的解决方法是使用漫反射颜色贴图,其alpha通道为1(假设每通道地图为8位,值为1-255)。因为alpha通道几乎为0,所以几乎所有背景图像都会显示出来。这主要是有效的,但由于阿尔法不是很零,它仍然会在明亮的区域产生明显的人工制品。
因此,为了解决这个问题,你可以使用带有实体alpha chanel的标准纹理贴图,但是将着色器修改器附加到" SCNShaderModifierEntryPointFragment"它只是将输出颜色的alpha通道设置为零。这是有效的,因为片段着色器修饰符位于零alpha剔除之后。
这里是整个着色器修饰符:
#pragma transparent
#pragma body
_output.color.a = 0;
注意" #pragma transparent"第一行中的声明 - 这是强制SceneKit使用其透明混合模式的必要条件,即使它不会这样做。
这不是一个完整的解决方案,因为它不能真正控制混合 - 它只是产生光束发光等的有用黑客 - 并且阴影处理当然不是最佳的虽然它可能,但它适用于这种情况。