Reputation: 2463
I'm trying to make my geometry look flat and not smooth in SceneKit. As you can see in the images, the green sphere has smooth shading by default in SceneKit. What I want is the flat "look" in the other image where it says "flat".
I don't see any options in SceneKit on how to disable this feature?
This is the code from my playground:
import Cocoa
import SceneKit
import QuartzCore
import XCPlayground
var sceneView = SCNView(frame:CGRect(x:0, y:0, width:300, height:300))
var scene = SCNScene()
sceneView.backgroundColor = NSColor.darkGrayColor()
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = true
XCPlaygroundPage.currentPage.liveView = sceneView
let g = SCNSphere(radius:1)
g.firstMaterial?.diffuse.contents = NSColor.greenColor()
g.firstMaterial?.litPerPixel = false
g.segmentCount = 5
let node = SCNNode(geometry:g)
node.position = SCNVector3(x:0, y:0, z:0)
scene.rootNode.addChildNode(node)
var spin = CABasicAnimation(keyPath:"rotation")
spin.toValue = NSValue(SCNVector4:SCNVector4(x:1, y:1, z:0, w:CGFloat(2.0*M_PI)))
spin.duration = 3
spin.repeatCount = HUGE
node.addAnimation(spin, forKey:"spin")
Upvotes: 4
Views: 2313
Reputation: 2127
It seems Apple will apply normal smoothing for you. This is more observe when SceneKit encounter a flat mesh. Remove the smoothed normals from mesh will make it looks low polygon.
If you use ModelI/O to load 3D asset. (For test I create MDLMesh
form SCNGeometry
)
SCNGeometry* flatGeoUsingModelIO(SCNGeometry *geo){
MDLMesh *mesh = [MDLMesh meshWithSCNGeometry:geo];
MDLMesh *newMesh = [MDLMesh newSubdividedMesh:mesh submeshIndex:0 subdivisionLevels:0];
[newMesh removeAttributeNamed:@"normals"];
//Replace current vertex normals with a non-smooth one. Same result with above line
//[newMesh addNormalsWithAttributeNamed:@"normals" creaseThreshold:1];
SCNGeometry *flatGeo = [SCNGeometry geometryWithMDLMesh:newMesh];
return flatGeo;
}
Or you are more familiar to SceneKit.
SCNGeometry* flatGeoUsingScnKit(SCNGeometry *geo){
NSArray<SCNGeometrySource*> *SourceArr = geo.geometrySources;
NSMutableArray<SCNGeometrySource*> *newSourceArr = [NSMutableArray new];
for (SCNGeometrySource *source in SourceArr) {
if (source.semantic != SCNGeometrySourceSemanticNormal) {
[newSourceArr addObject:source];
}
}
SCNGeometry *flatGeo = [SCNGeometry geometryWithSources:newSourceArr elements:geo.geometryElements];
return flatGeo;
}
This is low polygon SCNSphere
created from right one.
Upvotes: 2