(Direct3D 9)
材質描述多邊形如何反射光線或在 3D 場景中發出光線。 材質屬性詳述材質的擴散反射、環境反射、光線發出和反射醒目提示特性。 Direct3D 會使用 D3DMATERIAL9 結構來攜帶所有材質屬性資訊。 除了反射屬性之外,每個屬性都會描述為 RGBA 色彩,代表指定類型光線的紅色、綠色和藍色部分,以及 Alpha 混合因數。
擴散和環境反射
D3DMATERIAL9結構的擴散和環境成員描述材質如何反映場景中的環境和擴散光線。 因為大部分場景包含比環境光線更多的擴散光線,所以擴散反射在決定色彩時扮演了最大的部分。 此外,因為擴散光線是方向的,擴散光線的擴散角度會影響反射的整體強度。 當光線與頂點法線平行時,擴散反射是最大的。 隨著角度增加,擴散反射的效果會降低。 反射的光線量是傳入光線與頂點法線之間角度的余弦值,如下圖所示。
環境反射就像環境光線一樣,是非雙向的。 環境反射對轉譯物件的明顯色彩有較少的影響,但它會影響整體色彩,而且在稍微或沒有擴散光線會從材質反射時最明顯。 使用 D3DRS_AMBIENT 旗標呼叫 IDirect3DDevice9::SetRenderState 方法,會受到場景的環境光線所影響。
擴散和環境反射會一起運作,以判斷物件的感知色彩,而且通常是相同的值。 例如,若要轉譯藍色玻璃線物件,您可以建立只反映擴散和環境光線藍色元件的材質。 當放在具有白色光線的會議室中時,玻璃看起來會是藍色。 不過,在只有紅色光線的會議室中,相同的玻璃看起來會是黑色,因為其材質不會反射紅色光線。
排放
材質可用來讓呈現的物件顯示為自我亮度。 D3DMATERIAL9結構的 Emissive 成員是用來描述發出光線的色彩和透明度。 放射會影響物件的色彩,例如讓深色材質更亮,並呈現部分的發出色彩。
您可以使用材質的放射屬性來新增物件發出光線的假像,而不會產生將光線新增至場景的計算額外負荷。 在藍色玻璃的情況下,如果您想要讓玻璃變成亮起,但不會在場景中的其他物件上投射光線,則放射屬性會很有用。 請記住,具有放射屬性的材質不會發出光線,而其他物件可以在場景中反射。 若要達到此反射光線,您需要在場景中放置額外的光線。
反射
反射會在物件上建立醒目提示,使其看起來亮亮。 D3DMATERIAL9結構包含兩個成員,描述反射醒目提示色彩,以及材質的整體亮色。 您可以將反射成員設定為所需的 RGBA 色彩來建立反射醒目提示的色彩 - 最常見的色彩是白色或淺灰色。 您在 Power 成員中設定的值可控制反射效果的尖度。
反射醒目提示可能會產生顯著的效果。 再次在藍色玻璃類比上繪製:較大的 Power 值會建立更清楚的反射醒目提示,使玻璃看起來相當亮。 較小的值會增加效果的區域,並建立一個反射,讓玻璃外觀變淡。 若要讓物件真正無光,請將 Power 成員設定為零,並將 Specular 中的色彩設定為黑色。 試驗不同層級的反映,以針對您的需求產生實際的外觀。 下圖顯示兩個相同的模型。 左邊的反射功率為 10;右側的模型沒有反射。
設定材質屬性
Direct3D 轉譯裝置可以一次使用一組材質屬性來轉譯。
在 C++ 應用程式中,您可以準備 D3DMATERIAL9 結構來設定系統所使用的材質屬性,然後呼叫 IDirect3DDevice9::SetMaterial 方法。
若要準備 D3DMATERIAL9 結構以供使用,請設定 結構中的屬性資訊,以在轉譯期間建立所需的效果。 下列程式碼範例會設定紫色材質的 D3DMATERIAL9 結構,其白色反射醒目提示。
D3DMATERIAL9 mat;
// Set the RGBA for diffuse reflection.
mat.Diffuse.r = 0.5f;
mat.Diffuse.g = 0.0f;
mat.Diffuse.b = 0.5f;
mat.Diffuse.a = 1.0f;
// Set the RGBA for ambient reflection.
mat.Ambient.r = 0.5f;
mat.Ambient.g = 0.0f;
mat.Ambient.b = 0.5f;
mat.Ambient.a = 1.0f;
// Set the color and sharpness of specular highlights.
mat.Specular.r = 1.0f;
mat.Specular.g = 1.0f;
mat.Specular.b = 1.0f;
mat.Specular.a = 1.0f;
mat.Power = 50.0f;
// Set the RGBA for emissive color.
mat.Emissive.r = 0.0f;
mat.Emissive.g = 0.0f;
mat.Emissive.b = 0.0f;
mat.Emissive.a = 0.0f;
準備 D3DMATERIAL9 結構之後,您可以呼叫轉譯裝置的 IDirect3DDevice9::SetMaterial 方法來套用屬性。 這個方法接受備妥 的 D3DMATERIAL9 結構位址做為其唯一的參數。 您可以視需要呼叫 IDirect3DDevice9::SetMaterial ,以更新裝置的材質屬性。 下列程式碼範例示範這在程式碼中的外觀。
// This code example uses the material properties defined for
// the mat variable earlier in this topic. The pd3dDev is assumed
// to be a valid pointer to an IDirect3DDevice9 interface.
HRESULT hr;
hr = pd3dDev->SetMaterial(&mat);
if(FAILED(hr))
{
// Code to handle the error goes here.
}
當您建立 Direct3D 裝置時,目前的材質會自動設定為下表所示的預設值。
成員 | 值 |
---|---|
擴散 | (R:0、G:0、B:0、A:0) |
反射 | (R:0、G:0、B:0、A:0) |
環境 | (R:0、G:0、B:0、A:0) |
放射 | (R:0、G:0、B:0、A:0) |
電源 | (0.0) |
擷取材質屬性
您可以呼叫裝置的 IDirect3DDevice9::GetMaterial 方法來擷取轉譯裝置目前正在使用的材質屬性。 不同于 IDirect3DDevice9::SetMaterial 方法, IDirect3DDevice9::GetMaterial 不需要準備。 IDirect3DDevice9::GetMaterial方法會接受D3DMATERIAL9結構的位址,並在傳回之前填入所提供結構中描述目前材質屬性的資訊。
// For this example, the pd3dDev variable is assumed to
// be a valid pointer to an IDirect3DDevice9 interface.
HRESULT hr;
D3DMATERIAL9 mat;
hr = pd3dDev->GetMaterial(&mat);
if(FAILED(hr))
{
// Code to handle the error goes here.
}
注意
如果您的應用程式未指定用於轉譯的材質屬性,則系統會使用預設材質。 預設材質會反映所有擴散光線 - 白色,例如 , 沒有環境或反射反射,且沒有放射色彩。
相關主題