ios 3D引擎 SceneKit 開發(8) --SCNShape 的使用
部落格寫的沒有系統性,真是想到那寫到那。
前天有小夥伴問:
如何將一個2D的圖案轉化成具有深度的3D模型
其實很簡單,用SCNShape 就可以實現了,看到SCNShape,我們就會立刻想到CAShapeLayer,沒錯,我們可以用貝塞爾曲線畫一個2D 圖案,然後在設定一個Depth 就可以了,非常簡單,用法如下:
SCNShape *customShape = [SCNShape shapeWithPath:[self getBezierPath] extrusionDepth:4];
SCNNode *shapeNode = [SCNNode nodeWithGeometry:customShape];
[self getBezierPath] 為建立一個貝塞爾曲線的方法,大家這裡可以隨意建立自己的2D方案。
效果如下圖:
接下來我們說說 SCNShape 的 chamferRadius 這個屬性 , 字面意思:倒角半徑,很難理解對不對。我們在上圖中看到,生成的模型是有稜有角的,那我們拿銼刀把它打磨圓滑一點
customShape.chamferRadius = 0.5;
效果如下圖:
對比兩幅圖,我們可以一目瞭然的看到chamferRadius這個屬性的作用。chamferRadius的取值範圍[0, extrusionDepth / 2],預設值是0.
而接下來 chamferMode 這個屬性就決定我們拿 銼刀 只銼前面的一面,還是隻銼後面的一面,還是兩面都銼,它的值是個列舉值,如下:
typedef NS_ENUM(NSInteger, SCNChamferMode) {
SCNChamferModeBoth,
SCNChamferModeFront,
SCNChamferModeBack
} NS_ENUM_AVAILABLE(10_9, 8_0);
預設值為SCNChamferModeBoth
前面講過 長方體 有六個面可以貼不同的材質,而用SCNShape生成的幾何體兩面都銼的話,會生成5個面貼不同的材質,大家可能不清楚有那五個面,那我們再給他們設定材質,大家就會一目瞭然。
customShape.materials = @[[self differentColorMaterial:[UIColor redColor]],
[self differentColorMaterial:[UIColor greenColor]],
[self differentColorMaterial:[UIColor blueColor]],
[self differentColorMaterial:[UIColor yellowColor]],
[self differentColorMaterial:[UIColor whiteColor]]
];
-(SCNMaterial *)differentColorMaterial:(UIColor *)color{
SCNMaterial *material = [SCNMaterial material];
material.ambient.contents = material.diffuse.contents = material.specular.contents = [UIColor blackColor];
material.emission.contents = color;
return material;
}
從上圖所知五個面分別是:[前面,後面,側面,前銼面,後銼面];
如果我們把前面,後面,側面,後銼面 的材質設定為透明,並且把 chamferRadius 的值設定小一點的話,就會看到一個有趣的情況:
customShape.chamferRadius = 0.2;
SCNMaterial *outlineMaterial = [SCNMaterial material];
outlineMaterial.ambient.contents = outlineMaterial.diffuse.contents = outlineMaterial.specular.contents = [UIColor blackColor];
outlineMaterial.emission.contents = [UIColor whiteColor];
outlineMaterial.doubleSided = YES;
SCNMaterial *tranparentMaterial = [SCNMaterial material];
tranparentMaterial.transparency = 0.0;
customShape.materials = @[tranparentMaterial, tranparentMaterial, tranparentMaterial, outlineMaterial, tranparentMaterial];
如下圖,形成一個輪廓:
OK, 我們在額外畫一個特殊的東西:
注意DEMO 中 的 程式碼:
shape.chamferMode = SCNChamferModeFront;
shape.materials = @[tranparentMaterial, tranparentMaterial, tranparentMaterial, outlineMaterial, outlineMaterial];
由於我們只生成了前銼面,即使我們給後銼面設定了 白色材質outlineMaterial,它也是不起作用的。
注意點:
chamferMode 依賴於 chamferRadius,只有當chamferRadius 大於 0 時, chamferMode
才起作用。生成的材質面個數依賴於chamferMode,當然更依賴於chamferRadius,最少3個,最多5個。
模擬器有鋸齒,建議真機檢視。
偷懶寫不動了,chamferProfile 這個屬性的介紹後面再補吧。