這個知識點既重要又不那么重要又很重要。攤手。
簡單說,這個屬性就是給geometry貼圖。(下文中的“貼圖”,就是material的意思)
每個SCNMaterial有8個視覺特性,分別對應在明暗過程中不同的貼圖效果。每個視覺特性,都是SCNMaterialProperty的一個實例,可以提供一個顏色或紋理等2D內(nèi)容。SCNMaterial的lightingModelName也會影響到渲染的最終效果。詳見下文。
可以使用firstMaterial或者materials屬性添加一個或多個貼圖。多個幾何圖形可以用相同的貼圖,這樣修改貼圖就可以同時改變所有使用它的幾何。
創(chuàng)建貼圖
+ (instancetype)material;
創(chuàng)建一個新的貼圖,它的8個視覺特性的默認值參見下文“視覺特性配置”。
+ (instancetype)materialWithMDLMaterial:(MDLMaterial *)mdlMaterial;
根據(jù)MDLMaterial對象創(chuàng)建貼圖。
選擇陰影模型
@property(nonatomic, copy) SCNLightingModel lightingModelName;
光影渲染方式,詳見下。
typedef NSString *SCNLightingModel;
渲染貼圖的燈光和陰影算法的常數(shù)。

SCNLightingModelPhysicallyBased:基于現(xiàn)實的抽象效果。
SCNLightingModelPhong:將
ambient、diffuse和specular結合起來,用Phong公式計算的效果。SCNLightingModelLambert:只包含
ambient和diffuse的效果。SCNLightingModelConstant:只包含
ambient的效果。SCNLightingModelBlinn:將
ambient、diffuse和specular結合起來,用Blinn-Phong公式計算的效果。
視覺特性配置
@property(nonatomic, readonly) SCNMaterialProperty *diffuse;
漫射效果。
漫射的意思是光的數(shù)量和顏色均勻地反映在幾何表面的每一點上。它與視角沒有關系,可以理解成是設置基礎顏色或紋理。設置方法為diffuse.content,下同。
默認情況下是白色。下圖顯示的是一個實例,它的其他視覺特性使用的默認值。

場景中最終的渲染效果會根據(jù)所有視覺特性、燈光和其他的相關屬性共同決定。
@property(nonatomic, readonly) SCNMaterialProperty *ambient;
環(huán)境效果。
就是貼圖在在環(huán)境燈里映射出的效果。如果場景里沒有SCNLightTypeAmbient的燈光,那這個屬性將沒有效果。
默認情況下是深灰色。修改ambient不是在場景中被燈光照亮,而是直接使貼圖變成對應的顏色或紋理。貼圖默認對散射光和環(huán)境光是相同的,locksAmbientWithDiffuse默認值為YES。
如下圖:

@property(nonatomic, readonly) SCNMaterialProperty *specular;
鏡面效果。
用來模擬光澤,可以通過shininess屬性來調(diào)整鏡面的銳度。
默認情況下是黑色,貼圖看起來是陰暗無光澤的。將specular設置成亮色,會讓表面看起來閃閃發(fā)光。當你將圖片設置給specular時,圖片中每個像素點的亮度決定了貼圖上對應點的光澤。
如圖:

@property(nonatomic, readonly) SCNMaterialProperty *normal;
輪廓效果。
模擬輪廓效果需要每個點的方向信息。通常,geometry對象上自帶了這些信息,但是這限制了表面輪廓的細節(jié),因為一個幾何形狀只能為每個頂點提供一個法向量。如果增加頂點數(shù),又會增加性能成本。
此外,也可以使用紋理圖片來提供這些信息。由于圖片紋理可以儲存比幾何圖形更詳細的表面信息,我們可以用normal屬性來模擬粗糙的表面,比如石頭,浮雕等。
默認情況下是白色。將normal設置成純色,將根據(jù)幾何形狀進行渲染;將normal設置成圖片或其他紋理圖,將自動設置貼圖的litPerPixel=YES。
如圖:

@property(nonatomic, readonly) SCNMaterialProperty *reflective;
反射效果。
SceneKit不會渲染對象在場景中的真實映射,我們可以通過reflective來模擬這個效果。
默認情況下是白色,不會有反射的效果。將reflective設置成純色將只會給貼圖添加一層均勻的陰影,要想有反射效果,需要設置成圖片或其他紋理圖。
如圖:

@property(nonatomic, readonly) SCNMaterialProperty *emission;
發(fā)光效果。
可以利用圖片紋理來模擬表面發(fā)光的效果。不是說把貼圖當做光源,而是指發(fā)出的光不依賴與光源。想要創(chuàng)建一個看起來發(fā)光的對象,需要將幾何圖形和發(fā)光紋理與其他的光源結合起來。
默認情況下是黑色,沒有發(fā)光效果。將emission設置成純色只會均勻地增加與光源無關的顏色,要想有發(fā)光效果,需要設置成圖片或其他紋理圖,發(fā)光的部分用亮色,其他區(qū)域用暗色。
如圖:

@property(nonatomic, readonly) SCNMaterialProperty *transparent;
透明效果。
這個屬性可以選擇性地讓部分貼圖透明??梢允褂?code>transparency屬性來調(diào)整整體的透明度,或者使用SCNNode的opacity屬性來調(diào)整節(jié)點上的所有內(nèi)容。
默認情況下為黑色,表示完全不透明。將transparent設置成任何純色,會根據(jù)顏色的不透明度來整體淡化貼圖。想要讓部分貼圖透明,需要設置成圖片或其他紋理圖,然后根據(jù)alpha通道調(diào)整透明或不透明的區(qū)域。
如下圖:

@property(nonatomic, readonly) SCNMaterialProperty *multiply;
后期效果。
在貼圖的其他視覺特性與燈光以及其他相關的場景元素結合之后,將每個渲染的像素與multiply屬性提供的顏色相乘,渲染出最終的效果??梢允褂?br>
默認情況下是白色,表示沒有后期效果。
如下圖:

以上,8個視覺特性介紹完畢。下面還有一些其他特性
@property(nonatomic, readonly) SCNMaterialProperty *ambientOcclusion;
環(huán)境遮罩。
將一個環(huán)境遮罩紋理映射到表面。如果場景中沒有環(huán)境光(SCNLightTypeAmbient),這個屬性沒有效果。
如果這個屬性不是nil,SceneKit會忽略ambient屬性。
@property(nonatomic, readonly) SCNMaterialProperty *selfIllumination;
自照明。
這個屬性適用于所有貼圖。對于某些貼圖來說,讓它們自照明是很有必要的,比如光源被遮住的時候,如果設置了selfIllumination,它們可以通過其他的光來渲染效果。
@property(nonatomic, readonly) SCNMaterialProperty *metalness;
金屬材質(zhì)。
可以把這個屬性理解成折射指數(shù)。越高的值(越亮的顏色)會使表面看起來越有金屬感。
僅在lightingModelName=SCNLightingModelPhysicallyBased 時適用。
@property(nonatomic, readonly) SCNMaterialProperty *roughness;
平滑度。
可以把這個屬性理解成細節(jié),比如表面的突起或裂縫。通過這個屬性有助于亮度的計算,可以更真實地在粗糙或光滑的表面渲染效果。
僅在lightingModelName=SCNLightingModelPhysicallyBased 時適用。
@property(nonatomic, readonly) SCNMaterialProperty *displacement;

這個是iOS11的新特性,API沒有說明,我也沒用過。以后再補充。
自定義貼圖
@property(nonatomic, copy) NSString *name;
貼圖的名字。
@property(nonatomic) CGFloat shininess;
鏡面效果的銳度。
詳見上文的specular。
@property(nonatomic) CGFloat fresnelExponent;
反射效果的反射率。
詳見上文的reflective。
@property(nonatomic) CGFloat transparency;
透明效果的透明度。
詳見上文的transparent。
@property(nonatomic) SCNTransparencyMode transparencyMode;
用來計算透明度的模式。
typedef enum SCNTransparencyMode : NSInteger {
SCNTransparencyModeAOne = 0,
SCNTransparencyModeRGBZero = 1,
SCNTransparencyModeSingleLayer = 2,
SCNTransparencyModeDualLayer = 3,
SCNTransparencyModeDefault = SCNTransparencyModeAOne
} SCNTransparencyMode;
SCNTransparencyModeAOne:從顏色的alpha通道獲取透明度信息。1是不透明。默認值。
SCNTransparencyModeRGBZero:從顏色的亮度中獲取透明度信息。0是不透明。
SCNTransparencyModeDualLayer、SCNTransparencyModeSingleLayer也是iOS11新特性,API還沒有說明。
@property(nonatomic, getter=isLitPerPixel) BOOL litPerPixel;
是否會每個點單獨照明。詳見上文normal。
默認YES,將提供更好的呈現(xiàn)效果,但是比較耗性能。改成NO會在幾何圖形的每個頂點進行照明??梢蕴岣咪秩拘阅堋?/p>
@property(nonatomic, getter=isDoubleSided) BOOL doubleSided;
是不是渲染兩面。
幾何圖形分為內(nèi)、外兩面。根據(jù)幾何和相機的位置決定哪一面是可見的。
默認NO,只渲染外表面,改為YES后,將渲染內(nèi)外兩面,此時從幾何內(nèi)部仍然可以觀察的渲染效果。
@property(nonatomic) SCNCullMode cullMode;
剔除模式,就是不渲染哪一面。
typedef enum SCNCullMode : NSInteger {
SCNCullModeBack = 0,
SCNCullModeFront = 1
} SCNCullMode;
通常情況下,幾何的內(nèi)表面封閉在幾何圖形內(nèi),是不可見的。因此渲染內(nèi)表面并沒有明顯的效果,還會消耗性能。
該屬性的默認值是SCNCullBack,即不渲染內(nèi)表面。測試發(fā)現(xiàn),當doubleSided==YES時,這個屬性無效。
@property(nonatomic) SCNBlendMode blendMode;
混合模式。貼圖像素和其他的像素顏色混合的模式。
typedef enum SCNBlendMode : NSInteger {
SCNBlendModeAlpha = 0,
SCNBlendModeAdd = 1,
SCNBlendModeSubtract = 2,
SCNBlendModeMultiply = 3,
SCNBlendModeScreen = 4,
SCNBlendModeReplace = 5,
SCNBlendModeMax = 6
} SCNBlendMode;
SCNBlendModeAlpha:默認值,將兩個像素的顏色值相乘。
SCNBlendModeAdd:將源顏色添加到目標顏色上。類似發(fā)光的效果。
SCNBlendModeSubtract:從目標顏色中減去源顏色。
SCNBlendModeMultiply:將源顏色與背景顏色相乘。
SCNBlendModeScreen:將源顏色的反色與目標顏色的反色相混合。
SCNBlendModeReplace:用源顏色替換目標顏色,忽略alpha。
@property(nonatomic) BOOL locksAmbientWithDiffuse;
是否讓環(huán)境光與漫射光相同。
在模擬真實燈光時,通常物體表面會有單一的基礎顏色或者紋理。
當這個屬性為NO時就沒有這個限制,可以使用diffuse屬性提供一種顏色或紋理,用ambient屬性提供另一種顏色或紋理。
當這個屬性是YES,或者在SCNLightingModelPhysicallyBased模式時,將忽略ambient屬性,以確保只會有一種顏色或紋理。
這個屬性在OS X v10.9以前默認值是NO,之后的版本是YES。
@property(nonatomic) BOOL writesToDepthBuffer;
在渲染貼圖時是否產(chǎn)生深度信息。
默認值是YES。
@property(nonatomic) BOOL readsFromDepthBuffer;
在渲染貼圖時是否使用深度信息。
默認值是YES。
@property(nonatomic) SCNColorMask colorBufferWriteMask;
typedef enum SCNColorMask : NSInteger {
SCNColorMaskNone = 0,
SCNColorMaskRed = 0x1 << 3,
SCNColorMaskGreen = 0x1 << 2,
SCNColorMaskBlue = 0x1 << 1,
SCNColorMaskAlpha = 0x1 << 0,
SCNColorMaskAll = 0xf
} SCNColorMask;
@property(nonatomic) SCNFillMode fillMode;
typedef enum SCNFillMode : NSUInteger {
SCNFillModeFill = 0,
SCNFillModeLines = 1
} SCNFillMode;
以上幾個屬性也是iOS11新特性,API還沒有說明。
綜上,其實蘋果自己對自己的API也不太上心,都沒完全完成就發(fā)布了。以上部分API自己也并沒有理解透徹,如有理解不正確的地方,感謝斧正。