BasicEffect-material

Sidan uppdaterad :
Datum för skapande av sida :

sammanfattning

Ändra parametrarna som är relaterade till materialdelen av BasicEffect för att se hur modellen ser ut.

Omvärld

Förutsättningar

XNA-versioner som stöds
  • 4.0
Plattformar som stöds
  • Windows (XP SP2 eller senare, Vista, 7)
  • Xbox 360
  • Windows Phone 7 (på engelska)
Windows krävs Vertex Shader-version 2.0
Windows Pixel Shader-version som krävs 2.0

Omvärld

plattform
  • Windows 7 (på engelska)
  • Xbox 360
  • Windows Phone 7 (på engelska)

Så här arbetar du med exemplet

Fungerar tangentbordXbox 360-kontrollermuspekare
Välj de parametrar du vill ändra ↑、↓ Vänster styrspak ↑, ↓ Vänster knapp -
Ändra parametrar ←、→ Vänster styrspak ←, → ←→ Dra -

substans

Vad är BasicEffect?

Om du vill visa 3D-polygoner i XNA måste du skriva ett shader-program för att rita dem och bestämma hur du ska rita dem. Det gör du genom att skapa en separat effektfil, skriva ett program, läsa den som en effektklass (Effekt) och köra skuggningsprogrammet.

Det finns dock många fall där du inte behöver en speciell riteffekt, och även i sådana fall är en effekt nödvändig, så det är förvånansvärt besvärligt att bry sig om att implementera ett shader-program.

Därför förbereds grundläggande parametrar som material och ljus som egenskaper i förväg så att effekter enkelt kan hanteras "BasicEffect". Det är väldigt enkelt eftersom du inte behöver skapa en effektfil, du kan hantera det genom att helt enkelt skapa en instans av klassen.

Även om du läser in modelldata från innehållet anges BasicEffect som standard, så du behöver inte ens skapa en instans.

material

Material hänvisar huvudsakligen till egenskaperna hos materialet i ett ämne och används för att specificera ämnets färg, reflektionsgrad och styrka. Eftersom det har blivit möjligt att uttrycka det oberoende i skuggningsprogram kan definitionen av ett material ha en grov betydelse utan att vara fast, men BasicEffect har följande parametrar:

Alfa Ogenomskinlighet. Värdet 1,0 anger opaciteten och värdet 0,0 motsvarar fullständig genomskinlighet.
DiffuseColor Färgen på substansen i objektet som ska visas. Representera färger i RGB. Materialets skuggning reflekteras beroende på ljusets tillstånd.
EmissiveColor Den avgivna färgen på objektet som ska visas. Representera färger i RGB. Eftersom det är en färg som avger sitt eget ljus tillsätts färgen utan att påverkas av ljus.
Speglande färg Färgen på reflektionen av objektet som ska visas. Representera färger i RGB. Beroende på ljusets riktning och synvinkel kommer materialet att se ut att reflekteras.
SpecularPower (på engelska) Intensiteten i reflektionen av objektet som ska visas. Ju högre värde, desto mindre område som återspeglas.

Bild av väsentlig förändring

Bilden nedan visar materialets olika värden.

Ursprungligt tillstånd

Det här är tillståndet omedelbart efter att exempelmodelldata har lästs in.

初期状態

Alfa 1
Diffus (röd) 0.8
Diffus (grön) 0.8
Diffus (blå) 0
Emitterande (röd) 0
Emitterande (grön) 0
Sändande (blå) 0
Speglande (röd) 0
Speglande (grön) 0
Speglande (blå) 0
SpecularPower (på engelska) 5

Ändring av opacitet (alfa)

Det är då du ändrar opaciteten. Den blå färgen på bakgrunden syns svagt.

不透明度(Alpha)変更

Alfa 0.31
Diffus (röd) 0.8
Diffus (grön) 0.8
Diffus (blå) 0
Emitterande (röd) 0
Emitterande (grön) 0
Sändande (blå) 0
Speglande (röd) 0
Speglande (grön) 0
Speglande (blå) 0
SpecularPower (på engelska) 5

Diffusa modifieringar

Ämnets färg ändras så att det blir blåaktigt.

Diffuse 変更

Alfa 1
Diffus (röd) 0.05
Diffus (grön) 0.71
Diffus (blå) 1
Emitterande (röd) 0
Emitterande (grön) 0
Sändande (blå) 0
Speglande (röd) 0
Speglande (grön) 0
Speglande (blå) 0
SpecularPower (på engelska) 5

Emitterande ändringar

De röda och blå elementen i Emissive maximeras. Oavsett ljusets tillstånd bibehålls åtminstone det lila tillståndet.

Emissive 変更

Alfa 1
Diffus (röd) 0.8
Diffus (grön) 0.8
Diffus (blå) 0
Emitterande (röd) 1
Emitterande (grön) 0
Sändande (blå) 1
Speglande (röd) 0
Speglande (grön) 0
Speglande (blå) 0
SpecularPower (på engelska) 5

Speglande ändringar

Genom att ställa in Spegla kommer materialet att se reflekterande ut.

Specular 変更

Alfa 1
Diffus (röd) 0.8
Diffus (grön) 0.8
Diffus (blå) 0
Emitterande (röd) 0
Emitterande (grön) 0
Sändande (blå) 0
Speglande (röd) 1
Speglande (grön) 1
Speglande (blå) 1
SpecularPower (på engelska) 5

SpecularPower-modifiering

Om du ändrar SpecularPower ändras den reflekterande ytans räckvidd.

SpecularPower 変更

Alfa 1
Diffus (röd) 0.8
Diffus (grön) 0.8
Diffus (blå) 0
Emitterande (röd) 0
Emitterande (grön) 0
Sändande (blå) 0
Speglande (röd) 1
Speglande (grön) 1
Speglande (blå) 1
SpecularPower (på engelska) 20

fält

Fältet innehåller materialinformation som ska anges till BasicEffect. Dessutom har den parametrar för att välja menyer, men eftersom det bara är en parameter för drift kommer jag att utelämna detaljerna.

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

Hämta modellens material

Värdet på det material som anges i modellen som det initiala värdet hämtas. I det här exemplet skrivs koden utifrån antagandet att det bara finns en effektuppsättning i modellen.

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

Ställa in materialet

Exemplet anger ett värde till modellens BasicEffect. För "DiffuseColor", "EmissiveColor" och "SpecularColor" anges i en Vector3, inte i en Color-struktur. Ange elementen röd för X, grön för Y och blå för Z med värdena 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;
    }
}

I exemplet finns det kod som materialåtgärdskod och strängvisning av värden, men det finns delar som inte är direkt relaterade till BasicMaterial, så jag utelämnar förklaringen. Du kan ladda ned exemplet eller kolla in den fullständiga koden.

BasicEffect.Alpha egenskap

Hämtar och ställer in opaciteten. Ange ett värde i intervallet 0,0~1,0. flyta Hämta, ställ in

BasicEffect.DiffuseColor egenskap

Hämtar och ställer in diffusionsfärgen. X är röd, Y är grön, Z är blå och varje värde ligger i intervallet 0,0~1,0. Vektor3 Hämta, ställ in

BasicEffect.EmissiveColor egenskap

Hämtar och ställer in den avgivna färgen. X är röd, Y är grön, Z är blå och varje värde ligger i intervallet 0,0~1,0. Vektor3 Hämta, ställ in

BasicEffect.SpecularColor egenskap

Hämtar och ställer in den reflekterade färgen. X är röd, Y är grön, Z är blå och varje värde ligger i intervallet 0,0~1,0. Vektor3 Hämta, ställ in

BasicEffect.SpecularPower egenskap

Hämtar och ställer in intensiteten på reflektionen. Värdet anges som 0,0~. flyta Hämta, ställ in

Alla koder

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