0

My ultimate goal is to have an SCNNode representing an image floating in space. This is more or less easily accomplished with the current code I have below, but the problem is that the back side of the image isn't rendered and is thus transparent from the back. I want to be able to display a different image on the back so that there is something to see from both sides. the isDoubleSided property doesn't work here because it simply mimics what's on the front. Any Ideas? I looked into the idea of creating my own geometry from Sources and Elements but it seemed very complex for what should be really simple.

My current code:

private func createNode() -> SCNNode{
    let scaleFactor = image.size.width/0.2
    let width = image.size.width/scaleFactor
    let height = image.size.height/scaleFactor

    let geometry = SCNPlane(width: width, height: height)
    let material = SCNMaterial()
    material.diffuse.contents = image
    geometry.materials = [material]

    return SCNNode(geometry: geometry)
}

Thanks!

TheBrownCoder
  • 1,186
  • 1
  • 10
  • 18
  • Hi! Im working on an AR project too! Can you please show in your example code how you declare the image variable? – user287474 Jan 31 '18 at 20:31
  • @user287474 Check out my github and then let me know if you have any more questions! https://github.com/aivantg/ar-invaders – TheBrownCoder Jan 31 '18 at 23:41

1 Answers1

2

Since you want different images, you need to use different materials. SceneKit allows specifying material per geometry element. SCNPlane has only one element, that's why isDoubleSided just mirrors image on the back side. You have two options here:

  • Create two SCNPlane geometries, orient them back to back and assign different images to each geometry.firstMaterial.diffuse.contents
  • Create custom SCNGeometry from SCNGeometrySource (4 vertices of plane) and two SCNGeometryElements (one for each side: 2 triangles, 6 indices), and assign array of two materials (different images) to geometry.

The first option is easier, but looks more like a workaround.

Ef Dot
  • 768
  • 6
  • 18
  • So would that first option entail just adding a child node and putting it right behind the first plane? – TheBrownCoder Aug 07 '17 at 13:39
  • Tried it once I got to a computer and it worked! Thanks :) – TheBrownCoder Aug 07 '17 at 22:37
  • Another option is to use an SCNBox with a very small z value, then map the "front" and "back" planes of the box, which appear to be element 0 (front) and element 2 (back) of the material array. `boxGeometry.materials = [frontMat, baseMat, backMat, baseMat, baseMat, baseMat]` – Ben Stahl Jul 16 '19 at 22:28