gpt4 book ai didi

ios - 如何在SceneKit/ARKit中使用SCNTechnique制作 "masked"传送门效果?

转载 作者:行者123 更新时间:2023-11-29 11:32:05 26 4
gpt4 key购买 nike

我正在努力思考如何将 SCNTechnique 与 Scenekit 结合使用。

我尝试创建的效果可以在 Unity 中轻松实现,方法是向两种 Material 添加自定义着色器,使具有“过滤”着色器的对象仅在通过另一个着色器(入口)看到时才可见.我按照本教程在 Unity 中创建了它:https://www.youtube.com/watch?v=b9xUO0zHNXw

我试图在 SceneKit 中实现相同的效果,但我不确定如何应用 channel 。我正在查看 SCNTechnique,因为它有用于 stencilStates 的选项,但我不确定这是否可行。

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

最佳答案

如上评论所述,我不确定如何使用 Stencil Tests 实现 occlusion 效果,据我们所知,这是相当公平的(我经常使用该术语松散)在 Unity 中很容易做到。

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

Rendering Order 只是指:

The order the node’s content is drawn in relative to that of other nodes.

因此具有较大渲染顺序的 SCNNodes 最后渲染,反之亦然。

为了使肉眼几乎看不到对象,我们需要将 SCNMaterialtransparency 值设置为 0.0000001.

那么我们该怎么做呢?

在这个非常基本的例子中,它只是一个入口门和两堵墙,我们可以做这样的事情(这很容易适应更实质和更美观的东西):

这个例子有完整的注释,所以应该很容易理解我们在做什么。

/// 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
}

可以这样测试:

 let portal = portalNode()
portal.position = SCNVector3(0, 0, -1.5)
self.sceneView.scene.rootNode.addChildNode(portal)

希望它能为您指明正确的方向...

仅供引用,这里有一个很好的教程,来自 Ray Wenderlich这也会对你有用......

关于ios - 如何在SceneKit/ARKit中使用SCNTechnique制作 "masked"传送门效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52488027/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com