Materiali BasicEffect

Pagina aggiornata :
Data di creazione della pagina :

sommario

Manipolare i parametri relativi alla parte materiale di BasicEffect per visualizzare l'aspetto del modello.

Ambiente operativo

Prerequisiti

Versioni XNA supportate
  • 4.0
Piattaforme supportate
  • Windows (XP SP2 o versioni successive, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Versione Vertex Shader richiesta da Windows 2.0
Versione di Pixel Shader richiesta da Windows 2.0

Ambiente operativo

piattaforma
  • finestre 7
  • Xbox 360
  • Windows Phone 7

Come lavorare con l'esempio

Funziona tastieraController Xbox 360tocco del mouse
Selezionare i parametri che si desidera modificare ↑、↓ Levetta sinistra ↑, ↓ Pulsante sinistro -
Modifica dei parametri ←、→ Levetta sinistra ←, → ←→ Trascina -

sostanza

Che cos'è BasicEffect?

In XNA, se si desidera visualizzare poligoni 3D, è necessario scrivere un programma shader per disegnarli e decidere come disegnarli. A tale scopo, creare un file di effetti separato, scrivere un programma, leggerlo come classe di effetti (Effect) ed eseguire il programma shader.

Tuttavia, ci sono molti casi in cui non è necessario un effetto di disegno speciale e, anche in questi casi, è necessario un effetto, quindi è sorprendentemente ingombrante preoccuparsi di implementare un programma shader.

Pertanto, i parametri di base come i materiali e le luci vengono preparati in anticipo come proprietà in modo che gli effetti possano essere facilmente gestiti "BasicEffect". È molto semplice perché non è necessario creare un file di effetti, è possibile gestirlo semplicemente creando un'istanza della classe.

Anche se si caricano i dati del modello dal contenuto, BasicEffect è impostato per impostazione predefinita, quindi non è nemmeno necessario creare un'istanza.

materiale

Il materiale si riferisce principalmente alle caratteristiche del materiale di una sostanza e viene utilizzato per specificare il colore, il grado di riflessione e la resistenza della sostanza. Dal momento che è diventato possibile esprimerlo in modo indipendente nei programmi shader, la definizione di un materiale può avere un significato approssimativo senza essere fissa, ma BasicEffect ha i seguenti parametri:

Alfa Opacità. Un valore pari a 1,0 indica l'opacità, mentre il valore 0,0 rappresenta la trasparenza completa.
DiffuseColor Il colore della sostanza dell'oggetto da visualizzare. Rappresenta i colori in RGB. L'ombreggiatura del materiale viene riflessa a seconda dello stato della luce.
EmissiveColor Il colore emesso dell'oggetto da visualizzare. Rappresenta i colori in RGB. Poiché è un colore che emette luce propria, il colore viene aggiunto senza essere influenzato dalla luce.
Colore speculare Il colore del riflesso dell'oggetto da visualizzare. Rappresenta i colori in RGB. A seconda della direzione e del punto di vista della luce, il materiale sembrerà essere riflesso.
Potenza speculare L'intensità del riflesso dell'oggetto da visualizzare. Più alto è il valore, minore è l'area riflessa.

Immagine del cambiamento materiale

L'immagine sottostante mostra i diversi valori del materiale.

Stato iniziale

Questo è lo stato immediatamente dopo il caricamento dei dati del modello di esempio.

初期状態

Alfa 1
Diffusione (rosso) 0.8
Diffusa (verde) 0.8
Diffusa (blu) 0
Emissivo (rosso) 0
Emissivo (verde) 0
Emissivo (blu) 0
Speculare (rosso) 0
Speculare (verde) 0
Speculare (blu) 0
Potenza speculare 5

Modifica dell'opacità (alfa)

Questo è il momento in cui si modifica l'opacità. Il colore blu dello sfondo è debolmente visibile.

不透明度(Alpha)変更

Alfa 0.31
Diffusione (rosso) 0.8
Diffusa (verde) 0.8
Diffusa (blu) 0
Emissivo (rosso) 0
Emissivo (verde) 0
Emissivo (blu) 0
Speculare (rosso) 0
Speculare (verde) 0
Speculare (blu) 0
Potenza speculare 5

Modifiche diffuse

Il colore della sostanza viene modificato per renderla bluastra.

Diffuse 変更

Alfa 1
Diffusione (rosso) 0.05
Diffusa (verde) 0.71
Diffusa (blu) 1
Emissivo (rosso) 0
Emissivo (verde) 0
Emissivo (blu) 0
Speculare (rosso) 0
Speculare (verde) 0
Speculare (blu) 0
Potenza speculare 5

Modifiche emissive

Gli elementi rosso e blu di Emissive sono massimizzati. Indipendentemente dallo stato della luce, almeno lo stato viola viene mantenuto.

Emissive 変更

Alfa 1
Diffusione (rosso) 0.8
Diffusa (verde) 0.8
Diffusa (blu) 0
Emissivo (rosso) 1
Emissivo (verde) 0
Emissivo (blu) 1
Speculare (rosso) 0
Speculare (verde) 0
Speculare (blu) 0
Potenza speculare 5

Modifiche speculari

Impostando Speculare, il materiale apparirà riflettente.

Specular 変更

Alfa 1
Diffusione (rosso) 0.8
Diffusa (verde) 0.8
Diffusa (blu) 0
Emissivo (rosso) 0
Emissivo (verde) 0
Emissivo (blu) 0
Speculare (rosso) 1
Speculare (verde) 1
Speculare (blu) 1
Potenza speculare 5

Modifica di SpecularPower

La modifica della potenza speculare modifica l'intervallo della superficie riflettente.

SpecularPower 変更

Alfa 1
Diffusione (rosso) 0.8
Diffusa (verde) 0.8
Diffusa (blu) 0
Emissivo (rosso) 0
Emissivo (verde) 0
Emissivo (blu) 0
Speculare (rosso) 1
Speculare (verde) 1
Speculare (blu) 1
Potenza speculare 20

campo

Il campo contiene informazioni sul materiale da impostare su BasicEffect. Inoltre, ha parametri per la selezione dei menu, ma poiché è solo un parametro per il funzionamento, ometterò i dettagli.

/// <summary>
/// 不透明度
/// </summary>
private float alpha = 1.0f;

/// <summary>
/// ディフーズ
/// </summary>
private Vector3 diffuse = Vector3.One;

/// <summary>
/// エミッシブ
/// </summary>
private Vector3 emissive = Vector3.Zero;

/// <summary>
/// スペキュラー
/// </summary>
private Vector3 specular = Vector3.Zero;

/// <summary>
/// スペキュラーの強さ
/// </summary>
private float specularPower = 5.0f;

Recupero del materiale del modello

Viene recuperato il valore del materiale impostato nel modello come valore iniziale. In questo esempio, il codice viene scritto presupponendo che nel modello sia presente un solo set di effetti.

// ライトとビュー、プロジェクションはあらかじめ設定しておく
foreach (ModelMesh mesh in this.model.Meshes)
{
    foreach (BasicEffect effect in mesh.Effects)
    {
        // デフォルトのライト適用
        effect.EnableDefaultLighting();

        // ビューマトリックスをあらかじめ設定 ((0, 0, 6) から原点を見る)
        effect.View = Matrix.CreateLookAt(
            new Vector3(0.0f, 0.0f, 6.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.alpha = effect.Alpha;

        // ディフーズ
        this.diffuse = effect.DiffuseColor;

        // エミッシブ
        this.emissive = effect.EmissiveColor;

        // スペキュラー
        this.specular = effect.SpecularColor;

        // スペキュラーの強さ
        this.specularPower = effect.SpecularPower;
    }
}

Impostazione del materiale

Nell'esempio viene impostato un valore per l'oggetto BasicEffect del modello. Per "DiffuseColor", "EmissiveColor" e "SpecularColor", impostati in un oggetto Vector3, non in una struttura Color. Specificare gli elementi rosso per X, verde per Y e blu per Z con valori di 0,0~1,0.

// マテリアルを設定
foreach (ModelMesh mesh in this.model.Meshes)
{
    foreach (BasicEffect effect in mesh.Effects)
    {
        // 不透明度
        effect.Alpha = this.alpha;

        // ディフーズ
        effect.DiffuseColor = this.diffuse;

        // エミッシブ
        effect.EmissiveColor = this.emissive;

        // スペキュラー
        effect.SpecularColor = this.specular;

        // スペキュラーの強さ
        effect.SpecularPower = this.specularPower;
    }
}

Nell'esempio è presente codice come il codice dell'operazione del materiale e la visualizzazione di stringhe di valori, ma ci sono parti che non sono direttamente correlate a BasicMaterial, quindi ometterò la spiegazione. È possibile scaricare l'esempio o controllare il codice completo.

BasicEffect.Alpha proprietà

Ottiene e imposta l'opacità. Specificare un valore compreso tra 0,0~1,0. galleggiare Ottieni, imposta

BasicEffect.DiffuseColor proprietà

Ottiene e imposta il colore diffuso. X è rosso, Y è verde, Z è blu e ogni valore è compreso nell'intervallo 0.0~1.0. Vettore3 Ottieni, imposta

BasicEffect.EmissiveColor proprietà

Ottiene e imposta il colore emesso. X è rosso, Y è verde, Z è blu e ogni valore è compreso nell'intervallo 0.0~1.0. Vettore3 Ottieni, imposta

BasicEffect.SpecularColor proprietà

Ottiene e imposta il colore riflesso. X è rosso, Y è verde, Z è blu e ogni valore è compreso nell'intervallo 0.0~1.0. Vettore3 Ottieni, imposta

BasicEffect.SpecularPower proprietà

Ottiene e imposta l'intensità del riflesso. Il valore è specificato come 0.0~. galleggiare Ottieni, imposta

Tutti i codici

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 BasicEffectMaterial
{
    /// <summary>
    /// ゲームメインクラス
    /// </summary>
    public class GameMain : Microsoft.Xna.Framework.Game
    {
        /// <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 float alpha = 1.0f;

        /// <summary>
        /// ディフーズ
        /// </summary>
        private Vector3 diffuse = Vector3.One;

        /// <summary>
        /// エミッシブ
        /// </summary>
        private Vector3 emissive = Vector3.Zero;

        /// <summary>
        /// スペキュラー
        /// </summary>
        private Vector3 specular = Vector3.Zero;

        /// <summary>
        /// スペキュラーの強さ
        /// </summary>
        private float specularPower = 5.0f;

        /// <summary>
        /// 選択しているメニューのインデックス
        /// </summary>
        private int selectedMenuIndex = 0;

        /// <summary>
        /// パラメータの最大数
        /// </summary>
        private static int MaxParameterCount = 11;

        /// <summary>
        /// メニューリスト
        /// </summary>
        private static string[] MenuNameList = new string[]
            {
                "Alpha",
                "Diffuse (Red)",
                "Diffuse (Green)",
                "Diffuse (Blue)",
                "Emissive (Red)",
                "Emissive (Green)",
                "Emissive (Blue)",
                "Specular (Red)",
                "Specular (Green)",
                "Specular (Blue)",
                "SpecularPower"
            };

        /// <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()
        {
            // コンポーネントの初期化などを行います
            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, 6) から原点を見る)
                    effect.View = Matrix.CreateLookAt(
                        new Vector3(0.0f, 0.0f, 6.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.alpha = effect.Alpha;

                    // ディフーズ
                    this.diffuse = effect.DiffuseColor;

                    // エミッシブ
                    this.emissive = effect.EmissiveColor;

                    // スペキュラー
                    this.specular = effect.SpecularColor;

                    // スペキュラーの強さ
                    this.specularPower = effect.SpecularPower;
                }
            }
        }

        /// <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;
            }

            switch (this.selectedMenuIndex)
            {
                case 0: // 不透明度
                    this.alpha = MathHelper.Clamp(this.alpha + moveValue,
                                                  0.0f,
                                                  1.0f);
                    break;
                case 1: // ディフューズ (赤)
                    this.diffuse.X = MathHelper.Clamp(this.diffuse.X + moveValue,
                                                      0.0f,
                                                      1.0f);
                    break;
                case 2: // ディフューズ (緑)
                    this.diffuse.Y = MathHelper.Clamp(this.diffuse.Y + moveValue,
                                                      0.0f,
                                                      1.0f);
                    break;
                case 3: // ディフューズ (青)
                    this.diffuse.Z = MathHelper.Clamp(this.diffuse.Z + moveValue,
                                                      0.0f,
                                                      1.0f);
                    break;
                case 4: // エミッシブ (赤)
                    this.emissive.X = MathHelper.Clamp(this.emissive.X + moveValue,
                                                       0.0f,
                                                       1.0f);
                    break;
                case 5: // エミッシブ (緑)
                    this.emissive.Y = MathHelper.Clamp(this.emissive.Y + moveValue,
                                                       0.0f,
                                                       1.0f);
                    break;
                case 6: // エミッシブ (青)
                    this.emissive.Z = MathHelper.Clamp(this.emissive.Z + moveValue,
                                                       0.0f,
                                                       1.0f);
                    break;
                case 7: // スペキュラー (赤)
                    this.specular.X = MathHelper.Clamp(this.specular.X + moveValue,
                                                       0.0f,
                                                       1.0f);
                    break;
                case 8: // スペキュラー (緑)
                    this.specular.Y = MathHelper.Clamp(this.specular.Y + moveValue,
                                                       0.0f,
                                                       1.0f);
                    break;
                case 9: // スペキュラー (青)
                    this.specular.Z = MathHelper.Clamp(this.specular.Z + moveValue,
                                                       0.0f,
                                                       1.0f);
                    break;
                case 10: // スペキュラーの強さ
                    moveValue *= 5.0f;
                    this.specularPower = MathHelper.Clamp(this.specularPower + moveValue,
                                                          0.0f,
                                                          100.0f);
                    break;
            }

            // マテリアルを設定
            foreach (ModelMesh mesh in this.model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    // 不透明度
                    effect.Alpha = this.alpha;

                    // ディフーズ
                    effect.DiffuseColor = this.diffuse;

                    // エミッシブ
                    effect.EmissiveColor = this.emissive;

                    // スペキュラー
                    effect.SpecularColor = this.specular;

                    // スペキュラーの強さ
                    effect.SpecularPower = this.specularPower;
                }
            }

            // 入力情報を記憶
            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)
            {
                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 * 24.0f), Color.White);
            }

            // 各パラメータ //

            // 不透明度
            this.parameters[0] = this.alpha.ToString();

            // ディフューズ (赤)
            this.parameters[1] = this.diffuse.X.ToString();

            // ディフューズ (緑)
            this.parameters[2] = this.diffuse.Y.ToString();

            // ディフューズ (青)
            this.parameters[3] = this.diffuse.Z.ToString();

            // エミッシブ (赤)
            this.parameters[4] = this.emissive.X.ToString();

            // エミッシブ (緑)
            this.parameters[5] = this.emissive.Y.ToString();

            // エミッシブ (青)
            this.parameters[6] = this.emissive.Z.ToString();

            // スペキュラー (赤)
            this.parameters[7] = this.specular.X.ToString();

            // スペキュラー (緑)
            this.parameters[8] = this.specular.Y.ToString();

            // スペキュラー (青)
            this.parameters[9] = this.specular.Z.ToString();

            // スペキュラーの強さ
            this.parameters[10] = this.specularPower.ToString();

            for (int i = 0; i < this.parameters.Length; i++)
            {
                this.spriteBatch.DrawString(this.font,
                    this.parameters[i],
                    new Vector2(250.0f, 120.0f + i * 24.0f), Color.White);
            }

            // 選択インデックス
            this.spriteBatch.DrawString(this.font, "*",
                new Vector2(20.0f, 124.0f + this.selectedMenuIndex * 24.0f), Color.White);

            // スプライトの一括描画
            this.spriteBatch.End();

            // 登録された DrawableGameComponent を描画する
            base.Draw(gameTime);
        }
    }
}