首页 > 解决方案 > How to correctly render points in SceneKit with colours including alpha values?

问题描述

I am trying to render a collection of points in SceneKit all of which have an alpha value less than 1 as part of their colour. While this seems to work, it depends on the angle at which you are looking at the point.

My current method has been to create an array of vertices with corresponding colours and indices, wrap these up inside SCNGeometrySource/SCNGeometryElement and create a custom SCNGeometry from theses. The SCNGeometryElement for the indices is set to render as points. Some sample code below of how I'm setting this up.

var vertices = [SCNVector3]()
var colors = [float4]()
var indices = [UInt32]()

for x in 0...10 {
    for y in 0...10 {
        for z in 0...10 {
            vertices.append(SCNVector3(x - 5, y - 5, z - 5))
            colors.append(float4(0.7, 0.7, 0.7, 0.1))
            indices.append(UInt32(vertices.count - 1))
        }
    }
}

let vertexSource = SCNGeometrySource(vertices: vertices)

let colorsData = Data(bytes: &colors, count: colors.count * MemoryLayout<float4>.stride)
let colorSource = SCNGeometrySource(data: colorsData, semantic: .color, vectorCount: colors.count, usesFloatComponents: true, componentsPerVector: 4, bytesPerComponent: MemoryLayout<Float>.stride, dataOffset: 0, dataStride: MemoryLayout<float4>.stride)

let pointsElement = SCNGeometryElement(indices: indices, primitiveType: .point)
pointsElement.pointSize = 0.2
pointsElement.minimumPointScreenSpaceRadius = 1
pointsElement.maximumPointScreenSpaceRadius = 50

let geometry = SCNGeometry(sources: [vertexSource, colorSource], elements: [pointsElement])
let node = SCNNode(geometry: geometry)

scene.rootNode.addChildNode(node)

When my camera node is located as follow, everything looks good:

cameraNode.eulerAngles = SCNVector3(0, 0.5 * CGFloat.pi, 0)
cameraNode.position = SCNVector3(x: 10, y: 0, z: 0)

Expected rendering

However if I move my camera to the next face of the cube clockwise the alpha no longer renders:

cameraNode.eulerAngles = SCNVector3(0, -0.5 * CGFloat.pi, 0)
cameraNode.position = SCNVector3(x: -10, y: 0, z: 0)

Undesired rendering

Placing the camera half way gives a combination of the two:

cameraNode.eulerAngles = SCNVector3(0, 0, 0)
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)

Semi-expected rendering

标签: swiftmacosscenekitmetal

解决方案


推荐阅读