首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用SCNTechnique在SceneKit / ARKit中创建“蒙面”门户效果?

如何使用SCNTechnique在SceneKit / ARKit中创建“蒙面”门户效果?
EN

Stack Overflow用户
提问于 2018-09-24 22:11:12
回答 1查看 1.3K关注 0票数 3

我想了解如何在Scenekit中使用SCNTechnique。

我试图创建的效果可以很容易地通过添加一个自定义着色器到两个材料中来实现,使用“过滤”着色器的对象只能在通过另一个着色器(门户)看到时才可见。我遵循本教程,在Unity:https://www.youtube.com/watch?v=b9xUO0zHNXw中创建了本教程。

我正试图在SceneKit中实现同样的效果,但我不知道如何应用这些传球。我看SCNTechnique是因为它有stencilStates的选项,但我不确定这是否有效。

关于SCNTechnique的资源和教程非常少

EN

回答 1

Stack Overflow用户

发布于 2018-09-25 02:48:23

正如在上面的评论中提到的,我不知道如何使用occlusion实现Stencil Tests效果,正如我们所知道的那样,在Unity中它是公平的(我使用这个术语非常松散)。

尽管如此,我们可以在Swift中使用transparencyrendering order实现类似的效果。

Rendering Order只是指:

相对于其他节点,节点的内容是按顺序绘制的。

这样,呈现顺序更大的SCNNodes被呈现在最后,反之亦然。

为了使一个对象在肉眼中几乎不可见,我们需要将一个transparency值设置为SCNMaterial的一个值,比如0.0000001

那我们该怎么做?

在这个简单的门户门和两面墙的非常基本的例子中,我们可以这样做(这很容易适应更充实和美观的东西):

这个例子得到了充分的评价,所以我们应该很容易理解我们正在做的事情。

代码语言:javascript
复制
/// Generates A Portal Door And Walls Which Can Only Be Seen From Behind e.g. When Walking Through The Portsal
///
/// - Returns: SCNNode
func portalNode() -> SCNNode{

    //1. Create An SCNNode To Hold Our Portal
    let portal = SCNNode()

    //2. Create The Portal Door
    let doorFrame = SCNNode()

    //a. Create The Top Of The Door Frame
    let doorFrameTop = SCNNode()
    let doorFrameTopGeometry = SCNPlane(width: 0.55, height: 0.1)
    doorFrameTopGeometry.firstMaterial?.diffuse.contents = UIColor.black
    doorFrameTopGeometry.firstMaterial?.isDoubleSided = true
    doorFrameTop.geometry = doorFrameTopGeometry
    doorFrame.addChildNode(doorFrameTop)
    doorFrameTop.position = SCNVector3(0, 0.45, 0)

    //b. Create The Left Side Of The Door Frame
    let doorFrameLeft = SCNNode()
    let doorFrameLeftGeometry = SCNPlane(width: 0.1, height: 1)
    doorFrameLeftGeometry.firstMaterial?.diffuse.contents = UIColor.black
    doorFrameLeftGeometry.firstMaterial?.isDoubleSided = true
    doorFrameLeft.geometry = doorFrameLeftGeometry
    doorFrame.addChildNode(doorFrameLeft)
    doorFrameLeft.position = SCNVector3(-0.25, 0, 0)

    //c. Create The Right Side Of The Door Frame
    let doorFrameRight = SCNNode()
    let doorFrameRightGeometry = SCNPlane(width: 0.1, height: 1)
    doorFrameRightGeometry.firstMaterial?.diffuse.contents = UIColor.black
    doorFrameRightGeometry.firstMaterial?.isDoubleSided = true
    doorFrameRight.geometry = doorFrameRightGeometry
    doorFrame.addChildNode(doorFrameRight)
    doorFrameRight.position = SCNVector3(0.25, 0, 0)

    //d. Add The Portal Door To The Portal And Set Its Rendering Order To 200 Meaning It Will Be Rendered After Our Masks
    portal.addChildNode(doorFrame)
    doorFrame.renderingOrder = 200
    doorFrame.position = SCNVector3(0, 0, -1)

    //3. Create The Left Wall Enclosure To Hold Our Wall And The Occlusion Node
    let leftWallEnclosure = SCNNode()

    //a. Create The Left Wall And Set Its Rendering Order To 200 Meaning It Will Be Rendered After Our Masks
    let leftWallNode = SCNNode()
    let leftWallMainGeometry = SCNPlane(width: 0.5, height: 1)
    leftWallNode.geometry = leftWallMainGeometry
    leftWallMainGeometry.firstMaterial?.diffuse.contents = UIColor.red
    leftWallMainGeometry.firstMaterial?.isDoubleSided = true
    leftWallNode.renderingOrder = 200

    //b. Create The Left Wall Mask And Set Its Rendering Order To 10 Meaning It Will Be Rendered Before Our Walls
    let leftWallMaskNode = SCNNode()
    let leftWallMaskGeometry = SCNPlane(width: 0.5, height: 1)
    leftWallMaskNode.geometry = leftWallMaskGeometry
    leftWallMaskGeometry.firstMaterial?.diffuse.contents = UIColor.blue
    leftWallMaskGeometry.firstMaterial?.isDoubleSided = true
    leftWallMaskGeometry.firstMaterial?.transparency = 0.0000001
    leftWallMaskNode.renderingOrder = 10
    leftWallMaskNode.position = SCNVector3(0, 0, 0.001)

    //c. Add Our Wall And Mask To The Wall Enclosure
    leftWallEnclosure.addChildNode(leftWallMaskNode)
    leftWallEnclosure.addChildNode(leftWallNode)

    //4. Add The Left Wall Enclosure To Our Portal
    portal.addChildNode(leftWallEnclosure)
    leftWallEnclosure.position = SCNVector3(-0.55, 0, -1)

    //5. Create The Left Wall Enclosure
    let rightWallEnclosure = SCNNode()

    //a. Create The Right Wall And Set Its Rendering Order To 200 Meaning It Will Be Rendered After Our Masks
    let rightWallNode = SCNNode()
    let rightWallMainGeometry = SCNPlane(width: 0.5, height: 1)
    rightWallNode.geometry = rightWallMainGeometry
    rightWallMainGeometry.firstMaterial?.diffuse.contents = UIColor.red
    rightWallMainGeometry.firstMaterial?.isDoubleSided = true
    rightWallNode.renderingOrder = 200

    //b. Create The Right Wall Mask And Set Its Rendering Order To 10 Meaning It Will Be Rendered Before Our Walls
    let rightWallMaskNode = SCNNode()
    let rightWallMaskGeometry = SCNPlane(width: 0.5, height: 1)
    rightWallMaskNode.geometry = rightWallMaskGeometry
    rightWallMaskGeometry.firstMaterial?.diffuse.contents = UIColor.blue
    rightWallMaskGeometry.firstMaterial?.isDoubleSided = true
    rightWallMaskGeometry.firstMaterial?.transparency = 0.0000001
    rightWallMaskNode.renderingOrder = 10
    rightWallMaskNode.position = SCNVector3(0, 0, 0.001)

    //c. Add Our Wall And Mask To The Wall Enclosure
    rightWallEnclosure.addChildNode(rightWallMaskNode)
    rightWallEnclosure.addChildNode(rightWallNode)

    //6. Add The Left Wall Enclosure To Our Portal
    portal.addChildNode(rightWallEnclosure)
    rightWallEnclosure.position = SCNVector3(0.55, 0, -1)

    return portal
}

它可以像这样测试:

代码语言:javascript
复制
 let portal = portalNode()
 portal.position = SCNVector3(0, 0, -1.5)
 self.sceneView.scene.rootNode.addChildNode(portal)

希望它能给你指明正确的方向..。

在这里有一个很好的教程来自雷·温德里希,它也将对你有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52488027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档