材質(zhì)對(duì)幾何模型的影響
我們先建立一個(gè)工程,然后在聊木缝。
第一步,創(chuàng)建游戲?qū)S靡晥D
SCNView *scnView = [[SCNView alloc]initWithFrame:self.view.bounds];
scnView.backgroundColor = [UIColor blackColor];
scnView.scene = [SCNScene scene];
[self.view addSubview:scnView];
第二步,創(chuàng)建攝像頭
// 創(chuàng)建攝像頭
SCNCamera *camera = [SCNCamera camera];
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = camera;
cameraNode.position = SCNVector3Make(0, 0, 5);
[scnView.scene.rootNode addChildNode:cameraNode];
第三步:添加一個(gè)球體模型到視圖中
SCNSphere *sphere = [SCNSphere sphereWithRadius:1];
SCNNode *sphereNode = [SCNNode nodeWithGeometry:sphere];
[scnView.scene.rootNode addChildNode:sphereNode];
運(yùn)行一下:
[圖片上傳中...(image-4ca708-1510628124400-23)]
準(zhǔn)備工作已經(jīng)做好,接下來(lái)纬凤,正式進(jìn)入我們今天的內(nèi)容
材質(zhì)詳解
我們需要了解兩個(gè)類(lèi)SCNMaterialProperty 和 SCNMaterial * SCNMatrialProperty
有什么用?
1.包含顏色,紋理和其他可視元素等材質(zhì)屬性
2.控制紋理的包裝风纠、過(guò)濾和紋理坐標(biāo)變換
3.紋理的可視屬性決定了物體在燈光和陰影下的樣子
設(shè)置紋理屬性的方法有哪些?(contents)
1.使用UIImage (可以直接設(shè)置圖片的名稱(chēng))
2.六個(gè)圖片的數(shù)組
3.Core Animation 的layer 對(duì)象
4.Sprite Kit 紋理提供的靜態(tài)圖片
在什么地方可以使用SCNMatrialProperty
1.材質(zhì)屬性
2.SCNScene 的background
3.SCNLight的gobo屬性
4.綁定紋理采樣器自定義GLSL著色器源代碼片段 在類(lèi)中實(shí)現(xiàn) SCNShadable 屬性
a.如何創(chuàng)建紋理屬性
+ (instancetype)materialPropertyWithContents:(id)contents
提示:
也可以使用GLSL 創(chuàng)建,由于內(nèi)容過(guò)于多,暫時(shí)不講,中級(jí)篇也不講,高級(jí)會(huì)詳細(xì)講解蓖救。
b.紋理的屬性的內(nèi)容
var contents: AnyObject?
可以為一下幾個(gè)對(duì)象
顏色(NSColor/UIColor / CGColorRef)
圖片(NSImage/UIImage/CGImageRef)
圖片名稱(chēng)(NSString)或者路徑(NSURL)
圖片數(shù)組(NSArray)
核心動(dòng)畫(huà)層(CALayer)
紋理(SKText,MDLTexture,MTLTexture,GLKTextureInfo)
2D 場(chǎng)景(SKScene)
注意
1.如果設(shè)置圖片數(shù)組時(shí)舅桩,這個(gè)圖片必須為六張颗搂,并且大小要一致
2.Core Animation layer 使用 AVPlayerLayer
或者AVCaptureVideoPreviewLayer 呈現(xiàn) 捕捉到的視頻畫(huà)面 3.可以動(dòng)態(tài)的改變contents
c.設(shè)置材質(zhì)性能因子(取值范圍0-1,默認(rèn)值為1)
var intensity: CGFloat
會(huì)產(chǎn)生什么影響呢?
1.normal 屬性,強(qiáng)度變化的正常映射的表面的表觀粗糙度。降低強(qiáng)度使表面顯得更光滑
2.multiply 使用白色降低強(qiáng)度混物的材料性的顏色涉馁,有效降低顏色乘法效應(yīng)強(qiáng)度
3.對(duì)于其他屬性,會(huì)讓內(nèi)容變暗淡
怎么動(dòng)態(tài)的改變屬性?xún)?nèi)容呢?
千萬(wàn)別著急,現(xiàn)在還不是時(shí)候.中級(jí)篇會(huì)講
d.轉(zhuǎn)換應(yīng)用材料屬性的內(nèi)容
@property(nonatomic) SCNMatrix4 contentsTransform
先給兩張圖理解一下门岔,它干的事情吧,之后練習(xí)中我們?cè)僭敿?xì)介紹它都可以進(jìn)行哪些變化. 它變換的到底是什么:
紋理坐標(biāo)對(duì)應(yīng)顯示的圖片區(qū)域的大小
[圖片上傳中...(image-ba24de-1510628124399-22)]
[圖片上傳中...(image-f47556-1510628124399-21)]
e.包裝模式(紋理坐標(biāo)的的包裝行為)
幫你理解一下
比如正方體的表面是100 我們提供的圖片是50 這是我們可以,一種是原圖顯示烤送,或者放大顯示,或者重復(fù)顯示,這個(gè)包裝模式就是控制這些顯示方式的.
var wrapS: SCNWrapMode // 控制水平
var wrapT: SCNWrapMode // 控制垂直
默認(rèn)的值為:SCNWrapModeClamp.
我們看一下都有哪些可選項(xiàng):
typedef enum {
//紋理坐標(biāo)超高系統(tǒng)產(chǎn)生顏色的范圍,將使用紋理邊緣的顏色填充
SCNWrapModeClamp = 1,
// 當(dāng)紋理坐標(biāo)超高系統(tǒng)產(chǎn)生顏色的范圍,將重復(fù)使用紋理圖片
SCNWrapModeRepeat = 2,
//當(dāng)紋理坐標(biāo)超高系統(tǒng)產(chǎn)生顏色的范圍 使用指定的顏色填充
SCNWrapModeClampToBorder = 3,
// 當(dāng)紋理左邊超過(guò)系統(tǒng)差生顏色的范圍,將翻轉(zhuǎn)紋理圖片
SCNWrapModeMirror = 4,
} SCNWrapMode;
注意:
使用SCNWrapModeClampToBorder 時(shí),使用borderColor 屬性的顏色,代替超過(guò)圖片之外的顏色糠悯。
f.紋理濾波
這個(gè)屬性有什么用?
當(dāng)材料表面的部分出現(xiàn)較大或小于原來(lái)的紋理圖像時(shí)帮坚,紋理過(guò)濾決定了材料屬性的內(nèi)容的外觀
@property(nonatomic) SCNFilterMode minificationFilter
可選項(xiàng)
typedef enum : NSInteger {
//
SCNFilterModeNone = 0,
// 當(dāng)這個(gè)位置沒(méi)有紋理顏色時(shí),會(huì)采樣離他最近的顏色值
SCNFilterModeNearest = 1,
//當(dāng)這個(gè)位置沒(méi)有紋理顏色時(shí),線(xiàn)性插值顏色作為自己的顏色
SCNFilterModeLinear = 2,
} SCNFilterMode;
默認(rèn)值為 SCNFilterModeLinear
mipmap濾波
var mipFilter: SCNFilterMode
有什么用?
當(dāng)材料表面的部分出現(xiàn)較大或小于原來(lái)的紋理圖像時(shí)互艾,紋理過(guò)濾決定了材料屬性的內(nèi)容的外觀 , 主要針對(duì)(mipmap) Mipmap(有時(shí)候拼寫(xiě)成mipmap)是一種電腦圖形圖像技術(shù)试和,用于在三維圖像的二維代替物中達(dá)到立體感效應(yīng)
mipmap 有多厲害
可以增加渲染的性能:當(dāng)渲染的圖片比較小時(shí),SceneKit 會(huì)自動(dòng)創(chuàng)建若干個(gè)mipmap層,給材質(zhì)屬性的圖片內(nèi)容,渲染的時(shí)候,SceneKit 會(huì)自動(dòng)采樣mipmap層
可選值為
typedef enum : NSInteger {
SCNFilterModeNone = 0, // 默認(rèn)值 不用mipmap
SCNFilterModeNearest = 1,
SCNFilterModeLinear = 2, // 線(xiàn)性
} SCNFilterMode;
給張圖理解一下
[圖片上傳中...(image-cdc24-1510628124399-20)]
非均質(zhì)性(各向異性)紋理濾波
var maxAnisotropy: CGFloat
你應(yīng)該了解的?
1.用來(lái)過(guò)濾纫普、處理當(dāng)視角變化導(dǎo)致3D物體表面傾斜時(shí)造成的紋理錯(cuò)誤
2.各向異性濾波,可以提供紋理渲染質(zhì)量,當(dāng)紋理的表面出現(xiàn)在一個(gè)相對(duì)于相機(jī)的極端角度,這時(shí)往往是通過(guò)采樣多個(gè)mipmap層渲染每個(gè)像素,提高渲染質(zhì)量,但是消耗的渲染的成本阅悍。
3.SceneKit自動(dòng)增加或降低需要最大限度地提高渲染質(zhì)量渲染每個(gè)像素的各向異性,由該屬性指定的限制,渲染時(shí)所使用的最大各向異性水平依賴(lài)于使用中的圖形硬件,如果設(shè)置值為MAXFloat 約束使用最高的GPU 支持的 各向異性的值.
4.maxAnisotropy的值小于等于1 則禁止使用各向異性
注意:
如果使用各向異性濾波,必須使用mipmap ,也就是說(shuō)mipFilter 的值不能為SCNFilterModeNone.
給張圖理解一下各向異性
[圖片上傳中...(image-d6800c-1510628124399-19)]
紋理通道
@property(nonatomic) NSInteger mappingChannel
先解釋一下這屬性
幾何對(duì)象可能有多個(gè)紋理坐標(biāo)源,每個(gè)都對(duì)應(yīng)一個(gè)獨(dú)一無(wú)二的通道數(shù)字,你可以使用這些通道數(shù)字,去繪制材質(zhì)的內(nèi)容通過(guò)不同的方式
舉個(gè)例子幫你理解一下:
[圖片上傳中...(image-4587cd-1510628124399-18)]
很簡(jiǎn)單:
表示一個(gè)相框的一個(gè)幾何體可能會(huì)使用一組紋理坐標(biāo)來(lái)映射相框架本身的材質(zhì)昨稼,另一組紋理坐標(biāo)用于將圖片放置到框架中
到目前為止,我們把SCNMatrialProperty的屬性?xún)?nèi)容,已經(jīng)全部講解完畢,你理解了沒(méi)?接下來(lái),我們還要學(xué)習(xí)一個(gè)特別重要的類(lèi)(SCNMaterial)
SCNMaterial
上面的工程建好的你,可以跟著下面的步驟做节视。
講解這個(gè)類(lèi),我們換一種方式,我喜歡圖文并茂,我相信你也喜歡。
這幾點(diǎn)你要記牢了
1.材質(zhì)可以在多個(gè)幾何體重復(fù)使用
2.它是管理光線(xiàn)和陰影屬性以及決定幾何表面呈現(xiàn)出來(lái)的樣子
3.一個(gè)幾何體可以設(shè)置多個(gè)材質(zhì)
a.漫發(fā)射屬性(diffuse) 我們有一樣圖片是這樣的:
[圖片上傳中...(image-4fc0b6-1510628124399-17)]
上代碼:
sphere.firstMaterial.diffuse.contents = @"earth-diffuse.jpg";
運(yùn)行結(jié)果:
[圖片上傳中...(image-5e1304-1510628124399-16)]
總結(jié)一下:
1.這個(gè)屬性設(shè)置的幾何體的基本的顏色,好比是你穿的衣服假栓。
2.如果你不設(shè)置這個(gè)屬性,它默認(rèn)的contents內(nèi)容是顏色white
其實(shí)它的過(guò)程像穿衣服一樣
[圖片上傳中...(image-a603b4-1510628124399-15)]
影響環(huán)境光的相應(yīng)屬性(ambient)
先上代碼:
sphere.firstMaterial.locksAmbientWithDiffuse = YES;
sphere.firstMaterial.ambient.contents = [UIColor blueColor];
// 添加環(huán)境光
SCNNode *ambientlightNode = [SCNNode node];
ambientlightNode.light =[SCNLight light];
ambientlightNode.light.type = SCNLightTypeAmbient;
[scnView.scene.rootNode addChildNode:ambientlightNode];
給張圖理解一下
[圖片上傳中...(image-475029-1510628124399-14)]
鏡面材質(zhì)屬性(高光)
有什么效果寻行?
當(dāng)光照射到物體表面是,物體反射出來(lái)顏色
添加一張高光照片
[圖片上傳中...(image-c62f29-1510628124399-13)]
上代碼:
sphere.firstMaterial.specular.contents = @"earth-specular.jpg";
運(yùn)行結(jié)果:
[圖片上傳中...(image-5534ed-1510628124399-12)]
小提示:
如果你想要所有部分全部顯示高光,你可以給他設(shè)置白色
再給張圖理解一下
[圖片上傳中...(image-e8abb0-1510628124399-11)]
設(shè)置法線(xiàn)取向
理解:
1.按理來(lái)說(shuō),我們的法線(xiàn)都是垂直我們的表面的,通過(guò)這個(gè)屬性,可以模擬光在每個(gè)頂點(diǎn)的取向匾荆。
2.可以通過(guò)紋理圖片作為法線(xiàn)地圖,使用RGB 表示 XYZ
下圖就是一樣模擬法線(xiàn)坐標(biāo)的圖像
[圖片上傳中...(image-34ccfc-1510628124399-10)]
映射(reflectiv)
你可以這樣理解:
給材質(zhì)外邊加一個(gè)罩子,光能透過(guò)這個(gè)罩子照射到物體上,比如映射屬性為白色反射所有光,所以你看不見(jiàn)任何顏色,黑色吸收任何光,光能照射到物體上,物體能反射光,所以你能看見(jiàn)拌蜘。 下面是一張反射屬性紋理圖:
[圖片上傳中...(image-9a5b56-1510628124399-9)]
代碼:
sphere.firstMaterial.reflective.contents = @"earth-reflective.jpg";
// 映射因子沒(méi)有上限值
sphere.firstMaterial.fresnelExponent = 10;
執(zhí)行結(jié)果:
[圖片上傳中...(image-8e2d3b-1510628124399-8)]
設(shè)置自身發(fā)光
特點(diǎn):
自己能發(fā)光,不能照亮別的物體
首先我們添加一個(gè)黑色的聚光燈
SCNNode *spotLightNode = [SCNNode node];
spotLightNode.position = SCNVector3Make(0, 50, 0);
spotLightNode.rotation = SCNVector4Make(1, 0, 0, -M_PI/2.0);
spotLightNode.light = [SCNLight light];
spotLightNode.light.color = [UIColor blackColor];
spotLightNode.light.type = SCNLightTypeSpot;
[scnView.scene.rootNode addChildNode:spotLightNode];
運(yùn)行結(jié)果:
[圖片上傳中...(image-77c75e-1510628124399-7)]
我們添加一個(gè)自身發(fā)光的紋理圖片
[圖片上傳中...(image-7d79db-1510628124399-6)]
代碼:
sphere.firstMaterial.emission.contents = @"earth-emissive.jpg";
設(shè)置材質(zhì)的透明度
什么意思?
也就是說(shuō),讓這個(gè)幾何物體的部分或者全部能變成透明的,不好理解看圖
上代碼:
sphere.firstMaterial.transparent.contents = @"cloudsTransparency.png";
sphere.firstMaterial.transparencyMode = SCNTransparencyModeRGBZero;
// 設(shè)置透明比例 0為不透 沒(méi)有上限
sphere.firstMaterial.transparency = 2;
運(yùn)行結(jié)果:
[圖片上傳中...(image-49229c-1510628124399-5)]
[圖片上傳中...(image-6afaca-1510628124399-4)]
設(shè)置一個(gè)顏色值和物體著色完成夠的值相乘
我們先給物體添加一個(gè)自身材質(zhì)屬性和發(fā)光材質(zhì)屬性
sphere.firstMaterial.diffuse.contents = @"earth-diffuse.jpg" ;
sphere.firstMaterial.emission.contents = @"earth-emissive.jpg";
運(yùn)行結(jié)果:
[圖片上傳中...(image-b0bd0c-1510628124399-3)]
接下來(lái),我們讓這個(gè)結(jié)果和綠色相乘
sphere.firstMaterial.multiply.contents = [UIColor greenColor];
運(yùn)行結(jié)果:
[圖片上傳中...(image-3094bc-1510628124399-2)]
設(shè)置自照明
注意:
如果selfIllumination屬性不為nil, emission 屬性則不起作用 代碼: // 把所用的光照全部去掉 sphere.firstMaterial.selfIllumination.contents = [UIColor blueColor];
運(yùn)行結(jié)果:
[圖片上傳中...(image-eabdcc-1510628124398-1)]
材質(zhì)可以有名字的
@property(nonatomic, copy) NSString *name
如何渲染球體內(nèi)部
// 默認(rèn)渲染一邊
sphere.firstMaterial.doubleSided = true;
// 剔除正面
sphere.firstMaterial.cullMode = SCNCullFront;
// 剔除反面
sphere.firstMaterial.cullMode = SCNCullBack;
混合渲染模式
確定如何使用這種材料的像素顏色與渲染目標(biāo)中的其他像素顏色混合的模式
enum SCNBlendMode : Int {
case Alpha // 默認(rèn)值
case Add
case Subtract
case Multiply
case Screen
case Replace
}
渲染材質(zhì)是否產(chǎn)生深度信息
// 默認(rèn)YES
var writesToDepthBuffer: Bool
@property(nonatomic) BOOL writesToDepthBuffer
// 渲染是否優(yōu)先讀取深度信息 默認(rèn)為YES
var readsFromDepthBuffer: Bool
光照模式
NSString *const SCNLightingModelPhong
NSString *const SCNLightingModelBlinn
NSString *const SCNLightingModelLambert
NSString *const SCNLightingModelConstant
[圖片上傳中...(image-81e518-1510628124398-0)]
每個(gè)都有對(duì)應(yīng)的計(jì)算公式,舉個(gè)例子,比如SCNLightingModelBlinn
color = ambient* al + diffuse* max(0, dot(N, L)) + specular*pow(max(0, dot(H, N)), shininess)
可能暫時(shí)用不到,用到了再去官方資料查找就好了。
本節(jié)的內(nèi)容有點(diǎn)多,理解不了沒(méi)有關(guān)系,在使用過(guò)程中慢慢體會(huì)就行,后面我們大量使用今天的內(nèi)容,既然開(kāi)始了,就堅(jiān)持下去牙丽。