學(xué)習(xí)SceneKit之材質(zhì)

本系列所有文章目錄

獲取示例代碼


前言

前面我們介紹了幾何體的相關(guān)知識(shí)胜蛉,這篇我將為大家介紹材質(zhì),那什么是材質(zhì)呢色乾?簡單來說誊册,就是你的幾何體的外觀,比如是什么顏色暖璧,反光強(qiáng)度等等案怯。那么在SceneKit中我們可以改變幾何體的哪些外觀呢?接下來我將一一介紹澎办。

光照模型

提到材質(zhì)就不得不提到光照模型嘲碱。在現(xiàn)實(shí)生活中,我們有太陽局蚀,日光燈麦锯,蠟燭等可以產(chǎn)生光的光源,光照射在物體上琅绅,不同的物體呈現(xiàn)出不同的質(zhì)感扶欣,這些都是很平常的事情。但是在計(jì)算機(jī)里,想要使用光源照射3D模型料祠,產(chǎn)生出想要的質(zhì)感就不是那么平常了骆捧。在OpenGL中,我們需要使用Shader根據(jù)提供的材質(zhì)參數(shù)和光照來計(jì)算每個(gè)像素的顏色髓绽,從而產(chǎn)生物體被光照射的感覺敛苇。想要了解Shader中是如何實(shí)現(xiàn)光照模型的可以看我的兩篇文章基本光照高級光照。其中有涉及到lambert和blinn兩種光照模型顺呕。下面我將結(jié)合SceneKit簡單的介紹這兩種光照模型枫攀。

Lambert

在SceneKit中,使用SCNMaterial來表示材質(zhì)塘匣。SCNMaterial的一個(gè)屬性lightingModel表示的就是使用何種光照模型巷帝。如果我們選擇Lambert光照模型忌卤,并且設(shè)置如下屬性驰徊,并且把material賦給球形幾何體geometry

let material = SCNMaterial()
material.lightingModel = .lambert
material.diffuse.contents = UIColor.red
material.ambient.contents = UIColor.init(white: 0.1, alpha: 1)
material.locksAmbientWithDiffuse = false
geometry.materials = [material]

那么渲染出來的球體將會(huì)如下所示棍厂。


我們使用的燈光在(0,6,3)處超陆,所以球體上面是照射到燈光的,下面是灰色的时呀。這里涉及到了兩個(gè)光照分量,diffuseambient谨娜。diffuse表示幾何體的本色,所以燈光照射到的部分就是本色紅色趴梢,注意我用的燈光是白色的漠畜,如果燈光是其他顏色,則會(huì)和幾何體的本色混合坞靶,也就是兩個(gè)顏色進(jìn)行3維向量乘法憔狞。那燈光照射不到的地方呢?就是ambient環(huán)境光彰阴。環(huán)境光的出現(xiàn)是為了讓燈光照射不到的地方不會(huì)是全黑瘾敢,你可以試試把環(huán)境光改成其他顏色,看看渲染結(jié)果如何。由于PBR光照模型中ambientdiffuse是鎖定的廉丽,所以需要把locksAmbientWithDiffuse設(shè)置為false倦微,否則ambient只能和diffuse取相同的值。關(guān)于PBR光照模型我會(huì)在后面的文章單獨(dú)介紹正压。最后將material賦值給幾何體欣福,這里material是被放在一個(gè)數(shù)組里賦值的,如果你的幾何體有多個(gè)element焦履,系統(tǒng)會(huì)根據(jù)順序?yàn)槊總€(gè)element提供不同的材質(zhì)拓劝。第n個(gè)element會(huì)得到第n%材質(zhì)個(gè)數(shù)個(gè)材質(zhì)。

diffuse還和法線相關(guān)嘉裤,法線和光線的夾腳越小郑临,則越亮。法線就是上一篇代碼里的normals屑宠。

總的來說厢洞,Lambert模型就是最終顏色=光線和法線夾腳系數(shù)*光照顏色*本色diffuse + 環(huán)境色ambient

Blinn

Blinn光照模型其實(shí)就是在lambert基礎(chǔ)上加上高光典奉,我們將光照模型修改為.blinn躺翻,再設(shè)置高光的屬性。

material.lightingModel = .blinn
material.specular.contents = UIColor.white
material.shininess = 1.0

當(dāng)光線被反射后和我們視線的夾腳比較小的時(shí)候卫玖,在金屬或者玻璃等反光材質(zhì)下公你,會(huì)看到非常亮的區(qū)域,我們稱之為高光假瞬。越是光滑的物體陕靠,高光區(qū)域會(huì)越小。我們用shininess來表示物體的表面有多閃(光滑)脱茉,它的值從0到1剪芥。值越大,越光滑芦劣。下面是值為0.2和1的效果圖粗俱。material.specular表示高光的顏色,不過最終呈現(xiàn)的高光顏色受material.specular和燈光的顏色共同影響寸认,是它們顏色值的三維向量相乘偏塞。

shininess = 0.2

shininess = 1.0

材質(zhì)參數(shù)的取值

上面我只給材質(zhì)的參數(shù)賦予了顏色值灸叼,除了顏色古今,還可以賦予貼圖,或者說是圖片氓拼。diffusespecular都是可以接受圖片對象的抵碟。比如給diffuse賦值一張地球的貼圖。

material.diffuse.contents = UIImage.init(named: "earth.jpg")
從google淘來的地球貼圖

效果如下撬统。



specular接受的貼圖就比較特殊,是一張黑白兩色的圖颅崩。圖中黑色對應(yīng)的地方將沒有高光蕊苗。


下面兩張圖分別是使用了和沒使用specular貼圖的效果圖朽砰。第一張圖中明顯大海部分沒有高光。


使用了specular貼圖

沒有使用specular貼圖

不管是什么貼圖,都是需要幾何體提供UV數(shù)據(jù)的造锅,也就是所謂的貼圖坐標(biāo)哥蔚,在上一篇的代碼中有涉及到。

let uvs: [CGPoint] = [
        CGPoint(x: 0, y: 1),
        CGPoint(x: 0, y: 0),
        CGPoint(x: 1, y: 0),
        CGPoint(x: 1, y: 1),
        ]
    let uvSource = SCNGeometrySource.init(textureCoordinates:
uvs)

系統(tǒng)提供的球形幾何體已經(jīng)有了UV數(shù)據(jù)渤愁,所以才可以輕松的進(jìn)行貼圖抖格,關(guān)于貼圖的更多信息,會(huì)在后面的文章中介紹收奔,或者你也可以去看我寫的基于OpenGL的貼圖文章滓玖。

反射貼圖

SceneKit還提供了反射貼圖功能呢撞,可以使用CubeMap或者SphereMap來當(dāng)作環(huán)境貼圖殊霞。這里我只為大家演示一下,更深入的介紹會(huì)在后面的文章中進(jìn)行棒卷。下面是設(shè)置反射貼圖的代碼祝钢。cube-X.jpg等圖片都在demo項(xiàng)目中拦英。

material.reflective.contents = [
    UIImage.init(named: "cube-1.jpg"),
    UIImage.init(named: "cube-2.jpg"),
    UIImage.init(named: "cube-3.jpg"),
    UIImage.init(named: "cube-4.jpg"),
    UIImage.init(named: "cube-5.jpg"),
    UIImage.init(named: "cube-6.jpg"),
]
material.fresnelExponent = 1.7

效果圖如下疤估。是不是有一種被玻璃包裹的感覺。反射貼圖主要就是通過對CubeMap或者SphereMap的反射钞瀑,模擬物體反射周圍環(huán)境的一種技術(shù)雕什。


法線貼圖

我們上面有說過我們會(huì)給幾何體提供法線數(shù)據(jù)贷岸,但是這些數(shù)據(jù)是每個(gè)頂點(diǎn)才有一個(gè)吧碾,頂點(diǎn)之間區(qū)域的法線就只能通過線性插值來計(jì)算了倦春。法線貼圖則是通過貼圖的方式來彌補(bǔ)這一缺陷,更多原理性質(zhì)的介紹就不在這展開了尿庐,下面是例子用的法線貼圖。


通過CrazyBump生成

代碼設(shè)置也很簡單凡泣。

material.normal.contents = UIImage.init(named: "earth_NRM.png")

效果如下鞋拟。是不是瞬間有了凹凸感惹资。


總結(jié)

這篇文章主要介紹了材質(zhì)的一些基本功能褪测,還有很多其他的功能是沒有提到的。東西其實(shí)很多懈叹,要在一篇文章中全部鋪開不現(xiàn)實(shí)澄成,看完這一篇讀者心中對光照模型和材質(zhì)有個(gè)基本了解就可以了环揽。后面的文章會(huì)針對材質(zhì)中比較復(fù)雜的特性逐一進(jìn)行深入介紹庵佣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巴粪,一起剝皮案震驚了整個(gè)濱河市肛根,隨后出現(xiàn)的幾起案子派哲,更是在濱河造成了極大的恐慌芭届,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件持隧,死亡現(xiàn)場離奇詭異屡拨,居然都是意外死亡呀狼,警方通過查閱死者的電腦和手機(jī)赠潦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門她奥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怎棱,“玉大人拳恋,你說我怎么就攤上這事∠读蓿” “怎么了梆暖?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵厚掷,是天一觀的道長冒黑。 經(jīng)常有香客問我抡爹,道長芒划,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任苔可,我火速辦了婚禮焚辅,結(jié)果婚禮上同蜻,老公的妹妹穿的比我還像新娘湾蔓。我一直安慰自己默责,他們只是感情好咸包,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布烂瘫。 她就那樣靜靜地躺著,像睡著了一般坟比。 火紅的嫁衣襯著肌膚如雪芦鳍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天葛账,我揣著相機(jī)與錄音柠衅,去河邊找鬼。 笑死注竿,一個(gè)胖子當(dāng)著我的面吹牛茄茁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播巩割,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼付燥!你這毒婦竟也來了宣谈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤闻丑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后叁执,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琼牧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年抱究,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勋拟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啸胧。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陷谱,死狀恐怖渣窜,靈堂內(nèi)的尸體忽然破棺而出详瑞,到底是詐尸還是另有隱情,我是刑警寧澤驳庭,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布贝淤,位于F島的核電站,受9級特大地震影響离陶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜传藏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸叉弦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春呛占,著一層夾襖步出監(jiān)牢的瞬間糙捺,已是汗流浹背竟痰。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工莽鸿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粘拾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像暇咆,于是被迫代替她去往敵國和親爸业。 傳聞我的和親對象是個(gè)殘疾皇子扯旷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容