A Point Light Demo

A Point Light Demo

Point light示例程序與diffuse light示例的代碼非常相似。首先創建一個PointLightingMaterial類用於表示第7章所編寫的PointLight.fx effect。在該effect中結合了Blinn-Phong specular highlighting(鏡面高光)模型。PointLightMaterial中需要包含以下的變量聲明語句:


MATERIAL_VARIABLE_DECLARATION(WorldViewProjection)
MATERIAL_VARIABLE_DECLARATION(World)
MATERIAL_VARIABLE_DECLARATION(SpecularColor)
MATERIAL_VARIABLE_DECLARATION(SpecularPower)
MATERIAL_VARIABLE_DECLARATION(AmbientColor)
MATERIAL_VARIABLE_DECLARATION(LightColor)
MATERIAL_VARIABLE_DECLARATION(LightPosition)
MATERIAL_VARIABLE_DECLARATION(LightRadius)
MATERIAL_VARIABLE_DECLARATION(CameraPosition)

MATERIAL_VARIABLE_DECLARATION(ColorTexture)


在point light和diffuse lighting shader中,具有相同的輸入類型(position、texture coordinates和noraml)。因此,可以複製diffuse light示例中創建input layout和vertex buffer的代碼,或者使用一種機制在這兩個materials之間複用代碼。

在PointLightDemo類中可以大量使用DiffuseLightingDemo類的代碼,只需要把DirectionalLight類型的成員變量替換成一個PointLight類型,並增加一些成員變量用於表示specular color和power值。Point light示例程序中的渲染操作也與diffuse lighting示例中的基本相同,除了一些新增的shader變量。可以使用以下修改point light material:


XMMATRIX worldMatrix = XMLoadFloat4x4(&mWorldMatrix);
XMMATRIX wvp = worldMatrix * mCamera->ViewMatrix() *
mCamera->ProjectionMatrix();
XMVECTOR ambientColor = XMLoadColor(&mAmbientColor);

XMVECTOR specularColor = XMLoadColor(&mSpecularColor);


mMaterial->WorldViewProjection() << wvp;
mMaterial->World() << worldMatrix;
mMaterial->SpecularColor() << specularColor;
mMaterial->SpecularPower() << mSpecularPower;
mMaterial->AmbientColor() << ambientColor;
mMaterial->LightColor() << mPointLight->ColorVector();
mMaterial->LightPosition() << mPointLight->PositionVector();
mMaterial->LightRadius() << mPointLight->Radius();
mMaterial->ColorTexture() << mTextureShaderResourceView;

mMaterial->CameraPosition() << mCamera->PositionVector();


其中與diffuse light示例不同的是,新增了更新specular color和power值,以及light position和radius值。圖17.4顯示了point light示例程序的輸出結果,其中proxy model用於表示point light。


圖17.4 Output of the point light demo. (Texture from Reto Stöckli, NASA Earth Observatory.)
與diffuse lighting示例程序一樣,也可以在運行時調整point light。列表17.7列出了PointLightDemo::UpdatePointLight()函數的代碼,其中使用數字鍵盤4/6(x軸),3/9(y軸),8/2(z軸)分別控制point light沿着x軸,y軸和z軸進行平移。

列表17.7 Moving the Point Light

void PointLightDemo::UpdatePointLight(const GameTime& gameTime)
{
	static float pointLightIntensity = mPointLight->Color().a;
	float elapsedTime = (float)gameTime.ElapsedGameTime();

	// Update point light intensity		
	if (mKeyboard->IsKeyDown(DIK_HOME) && pointLightIntensity < UCHAR_MAX)
	{
		pointLightIntensity += LightModulationRate * elapsedTime;

		XMCOLOR pointLightLightColor = mPointLight->Color();
		pointLightLightColor.a = (UCHAR)XMMin<float>(pointLightIntensity, UCHAR_MAX);
		mPointLight->SetColor(pointLightLightColor);
	}
	if (mKeyboard->IsKeyDown(DIK_END) && pointLightIntensity > 0)
	{
		pointLightIntensity -= LightModulationRate * elapsedTime;

		XMCOLOR pointLightLightColor = mPointLight->Color();
		pointLightLightColor.a = (UCHAR)XMMax<float>(pointLightIntensity, 0.0f);
		mPointLight->SetColor(pointLightLightColor);
	}

	// Move point light
	XMFLOAT3 movementAmount = Vector3Helper::Zero;
	if (mKeyboard != nullptr)
	{
		if (mKeyboard->IsKeyDown(DIK_NUMPAD4))
		{
			movementAmount.x = -1.0f;
		}

		if (mKeyboard->IsKeyDown(DIK_NUMPAD6))
		{
			movementAmount.x = 1.0f;
		}

		if (mKeyboard->IsKeyDown(DIK_NUMPAD9))
		{
			movementAmount.y = 1.0f;
		}

		if (mKeyboard->IsKeyDown(DIK_NUMPAD3))
		{
			movementAmount.y = -1.0f;
		}

		if (mKeyboard->IsKeyDown(DIK_NUMPAD8))
		{
			movementAmount.z = -1.0f;
		}

		if (mKeyboard->IsKeyDown(DIK_NUMPAD2))
		{
			movementAmount.z = 1.0f;
		}
	}

	XMVECTOR movement = XMLoadFloat3(&movementAmount) * LightMovementRate * elapsedTime;
	mPointLight->SetPosition(mPointLight->PositionVector() + movement);
	mProxyModel->SetPosition(mPointLight->Position());
}


A Spotlight Demo

一個Spotlight示例程序與前面兩個示例的創建方式完全一樣,因此把創建spotlight示例程序作爲一個練習,需要創建一個用於表示SpotLight.fx effect的material類以及對應的示例組件。圖17.5顯示了spotlight示例的輸入結果,在本書的配套網站提供了完整的示例。


圖17.5 Output of the spotlight demo.
要在程序運行時調整spotlight,需要結合使用directional和point ligth示例中的操作方式。其中鍵盤方向鍵用於控制spotlight的方向,數字鍵用於更新spotlight的座標位置。

總結

本章創建一系列的類用於支持directional,point和spotlights。並創建對應的material用於應用程序與shader進行交互,這些shader來自於第6章和第7章。然後創建一些示例程序用於演示這些數據類型的用法。本章也是第三部分“Rendering with DirectX”的最後一章。在下一部分,我們將研究一些更高級的渲染課題。

Exercises

1. Develop the spotlight demo discussed in the chapter.
2. Create materials for the environment mapping, transparency mapping, normal mapping, and displacement mapping shaders you authored in Chapter 8, “Gleaming the Cube,” and Chapter 9, “Normal Mapping and Displacement Mapping.” Develop corresponding demo application to exercise these materials.
1、編寫一個本章討論的spotlight示例程序。
2、創建一些materials類用於表示environment mapping,transparency mapping,normal mapping以及displacement mapping shaders,這些shaders分別在第8章和第9章編寫的。最後創建對應的示例程序用於練習這些materials。
發佈了5 篇原創文章 · 獲贊 27 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章