Materiály BasicEffect

Stránky aktualizovány :
Datum vytvoření stránky :

shrnutí

Manipulujte s parametry souvisejícími s materiálovou částí BasicEffect, abyste viděli, jak model vypadá.

Provozní prostředí

Požadavky

Podporované verze XNA
  • 4.0
Podporované platformy
  • Windows (XP SP2 nebo novější, Vista, 7)
  • Konzole Xbox 360
  • Windows Phone 7
Požadovaná verze Vertex Shader systému Windows 2.0
Požadovaná verze Pixel Shader systému Windows 2.0

Provozní prostředí

nástupiště
  • Systém Windows 7
  • Konzole Xbox 360
  • Windows Phone 7

Jak pracovat s ukázkou

Funguje klávesniceOvladač Xbox 360dotykdotyková myš
Vyberte parametry, které chcete změnit ↑、↓ Levá páčka ↑, ↓ Levé tlačítko -
Změna parametrů ←、→ Levá páčka ←, → ←→ Tažení -

hmota

Co je BasicEffect?

Pokud chcete v XNA zobrazit 3D polygony, musíte napsat shader program, který je nakreslí a rozhodne, jak je nakreslit. Chcete-li to provést, vytvořte samostatný soubor efektů, napište program, přečtěte jej jako třídu efektů (Effect) a spusťte program shaderu.

Existuje však mnoho případů, kdy nepotřebujete speciální vykreslovací efekt, a i v takových případech je efekt nezbytný, takže je překvapivě těžkopádné obtěžovat se implementací shaderového programu.

Proto jsou základní parametry, jako jsou materiály a světla, předem připraveny jako vlastnosti, aby bylo možné efekty snadno zpracovat "BasicEffect". Je to velmi snadné, protože nemusíte vytvářet soubor efektů, můžete to zvládnout jednoduchým vytvořením instance třídy.

I když načtete data modelu z obsahu, BasicEffect je ve výchozím nastavení nastaveno, takže ani nemusíte vytvářet instanci.

materiál

Materiál se týká především vlastností materiálu látky a používá se k určení barvy, stupně odrazu a pevnosti látky. Vzhledem k tomu, že je možné jej vyjádřit nezávisle v shader programech, definice materiálu může mít hrubý význam, aniž by byla pevná, ale BasicEffect má následující parametry:

Alfa Neprůhlednost. Hodnota 1,0 označuje neprůhlednost a hodnota 0,0 představuje úplnou průhlednost.
DiffuseColor (Barva difuze) Barva látky objektu, který má být zobrazen. Reprezentuje barvy v RGB. Stínování materiálu se odráží v závislosti na stavu světla.
EmissiveColor (Barva emise) Vyzařovaná barva objektu, který se má zobrazit. Reprezentuje barvy v RGB. Vzhledem k tomu, že se jedná o barvu, která vyzařuje své vlastní světlo, barva se přidává, aniž by byla ovlivněna světlem.
Barva zrcadla Barva odrazu objektu, který má být zobrazen. Reprezentuje barvy v RGB. V závislosti na směru a úhlu pohledu světla se bude zdát, že se materiál odráží.
Síla odlesku Intenzita odrazu objektu, který má být zobrazen. Čím vyšší hodnota, tím menší zrcadlená plocha.

Obraz materiální změny

Obrázek níže ukazuje různé hodnoty materiálu.

Počáteční stav

Jedná se o stav ihned po načtení ukázkových dat modelu.

初期状態

Alfa 1
Difúzní (červená) 0.8
Difúzní (zelená) 0.8
Difúzní (modrá) 0
Emisní (červená) 0
Emisní (zelená) 0
Emisní (modrá) 0
Zrcadlo (červená) 0
Odlesk (zelená) 0
Odlesk (modrá) 0
Síla odlesku 5

Změna krytí (alfa)

To je, když změníte krytí. Modrá barva pozadí je slabě viditelná.

不透明度(Alpha)変更

Alfa 0.31
Difúzní (červená) 0.8
Difúzní (zelená) 0.8
Difúzní (modrá) 0
Emisní (červená) 0
Emisní (zelená) 0
Emisní (modrá) 0
Zrcadlo (červená) 0
Odlesk (zelená) 0
Odlesk (modrá) 0
Síla odlesku 5

Difúzní modifikace

Barva látky se změní tak, aby byla namodralá.

Diffuse 変更

Alfa 1
Difúzní (červená) 0.05
Difúzní (zelená) 0.71
Difúzní (modrá) 1
Emisní (červená) 0
Emisní (zelená) 0
Emisní (modrá) 0
Zrcadlo (červená) 0
Odlesk (zelená) 0
Odlesk (modrá) 0
Síla odlesku 5

Emisní modifikace

Červené a modré prvky emisivy jsou maximalizovány. Bez ohledu na stav světla je zachován alespoň fialový stav.

Emissive 変更

Alfa 1
Difúzní (červená) 0.8
Difúzní (zelená) 0.8
Difúzní (modrá) 0
Emisní (červená) 1
Emisní (zelená) 0
Emisní (modrá) 1
Zrcadlo (červená) 0
Odlesk (zelená) 0
Odlesk (modrá) 0
Síla odlesku 5

Změny odlesků

Nastavením možnosti Odlesk bude materiál vypadat jako odrazivý.

Specular 変更

Alfa 1
Difúzní (červená) 0.8
Difúzní (zelená) 0.8
Difúzní (modrá) 0
Emisní (červená) 0
Emisní (zelená) 0
Emisní (modrá) 0
Zrcadlo (červená) 1
Odlesk (zelená) 1
Odlesk (modrá) 1
Síla odlesku 5

Modifikace SpecularPower

Změna SpecularPower změní rozsah odrazivého povrchu.

SpecularPower 変更

Alfa 1
Difúzní (červená) 0.8
Difúzní (zelená) 0.8
Difúzní (modrá) 0
Emisní (červená) 0
Emisní (zelená) 0
Emisní (modrá) 0
Zrcadlo (červená) 1
Odlesk (zelená) 1
Odlesk (modrá) 1
Síla odlesku 20

pole

Pole obsahuje informace o materiálu, které mají být nastaveny na hodnotu BasicEffect. Kromě toho má parametry pro výběr nabídek, ale protože se jedná pouze o parametr pro ovládání, vynechám podrobnosti.

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

Načtení materiálu modelu

Načte se hodnota materiálu nastaveného v modelu jako počáteční hodnota. V této ukázce je kód napsán za předpokladu, že v modelu je nastaven pouze jeden efekt.

// ライトとビュー、プロジェクションはあらかじめ設定しておく
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;
    }
}

Nastavení materiálu

Ukázka nastaví hodnotu na BasicEffect modelu. Pro "DiffuseColor", "EmissiveColor" a "SpecularColor" nastavte ve Vector3, nikoli ve Color struktuře. Určete prvky červené pro X, zelené pro Y a modré pro Z s hodnotami 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;
    }
}

V ukázce je kód jako kód operace s materiálem a řetězcové zobrazení hodnot, ale jsou tam části, které přímo nesouvisejí se BasicMaterial, takže vysvětlení vynechám. Můžete si stáhnout ukázku nebo se podívat na celý kód.

BasicEffect.Alpha vlastnost

Získá a nastaví krytí. Zadejte hodnotu v rozsahu 0.0~1.0. plout získat, nastavit

BasicEffect.DiffuseColor vlastnost

Získá a nastaví difúzní barvu. X je červená, Y je zelená, Z je modrá a každá hodnota je v rozsahu 0.0~1.0. Vektor3 získat, nastavit

BasicEffect.EmissiveColor vlastnost

Získá a nastaví vygenerovanou barvu. X je červená, Y je zelená, Z je modrá a každá hodnota je v rozsahu 0.0~1.0. Vektor3 získat, nastavit

BasicEffect.SpecularColor vlastnost

Získá a nastaví odraženou barvu. X je červená, Y je zelená, Z je modrá a každá hodnota je v rozsahu 0.0~1.0. Vektor3 získat, nastavit

BasicEffect.SpecularPower vlastnost

Získá a nastaví intenzitu odrazu. Hodnota je zadána jako 0.0~. plout získat, nastavit

Všechny kódy

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