共用方式為


材料(Direct3D 9)

材質描述多邊形如何反射光線或在 3D 場景中發出光線。 材質屬性會詳細說明材質的擴散反射、環境反射、光線發射和反射醒目提示特性。 Direct3D 會使用 D3DMATERIAL9 結構來攜帶所有材料屬性資訊。 除了反射屬性之外,每個屬性都會描述為 RGBA 色彩,代表所反映特定光線類型的紅色、綠色和藍色部分,以及 Alpha 混合因數。

擴散和環境反射

D3DMATERIAL9 結構的擴散和環境成員描述材質如何反映場景中的環境和擴散光線。 由於大部分場景包含的擴散光線比環境光線多,擴散反射在決定色彩方面扮演了最大的角色。 此外,由於擴散光線是方向的,擴散光線的發病率角度會影響反射的整體強度。 當光線與頂點正常平行時,擴散反射最大。 隨著角度增加,擴散反射的效果會減弱。 反射的光線量是傳入光線與頂點常態之間角度的餘弦值,如下圖所示。

反射光線量 圖例

環境反射,例如環境光線,是非雙向的。 環境反射對轉譯對象的明顯色彩的影響較小,但它確實會影響整體色彩,而且當材質很少或沒有擴散光線反射時,最明顯。 使用 D3DRS_AMBIENT 旗標呼叫 IDirect3DDevice9::SetRenderState 方法,會影響材質的環境反射。

擴散和環境反射會一起運作,以判斷物件的感知色彩,而且通常是相同的值。 例如,若要轉譯藍色水晶物件,您可以建立只反映擴散和環境光線藍色元件的材質。 當用白色光線放在房間里時,水晶看起來是藍色的。 然而,在只有紅燈的房間里,同樣的水晶看起來會是黑色的,因為它的材料不會反射紅光。

排放

材質可以用來讓轉譯的物件看起來是自我發光的。 D3DMATERIAL9 結構的Emissive成員用來描述發出光線的色彩和透明度。 排放會影響物件的色彩,例如,使深色材質變亮,並承擔所發出色彩的一部分。

您可以使用材質的Emissive屬性來新增對象發出光線的錯覺,而不會產生將光線新增至場景的計算額外負荷。 在藍色水晶的情況下,如果您想要使水晶顯示為亮起,但不會在場景中的其他物件上投下光線,則顯色屬性很有用。 請記住,具有外射屬性的材料不會發出可以由場景中其他物件反映的光線。 若要達到此反射光線,您必須在場景中放置額外的光線。

反射反射

反射會在對象上產生醒目提示,使其看起來閃亮。 D3DMATERIAL9 結構包含兩個成員,描述反射醒目提示色彩,以及材質的整體閃亮。 您可以將反射成員設定為所需的 RGBA 色彩,以建立反射醒目提示的色彩-最常見的色彩為白色或淺灰色。 您在 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.
}

注意

如果您的應用程式未指定呈現材質屬性,則系統會使用預設材質。 默認材質會反映所有擴散光線 -- 例如 - 沒有環境或反射反射,也沒有反射色彩。

 

燈和材質