iOS 3D 之 SceneKit框架Demo分析


Scene Kit 是Apple 向 OS X 開發者們提供的 Cocoa 下的 3D 渲染框架。  

Scene Kit 建立在 OpenGL 的基礎上,包含了如光照、模型、材質、攝像機等高級引擎特性,這些組件都是面向對象的,你可以用熟悉的 Objective-C 或 Swift 語言來編寫代碼。假如你用過 OpenGL 最早的版本,那時還沒有 shader,只能苦逼的使用各種底層受限制的 API 開發。而 Scene Kit 就好了很多,對於大多數需求 (甚至像動態陰影等高級特性),使用它提供的上層 API 來配置,就已經足夠了。

創建一個項目:

 

 

 

在demo中比一般的文件多了一個scnasssets文件夾,這個是存放3d模型的文件夾,打開可以看到.scn后綴的文件,這個就是xcode識別的模型文件后綴的一種

 

 

    // create a new scene
    //創建一個場景scene
    SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/ship.scn"];
    
    //實例化SCNcene,場景本身並不可見,需要添加在SceneView的場景上
    //創建並添加一個相冊到scene
    //這段代碼是用來創建並配置攝像機。攝像機處於的位置即視角所看的位置。  注意這里創建攝像機是創建了一個SCNNode,賦值了node的屬性。這里需要了解一下node的作用。在SceneKit中,node即節點是非常關鍵的部分。node本身同樣是不可見的,它的作用是節點化各個部件。比如一輛車,車身和方向盤都是模型,可以把方向盤的node添加在車身模型的node上,這樣在車移動的時候,車模型的子node也會一起移動。車身各部件之間的相對位置是不變的。這樣可以大大節省工作量。在渲染場景的時候,sceneKit會遍歷所有的子node,cameraNode設置了屬性camera,並把自己添加在了scene的rootNode上才會在scene顯示的時候起作用
    
    // create and add a camera to the scene
    SCNNode *cameraNode = [SCNNode node];
    cameraNode.camera = [SCNCamera camera];
    [scene.rootNode addChildNode:cameraNode];
    
    //設置camera
    // place the camera
    cameraNode.position = SCNVector3Make(0, 0, 15);
    
    //代碼用來創建並配置燈光效果。在3d成像中,燈光是很重要的一個環節。燈光和陰影可以讓物體更有質感。light的type有四種,大家可以嘗試。
    //創建light到scene
    // create and add a light to the scene
    SCNNode *lightNode = [SCNNode node];
    lightNode.light = [SCNLight light];
    lightNode.light.type = SCNLightTypeOmni;
    lightNode.position = SCNVector3Make(0, 10, 10);
    [scene.rootNode addChildNode:lightNode];
    
    
    // create and add an ambient light to the scene
    SCNNode *ambientLightNode = [SCNNode node];
    ambientLightNode.light = [SCNLight light];
    ambientLightNode.light.type = SCNLightTypeAmbient;
    ambientLightNode.light.color = [UIColor darkGrayColor];
    [scene.rootNode addChildNode:ambientLightNode];
    
    
    //得到飛機模型。注意這個方法recursively:(BOOL)的意思為是否在子node中查詢。node是樹形結構,會返回第一個遇到的@“ship”node。
    // retrieve the ship node
    SCNNode *ship = [scene.rootNode childNodeWithName:@"ship" recursively:YES];
    
    
    //讓飛機繞y軸飛行。這里的動畫是SCNAction,封裝性和使用方法與UIVIew的二維動畫類似,相當便捷。
    // animate the 3d object
    [ship runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    
    //得到用於展示的SCNView,並配置scnView的scene。
    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;
    
    // set the scene to the view
    scnView.scene = scene;
    
    
    //設置允許用戶控制攝像機,顯示狀態,(fps等)一般是在開發中用作調試的
    
    // allows the user to manipulate the camera
    scnView.allowsCameraControl = YES;
        
    // show statistics such as fps and timing information
    scnView.showsStatistics = YES;
    
    // configure the view
    scnView.backgroundColor = [UIColor blackColor];
    
    //添加手勢
    // add a tap gesture recognizer
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    NSMutableArray *gestureRecognizers = [NSMutableArray array];
    [gestureRecognizers addObject:tapGesture];
    [gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers];
    scnView.gestureRecognizers = gestureRecognizers;
    //這就是官方demo的基本內容。實現了一個模型的顯示和動畫。告訴了我們模型想變為可見,需要攝像機模擬視角,燈光和周圍燈光展示,添加在根node中。

 

- (void) handleTap:(UIGestureRecognizer*)gestureRecognize
{
    //去到SCNView
    // retrieve the SCNView
    SCNView *scnView = (SCNView *)self.view;
    
    //找到對應的node
    // check what nodes are tapped
    CGPoint p = [gestureRecognize locationInView:scnView];
    NSArray *hitResults = [scnView hitTest:p options:nil];
    
    // check that we clicked on at least one object
    if([hitResults count] > 0){
        // retrieved the first clicked object
        SCNHitTestResult *result = [hitResults objectAtIndex:0];
        
        // get its material
        SCNMaterial *material = result.node.geometry.firstMaterial;
        
        // highlight it
        [SCNTransaction begin];
        [SCNTransaction setAnimationDuration:0.5];
        
        // on completion - unhighlight
        [SCNTransaction setCompletionBlock:^{
            [SCNTransaction begin];
            [SCNTransaction setAnimationDuration:0.5];
            
            material.emission.contents = [UIColor blackColor];
            
            [SCNTransaction commit];
        }];
        
        material.emission.contents = [UIColor redColor];
        
        [SCNTransaction commit];
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM