1. 程式人生 > >ios 3D引擎 SceneKit 開發(8) --SCNShape 的使用

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,它也是不起作用的。

注意點:

  1. chamferMode 依賴於 chamferRadius,只有當chamferRadius 大於 0 時, chamferMode
    才起作用。

  2. 生成的材質面個數依賴於chamferMode,當然更依賴於chamferRadius,最少3個,最多5個。

  3. 模擬器有鋸齒,建議真機檢視。

  4. 偷懶寫不動了,chamferProfile 這個屬性的介紹後面再補吧。