在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ Scene Kit
與四軸無(wú)人機(jī)的通訊
在沙盒中編寫(xiě)腳本
結(jié)構(gòu)體和值類型
深入理解 CocoaPods
UICollectionView + UIKit 力學(xué)
NSString 與 Unicode
代碼簽名探析
測(cè)試
架構(gòu)
第二期-并發(fā)編程
Metal
自定義控件
iOS 中的行為
行為驅(qū)動(dòng)開(kāi)發(fā)
Collection View 動(dòng)畫(huà)
截圖測(cè)試
MVVM 介紹
使 Mac 應(yīng)用數(shù)據(jù)腳本化
一個(gè)完整的 Core Data 應(yīng)用
插件
字符串
為 iOS 建立 Travis CI
先進(jìn)的自動(dòng)布局工具箱
動(dòng)畫(huà)
為 iOS 7 重新設(shè)計(jì) App
XPC
從 NSURLConnection 到 NSURLSession
Core Data 網(wǎng)絡(luò)應(yīng)用實(shí)例
GPU 加速下的圖像處理
自定義 Core Data 遷移
子類
與調(diào)試器共舞 - LLDB 的華爾茲
圖片格式
并發(fā)編程:API 及挑戰(zhàn)
IP,TCP 和 HTTP
動(dòng)畫(huà)解釋
響應(yīng)式 Android 應(yīng)用
初識(shí) TextKit
客戶端
View-Layer 協(xié)作
回到 Mac
Android
Core Image 介紹
自定義 Formatters
Scene Kit
調(diào)試
項(xiàng)目介紹
Swift 的強(qiáng)大之處
測(cè)試并發(fā)程序
Android 通知中心
調(diào)試:案例學(xué)習(xí)
從 UIKit 到 AppKit
iOS 7 : 隱藏技巧和變通之道
安全
底層并發(fā) API
消息傳遞機(jī)制
更輕量的 View Controllers
用 SQLite 和 FMDB 替代 Core Data
字符串解析
終身學(xué)習(xí)的一代人
視頻
Playground 快速原型制作
Omni 內(nèi)部
同步數(shù)據(jù)
設(shè)計(jì)優(yōu)雅的移動(dòng)游戲
繪制像素到屏幕上
相機(jī)與照片
音頻 API 一覽
交互式動(dòng)畫(huà)
常見(jiàn)的后臺(tái)實(shí)踐
糟糕的測(cè)試
避免濫用單例
數(shù)據(jù)模型和模型對(duì)象
Core Data
字符串本地化
View Controller 轉(zhuǎn)場(chǎng)
照片框架
響應(yīng)式視圖
Square Register 中的擴(kuò)張
DTrace
基礎(chǔ)集合類
視頻工具箱和硬件加速
字符串渲染
讓東西變得不那么糟
游戲中的多點(diǎn)互聯(lián)
iCloud 和 Core Data
Views
虛擬音域 - 聲音設(shè)計(jì)的藝術(shù)
導(dǎo)航應(yīng)用
線程安全類的設(shè)計(jì)
置換測(cè)試: Mock, Stub 和其他
Build 工具
KVC 和 KVO
Core Image 和視頻
Android Intents
在 iOS 上捕獲視頻
四軸無(wú)人機(jī)項(xiàng)目
Mach-O 可執(zhí)行文件
UI 測(cè)試
值對(duì)象
活動(dòng)追蹤
依賴注入
Swift
項(xiàng)目管理
整潔的 Table View 代碼
Swift 方法的多面性
為什么今天安全仍然重要
Core Data 概述
Foundation
Swift 的函數(shù)式 API
iOS 7 的多任務(wù)
自定義 Collection View 布局
測(cè)試 View Controllers
訪談
收據(jù)驗(yàn)證
數(shù)據(jù)同步
自定義 ViewController 容器轉(zhuǎn)場(chǎng)
游戲
調(diào)試核對(duì)清單
View Controller 容器
學(xué)無(wú)止境
XCTest 測(cè)試實(shí)戰(zhàn)
iOS 7
Layer 中自定義屬性的動(dòng)畫(huà)
第一期-更輕量的 View Controllers
精通 iCloud 文檔存儲(chǔ)
代碼審查的藝術(shù):Dropbox 的故事
GPU 加速下的圖像視覺(jué)
Artsy
照片擴(kuò)展
理解 Scroll Views
使用 VIPER 構(gòu)建 iOS 應(yīng)用
Android 中的 SQLite 數(shù)據(jù)庫(kù)支持
Fetch 請(qǐng)求
導(dǎo)入大數(shù)據(jù)集
iOS 開(kāi)發(fā)者的 Android 第一課
iOS 上的相機(jī)捕捉
語(yǔ)言標(biāo)簽
同步案例學(xué)習(xí)
依賴注入和注解,為什么 Java 比你想象的要好
編譯器
基于 OpenCV 的人臉識(shí)別
玩轉(zhuǎn)字符串
相機(jī)工作原理
Build 過(guò)程

Scene Kit

在 WWDC 2012 (那時(shí) OS X 系統(tǒng)還在用喵系命名),Apple 向 OS X 開(kāi)發(fā)者們介紹了 Scene Kit,這個(gè) Cocoa 下的 3D 渲染框架。在第一版通用 3D 渲染器發(fā)布后,一年內(nèi)又陸續(xù)增加了像 shader (著色器) 修改器、節(jié)點(diǎn)約束、骨骼動(dòng)畫(huà)等幾個(gè)強(qiáng)大的特性 (隨 Mavericks 發(fā)布)。今年,Scene Kit 變的更加強(qiáng)大,支持了粒子效果、物理引擎、腳本事件以及多通道分層渲染等多種技術(shù),而且,對(duì)于很多人來(lái)說(shuō)更關(guān)鍵的是,它終于可以在 iOS 中使用了。

一上手,我發(fā)現(xiàn) Scene Kit 最強(qiáng)大和脫穎而出的地方,就是可以與 Core Image,Core Animation,Sprite Kit 等已有的圖形框架相互整合及協(xié)作,這在其他游戲引擎中可不常見(jiàn),但如果你本身就是個(gè) Cocoa 或 Cocoa Touch 框架下的的開(kāi)發(fā)者的話,就會(huì)感到相當(dāng)親切了。

Scene Kit 概要

Scene Kit 建立在 OpenGL 的基礎(chǔ)上,包含了如光照、模型、材質(zhì)、攝像機(jī)等高級(jí)引擎特性,這些組件都是面向?qū)ο蟮?,你可以用熟悉?Objective-C 或 Swift 語(yǔ)言來(lái)編寫(xiě)代碼。假如你用過(guò) OpenGL 最早的版本,那時(shí)還沒(méi)有 shader,只能苦逼的使用各種底層受限制的 API 開(kāi)發(fā)。而 Scene Kit 就好了很多,對(duì)于大多數(shù)需求 (甚至像動(dòng)態(tài)陰影和景深這種高級(jí)特性),使用它提供的上層 API 來(lái)配置,就已經(jīng)足夠了。

不僅如此,Scene Kit 還允許你直接調(diào)用底層 API,或自己寫(xiě) shader 進(jìn)行手動(dòng)渲染 (GLSL)。

節(jié)點(diǎn) (Nodes)

不僅是光照、模型、材質(zhì)、攝像機(jī)這幾個(gè)具體的對(duì)象,Scene Kit 使用節(jié)點(diǎn) (在3D圖形學(xué)中,像這樣的樹(shù)狀節(jié)點(diǎn)結(jié)構(gòu)一般被稱做 scene graph,這也是 Scene Kit 名稱由來(lái)的一種解釋) 以樹(shù)狀結(jié)構(gòu)來(lái)組織內(nèi)容,每個(gè)節(jié)點(diǎn)都存儲(chǔ)了相對(duì)其父節(jié)點(diǎn)的位移、旋轉(zhuǎn)角度、縮放等信息,父節(jié)點(diǎn)也是如此,一直向上,直到根節(jié)點(diǎn)。假如要給一個(gè)節(jié)點(diǎn)確定一個(gè)位置,就必須將它掛載到節(jié)點(diǎn)樹(shù)中的某個(gè)節(jié)點(diǎn)上,可以使用下面的幾個(gè)操作方法:

  • addChildNode(_:)
  • insertChildNode(_: atIndex:)
  • removeFromParentNode()

這些方法與 iOS 和 OS X 中管理 view 和 layer 層級(jí)方法如出一轍。

幾何模型對(duì)象

Scene Kit 內(nèi)建了幾種簡(jiǎn)單的幾何模型,如盒子、球體、平面、圓錐體等,但對(duì)于游戲來(lái)說(shuō),一般都會(huì)從文件中加載3D模型。你可以通過(guò)制定文件名來(lái)導(dǎo)入 (或?qū)С? COLLADA 格式的模型文件:

let chessPieces = SCNScene(named: "chess pieces") // SCNScene?

如果一個(gè)從文件里加載的場(chǎng)景可以全部顯示時(shí),將其設(shè)置成 SCNView 的 scene 就好了;但如果加載的場(chǎng)景文件中包含了多個(gè)對(duì)象,只有一部分對(duì)象要顯示在屏幕上時(shí),就可以通過(guò)名字找到這個(gè)對(duì)象,再手動(dòng)加載到 view 上:

if let knight = chessPieces.rootNode.childNodeWithName("Knight", recursively: true) {
    sceneView.scene?.rootNode.addChildNode(knight)
}

這是一個(gè)對(duì)導(dǎo)入文件原始節(jié)點(diǎn)的引用,其中包含了任一和每一個(gè)子節(jié)點(diǎn),也包括了模型對(duì)象 (包括其材質(zhì)),光照,以及綁定在這些節(jié)點(diǎn)上的攝像機(jī)。只要傳入的名字一樣,不論調(diào)用多少次,返回的都是對(duì)同一個(gè)對(duì)象的引用。

http://wiki.jikexueyuan.com/project/objc/images/18-4.png" alt="" />

若需要在場(chǎng)景中擁有一個(gè)節(jié)點(diǎn)的多個(gè)拷貝,如在一個(gè)國(guó)際象棋棋盤上顯示兩個(gè)馬,你可以對(duì)馬這個(gè)節(jié)點(diǎn)進(jìn)行 copyclone (遞歸的copy)。這將會(huì)拷貝一份節(jié)點(diǎn)的引用,但兩份引用所指向的材質(zhì)對(duì)象和模型對(duì)象仍然是原來(lái)那個(gè)。所以,想要單獨(dú)改變副本材質(zhì)的話,需要再copy一份模型對(duì)象,并對(duì)這個(gè)新的模型對(duì)象設(shè)置新材質(zhì)。copy一個(gè)模型對(duì)象的速度仍然很快,開(kāi)銷也不高,因?yàn)楦北疽玫捻旤c(diǎn)數(shù)據(jù)還是同一份。

帶有骨骼動(dòng)畫(huà)的模型對(duì)象也會(huì)擁有一個(gè)皮膚對(duì)象,它提供了對(duì)骨骼中各個(gè)節(jié)點(diǎn)的訪問(wèn)接口,以及管理骨骼和模型間連接的功能。每個(gè)單獨(dú)的骨骼都可以被移動(dòng)和旋轉(zhuǎn),而復(fù)雜的動(dòng)畫(huà)需要同時(shí)對(duì)多塊骨骼進(jìn)行操作,如一個(gè)角色走路的動(dòng)畫(huà),很可能就是從文件讀取并加到對(duì)象上的 (而不是用代碼一根骨頭一根骨頭的寫(xiě))。

光照

Scene Kit 中完全都是動(dòng)態(tài)光照,使用起來(lái)一般會(huì)很簡(jiǎn)單,但也意味著與完整的游戲引擎相比,光照這塊進(jìn)步并不明顯。Scene Kit 提供四種類型的光照:環(huán)境光、定向光源、點(diǎn)光源和聚光燈。

通常來(lái)說(shuō),旋轉(zhuǎn)坐標(biāo)軸和變換角度并不是設(shè)定光照的最佳方法。下面的例子表示一個(gè)光照對(duì)象通過(guò)一個(gè)節(jié)點(diǎn)對(duì)象來(lái)設(shè)置空間坐標(biāo),再通過(guò) "look at" 約束,將光照對(duì)象約束到了目標(biāo)對(duì)象上,即使它移動(dòng),光照也會(huì)一直朝向目標(biāo)對(duì)象。

let spot = SCNLight()
spot.type = SCNLightTypeSpot
spot.castsShadow = true

let spotNode = SCNNode()
spotNode.light = spot
spotNode.position = SCNVector3(x: 4, y: 7, z: 6)

let lookAt = SCNLookAtConstraint(target: knight)
spotNode.constraints = [lookAt]

http://wiki.jikexueyuan.com/project/objc/images/18-5.gif" alt="" />

動(dòng)畫(huà)

Scene Kit 的對(duì)象中絕大多數(shù)屬性都是可以進(jìn)行動(dòng)畫(huà)的,就像 Cocoa (或 Cocoa Touch) 框架一樣,你可以創(chuàng)建一個(gè) CAAnimation 對(duì)象,并指定一個(gè) key path (甚至可以 "position.x") ,然后向一個(gè)對(duì)象施加這個(gè)動(dòng)畫(huà)。同樣的,你可以在 SCNTransaction 的 "begin" 和 "commit" 調(diào)用間去改變值,和剛才的 CAAnimation 非常相似:

let move = CABasicAnimation(keyPath: "position.x")
move.byValue  = 10
move.duration = 1.0
knight.addAnimation(move, forKey: "slide right")

Scene Kit 也提供了像 Sprite Kit 那樣的 action 形式的動(dòng)畫(huà) API,你可以創(chuàng)建串行的動(dòng)畫(huà)組,也支持自定義 action 來(lái)協(xié)同使用。與 Core Animation 不同的是,這些 action 作為游戲循環(huán)的一部分執(zhí)行,在每一幀都更新模型對(duì)象的值,而不只是更新表現(xiàn)層的節(jié)點(diǎn)。

假如你之前用過(guò) Sprite Kit,會(huì)發(fā)現(xiàn) Scene Kit 除了變成了 3D 之外,沒(méi)有太多陌生的東西。目前,在 iOS8 (首次支持 Scene Kit) 和 OS X 10.10 下,Scene Kit 和 Sprite Kit 可以協(xié)同工作:對(duì) Sprite Kit 來(lái)說(shuō),3D 模型可以與 2D 精靈混合使用;對(duì) Scene Kit 來(lái)說(shuō),Sprite Kit 中的場(chǎng)景和紋理可以作為 Scene Kit 的紋理貼圖,而且 Sprite Kit 的場(chǎng)景可以作為 Scene Kit 場(chǎng)景的蒙層 (如3D游戲中的2D菜單面板,譯者注。兩套非常像的API和概念 (像場(chǎng)景啊,節(jié)點(diǎn)啊,約束啊兩邊都有) 讓人容易混淆。)

開(kāi)始用 Scene Kit 寫(xiě)游戲

不僅是動(dòng)作和紋理,Scene Kit 和 Sprite Kit 還有很多相同之處。當(dāng)開(kāi)始寫(xiě)游戲的時(shí)候,Scene Kit 和它 2D 版本的小伙伴非常相似,它們的游戲循環(huán)步驟完全一致,使用下面幾個(gè)代理回調(diào):

  1. 更新場(chǎng)景
  2. 應(yīng)用動(dòng)畫(huà)/動(dòng)作
  3. 模擬物理效果
  4. 應(yīng)用約束
  5. 渲染

http://wiki.jikexueyuan.com/project/objc/images/18-6.png" alt="" />

這些回調(diào)在每幀被調(diào)用,并用來(lái)執(zhí)行游戲相關(guān)的邏輯,如用戶輸入,AI (人工智能) 和游戲腳本。

處理用戶輸入

Scene Kit 與普通 Cocoa 或 Cocoa Touch 應(yīng)用使用一樣的機(jī)制來(lái)處理用戶輸入,如鍵盤事件、鼠標(biāo)事件、觸摸事件和手勢(shì)識(shí)別,而主要區(qū)別在于 Scene Kit 中只有一個(gè)視圖,場(chǎng)景視圖 (scene view) 。像鍵盤事件或如捏取、滑動(dòng)、旋轉(zhuǎn)的手勢(shì),只要知道事件的發(fā)生就好了,但像鼠標(biāo)點(diǎn)擊,或觸碰、拖動(dòng)手勢(shì)等就需要知道具體的事件信息了。

這些情況下,scene view 可以使用 -hitTest(_: options:) 來(lái)做點(diǎn)擊測(cè)試。與通常的視圖只返回被點(diǎn)擊的子 view 或子 layer 不同,Scene Kit 返回一個(gè)數(shù)組,里面存有每個(gè)相交的模型對(duì)象以及從攝像機(jī)投向這個(gè)測(cè)試點(diǎn)的射線。每個(gè) hit test 的結(jié)果包含被擊中模型的節(jié)點(diǎn)對(duì)象,也包含了交點(diǎn)的詳細(xì)信息 (交點(diǎn)坐標(biāo)、交點(diǎn)表面法線,交點(diǎn)的紋理坐標(biāo))。多數(shù)情況下,知道第一個(gè)被擊中的節(jié)點(diǎn)就足夠了:

if let firstHit = sceneView.hitTest(tapLocation, options: nil)?.first as? SCNHitTestResult  {
    let hitNode = firstHit.node
    // do something with the node that was hit...
}

擴(kuò)展默認(rèn)渲染流程

光照和材質(zhì)的配置方法很易用,但有局限性。假如你有寫(xiě)好的 OpenGL 著色器 (shader),可以用于完全自定制的進(jìn)行材質(zhì)渲染;如果你只想修改下默認(rèn)的渲染,Scene Kit 暴露了 4 個(gè)入口用于插入 shader代碼 (GLSL) 來(lái)改變默認(rèn)渲染。Scene Kit 在不同入口點(diǎn)分別提供了對(duì)旋轉(zhuǎn)矩陣、模型數(shù)據(jù)、樣本貼圖及渲染后輸出的色值的訪問(wèn)。

比如,下面的 GLSL 代碼被用在模型數(shù)據(jù)的入口點(diǎn)中,可以將模型對(duì)象上所有點(diǎn)沿 x 軸扭曲。這是通過(guò)定義一個(gè)函數(shù)來(lái)創(chuàng)建一個(gè)旋轉(zhuǎn)變換,并將其應(yīng)用在模型的位置和法線上。同時(shí),也自定義了一個(gè) "uniform" 變量來(lái)決定對(duì)象該如何被扭曲。

// a function that creates a rotation transform matrix around X
mat4 rotationAroundX(float angle)
{
    return mat4(1.0,    0.0,         0.0,        0.0,
                0.0,    cos(angle), -sin(angle), 0.0,
                0.0,    sin(angle),  cos(angle), 0.0,
                0.0,    0.0,         0.0,        1.0);
}

#pragma body

uniform float twistFactor = 1.0;
float rotationAngle = _geometry.position.x * twistFactor;
mat4 rotationMatrix = rotationAroundX(rotationAngle);

// position is a vec4
_geometry.position *= rotationMatrix;

// normal is a vec3
vec4 twistedNormal = vec4(_geometry.normal, 1.0) * rotationMatrix;
_geometry.normal   = twistedNormal.xyz;

著色修改器 (Shader modifier) 既可以綁定在模型對(duì)象上,也可以綁定在它的材質(zhì)對(duì)象上。這兩個(gè)類都完全支持 key-value coding (KVC),你可以指定任意 key 進(jìn)行賦值。在 shader 中聲明的 "twistFactor" uniform 變量使得 Scene Kit 在這個(gè)值改變時(shí)自動(dòng)重新綁定 uniform,這使得你也可以用 KVC 來(lái)實(shí)現(xiàn):

torus.setValue(5.0, forKey: "twistFactor")

使用這個(gè) key path 的 CAAnimation 也 ok:

let twist = CABasicAnimation(keyPath: "twistFactor")
twist.fromValue = 5
twist.toValue   = 0
twist.duration  = 2.0

torus.addAnimation(twist, forKey: "Twist the torus")

http://wiki.jikexueyuan.com/project/objc/images/18-7.gif" alt="" />

延時(shí)著色

即使在純 OpenGL 環(huán)境下,有些圖像效果也無(wú)法通過(guò)一次渲染 pass 完成,我們可以將不同 shader 進(jìn)行序列操作,以達(dá)到后續(xù)處理的目的,稱為延時(shí)著色。Scene Kit 使用 SCNTechnique 類來(lái)表示這種技術(shù)。它使用字典來(lái)創(chuàng)建,字典中定義了繪圖步驟、輸入輸出、shader 文件、符號(hào)等等。

第一個(gè)渲染 pass 永遠(yuǎn)是 Scene Kit 的默認(rèn)渲染,它輸出場(chǎng)景的顏色和景深。如果你不想這時(shí)計(jì)算色值,可以將材質(zhì)設(shè)置成"恒定"的光照模型,或者將場(chǎng)景里所有光照都設(shè)置成環(huán)境光。

比如,從 Scene Kit 渲染流程的第一個(gè) pass 獲取景深,第二個(gè)獲取法線,第三個(gè)對(duì)其執(zhí)行邊界檢測(cè),你即可以沿輪廓也可以沿邊緣畫(huà)粗線:

http://wiki.jikexueyuan.com/project/objc/images/18-8.png" alt="" />


延伸閱讀

如果你想了解更多使用 Scene Kit 做游戲的知識(shí)的話,我推薦今年的 WWDC 中的 "Building a Game with Scene Kit" video,并看看 Bananas sample code.

如果你想學(xué)習(xí) Scene Kit 基礎(chǔ)知識(shí),我推薦看這一年的去年的 "What's New in Scene Kit" 相關(guān)視頻。如果你還想學(xué)習(xí)更多,可以關(guān)注我即將發(fā)布的這個(gè)主題的書(shū)