第六節(jié) - 燈光詳解

燈光篇

本節(jié)學(xué)習(xí)目標(biāo)

今天我們要學(xué)習(xí)的SceneKit 游戲框架中的幾種光以及如何使用它們!

學(xué)習(xí)任務(wù)

1.熟悉SCNLight 類(lèi) 2.理解四種光源的作用 3.學(xué)會(huì)如何選擇在游戲場(chǎng)景中使用光源.

光的介紹

  • 環(huán)境光(SCNLightTypeAmbient)

這種光的特點(diǎn),沒(méi)有方向轴捎,位置在無(wú)窮遠(yuǎn)處,光均勻的散射到物體上.

環(huán)境光
  • 點(diǎn)光源(SCNLightTypeOmni)

有固定的位置洞渤,方向360度,可以衰減

點(diǎn)光源
  • 平行方向光(SCNLightTypeDirectional)

只有照射的方向橙凳,沒(méi)有位置,不會(huì)衰減

平行方向光源
  • 聚焦光源(SCNLightTypeSpot) 可

光源有固定的位置丘损,也有方向,也有照射區(qū)域 奕筐,可以衰減

聚焦光源

SCNLight 介紹

我們使用光源,主要用到的類(lèi)就是SCNLight,我們把這個(gè)類(lèi)的屬性分析一下舱痘。

  • 創(chuàng)建光對(duì)象

     +(instancetype)light; 
    
  • 設(shè)置燈光類(lèi)型,就是上面講的那個(gè)類(lèi)型

    @property(nonatomic, copy) NSString *type;
    
  • 燈光的顏色

     @property(nonatomic, retain) id color;
    
  • 燈光的名字,可以用來(lái)索引燈光用

    @property(nonatomic, copy, nullable) NSString *name;
    
  • 是否支持投射陰影,注意,這個(gè)屬性只在點(diǎn)光源或者平行方向光源起作用

    @property(nonatomic) BOOL castsShadow; 
    
  • 設(shè)置陰影的顏色救欧,默認(rèn)為透明度為50%的黑色

    @property(nonatomic, retain) id shadowColor;
    
  • 設(shè)置陰影的采樣角度 默認(rèn)值為3

    @property(nonatomic) CGFloat shadowRadius;
    
  • 設(shè)置陰影貼圖的大小,陰影貼圖越大衰粹,陰影越精確,但計(jì)算速度越慢笆怠。如果設(shè)置為{ 0 0}陰影貼圖的大小自動(dòng)選擇铝耻,默認(rèn)為{0,0}

    @property(nonatomic) CGSize shadowMapSize NS_AVAILABLE(10_10, 8_0);
    
  • 設(shè)置每一幀計(jì)算陰影貼圖的次數(shù)蹬刷,默認(rèn)為一次

     @property(nonatomic) NSUInteger shadowSampleCount NS_AVAILABLE(10_10, 8_0);
    
  • 設(shè)置陰影模式(默認(rèn))

    @property(nonatomic) SCNShadowMode shadowMode NS_AVAILABLE(10_10, 8_0);
    // 可選值為下面三種
    SCNShadowModeForward   = 0, 通過(guò)Alpha值得變化決定陰影
    SCNShadowModeDeferred  = 1, 根據(jù)最后的顏色決定陰影瓢捉,一般不太用,除非有多個(gè)光源作用的情況下
     SCNShadowModeModulated = 2 光沒(méi)有作用办成,只投射陰影泡态,一般用于圖案作為陰影的情況下,比如鏡像漸變圖像(黑白)
    
  • 陰影的深度偏移量

    @property(nonatomic) CGFloat shadowBias NS_AVAILABLE(10_10, 8_0);
    
  • 平行方向放陰影比例值調(diào)節(jié)

     @property(nonatomic) CGFloat orthographicScale NS_AVAILABLE(10_10, 8_0);
    
  • 光作用的范圍

     @property(nonatomic) CGFloat zFar NS_AVAILABLE(10_10, 8_0);
     @property(nonatomic) CGFloat zNear NS_AVAILABLE(10_10, 8_0);
    
  • 光衰減的開(kāi)始距離和結(jié)束距離(Omni or Spot light)

    @property(nonatomic) CGFloat attenuationStartDistance NS_AVAILABLE(10_10, 8_0);// 默認(rèn)為0
    @property(nonatomic) CGFloat attenuationEndDistance NS_AVAILABLE(10_10, 8_0);// 默認(rèn)為1
    @property(nonatomic) CGFloat attenuationFalloffExponent NS_AVAILABLE(10_10, 8_0);// 1 表示線性減弱 2表示平方減弱
    
  • 聚焦光的發(fā)射點(diǎn)的方向和光線強(qiáng)度最弱的時(shí)候的夾角

    @property(nonatomic) CGFloat spotInnerAngle  NS_AVAILABLE(10_10, 8_0);// 默認(rèn)為0度
    @property(nonatomic) CGFloat spotOuterAngle  NS_AVAILABLE(10_10, 8_0);// 默認(rèn)為45度
    
  • 當(dāng)你要使用碰撞檢測(cè)時(shí)迂卢,請(qǐng)?jiān)O(shè)置下面的屬性

    @property(nonatomic) NSUInteger categoryBitMask NS_AVAILABLE(10_10, 8_0);
    
  • 點(diǎn)光源材質(zhì)屬性(只支持spot類(lèi)型)

    @property(nonatomic, readonly, nullable) SCNMaterialProperty *gobo NS_AVAILABLE(10_9, 8_0);
    

你最?lèi)?ài)的代碼部分

我們已經(jīng)熟悉了光源類(lèi)的具體使用方法,下面我們就來(lái)驗(yàn)證一下理論的真實(shí)性某弦!

第一步.創(chuàng)建工程

創(chuàng)建工程

第二步.添加游戲框架

image

第三步.創(chuàng)建一個(gè)游戲框架專(zhuān)屬的視圖(SCNView類(lèi)型)

    self.gameView = [[SCNView alloc]initWithFrame:self.view.bounds];
    self.gameView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.gameView];
運(yùn)行一下,如果界面是下面這樣,表示創(chuàng)建成功
![運(yùn)行結(jié)果](http://upload-images.jianshu.io/upload_images/1594482-f87efb77b12fb74d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我們把攝像機(jī)控制打開(kāi),方便我們觀察視圖

     self.gameView.allowsCameraControl = true;

第四步.設(shè)置場(chǎng)景

友情提示

SCNView 對(duì)象的scene 屬性,系統(tǒng)默認(rèn)為nil,所以我們必須手動(dòng)創(chuàng)建scene

    self.gameView.scene = [SCNScene scene];

第五步.我們給游戲視圖中添加一個(gè)正方形塊節(jié)點(diǎn)和一個(gè)球體節(jié)點(diǎn)

    // 創(chuàng)建正方塊
    SCNBox *box = [SCNBox boxWithWidth:0.5 height:0.5 length:0.5 chamferRadius:0];// 正方體

    // 創(chuàng)建球體
    SCNSphere *sphere = [SCNSphere sphereWithRadius:0.1];// 設(shè)置球體半徑為0.1

    // 把兩個(gè)結(jié)合體綁定到節(jié)點(diǎn)上
    SCNNode *boxNode = [SCNNode node];
    boxNode.geometry = box;
    boxNode.position = SCNVector3Make(0, 0, -11); // 把節(jié)點(diǎn)的位置固定在(0,0,-11)
    SCNNode *sphereNode = [SCNNode node];
    sphereNode.geometry = sphere;
    sphereNode.position = SCNVector3Make(0, 0, -10); // 把節(jié)點(diǎn)的位置固定在(0,0,-11)

    // 添加節(jié)點(diǎn)到場(chǎng)景中去
    [self.gameView.scene.rootNode addChildNode:boxNode];
    [self.gameView.scene.rootNode addChildNode:sphereNode];

運(yùn)行結(jié)果:

Scenekit_03.gif

第六步.我們給場(chǎng)景中只添加一個(gè)環(huán)境光

 SCNLight *light = [SCNLight light]; // 創(chuàng)建燈光
 light.type = SCNLightTypeAmbient; // 設(shè)置燈光類(lèi)型
 light.color = [UIColor yellowColor]; // 設(shè)置燈光顏色

SCNNode *lightNode = [SCNNode node];
lightNode.light  = light;
[self.gameView.scene.rootNode addChildNode:lightNode];

運(yùn)行結(jié)果

環(huán)境光

問(wèn)題1:設(shè)置顏色為yellowColor 為什么物體不是yellow呢而克?

因?yàn)槲矬w材質(zhì)中沒(méi)有黃色成分,比如你傳的是一件綠色的衣服,你用黃光照射他,你不可能看見(jiàn)衣服是綠色或者黃色的,這里你可以把物體的顏色變?yōu)辄S色試試看靶壮。

問(wèn)題2:那為什么和不添加環(huán)境光一樣的效果呢?

因?yàn)橄到y(tǒng)本身如果我們不提供任何光源员萍,它會(huì)自動(dòng)添加環(huán)境光腾降,如果檢測(cè)到我們添加了光源,它將不會(huì)幫我們添加環(huán)境光

第七步.我們向游戲場(chǎng)景中只添加一個(gè)點(diǎn)光源

SCNLight *light = [SCNLight light];// 創(chuàng)建光對(duì)象
light.type = SCNLightTypeOmni;// 設(shè)置類(lèi)型
light.color = [UIColor yellowColor]; // 設(shè)置光的顏色

SCNNode *lightNode = [SCNNode node];
lightNode.position = SCNVector3Make(0, 0, 100); // 設(shè)置光源節(jié)點(diǎn)的位置
lightNode.light  = light;
[self.gameView.scene.rootNode addChildNode:lightNode]; // 添加到場(chǎng)景中去

運(yùn)行結(jié)果:

Scenekit_03.gif

我們的點(diǎn)光源的位置為(0,0,100),我們把位置改為(0,100,100),看一下效果碎绎,對(duì)比一下螃壤,你就掌握了這種光的特點(diǎn)

改變位置后

點(diǎn)光源的特顯,你應(yīng)該明白了筋帖!我們繼續(xù)奸晴!

第八步.只添加一個(gè)平行方向光源

我們一開(kāi)始說(shuō)了這種光源的特點(diǎn):只有方向,沒(méi)有位置,我們驗(yàn)證一下

SCNLight *light = [SCNLight light];// 創(chuàng)建光對(duì)象
light.type = SCNLightTypeDirectional;// 設(shè)置類(lèi)型
light.color = [UIColor yellowColor]; // 設(shè)置光的顏色

SCNNode *lightNode = [SCNNode node];
lightNode.position = SCNVector3Make(0, 10, -100); // 設(shè)置光源節(jié)點(diǎn)的位置
lightNode.light  = light;
[self.gameView.scene.rootNode addChildNode:lightNode]; // 添加到場(chǎng)景中去

位置為(0,0,-100)運(yùn)行結(jié)果

Scenekit_03.gif

下面我們把它的位置放在(1000,1000,1000) 看一下結(jié)果

位置在(1000,1000,1000)

一點(diǎn)變化也沒(méi)有,接著下面我們改變一下照射方向,這種光的默認(rèn)方向?yàn)閦軸負(fù)方向幕随,我們把它設(shè)置成Y軸負(fù)方向

lightNode.rotation = SCNVector4Make(1, 0, 0, -M_PI/2.0);

看一下運(yùn)行結(jié)果

光照方向Y軸負(fù)方向

我相信你已經(jīng)明白了這種光的特點(diǎn).

第九步.添加聚焦光源

 SCNLight *light = [SCNLight light];// 創(chuàng)建光對(duì)象
light.type = SCNLightTypeSpot;// 設(shè)置類(lèi)型
light.color = [UIColor yellowColor]; // 設(shè)置光的顏色
light.castsShadow = TRUE;// 捕捉陰影
SCNNode *lightNode = [SCNNode node];
lightNode.position = SCNVector3Make(0, 0, -9); // 設(shè)置光源節(jié)點(diǎn)的位置
lightNode.light  = light;
[self.gameView.scene.rootNode addChildNode:lightNode]; // 添加到場(chǎng)景中去

運(yùn)行結(jié)果:

聚焦光源

我們?cè)囍褂靡幌抡丈浞秶膶傩?讓它只照射到球

SCNLight *light = [SCNLight light];// 創(chuàng)建光對(duì)象
light.type = SCNLightTypeSpot;// 設(shè)置類(lèi)型
light.color = [UIColor yellowColor]; // 設(shè)置光的顏色
light.castsShadow = TRUE;// 捕捉陰影

light.zFar = 10; // 設(shè)置它最遠(yuǎn)能照射單位10 的地方,也就是說(shuō)只能照到 球體的位置
SCNNode *lightNode = [SCNNode node];
lightNode.position = SCNVector3Make(0, 0, 0); // 設(shè)置光源節(jié)點(diǎn)的位置
lightNode.light  = light;
[self.gameView.scene.rootNode addChildNode:lightNode]; // 添加到場(chǎng)景中去

運(yùn)行:

讓學(xué)習(xí)成為一種習(xí)慣

有的朋友要問(wèn)了蚁滋,那怎么還能看見(jiàn)后面的立方體的,這是因?yàn)槲矬w都存在漫反射赘淮,這個(gè)屬于自然現(xiàn)象辕录,你用手電筒可以去試試!那如何才能讓它看不見(jiàn)后面的立方體呢梢卸?設(shè)置光的發(fā)射角度走诞,上代碼:

 light.spotOuterAngle = 2;

運(yùn)行結(jié)果:

讓學(xué)習(xí)成為一種習(xí)慣

上面的幾種光的基本特性講解完畢,本節(jié)的內(nèi)容你掌握了嗎?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛤高,一起剝皮案震驚了整個(gè)濱河市蚣旱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戴陡,老刑警劉巖塞绿,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恤批,居然都是意外死亡异吻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)喜庞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诀浪,“玉大人,你說(shuō)我怎么就攤上這事延都±字恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵晰房,是天一觀的道長(zhǎng)求摇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)殊者,這世上最難降的妖魔是什么与境? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮幽污,結(jié)果婚禮上嚷辅,老公的妹妹穿的比我還像新娘。我一直安慰自己距误,他們只是感情好簸搞,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著准潭,像睡著了一般趁俊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刑然,一...
    開(kāi)封第一講書(shū)人閱讀 52,196評(píng)論 1 308
  • 那天寺擂,我揣著相機(jī)與錄音,去河邊找鬼。 笑死怔软,一個(gè)胖子當(dāng)著我的面吹牛垦细,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挡逼,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼括改,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了家坎?” 一聲冷哼從身側(cè)響起嘱能,我...
    開(kāi)封第一講書(shū)人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虱疏,沒(méi)想到半個(gè)月后惹骂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡做瞪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年对粪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穿扳。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衩侥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矛物,到底是詐尸還是另有隱情茫死,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布履羞,位于F島的核電站峦萎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忆首。R本人自食惡果不足惜爱榔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望糙及。 院中可真熱鬧详幽,春花似錦、人聲如沸浸锨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柱搜。三九已至迟郎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聪蘸,已是汗流浹背宪肖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工表制, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人控乾。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓么介,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親阱持。 傳聞我的和親對(duì)象是個(gè)殘疾皇子夭拌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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