場景提供預設材質定義 (.sfm
),可讓開發人員輕鬆取得出色的結果。如果開發人員想深度自訂資產的外觀,可以在資產定義中指定 source
屬性,以建立自己的素材定義 (*.mat
檔案) 並套用至資產。
核心概念
- Material
- 材質定義了途徑的視覺外觀。為了完整描述及轉譯途徑,材質會提供以下資訊:
- Material 模型
- 可控管的命名參數組合
- 光柵狀態 (混合模式、反向滾壓等)
- 頂點著色器程式碼
- 片段著色器程式碼
- Material 模型
- 質感設計模型又稱為「陰影模型」或「亮度模型」,用來定義途徑的內建屬性。這些屬性會直接影響光源的計算方式,也會影響表面外觀。
- 材質定義
- 文字檔案,說明材質所需的所有資訊。本頁說明 (
*.mat
) 材質定義檔案的結構和格式。
材質定義
材質定義是一個文字檔,用於說明材質所需的所有資訊:
- 名稱
- 使用者參數
- Material 模型
- 必要屬性
- 內插類型 (稱為變數)
- 光柵狀態 (混合模式等)
- 著色器程式碼 (片段著色器,選用頂點著色器)
格式化
材質定義格式是一種以 JSON 為基礎的格式,我們稱為 JSONish。頂層材質定義包含使用 3 個不同區塊的 JSON 物件標記法:
material {
// material properties
}
vertex {
// vertex shader, optional
}
fragment {
// fragment shader
}
有效的可行材質定義必須包含 material
區塊和 fragment
區塊。vertex
區塊是選用項目。
與 JSON 的差異
在 JSON 中,物件由鍵/值組合組成。JSON 組合具備下列語法:
"key" : value
值可以是字串、數字、物件、陣列或常值 (true
、false
或 null
)。雖然這個語法在質感定義中已完全有效,但也接受 JSON 格式的無引號字串變數:
key : value
如果字串包含空格,引號仍會保留。
vertex
和 fragment
區塊包含未逸出且未加引號的 GLSL 程式碼,這在 JSON 中無效。
可以使用單行 C++ 樣式註解。
成對的索引鍵區分大小寫。
成對的值不會區分大小寫。
範例
以下程式碼範例列出有效的材質定義範例。這個定義使用光源材質模型,使用預設的不透明混合模式,需要在轉譯網格中顯示一組 UV 座標並定義 3 個使用者參數。本文件的以下各節將詳細說明 material
和 fragment
區塊。
material {
name : "Textured material",
parameters : [
{
type : sampler2d,
name : texture
},
{
type : float,
name : metallic
},
{
type : float,
name : roughness
}
],
requires : [
uv0
],
shadingModel : lit,
blending : opaque
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, getUV0());
material.metallic = materialParams.metallic;
material.roughness = materialParams.roughness;
}
}
Material 區塊
材質區塊為必要區塊,其中包含屬性組合清單,用於說明所有非著色器資料。
name
- 類型
string
- 值
- 任何字串。如果名稱含有空格,則必須使用雙引號。
- 說明
- 設定教材的名稱。該名稱會在執行階段保留,以供偵錯使用。
material {
name : stone
}
material {
name : "Wet pavement"
}
shadingModel
material {
shadingModel : unlit
}
參數
- 類型
- 參數物件的陣列
- 值
每個項目都是包含
name
和type
屬性的物件,兩者皆為string
類型。名稱必須是有效的 GLSL ID。類型必須為下表所述的其中一種類型。類型 說明 bool 單一布林值 布林值 2 兩個布林值的向量 布林值 3 包含 3 個布林值的向量 布林值 4 4 布林值向量 浮動 單浮動式 浮點值 2 2 個浮點的向量 浮點值 3 3 個浮點的向量 浮點值 4 4 浮點向量 int 單一整數 int2 2 個整數的向量 int3 3 個整數的向量 int4 4 個整數的向量 sampler2d 2D 紋理 samplerExternal 外部紋理。詳情請參閱 ExternalTexture 和 setExternalTexture() - 取樣器
取樣器類型也可以指定
format
(預設為float
) 和precision
(預設為default
)。格式可以是int
或float
其中之一。精確度可以是default
(平台的最佳精確度,電腦一般為high
,在行動裝置上為medium
),low
、medium
、high
。- 說明
列出材質所需的參數。這些參數可以在執行階段使用 Sceneform' 材質 API 設定。從著色器存取參數的方式因參數類型而異:
- 範例範例類型:使用前置字串為
materialParams_
的參數名稱。例如materialParams_myTexture
。 - 其他類型:使用參數名稱做為稱為
materialParams
的結構欄位。例如materialParams.myColor
。
- 範例範例類型:使用前置字串為
material {
parameters : [
{
type : float4,
name : albedo
},
{
type : sampler2d,
format : float,
precision : high,
name : roughness
},
{
type : float2,
name : metallicReflectance
}
],
requires : [
uv0
],
shadingModel : lit,
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = materialParams.albedo;
material.roughness = texture(materialParams_roughness, getUV0());
material.metallic = materialParams.metallicReflectance.x;
material.reflectance = materialParams.metallicReflectance.y;
}
}
需要
- 類型
string
的陣列- 值
- 所有項目都必須是
uv0
、uv1
、color
、tangents
中的任一項。 - 說明
- 列出材質所需的頂點屬性。
position
屬性會自動包含,無須指定。選取任何非unlit
的陰影模型時,必須自動提供tangents
屬性。請參閱這份文件的著色器一節,進一步瞭解如何從著色器存取這些屬性。
material {
parameters : [
{
type : sampler2d,
name : texture
},
],
requires : [
uv0
],
shadingModel : lit,
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, getUV0());
}
}
variables
- 類型
string
的陣列- 值
- 最多 4 個字串,且每個字串都必須是有效的 GLSL ID。
- 說明
- 定義由材質和頂點著色器輸出的自訂內插器 (或變數)。陣列的各個項目會定義內插名稱。片段著色器中的全名是含有
variable_
前置字串的內插名稱。舉例來說,如果您宣告名為eyeDirection
的變數,便可使用variable_eyeDirection
在片段著色器中存取該變數。在頂點著色器中,內插名稱只是MaterialVertexInputs
結構的成員 (在此範例中為material.eyeDirection
)。著色器中的每個內插類型都是float4
(vec4
)。
material {
name : Skybox,
parameters : [
{
type : sampler2d,
name : skybox
}
],
variables : [
eyeDirection
],
vertexDomain : device,
depthWrite : false,
shadingModel : unlit
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
float theta = acos(variable_eyeDirection.y);
float phi = atan(variable_eyeDirection.z / variable_eyeDirection.x) +
(variable_eyeDirection.x > 0.0 ? 0.0 : PI);
material.baseColor = texture(materialParams_skybox,
vec2((phi + PI / 2.0) / (2.0 * PI), theta / PI));
}
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
float3 p = getPosition().xyz;
float3 u = mulMat4x4Float3(getViewFromClipMatrix(), p).xyz;
material.eyeDirection.xyz = mulMat3x3Float3(getWorldFromViewMatrix(), u);
}
}
混和
- 類型
string
- 值
opaque
、transparent
、fade
、add
、masked
中的任一項目。預設為opaque
。- 說明
定義轉譯的物件與轉譯目標內容混合方式/使用方式。可能的混合模式如下:
- 不透明:混合停用,材質和輸出內容的 Alpha 通道會遭到忽略。
- 透明:已啟用混合功能。材料的輸出以算繪目標與 Alpha 版重疊,使用 Porter-Duff' 的來源 over 規則這個混合模式假設預先套用 Alpha 版。
- 淡出效果:運作方式為
transparent
,但透明度也會套用至鏡面光源。在transparent
模式中,材質的 Alpha 值僅適用於漫反光。這種混合模式有助於將打光物體淡入和淡出。 - 新增:已啟用混合功能。素材的輸出內容會新增至轉譯目標的內容。
- 遮罩:停用混合功能。這個混合模式支援 Alpha 版遮蓋。材質的 Alpha 通道會定義是否要捨棄片段。詳情請參閱「maskThreshold」部分。
material {
blending : transparent
}
頂點網域
- 類型
string
- 值
object
、world
、view
、device
中的任一項。預設為object
。- 說明
定義轉譯網格的網域 (或座標空間)。網域會影響頂點著色器中的轉換方式。可用的網域如下:
- 物件:頂點在物件 (或模型) 座標空間中定義。使用轉譯的物件和#39; 轉換矩陣 轉換頂點
- 世界:頂點會定義於世界座標空間。頂點不會使用轉譯的物件轉換而轉換。
- 檢視畫面:頂點定義於檢視畫面 (或眼睛或相機) 座標空間。頂點不會使用轉譯的物件轉換進行轉換。
- 裝置:頂點會在正規裝置 (或剪輯) 座標空間中定義。頂點不會使用轉譯的物件轉換而轉換。
material {
vertexDomain : device
}
內插
- 類型
string
- 值
- 「
smooth
」中的任一項目,flat
。預設為smooth
。 - 說明
- 定義在頂點之間插入內插類型 (或變數) 的方式。將這項屬性設為
smooth
時,系統會對每個內插器執行正確的正確插值。設為flat
時,系統不會執行內插功能,且所有三角形內的所有片段都會以同樣的狀態覆蓋。
material {
interpolation : flat
}
復原
- 類型
string
- 值
none
、front
、back
、frontAndBack
中的任一項。預設為back
。- 說明
- 定義要剪輯的三角形:無、前置三角形、後向三角形或全部。
material {
culling : none
}
色彩寫入
- 類型
boolean
- 值
true
或false
預設為true
。- 說明
- 用於啟用或停用色緩衝區的寫入功能。
material {
colorWrite : false
}
深度寫入
- 類型
boolean
- 值
true
或false
預設為true
。- 說明
- 用於啟用或停用深度緩衝區寫入功能。
material {
depthWrite : false
}
深度文化
- 類型
boolean
- 值
true
或false
預設為true
。- 說明
- 用於啟用或停用深度測試。停用深度測試時,包含此材質轉譯的物件一律會顯示在其他不透明物件上方。
material {
depthCulling : false
}
雙面
- 類型
boolean
- 值
true
或false
預設為false
。- 說明
- 啟用或停用雙向轉譯功能。設為
true
時,culling
會自動設為none
;如果三角形是後面,三角形會自動正常翻轉為正面。
material {
doubleSided : true
}
資訊公開
- 類型
string
- 值
default
、twoPassesOneSide
或twoPassesTwoSides
中的任一項。預設為default
。- 說明
- 控管透明物件的呈現方式。只有在
blending
模式不是opaque
時,才有效。雖然上述方法均無法準確反映理想的幾何圖形,但實際上通常足夠。
有三種透明度模式:
default
:透明物件會正常轉譯,並遵循culling
模式等。twoPassesOneSide
:透明物件會先在深度緩衝區中算繪,再於顏色緩衝區中算繪,以遵循cullling
模式。這實際上只會成功顯示透明物件的一半,如下所示。twoPassesTwoSides
:透明物件會在色彩緩衝區中算繪兩次:首先是其背面,接著是前方。這個模式可以讓您轉譯兩組臉孔,同時減少或消除排序問題,如下所示。twoPassesTwoSides
可與doubleSided
結合使用以獲得更好的效果。
material {
transparency : twoPassesOneSide
}
遮罩閾值
- 類型
number
- 值
- 介於
0.0
和1.0
之間的值。預設為0.4
。 - 說明
- 設定當
blending
模式設為masked
時,不得捨棄片段的最小 Alpha 值。當混合模式不是masked
時,系統會忽略這個值。這個值可用於控制 Alpha 遮蓋物件的外觀。
material {
blending : masked,
maskThreshold : 0.5
}
shadowMultiplier
- 類型
boolean
- 值
true
或false
預設為false
。- 說明
- 僅適用於
unlit
著色模型。如果啟用這個屬性,則材質計算的最終顏色乘以陰影因子 (或瀏覽權限)。這可讓您建立透明的陰影接收物件 (例如:AR 中的隱形地面平面)。
material {
name : "Invisible shadow plane",
shadingModel : unlit,
shadowMultiplier : true,
blending : transparent
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// baseColor defines the color and opacity of the final shadow
material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);
}
}
子類篩選器
- 類型
string
的陣列- 值
- 每個項目必須是
dynamicLighting
、directionalLighting
、shadowReceiver
或skinning
中的任一項。 - 說明
- 用於指定應用程式不需要的著色器變數清單。這些程式碼著色器會在程式碼產生階段遭到略過,因此可以降低材質的整體大小。請注意,部分變化版本可能會自動篩除。舉例來說,所有編譯相關的變數 (
directionalLighting
等) 在編譯unlit
材料時都會被篩除。請謹慎使用變化版本篩選器,篩選出執行階段所需的變數可能會導致當機。
變化版本的說明: - directionalLighting
,適用於情境中的光源 - dynamicLighting
,適用於情境中的非定向光源 (點、位置等) - shadowReceiver
,用於物件接收陰影時使用 - skinning
,在物件使用 GPU 膚色建立動畫效果時使用
material {
name : "Invisible shadow plane",
shadingModel : unlit,
shadowMultiplier : true,
blending : transparent,
variantFilter : [ skinning ]
}
頂點區塊
頂點區塊為選用項目,可用來控制素材的頂點陰影階段。頂點區塊必須包含有效的 ESSL 3.0 程式碼 (OpenGL ES 3.0 中支援的 GLSL 版本)。您可以在頂點區塊中建立多個函式,但「必須」宣告 materialVertex
函式:
vertex {
void materialVertex(inout MaterialVertexInputs material) {
// vertex shading code
}
}
著色系統會在執行階段自動叫用這個函式,並讓您使用 MaterialVertexInputs
結構讀取及修改 Material 屬性。結構的完整定義請參閱質感設計端點輸入一節。
您可以使用這個結構來計算自訂變數/內插器,或修改屬性的值。舉例來說,下列頂點區塊會隨著時間改變頂點的色彩和 UV 座標:
material {
requires : [uv0, color]
}
vertex {
void materialVertex(inout MaterialVertexInputs material) {
material.color *= sin(getTime());
material.uv0 *= sin(frameUniforms.time);
}
}
除了 MaterialVertexInputs
結構以外,頂點陰影程式碼也可以使用著色器公用 API 一節中列出的所有公用 API。
材質頂點輸入
struct MaterialVertexInputs {
float4 color; // if the color attribute is required
float2 uv0; // if the uv0 attribute is required
float2 uv1; // if the uv1 attribute is required
float3 worldNormal; // only if the shading model is not unlit
float4 worldPosition; // always available
// variable* names are replaced with actual names
float4 variable0; // if 1 or more variables is defined
float4 variable1; // if 2 or more variables is defined
float4 variable2; // if 3 or more variables is defined
float4 variable3; // if 4 or more variables is defined
};
片段區塊
片段區塊必須用來控製材料的片段陰影階段。片段區塊必須包含有效的 ESSL 3.0 程式碼 (OpenGL ES 3.0 中支援的 GLSL 版本)。您可以在頂點區塊中建立多個函式,但「必須」宣告 material
函式:
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// fragment shading code
}
}
著色系統會在執行階段自動叫用這個函式,並讓您使用 MaterialInputs
結構讀取及修改 Material 屬性。結構的完整定義請參閱 Material 片段輸入部分。請參閱本文的「材質模型」部分,取得結構各個成員的完整定義。
material()
函式的目標是計算所選陰影模型的專屬材質屬性。例如,下列片段區塊使用標準亮光模型建立光滑的紅色金屬:
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor.rgb = vec3(1.0, 0.0, 0.0);
material.metallic = 1.0;
material.roughness = 0.0;
}
}
prepMaterial 函式
請注意,在離開 material()
函式之前,您必須呼叫 prepareMaterial(material)
。這個 prepareMaterial
函式會設定 Material 模型的內部狀態。Fragment API 區段中提及的某些 API (例如 shading_normal
) 只能在叫用 prepareMaterial()
「之後」存取。
請特別注意,normal
屬性 (如材質片段輸入 一節所述) 在修改 prepareMaterial()
之前才會有影響。下列為片段著色器的片段,可正確修改 normal
屬性,以實作具有碰撞映射的光滑紅色塑膠:
fragment {
void material(inout MaterialInputs material) {
// fetch the normal in tangent space
vec3 normal = texture(materialParams_normalMap, getUV0()).xyz;
material.normal = normal * 2.0 - 1.0;
// prepare the material
prepareMaterial(material);
// from now on, shading_normal, etc. can be accessed
material.baseColor.rgb = vec3(1.0, 0.0, 0.0);
material.metallic = 0.0;
material.roughness = 1.0;
}
}
Material 片段輸入內容
struct MaterialInputs {
float4 baseColor; // default: float4(1.0)
float4 emissive; // default: float4(0.0)
// no other field is available with the unlit shading model
float roughness; // default: 1.0
float metallic; // default: 0.0, not available with cloth
float reflectance; // default: 0.5, not available with cloth
float ambientOcclusion; // default: 0.0
// not available when the shading model is cloth
float clearCoat; // default: 1.0
float clearCoatRoughness; // default: 0.0
float3 clearCoatNormal; // default: float3(0.0, 0.0, 1.0)
float anisotropy; // default: 0.0
float3 anisotropyDirection; // default: float3(1.0, 0.0, 0.0)
// only available when the shading model is cloth
float3 sheenColor; // default: sqrt(baseColor)
float3 subsurfaceColor; // default: float3(0.0)
// not available when the shading model is unlit
// must be set before calling prepareMaterial()
float3 normal; // default: float3(0.0, 0.0, 1.0)
}
著色器公用 API
類型
雖然可以直接使用 GLSL 類型 (vec4
或 mat4
),但我們建議使用下列類型別名:
名稱 | GLSL 類型 | 說明 |
---|---|---|
布林值 | BVEC2 | 包含 2 個布林值的向量 |
布林值 3 | Bvec3 | 包含 3 個布林值的向量 |
布林值 4 | Bvec4 | 包含 4 個布林值的向量 |
整數 2 | ivec2 | 包含 2 個整數的向量 |
整數 3 | ivec3 | 包含 3 個整數的向量 |
整數 4 | ivec4 | 包含 4 個整數的向量 |
uint2 | Uvec2 | 包含 2 個無符號整數的向量 |
uint3 | Uvec3 | 包含 3 個無符號整數的向量 |
uint4 | Uvec4 | 包含 4 個無符號整數的向量 |
浮點 2 | 浮點值 2 | 包含 2 個浮點的向量 |
浮點 3 | 浮點值 3 | 包含 3 個浮點的向量 |
float4 | 浮點值 4 | 包含 4 個浮點的向量 |
float4x4 | 墊 4 | 4x4 浮點矩陣 |
float3x3 | 墊片 3 | 3x3 浮點矩陣 |
數學
名稱 | 類型 | 說明 |
---|---|---|
PI | 浮動 | 代表 \(\pi\)的常數 |
HALF_PI | 浮點值 | 代表\(\frac{\pi}{2}\)的常數 |
saturate(float x) | 浮點值 | 將指定的值限制在 0.0 到 1.0 之間 |
pow5(浮點 x) | 浮動 | 運算 \(x^5\) |
sq(浮動 x) | 浮動 | 運算 \(x^2\) |
max3(float3 v) | 浮點值 | 傳回指定 float3 的最大值 |
mulMat4x4Float3(float4x4m, float3 v) | float4 | 傳回 \(m * v\) |
mulMat3x3Float3(float4x4m, float3 v) | float4 | 傳回 \(m * v\) |
矩陣
名稱 | 類型 | 說明 |
---|---|---|
getViewFromWorldMatrix() | float4x4 | 從世界空間轉換為檢視/眼睛空間的矩陣 |
getWorldFromViewMatrix() | float4x4 | 從檢視/眼睛空間轉換成世界空間的矩陣 |
getClipFromViewMatrix() | float4x4 | 從觀看/眼睛空間轉換成剪輯 (NDC) 空間的矩陣 |
getViewFromClipMatrix() | float4x4 | 將片段 (NDC) 空間轉換為檢視/眼部空間的矩陣 |
getClipFromWorldMatrix() | float4x4 | 可從世界轉換為剪輯 (NDC) 空間的矩陣 |
影格常數
名稱 | 類型 | 說明 |
---|---|---|
getResolution() | 浮點值 4 | 以像素為單位的檢視畫面解析度:width 、height 、1 / width 、1 / height |
getWorldCameraPosition() | 浮點值 3 | 相機/眼睛在世界空間中的位置 |
getTime() | 浮動 | Sceneform 引擎初始化後的所需時間 (以秒為單位),可能會定期重設,以免精確度損失 |
getImpression() | 浮動 | 相機的光度曝露 |
getEV100() | 浮動 | 相機的 ISO 100 曝光值 |
僅限 Vertex
下列 API 僅適用於頂點區塊:
名稱 | 類型 | 說明 |
---|---|---|
getPosition() | float4 | 由材質定義的網域中的頂點位置 (預設值:物件/模型空間) |
getWorldFromModelMatrix() | float4x4 | 將模型 (物件) 空間轉換為世界空間的矩陣 |
getWorldFromModelNormalMatrix() | float3x3 | 可將法線 (物件) 空間空間轉換為世界空間的矩陣 |
僅限片段
下列 API 僅適用於片段區塊:
名稱 | 類型 | 說明 |
---|---|---|
getWorldTangentFrame() | float3x3 | 在每個資料欄中,包含世界空間中頂點的 tangent (frame[0] )、bi-tangent (frame[1] ) 和 normal (frame[2] ) 的矩陣。如果材質不會計算串場廣告映射的切線空間,或者陰影並非不同的非均質,則這個矩陣中只有 normal 有效。 |
getWorldPosition() | float3 | 片段在世界空間中的位置 |
getWorldViewVector() | float3 | 從片段位置到眼睛的世界空間正規化向量 |
getWorldNormalVector() | float3 | 串場廣告空間後正常化的標準空間 (必須在 prepareMaterial() 之後使用) |
getWorldReflectedVector() | float3 | 可反映檢視畫面向量的正常檢視畫面 (必須在 prepareMaterial() 之後使用) |
getNdotV() | 浮點值 | dot(normal,
view) 的結果,一律大於 0 (必須在 prepareMaterial() 之後使用) |
getColor() | float4 | 需要插色的片段顏色 (如果需要色彩屬性) |
getUV0() | float2 | 如果需要 uv0 屬性,則第一組內插式 UV 座標 |
getUV1() | float2 | 如果需要 uv1 屬性,則第一組內插式 UV 座標 |
inverseTonemap(float3) | float3 | 將反向色調對應運算子套用至指定的線性 sRGB 顏色。這項作業可能為約略值 |
inverseTonemapSRGB(float3) | float3 | 將反向色調對應運算子套用至指定的非線性 sRGB 顏色。這項作業約為 |
luminance(float3) | 浮點值 | 計算指定線性 sRGB 顏色的亮度 |
材質模型
場景資料可使用下列其中一種質感模型:
- 亮光 (或標準)
- 布
- 打光
Lit 模型
照明模型是 Sceneform' 標準材質模型。此實體式著色模型經過設計,可與其他常見工具和引擎 (例如 Unity 5、Unreal Engine 4、Substance Designer 或 Marmoset Toolpack) 具有良好的互通性。
此質感模型可用於描述大量非金屬表面 (電工) 或金屬表面 (導體)。
使用標準屬性控管材質外觀時,可以使用下表中說明的屬性。
標準模型的屬性
屬性 | 定義 |
---|---|
baseColor | 非金屬表面的漫反射配置,金屬表面的鏡片顏色 |
Metallic | 途徑似乎是電傳 (0.0) 還是導電 (1.0)。通常用做二進位值 (0 或 1) |
粗糙度 | 感知表面的平滑度 (1.0) 或粗糙度 (0.0)。平滑的表面顯示了清晰的反射 |
反射 | 中階表面的發射率為電流反射。這樣可直接控制反射的強度 |
ClearCoat | 透明外套層的強度 |
clearCoatRoughness | 感知平滑層層的平滑度或粗糙度 |
非均質性 | 切線或位元方向的各向異性 |
無異質方向 | 當地途徑方向 |
ambientOcclusion | 定義透過表面點能夠存取的環境光度。每個像素的陰影係數介於 0.0 到 1.0 之間 |
一般 | 使用擴音對應來覆寫表面的詳細資料 (一般對應) |
clearCoatNormal | 使用「bumap map」(常規對應) 來清除透明外套層的詳細資料 (一般對應) |
幹擾 | 使用其他漫反射模擬模擬模擬表面 (例如霓虹燈等)這項屬性在大量花卉傳遞的 HDR 管線中非常實用 |
下表說明每個屬性的類型和範圍。
屬性 | 類型 | 範圍 | 注意事項 |
---|---|---|---|
baseColor | 浮點值 4 | [0..1]。 | 預先乘以線性 RGB |
金屬樂 | 浮動 | [0..1]。 | 應為 0 或 1 |
粗糙度 | 浮動 | [0..1]。 | |
反射 | 浮動 | [0..1]。 | 偏好值 > 0.35 |
ClearCoat | 浮動 | [0..1]。 | 應為 0 或 1 |
clearCoatRoughness | 浮動 | [0..1]。 | 重新對應至 [0..0.6] |
非均質性 | 浮點值 | [-1..1] | 這個值為正值時,非均質方向為切線方向 |
anisotropyDirection | float3 | [0..1] | 線性 RGB,對切線空間編碼方向向量 |
ambientOcclusion | 浮動 | [0..1]。 | |
一般 | float3 | [0..1] | 線性 RGB,對切線空間編碼方向向量 |
clearCoatNormal | float3 | [0..1] | 線性 RGB,對切線空間編碼方向向量 |
幹擾 | float4 | rgb=[0..1], a=[-n..n] | Alpha 版是曝光補償 |
基本顏色
baseColor
屬性定義了物件的感知色彩 (有時稱為 albedo)。baseColor
的效果取決於途徑的性質,由 Metallic 一節說明的 metallic
屬性所控制。
- 非金屬 (電業)
用於定義表面的漫反射顏色。如果值在 0 到 255 之間編碼,或是範圍 [0.04..0.94] 到 0 到 1 之間,則實際值通常位於 [10..240] 範圍內。下表為非金屬表面的基本顏色範例。
金屬音樂 sRGB 十六進位數 顏色 珊瑚色 0.19、0.19、0.19 #323232 橡膠 0.21、0.21、0.21 #353535 泥濘 0.33、0.24、0.19 #553d31 木材 0.53、0.36、0.24 #875c3c 植被 0.48、0.51、0.31 #7b824e Brick 0.58、0.49、0.46 #947d75 沙 0.69、0.66、0.52 #b1a884 Concrete 0.75、0.75、0.73 #c0bfbb - 金屬 (導電)
定義途徑的鏡面色。如果這個值是在 0 到 255 之間編碼,或是範圍 [0.66..1.0] 到 0 到 1 之間,則實際值通常會落在 [170..255] 範圍內。請參閱下表,瞭解金屬表面的基本顏色範例。
金屬音樂 sRGB 十六進位數 顏色 銀色 0.98、0.98、0.96 #faf9f5 鋁 0.96、0.96、0.96 #f4f5f5 Titan 0.81、0.78、0.76 #cec8c2 鐵 0.76、0.74、0.73 #c0bdba 白金級 0.84、0.82、0.79 #d6d1c8 鑠金獎 1.00、0.87、0.62 #fedc9d 黃銅 0.96、0.89、0.68 #f4e4ad 銅 0.98、0.85、0.72 #fbd8b8
金屬
metallic
屬性會定義途徑是否為金屬 (「導體」) 或非金屬 (電電) 表面。這個屬性應用於二進位值,設為 0 或 1。使用紋理時,中繼值只能在不同類型表面之間建立轉場。
這個屬性會大幅改變表面的外觀。非金屬表面會呈現色差反射和光學鏡面反射 (反射光不會改變顏色)。金屬表面沒有任何反射和反射鏡的鏡面反射 (反射光會沿用 baseColor
所定義的途徑顏色)。
metallic
的效果如下所示 (按一下圖片即可查看較大的版本)。
粗糙度
roughness
屬性可控制介面的感知平滑度。將 roughness
設為 0 時,表面可保持光滑流暢。表面越粗糙,就是「反映者」。反思就是這個屬性通常在其他引擎和工具中稱為「光暈」,正好與粗糙度 (roughness = 1 - glossiness
) 相反。
非金屬
roughness
對非金屬介面的影響 (按一下圖片即可查看較大版本)。
金屬
roughness
對金屬介面的影響 (按一下圖片即可查看較大的版本)。
感受
reflectance
屬性只會影響非金屬表面。這個屬性可用來控制鏡面強度。這個值定義於 0 和 1 之間,代表重新對應百分比的百分比。舉例來說,預設值 0.5 對應 4% 的反射率。您應避免使用低於 0.35 (2% 反射率) 的值,因為現實世界中沒有任何材質的低反射率。
reflectance
對非金屬介面的影響 (按一下圖片即可查看較大版本)。
下圖顯示常見值以及與對應函式之間的關係。
下表說明各種材質類型的可接受的反射率值 (實際材質的值低於 2%)。
Material | 感受 | 屬性值 |
---|---|---|
水域 | 2% | 0.35 |
布料 | 4% 至 5.6% | 0.5 至 0.59 |
常見的液體 | 2% 至 4% | 0.35 至 0.5 |
常見寶石 | 5% 至 16% | 0.56 至 1.0 |
塑膠、玻璃 | 4% 至 5% | 0.5 至 0.56 |
其他電氣材料 | 2% 至 5% | 0.35 至 0.56 |
眼睛 | 2.5% | $0.39 美元 |
外觀 | 2.8% | 0.42 |
美髮 | 4.6% | 0.54 |
牙齒 | 5.8% | 0.6 |
預設值 | 4% | 0.5 |
清除外套
多層材質相當常見,特別是在基礎層上有半透明層的材質。這類材料的範例包括油漆、汽水罐、漆木和壓克力。
clearCoat
屬性可用來描述包含兩個圖層的材質。明確的外套層應一律為全向和電感。下圖比較了標準材質模型 (左側) 和透明外套模型 (右側) 上的碳纖維材質。
clearCoat
屬性可控制明確的外套層強度。這項要求應視為二進位值,並設為 0 或 1。中繼值有助於控製表面上具有明確外層層的部分,以及沒有哪些區域之間的轉換效果。
clearCoat
對約略金屬的影響 (點選圖片即可查看較大版本)。
清除外套粗糙度
clearCoatRoughness
屬性與 roughness
屬性類似,但僅適用於清除外套層。此外,由於清除外層層永不完全粗糙,因此 0 和 1 之間的值會在內部重新對應為 0 到 0.6 的實際粗糙度。
clearCoatRoughness
對約略金屬的影響 (按一下圖片即可查看較大的版本)。
非均質
許多實際材質 (例如拉絲金屬) 只能使用非均質反射模型複製。您可以使用 anisotropy
屬性,將預設材質從非均質模型變更為非均質模型。下圖比較了非均質材料 (左側) 和天平材料 (右側)。
將 anisotropy
從 0.0 (左) 到 1.0 (右側) 的差異在粗糙度金屬表面上 (按一下圖片即可查看較大的版本)。
下圖顯示如何使用正值或負值來控制非均質醒目顯示的方向:正值 (左) 定義切線方向的非均質,以及正方向的負值 (右側)。
非均質方向
anisotropyDirection
屬性會在特定點定義途徑的方向,因此控制鏡面醒目顯示的形狀。指定為 3 個值的向量,通常由紋理組成,會編碼到途徑的本機路線。
以下程式碼顯示了在有方向貼圖的金屬上算繪 anisotropyDirection
的效果 (按一下圖片即可查看較大的版本)。
用來呈現上圖的方向地圖如下所示。
環境遮蔽
ambientOcclusion
屬性會定義透過途徑存取的環境光度。以 0.0 (完全覆蓋) 和 1.0 (完全亮燈) 之間的每像素陰影係數計算。這個屬性只會影響光柵間接光源 (圖片型照明),不會影響定向、點和光源等直接光源,也不會影響鏡面照明。下圖比較了沒有擴散環境光遮蔽 (左) 和與其 (右) 的材質。
正常
normal
屬性會定義特定時間點的介面法線。通常是來自法線圖紋理,因此每像素的屬性不同。正切空間提供法向量,表示 +Z 指向表面外。
例如,假設我們要想顯示一件掛著絨衣皮革的家具。建立幾何圖形時,為了正確顯示疊加模式,將需要過多三角形,因此我們將高多邊形網格烘焙為法線圖。接著,即可將基本地圖套用至簡化的網格。下圖比較了不含正映射的簡單網格 (左) 與右側圖像 (右側)。
請注意,normal
屬性會影響基礎層,而非明確的外層。
清除外套
clearCoatNormal
屬性定義了特定點上的透明漆層的正常值。運作方式與 normal
屬性相同。
發射
emissive
屬性可用來模擬介面發出的額外光源。定義為 float4
值,其中包含 RGB 顏色 (線性空間) 和曝光補償值 (Alpha 管道)。
雖然曝光值實際上會反映相機設定的組合,但攝影師通常用於描述光強度。因此,相機可讓相機為曝光不足或曝光不足的圖片曝光補償。這項設定可用於藝術控制,但有助於達到適當的曝光度 (例如,曝光時的 18% 會是灰色)。
排放屬性的曝光補償值可用於強制發光的顏色比目前的曝光更亮 (正值) 或更暗 (負值)。如果已啟用花卉花卉效果,則使用正面的補償補償方式,可允許表面開花。
佈局模型
前述的所有 Material 模型旨在模擬以巨集和微觀設計的模擬介面。不過,衣服和織布通常由鬆耦合的執行緒以吸收並散射事件光源組成。與硬性表面相比,布料的特徵是柔和的鏡面強片和較大的落體,並帶有模糊光源導致的向前/向後散佈所導致。有些布料也會呈現雙色鏡片顏色 (例如天鵝絨)。
下圖比較使用標準模型 (左側) 和布料模型 (右側) 算繪的丹寧布料。請注意,標準材質模型無法擷取牛仔布料樣本 (左側) 的外觀。表面看起來像是堅硬的 (近似塑膠材質),與布料相比,比一件布料更類似。這也顯示了因吸收和散佈導致的柔軟鏡面柔軟程度,對於將生活巧妙地融入布料的重要性。
Velvet 是布料模型的常見用途。如下圖所示,這類布料因正向和反向散佈而產生強烈的邊緣光照。這些散佈事件是由直立在布料表面的纖維所引起。當事件光源從與檢視方向相反的方向產生時,光纖會將光散射。同樣地,當光源從觀看方向的方向相同時,光纖會散熱。
但請注意,有些布料類型仍是由硬質材質材質製成。舉例來說,可以使用標準或非均質材料模型重新建立皮革、絲綢和拋光。
布料模型包含先前針對標準材質模式定義的所有參數,但 Metallic 和 reflectance 除外。下表有兩個額外參數可用。
參數 | 定義 |
---|---|
sheenColor | 用於建立雙色鏡面布料的鏡面色調 (預設為 \(\sqrt{baseColor}\)) |
subsurfaceColor | 在散佈後透過材質吸收和色調的色調 |
下表說明每個屬性的類型和範圍。
屬性 | 類型 | 範圍 | 注意事項 |
---|---|---|---|
sheenColor | 浮點值 3 | [0..1]。 | 線性 RGB |
subsurfaceColor | 浮點值 3 | [0..1]。 | 線性 RGB |
如要建立類似天鵝絨的材質,基本顏色可設為黑色 (或深色)。應改為在顏色上設定顏色。如要建立較常見的布料 (例如丹寧布、棉質等),請使用基本色色做為色階,並使用預設色調顏色,或將色調顏色設為基本顏色的亮度。
亮色
sheenColor
屬性可用來直接修改鏡面反射。可進一步控制布料的外觀,並讓使用者能夠建立雙色鏡面材質。
下圖為比較有 (沒有) 和有 (右) 色調的藍色布料 (點選圖片即可查看較大的版本)。
子介面顏色
subsurfaceColor
屬性並非以實體為基礎,可用於模擬某些類型布料的光吸收、部分吸收和重新發光。這一點有助於製作柔軟的布料。
下圖說明 subsurfaceColor
的效果。顯示白布 (左欄) 與白色布料散佈 (右欄) 的白布。按一下圖片即可查看較大的版本。
未打光模式
未打光材料模型可用來關閉所有光源運算。其主要用途是轉譯預先打光的元素,例如立方體對應、外部內容 (例如影片或相機)、使用者介面、視覺化/偵錯等。未亮相模型只會公開下表中的兩個屬性。
屬性 | 定義 |
---|---|
baseColor | 介面擴散色彩 |
幹擾 | 可模擬發光錶面的其他擴散色彩。這項屬性在大量花卉傳遞的 HDR 管線中非常實用 |
下表說明每個屬性的類型和範圍。
屬性 | 類型 | 範圍 | 注意事項 |
---|---|---|---|
baseColor | 浮點值 4 | [0..1]。 | 預先乘以線性 RGB |
幹擾 | float4 | rgb=[0..1], a=N/A | 預先乘法的線性 RGB 將忽略 Alpha 版 |
emissive
的值會存在時直接新增至 baseColor
。如果使用 HDB 管道設定花朵通過,emissive
的主要用途就是強制強制亮光。
下圖顯示用於顯示偵錯資訊的未亮面材質模型 (按一下圖片即可查看較大的版本)。
處理顏色
線性顏色
如果顏色資料來自紋理,請務必使用 sRGB 紋理,從 sRGB 到線性的自動硬體轉換功能中受益。如果色彩資料會以參數形式傳遞至材質,您可以在每個顏色管道上執行以下演算法,從 sRGB 轉換為線性:
float sRGB_to_linear(float color) {
return color <= 0.04045 ? color / 12.92 : pow((color + 0.055) / 1.055, 2.4);
}
或者,您也可以使用下列其中一個價格較低的版本,如下所示:
// Cheaper
linearColor = pow(color, 2.2);
// Cheapest
linearColor = color * color;
乘數 Alpha 版
如果顏色的 RGB 元件乘以 Alpha 通道,顏色就會使用經過乘數的 Alpha 版:
// Compute pre-multiplied color
color.rgb *= color.a;
如果從紋理取樣了顏色,則只需要確保紋理資料已預先乘以。在 Android 裝置上,根據預設,只要從點陣圖上傳的所有紋理都會預先經過倍數計算。