BasicEffect 燈光
總結
操作與 BasicEffect 的燈光部分相關的參數,以查看模型的顯示方式。
操作環境
先決條件
支援的 XNA 版本 |
|
支援的平臺 |
|
Windows 所需的頂點著色器版本 | 2.0 |
Windows 所需的像素著色器版本 | 2.0 |
操作環境
平臺 |
|
如何使用範例
工作鍵盤Xbox | 360控制器滑鼠 | 觸摸 | ||
---|---|---|---|---|
選擇要更改的參數 | ↑、↓ | 左搖桿 ↑, ↓ | 左鍵 | - |
更改參數 | ←、→ | 左搖桿←,→ | ←→ 拖動 | - |
物質
光
燈光用於表示物質的陰影。 在 XNA 中,燈光不會設置為環境設置之一,而是設置為單個效果。
BasicEffect 中有三個平行光源可用,每個光源都具有以下參數:
啟用 | 設置光源是否可用。 |
漫反射顏色 | 光的顏色。 最終顏色是通過將其與物質的顏色組合來輸出的。 |
鏡面顏色 | 反射光的顏色。 它會影響物質的反射顏色。 |
方向 | 光的方向。 |
還有一些屬性是單個燈共有的。
環境光顏色 | 設置獨立於光源的物質亮度。 |
PreferPerPixelLighting | 您可以指定是否以像素為單位計算照明。 |
光變化的圖像
下圖顯示了燈光的不同值。 在示例中,所有三個燈都已啟用,但在下圖中,僅使用一個燈來顯示它。
初始狀態
這是載入範例模型數據后立即出現的狀態。
漫反射(紅色) | 1 |
漫反射(綠色) | 0.96 |
漫反射(藍色) | 0.80 |
鏡面反射(紅色) | 1 |
鏡面反射(綠色) | 0.96 |
鏡面反射(藍色) | 0.80 |
方向 X | -0.52 |
方向 Y | -0.57 |
Z方向 | -0.62 |
AmbientLightColor(紅色) | 0.05 |
AmbientLightColor(綠色) | 0.09 |
AmbientLightColor(藍色) | 0.18 |
PreferPerPixelLighting | 假 |
漫反射顏色修改
更改光源的 DiffuseColor。 由於紅色和藍色設置為 0,綠色設置為 1,因此僅突出顯示模型的綠色部分。 (紅色和藍色也隱約可見,但這是由於環境光造成的。
漫反射(紅色) | 0 |
漫反射(綠色) | 1 |
漫反射(藍色) | 0 |
鏡面反射(紅色) | 1 |
鏡面反射(綠色) | 0.96 |
鏡面反射(藍色) | 0.80 |
方向 X | -0.52 |
方向 Y | -0.57 |
Z方向 | -0.62 |
AmbientLightColor(紅色) | 0.05 |
AmbientLightColor(綠色) | 0.09 |
AmbientLightColor(藍色) | 0.18 |
PreferPerPixelLighting | 假 |
鏡面反射顏色變化
改變反射光的顏色。 由於只設置了綠色,因此反射部分的顏色只是綠色元素。
漫反射(紅色) | 1 |
漫反射(綠色) | 0.96 |
漫反射(藍色) | 0.80 |
鏡面反射(紅色) | 0 |
鏡面反射(綠色) | 1 |
鏡面反射(藍色) | 0 |
方向 X | -0.52 |
方向 Y | -0.57 |
Z方向 | -0.62 |
AmbientLightColor(紅色) | 0.05 |
AmbientLightColor(綠色) | 0.09 |
AmbientLightColor(藍色) | 0.18 |
PreferPerPixelLighting | 假 |
方向改變
您可以通過更改方向來更改燈光的方向。 通常,僅使用方向,因此向量被歸一化。
漫反射(紅色) | 1 |
漫反射(綠色) | 0.96 |
漫反射(藍色) | 0.80 |
鏡面反射(紅色) | 1 |
鏡面反射(綠色) | 0.96 |
鏡面反射(藍色) | 0.80 |
方向 X | 0.67 |
方向 Y | 0.54 |
Z方向 | -0.34 |
AmbientLightColor(紅色) | 0.05 |
AmbientLightColor(綠色) | 0.09 |
AmbientLightColor(藍色) | 0.18 |
PreferPerPixelLighting | 假 |
環境光顏色變化
紅色和藍色環境光最大化,綠色設置為0。 如果你看一下光線不照射的區域,你可以清楚地看到綠色、紅色和藍色陰影之間的區別。
漫反射(紅色) | 1 |
漫反射(綠色) | 0.96 |
漫反射(藍色) | 0.80 |
鏡面反射(紅色) | 1 |
鏡面反射(綠色) | 0.96 |
鏡面反射(藍色) | 0.80 |
方向 X | -0.52 |
方向 Y | -0.57 |
Z方向 | -0.62 |
AmbientLightColor(紅色) | 1 |
AmbientLightColor(綠色) | 0 |
AmbientLightColor(藍色) | 1 |
PreferPerPixelLighting | 假 |
PreferPerPixelLighting 修改
將 PreferPerPixelLighting 設置為 True 以允許逐圖元照明計算。 在圖中很難看到,但在頂點級照明的情況下,多邊形的邊界在某種程度上是可見的,但在逐圖元照明的情況下,可以表達非常平滑的陰影。
順便說一句,如果不支援圖元著色器 2.0,則無法使用 PreferPerPixelLighting 屬性。 此外,如果您使用多個燈,它可能看起來很奇怪。
漫反射(紅色) | 1 |
漫反射(綠色) | 0.96 |
漫反射(藍色) | 0.80 |
鏡面反射(紅色) | 1 |
鏡面反射(綠色) | 0.96 |
鏡面反射(藍色) | 0.80 |
方向 X | -0.52 |
方向 Y | -0.57 |
Z方向 | -0.62 |
AmbientLightColor(紅色) | 0.05 |
AmbientLightColor(綠色) | 0.09 |
AmbientLightColor(藍色) | 0.18 |
PreferPerPixelLighting | 真 |
每頂點照明每圖元 | 照明 |
---|---|
光源的參數類定義
由於 BasicEffect 可以有多個燈光,因此我們創建了一個用於設置燈光參數的類。 這些參數與可為 BasicEffect 光源 (BasicDirectionalLight) 設置的參數相同。
<summary>
ライトパラメータ
</summary>
public class LightParameter
{
<summary>
ライト有効フラグ
</summary>
public bool Enabled;
<summary>
ディフューズカラー
</summary>
public Vector3 DiffuseColor;
<summary>
スペキュラーカラー
</summary>
public Vector3 SpecularColor;
<summary>
ライトの方向
</summary>
public Vector3 Direction;
}
田
定義設置光源所需的參數。 由於您可以為燈光設置三盞燈,因此陣列中的元素數也是三盞。 其他欄位用於功能表操作、字元顯示等,請參考完整代碼。
<summary>
選択しているライトのインデックス
</summary>
private int selectedLightIndex = 0;
<summary>
ライトのパラメータ
</summary>
private LightParameter[] lightParameters = new LightParameter[]
{
new LightParameter(),
new LightParameter(),
new LightParameter()
};
<summary>
アンビエントカラー
</summary>
private Vector3 ambientLightColor = Vector3.Zero;
<summary>
ピクセル単位のライティング
</summary>
private bool isPreferPerPixelLighting = false;
默認寫入採集
BasicEffect.EnableDefaultLighting 方法將 XNA Framework 指定的燈光參數設置為效果。 我們獲取此值是為了將其保留一次。 (在示例中,它採用多次獲取的形式,但經過簡化,因為如果編寫代碼來單獨獲取它,它會很長。
// ライトとビュー、プロジェクションはあらかじめ設定しておく
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
// デフォルトのライト適用
effect.EnableDefaultLighting();
// ビューマトリックスをあらかじめ設定 ((0, 0, 8) から原点を見る)
effect.View = Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 8.0f),
Vector3.Zero,
Vector3.Up
);
// プロジェクションマトリックスをあらかじめ設定
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
(float)this.GraphicsDevice.Viewport.Width /
(float)this.GraphicsDevice.Viewport.Height,
1.0f,
100.0f
);
// デフォルトのパラメータを受け取る
this.lightParameters[0].Enabled = effect.DirectionalLight0.Enabled;
this.lightParameters[0].DiffuseColor = effect.DirectionalLight0.DiffuseColor;
this.lightParameters[0].SpecularColor = effect.DirectionalLight0.SpecularColor;
this.lightParameters[0].Direction = effect.DirectionalLight0.Direction;
this.lightParameters[1].Enabled = effect.DirectionalLight1.Enabled;
this.lightParameters[1].DiffuseColor = effect.DirectionalLight1.DiffuseColor;
this.lightParameters[1].SpecularColor = effect.DirectionalLight1.SpecularColor;
this.lightParameters[1].Direction = effect.DirectionalLight1.Direction;
this.lightParameters[2].Enabled = effect.DirectionalLight2.Enabled;
this.lightParameters[2].DiffuseColor = effect.DirectionalLight2.DiffuseColor;
this.lightParameters[2].SpecularColor = effect.DirectionalLight2.SpecularColor;
this.lightParameters[2].Direction = effect.DirectionalLight2.Direction;
// アンビエントカラー
this.ambientLightColor = effect.AmbientLightColor;
// ピクセル単位のライティング
this.isPreferPerPixelLighting = effect.PreferPerPixelLighting;
}
}
設置燈光
我正在為模型的 BasicEffect 設置燈光。 該值只需設置為 BasicEffect 的 light 參數即可。 燈光參數更改操作的代碼請單獨參考完整代碼。
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
for (int i = 0; i < this.lightParameters.Length; i++)
{
// ライトを取得
BasicDirectionalLight light = null;
switch (i)
{
case 0:
light = effect.DirectionalLight0;
break;
case 1:
light = effect.DirectionalLight1;
break;
case 2:
light = effect.DirectionalLight2;
break;
}
// ライト有効フラグ
light.Enabled = this.lightParameters[i].Enabled;
// ライトのディフーズカラー
light.DiffuseColor = this.lightParameters[i].DiffuseColor;
// ライトのスペキュラーカラー
light.SpecularColor = this.lightParameters[i].SpecularColor;
// ライトの方向
light.Direction = this.lightParameters[i].Direction;
}
// アンビエントカラー
effect.AmbientLightColor = this.ambientLightColor;
// ピクセル単位のライティング
effect.PreferPerPixelLighting = this.isPreferPerPixelLighting;
}
}
BasicEffect.DirectionalLight0
財產
獲取第一個並聯光源參數。 | 基本方向光 | 獲取 |
BasicEffect.DirectionalLight1
財產
獲取第二個平行光源參數。 | 基本方向光 | 獲取 |
BasicEffect.DirectionalLight2
財產
獲取第三個平行光源參數。 | 基本方向光 | 獲取 |
BasicEffect.AmbientLightColor
財產
獲取和設置環境光的顏色。 X 為紅色,Y 為綠色,Z 為藍色,每個值都在 0.0~1.0 範圍內。 | 向量3 | 獲取、設置 |
BasicEffect.PreferPerPixelLighting
財產
如果設置為 true,則可以按圖元執行照明計算。 但是,若要使此屬性為 true,它必須支援圖元著色器 2.0 或更高版本。 如果設置為 false,則將按頂點執行照明計算。 | 布爾值 | 獲取、設置 |
BasicDirectionalLight.Enabled
財產
設置和禁用燈光。 | 布爾值 | 獲取、設置 |
BasicDirectionalLight.DiffuseColor
財產
獲取和設置光源的漫反射顏色。 X 為紅色,Y 為綠色,Z 為藍色,每個值都在 0.0~1.0 範圍內。 | 向量3 | 獲取、設置 |
BasicDirectionalLight.SpecularColor
財產
獲取和設置光源的反射顏色。 X 為紅色,Y 為綠色,Z 為藍色,每個值都在 0.0~1.0 範圍內。 | 向量3 | 獲取、設置 |
BasicDirectionalLight.Direction
財產
獲取和設置光源的方向。 | 向量3 | 獲取、設置 |
所有代碼
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif
namespace BasicEffectLight
{
<summary>
ゲームメインクラス
</summary>
public class GameMain : Microsoft.Xna.Framework.Game
{
<summary>
ライトパラメータ
</summary>
public class LightParameter
{
<summary>
ライト有効フラグ
</summary>
public bool Enabled;
<summary>
ディフューズカラー
</summary>
public Vector3 DiffuseColor;
<summary>
スペキュラーカラー
</summary>
public Vector3 SpecularColor;
<summary>
ライトの方向
</summary>
public Vector3 Direction;
}
<summary>
グラフィックデバイス管理クラス
</summary>
private GraphicsDeviceManager graphics = null;
<summary>
スプライトのバッチ化クラス
</summary>
private SpriteBatch spriteBatch = null;
<summary>
スプライトでテキストを描画するためのフォント
</summary>
private SpriteFont font = null;
<summary>
直前のキーボード入力の状態
</summary>
private KeyboardState oldKeyboardState = new KeyboardState();
<summary>
直前のマウスの状態
</summary>
private MouseState oldMouseState = new MouseState();
<summary>
直前のゲームパッド入力の状態
</summary>
private GamePadState oldGamePadState = new GamePadState();
<summary>
モデル
</summary>
private Model model = null;
<summary>
選択しているメニューのインデックス
</summary>
private int selectedMenuIndex = 0;
<summary>
選択しているライトのインデックス
</summary>
private int selectedLightIndex = 0;
<summary>
ライトのパラメータ
</summary>
private LightParameter[] lightParameters = new LightParameter[]
{
new LightParameter(),
new LightParameter(),
new LightParameter()
};
<summary>
アンビエントカラー
</summary>
private Vector3 ambientLightColor = Vector3.Zero;
<summary>
ピクセル単位のライティング
</summary>
private bool isPreferPerPixelLighting = false;
<summary>
パラメータの最大数
</summary>
private static int MaxParameterCount = 15;
<summary>
メニューリスト
</summary>
private static string[] MenuNameList = new string[]
{
"LightIndex",
"Light Enable",
"DiffuseColor (Red)",
"DiffuseColor (Green)",
"DiffuseColor (Blue)",
"SpecularColor (Red)",
"SpecularColor (Green)",
"SpecularColor (Blue)",
"Direction X",
"Direction Y",
"Direction Z",
"AmbientLightColor (Red)",
"AmbientLightColor (Green)",
"AmbientLightColor (Blue)",
"PreferPerPixelLighting",
};
<summary>
パラメータテキストリスト
</summary>
private string[] parameters = new string[MaxParameterCount];
<summary>
GameMain コンストラクタ
</summary>
public GameMain()
{
// グラフィックデバイス管理クラスの作成
this.graphics = new GraphicsDeviceManager(this);
// ゲームコンテンツのルートディレクトリを設定
this.Content.RootDirectory = "Content";
#if WINDOWS_PHONE
// Windows Phone のデフォルトのフレームレートは 30 FPS
this.TargetElapsedTime = TimeSpan.FromTicks(333333);
// バックバッファサイズの設定
this.graphics.PreferredBackBufferWidth = 480;
this.graphics.PreferredBackBufferHeight = 800;
// フルスクリーン表示
this.graphics.IsFullScreen = true;
#endif
// ウインドウ上でマウスのポインタを表示するようにする
this.IsMouseVisible = true;
}
<summary>
ゲームが始まる前の初期化処理を行うメソッド
グラフィック以外のデータの読み込み、コンポーネントの初期化を行う
</summary>
protected override void Initialize()
{
// TODO: ここに初期化ロジックを書いてください
// コンポーネントの初期化などを行います
base.Initialize();
}
<summary>
ゲームが始まるときに一回だけ呼ばれ
すべてのゲームコンテンツを読み込みます
</summary>
protected override void LoadContent()
{
// テクスチャーを描画するためのスプライトバッチクラスを作成します
this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
// フォントをコンテンツパイプラインから読み込む
this.font = this.Content.Load<SpriteFont>("Font");
// モデルを作成
this.model = this.Content.Load<Model>("Model");
// ライトとビュー、プロジェクションはあらかじめ設定しておく
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
// デフォルトのライト適用
effect.EnableDefaultLighting();
// ビューマトリックスをあらかじめ設定 ((0, 0, 8) から原点を見る)
effect.View = Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 8.0f),
Vector3.Zero,
Vector3.Up
);
// プロジェクションマトリックスをあらかじめ設定
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
(float)this.GraphicsDevice.Viewport.Width /
(float)this.GraphicsDevice.Viewport.Height,
1.0f,
100.0f
);
// デフォルトのパラメータを受け取る
this.lightParameters[0].Enabled = effect.DirectionalLight0.Enabled;
this.lightParameters[0].DiffuseColor = effect.DirectionalLight0.DiffuseColor;
this.lightParameters[0].SpecularColor = effect.DirectionalLight0.SpecularColor;
this.lightParameters[0].Direction = effect.DirectionalLight0.Direction;
this.lightParameters[1].Enabled = effect.DirectionalLight1.Enabled;
this.lightParameters[1].DiffuseColor = effect.DirectionalLight1.DiffuseColor;
this.lightParameters[1].SpecularColor = effect.DirectionalLight1.SpecularColor;
this.lightParameters[1].Direction = effect.DirectionalLight1.Direction;
this.lightParameters[2].Enabled = effect.DirectionalLight2.Enabled;
this.lightParameters[2].DiffuseColor = effect.DirectionalLight2.DiffuseColor;
this.lightParameters[2].SpecularColor = effect.DirectionalLight2.SpecularColor;
this.lightParameters[2].Direction = effect.DirectionalLight2.Direction;
// アンビエントカラー
this.ambientLightColor = effect.AmbientLightColor;
// ピクセル単位のライティング
this.isPreferPerPixelLighting = effect.PreferPerPixelLighting;
}
}
}
<summary>
ゲームが終了するときに一回だけ呼ばれ
すべてのゲームコンテンツをアンロードします
</summary>
protected override void UnloadContent()
{
// TODO: ContentManager で管理されていないコンテンツを
// ここでアンロードしてください
}
<summary>
描画以外のデータ更新等の処理を行うメソッド
主に入力処理、衝突判定などの物理計算、オーディオの再生など
</summary>
<param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
protected override void Update(GameTime gameTime)
{
// 入力デバイスの状態取得
KeyboardState keyboardState = Keyboard.GetState();
MouseState mouseState = Mouse.GetState();
GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
// Xbox 360 コントローラ、Windows Phone の BACK ボタンを押したときに
// ゲームを終了させます
if (gamePadState.Buttons.Back == ButtonState.Pressed)
{
this.Exit();
}
// メニューの選択
if ((keyboardState.IsKeyDown(Keys.Up) && this.oldKeyboardState.IsKeyUp(Keys.Up)) ||
(gamePadState.ThumbSticks.Left.Y >= 0.5f &&
this.oldGamePadState.ThumbSticks.Left.Y < 0.5f))
{
// 選択メニューをひとつ上に移動
this.selectedMenuIndex =
(this.selectedMenuIndex + this.parameters.Length - 1) % this.parameters.Length;
}
if ((keyboardState.IsKeyDown(Keys.Down) && this.oldKeyboardState.IsKeyUp(Keys.Down)) ||
(gamePadState.ThumbSticks.Left.Y <= -0.5f &&
this.oldGamePadState.ThumbSticks.Left.Y > -0.5f) ||
(this.oldMouseState.LeftButton == ButtonState.Pressed &&
mouseState.LeftButton == ButtonState.Released))
{
// 選択メニューをひとつ下に移動
this.selectedMenuIndex =
(this.selectedMenuIndex + this.parameters.Length + 1) % this.parameters.Length;
}
// 各マテリアルの値を操作
float moveValue = 0.0f;
if (keyboardState.IsKeyDown(Keys.Left))
{
moveValue -= (float)gameTime.ElapsedGameTime.TotalSeconds;
}
if (keyboardState.IsKeyDown(Keys.Right))
{
moveValue += (float)gameTime.ElapsedGameTime.TotalSeconds;
}
if (mouseState.LeftButton == ButtonState.Pressed)
{
moveValue += (mouseState.X - this.oldMouseState.X) * 0.005f;
}
if (gamePadState.IsConnected)
{
moveValue += gamePadState.ThumbSticks.Left.X *
(float)gameTime.ElapsedGameTime.TotalSeconds;
}
if (moveValue != 0.0f)
{
LightParameter selectedLight = this.lightParameters[this.selectedLightIndex];
switch (this.selectedMenuIndex)
{
case 0:
// ライトのインデックス
if ((keyboardState.IsKeyDown(Keys.Left) &&
this.oldKeyboardState.IsKeyUp(Keys.Left)) ||
(mouseState.LeftButton == ButtonState.Pressed &&
(mouseState.X - this.oldMouseState.X) >= 5) ||
(gamePadState.ThumbSticks.Left.X >= 0.5f &&
this.oldGamePadState.ThumbSticks.Left.X < 0.5f))
{
// ライトのインデックスをひとつ減らす
this.selectedLightIndex =
(this.selectedLightIndex + this.lightParameters.Length - 1) %
this.lightParameters.Length;
}
if ((keyboardState.IsKeyDown(Keys.Right) &&
this.oldKeyboardState.IsKeyUp(Keys.Right)) ||
(mouseState.LeftButton == ButtonState.Pressed &&
(mouseState.X - this.oldMouseState.X) <= -5) ||
(gamePadState.ThumbSticks.Left.X <= -0.5f &&
this.oldGamePadState.ThumbSticks.Left.X > -0.5f))
{
// ライトのインデックスをひとつ増やす
this.selectedLightIndex =
(this.selectedLightIndex + this.lightParameters.Length + 1) %
this.lightParameters.Length;
}
if (mouseState.LeftButton == ButtonState.Pressed)
{
this.selectedLightIndex = (int)(
MathHelper.Clamp((float)mouseState.X / this.GraphicsDevice.Viewport.Width * 3, 0, 2));
}
break;
case 1:
// ライト有効フラグ
selectedLight.Enabled = (moveValue > 0.0f);
break;
case 2:
// ライトのディフーズカラー(赤)
Vector3 diffuseX = selectedLight.DiffuseColor;
diffuseX.X = MathHelper.Clamp(diffuseX.X + moveValue, 0.0f, 1.0f);
selectedLight.DiffuseColor = diffuseX;
break;
case 3:
// ライトのディフーズカラー(緑)
Vector3 diffuseY = selectedLight.DiffuseColor;
diffuseY.Y = MathHelper.Clamp(diffuseY.Y + moveValue, 0.0f, 1.0f);
selectedLight.DiffuseColor = diffuseY;
break;
case 4:
// ライトのディフーズカラー(青)
Vector3 diffuseZ = selectedLight.DiffuseColor;
diffuseZ.Z = MathHelper.Clamp(diffuseZ.Z + moveValue, 0.0f, 1.0f);
selectedLight.DiffuseColor = diffuseZ;
break;
case 5:
// ライトのスペキュラーカラー(赤)
Vector3 specularX = selectedLight.SpecularColor;
specularX.X = MathHelper.Clamp(specularX.X + moveValue, 0.0f, 1.0f);
selectedLight.SpecularColor = specularX;
break;
case 6:
// ライトのスペキュラーカラー(緑)
Vector3 specularY = selectedLight.SpecularColor;
specularY.Y = MathHelper.Clamp(specularY.Y + moveValue, 0.0f, 1.0f);
selectedLight.SpecularColor = specularY;
break;
case 7:
// ライトのスペキュラーカラー(青)
Vector3 specularZ = selectedLight.SpecularColor;
specularZ.Z = MathHelper.Clamp(specularZ.Z + moveValue, 0.0f, 1.0f);
selectedLight.SpecularColor = specularZ;
break;
case 8:
// ライトの方向X
Vector3 directionX = selectedLight.Direction;
directionX.X += moveValue;
selectedLight.Direction = directionX;
break;
case 9:
// ライトの方向Y
Vector3 directionY = selectedLight.Direction;
directionY.Y += moveValue;
selectedLight.Direction = directionY;
break;
case 10:
// ライトの方向Z
Vector3 directionZ = selectedLight.Direction;
directionZ.Z += moveValue;
selectedLight.Direction = directionZ;
break;
case 11:
// アンビエントカラー(赤)
this.ambientLightColor.X =
MathHelper.Clamp(this.ambientLightColor.X + moveValue, 0.0f, 1.0f);
break;
case 12:
// アンビエントカラー(緑)
this.ambientLightColor.Y =
MathHelper.Clamp(this.ambientLightColor.Y + moveValue, 0.0f, 1.0f);
break;
case 13:
// アンビエントカラー(青)
this.ambientLightColor.Z =
MathHelper.Clamp(this.ambientLightColor.Z + moveValue, 0.0f, 1.0f);
break;
case 14:
// ピクセル単位のライティング
this.isPreferPerPixelLighting = (moveValue > 0.0f);
break;
}
}
// ライトを設定
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
for (int i = 0; i < this.lightParameters.Length; i++)
{
// ライトを取得
DirectionalLight light = null;
switch (i)
{
case 0:
light = effect.DirectionalLight0;
break;
case 1:
light = effect.DirectionalLight1;
break;
case 2:
light = effect.DirectionalLight2;
break;
}
// ライト有効フラグ
light.Enabled = this.lightParameters[i].Enabled;
// ライトのディフーズカラー
light.DiffuseColor = this.lightParameters[i].DiffuseColor;
// ライトのスペキュラーカラー
light.SpecularColor = this.lightParameters[i].SpecularColor;
// ライトの方向
light.Direction = this.lightParameters[i].Direction;
}
// アンビエントカラー
effect.AmbientLightColor = this.ambientLightColor;
// ピクセル単位のライティング
effect.PreferPerPixelLighting = this.isPreferPerPixelLighting;
}
}
// 入力情報を記憶
this.oldKeyboardState = keyboardState;
this.oldMouseState = mouseState;
this.oldGamePadState = gamePadState;
// 登録された GameComponent を更新する
base.Update(gameTime);
}
<summary>
描画処理を行うメソッド
</summary>
<param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
protected override void Draw(GameTime gameTime)
{
// 画面を指定した色でクリアします
this.GraphicsDevice.Clear(Color.CornflowerBlue);
// 深度バッファを有効にする
this.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
// モデルを描画
foreach (ModelMesh mesh in this.model.Meshes)
{
#if WINDOWS_PHONE
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = Matrix.CreateRotationZ(-MathHelper.PiOver2);
}
#endif
mesh.Draw();
}
// スプライトの描画準備
this.spriteBatch.Begin();
// 操作
this.spriteBatch.DrawString(this.font,
"Up, Down : Select Menu",
new Vector2(20.0f, 20.0f), Color.White);
this.spriteBatch.DrawString(this.font,
"Left, right : Change Value",
new Vector2(20.0f, 45.0f), Color.White);
this.spriteBatch.DrawString(this.font,
"MouseClick & Drag :",
new Vector2(20.0f, 70.0f), Color.White);
this.spriteBatch.DrawString(this.font,
" Select Menu & Change Value",
new Vector2(20.0f, 95.0f), Color.White);
// 各メニュー //
for (int i = 0; i < MenuNameList.Length; i++)
{
this.spriteBatch.DrawString(this.font,
MenuNameList[i],
new Vector2(40.0f, 120.0f + i * 20.0f), Color.White);
}
// 各パラメータ //
LightParameter selectedLight = this.lightParameters[this.selectedLightIndex];
// ライトのインデックス
this.parameters[0] = this.selectedLightIndex.ToString();
// ライトの有効フラグ
this.parameters[1] = selectedLight.Enabled.ToString();
// ライトのディフーズカラー(赤)
this.parameters[2] = selectedLight.DiffuseColor.X.ToString();
// ライトのディフーズカラー(緑)
this.parameters[3] = selectedLight.DiffuseColor.Y.ToString();
// ライトのディフーズカラー(青)
this.parameters[4] = selectedLight.DiffuseColor.Z.ToString();
// ライトのスペキュラーカラー(赤)
this.parameters[5] = selectedLight.SpecularColor.X.ToString();
// ライトのスペキュラーカラー(緑)
this.parameters[6] = selectedLight.SpecularColor.Y.ToString();
// ライトのスペキュラーカラー(青)
this.parameters[7] = selectedLight.SpecularColor.Z.ToString();
// ライトの方向X
this.parameters[8] = selectedLight.Direction.X.ToString();
// ライトの方向Y
this.parameters[9] = selectedLight.Direction.Y.ToString();
// ライトの方向Z
this.parameters[10] = selectedLight.Direction.Z.ToString();
// アンビエントカラー(赤)
this.parameters[11] = this.ambientLightColor.X.ToString();
// アンビエントカラー(緑)
this.parameters[12] = this.ambientLightColor.Y.ToString();
// アンビエントカラー(青)
this.parameters[13] = this.ambientLightColor.Z.ToString();
// ピクセル単位のライティング
this.parameters[14] = this.isPreferPerPixelLighting.ToString();
for (int i = 0; i < this.parameters.Length; i++)
{
this.spriteBatch.DrawString(this.font,
this.parameters[i],
new Vector2(300.0f, 120.0f + i * 20.0f), Color.White);
}
// 選択インデックス
this.spriteBatch.DrawString(this.font, "*",
new Vector2(20.0f, 124.0f + this.selectedMenuIndex * 20.0f), Color.White);
// スプライトの一括描画
this.spriteBatch.End();
// 登録された DrawableGameComponent を描画する
base.Draw(gameTime);
}
}
}