如何在SCNTechnique中使用模板?

时间:2017-01-01 21:27:11

标签: scenekit stencil-buffer scntechnique

基本上,我想在立方体周围渲染轮廓。为此,我想我可以使用具有以下渲染过程的SCNTechnique

  1. 正常渲染立方体,并将其占用的像素写入模板缓冲区。
  2. 如果第一遍中没有与模板相交,则渲染稍大的立方体。
  3. 问题是,SCNTechnique中的模具文档非常稀疏,我无法确切知道如何使用它。

    我已经成功绘制轮廓,首先绘制较大的'轮廓立方体',然后禁用深度测试,然后绘制正常的立方体,这样做效果相当不错,但是由于其他并发症,我想使用模板这种方法。

    为了让它使用模板缓冲区工作,我的第一个传递stencilStates看起来像(以及为什么我认为我需要属性):

    clear = YES  // To clear the buffer from last 
    enable = YES // To write to the buffer
    behavior:
        writeMask = 1     // Use bit 1
        function = always // Always write to stencil regardless?
    

    第二遍stencilStates看起来像是:

    clear = NO   // Keep the buffer from last step
    enable = NO  // Don't write to the buffer (only read?)
    behavior:
        readMask = 1      // Use bit 1
        fail     = keep   // Not sure if these...
        pass     = zero   // ...should be the other way round
    

    模板缓冲行为有很多a few other properties,但我不确定我需要哪些以及如何使用它们。我也不确定是否需要将模板缓冲区列为每次传递的输入或输出?

    编辑1:这是完全我想要实现的内容,通过首先绘制蓝色,更大的轮廓立方体而不写入深度缓冲区来呈现:

    Cube with blue outline

    如果不是因为在这个庄园中画一些副作用,我会离开这样的实现,但我认为模板方法会避免这些副作用,我认为知道如何有用无论如何要使用它们!

    编辑2:我一直在玩,试图直接使用OpenGL(在C中)产生类似的效果。我并没有假装完全理解模板是如何工作的(我基本上借用了code from a tutorial),但这些命令产生了我想要实现的目标。

    在绘制主立方体之前,写入模板缓冲区:

    glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to 1
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glStencilMask(0xFF); // Write to stencil buffer
    glClear(GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default)
    

    绘制主立方体之后,在绘制较大的轮廓立方体之前,测试当前的模板缓冲区:

    glStencilFunc(GL_EQUAL, 0, 0xFF); // Pass test if stencil value is 0
    glStencilMask(0x00); // Don't write anything to stencil buffer
    

    因此,问题是如何使用SCNTechnique来实现上述目标。

1 个答案:

答案 0 :(得分:0)

您可以使用SCNTechnique绘制轮廓。我们的想法是将对象蒙版绘制到缓冲区,模糊蒙版的一个通道,然后将其与原始渲染帧组合。该组合着色器检查模糊通道和非模糊通道,并仅将轮廓渲染到对象外部。

有一个例子可以在这里围绕节点绘制光晕:https://github.com/laanlabs/SCNTechniqueGlow 你应该能够修改它以获得你想要的效果。