Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARKit billboarding effect with SceneKit

I am looking to add a billboarding effect that is similar to this application: https://twitter.com/marpi_/status/897130955105644544

I would like SCNodes that use SCNText geometry to always face the camera.

I have attempted with out success:

  • SCNLookAtConstraint with sceneView.pointOfView as the target, but this rotates the node to face away from the camera, resulting in backwards text, and unable to change the nodes position or euler angle.

Out of the box, an SKLabelNode will always face the camera in ARKit, which is exactly what I want, except using SCNText.

like image 871
klmitchell2 Avatar asked Aug 16 '17 21:08

klmitchell2


2 Answers

You should check out SCNBillboardConstraint

Updated Code

let textGeometry = SCNText(string: "Hello, World!", extrusionDepth: 1.0)
textGeometry.font = UIFont(name: "Arial", size: 2)
textGeometry.firstMaterial!.diffuse.contents = UIColor.red
let textNode = SCNNode(geometry: textGeometry)

// Update object's pivot to its center
// https://stackoverflow.com/questions/44828764/arkit-placing-an-scntext-at-a-particular-point-in-front-of-the-camera
let (min, max) = textGeometry.boundingBox
let dx = min.x + 0.5 * (max.x - min.x)
let dy = min.y + 0.5 * (max.y - min.y)
let dz = min.z + 0.5 * (max.z - min.z)
textNode.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)

textNode.scale = SCNVector3(0.01, 0.01, 0.01)

let plane = SCNPlane(width: 0.2, height: 0.2)
let blueMaterial = SCNMaterial()
blueMaterial.diffuse.contents = UIColor.blue
plane.firstMaterial = blueMaterial
let parentNode = SCNNode(geometry: plane) // this node will hold our text node

let yFreeConstraint = SCNBillboardConstraint()
yFreeConstraint.freeAxes = .Y // optionally
parentNode.constraints = [yFreeConstraint] // apply the constraint to the parent node

parentNode.position = SCNVector3(0, 0, -0.5)
parentNode.addChildNode(textNode)

sceneView.scene.rootNode.addChildNode(parentNode) // add our text holder to the scene

It seems that applying billboard constraint directly to the text node resets its position and scale, so the text node gets huge and positioned at 0,0,0 relative to the camera. Don't know why :( But applying the constraint to the parent node works fine.

like image 166
swasta Avatar answered Oct 05 '22 09:10

swasta


You were almost there!

Just modify the text's node's pivot to rotate it by 180 degrees (Obj-C).

node.pivot = SCNMatrix4MakeRotation(M_PI, 0, 1, 0);
like image 35
diviaki Avatar answered Oct 05 '22 09:10

diviaki