Search code examples
iosswiftsprite-kitscenekitcgpath

Fill SKShapeNode CGPath SCNMaterial


I have a method that renders 2D shapes on top of a 3D sphere. I'm using SpriteKit for the 2D shapes and SceneKit for the 3D content.

I want to be able to fill the color of my SKShapeNode and then apply the material to the SCNNode

let path = generatePinPath(nodeWidth: 120)
let scene = SKScene(size: CGSize(width: 120, height: 75))
let pinShape = SKShapeNode(path: path)
pinShape.name = "A Label"
pinShape.fillColor = SKColor.red
pinShape.strokeColor = SKColor.white
pinShape.lineWidth = 3

scene.addChild(pinShape)


let materialProperty = SCNMaterial()
materialProperty.diffuse.contents = scene

planeGeometry.firstMaterial = materialProperty
planeGeometry.firstMaterial?.isDoubleSided = false

let node = SCNNode(geometry: planeGeometry)
nodes.append(node)

My generatePinPath method looks like this:

func generatePinPath(nodeWidth: Int) -> CGMutablePath {
  let path = CGMutablePath()
  path.move(to: CGPoint(x: 20, y: 0)
  path.addLine(to: CGPoint(x: CGFloat(nodeWidth - 20), y: 0))
  path.addCurve(to: CGPoint(x: CGFloat(nodeWidth - 20), y: 53), control1: CGPoint(x: CGFloat(nodeWidth), y: 0), control2: CGPoint(x: CGFloat(nodeWidth), y: 53))
  path.addLine(to: CGPoint(x: CGFloat(nodeWidth / 2) + 20, y: 53))
  path.closeSubpath()
  return path
}

When the shape renders on the 3D space, the red color is present but it is "bleeding" outside of the defined path. I don't know why this is happening, I just assumed that the path would constrain the color inside of itself. The stroke color and lines are rendering as expected.


Solution

  • It's possible that the "SpriteKit rendering inside SceneKit rendering" code path has an issue. What happens if you use a CAShapeLayer instead of SKShapeNode?