Materiali BasicEffect

Stran posodobljena :
Datum ustvarjanja strani :

Povzetek

Manipulirajte s parametri, povezanimi z materialnim delom BasicEffect, da vidite, kako izgleda model.

Delovno okolje

Predpogoji

Podprte različice XNA
  • 4.0
Podprte platforme
  • Windows (XP s servisnim paketom SP2 ali novejšim, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Zahtevana različica senčila vozlišč za Windows 2.0
Zahtevana je različica osenčila slikovnih pik v sistemu Windows 2.0

Delovno okolje

peron
  • Windows 7
  • Xbox 360
  • Windows Phone 7

Kako delati z vzorcem

na
Deluje tipkovnicaXbox 360 krmilnik miškedotik
Izberite parametre, ki jih želite spremeniti ↑、↓ Leva palica ↑, ↓ Levi gumb -
Spreminjanje parametrov ←、→ Leva palica ←, → ←→ povleci -

snov

Kaj je BasicEffect?

Če želite v XNA prikazati 3D poligone, morate napisati program senčila, da jih narišete in se odločite, kako jih narisati. Če želite to narediti, ustvarite ločeno datoteko z učinki, napišite program, ga preberite kot razred učinka (učinek) in izvedite program senčila.

Vendar pa obstaja veliko primerov, ko ne potrebujete posebnega učinka risanja, in tudi v takih primerih je potreben učinek, zato je presenetljivo okorno skrbeti za izvajanje programa senčila.

Zato so osnovni parametri, kot so materiali in luči, vnaprej pripravljeni kot lastnosti, tako da je učinke mogoče enostavno obvladovati "BasicEffect". To je zelo enostavno, ker vam ni treba ustvariti datoteke z učinki, lahko jo rešite tako, da preprosto ustvarite primerek razreda.

Tudi če naložite podatke modela iz vsebine, je BasicEffect privzeto nastavljen, zato vam primerka sploh ni treba ustvariti.

Material

Material se nanaša predvsem na značilnosti materiala snovi in se uporablja za določanje barve, stopnje odbojnosti in trdnosti snovi. Ker ga je mogoče neodvisno izraziti v programih senčila, ima lahko definicija materiala grob pomen, ne da bi bila določena, vendar ima BasicEffect naslednje parametre:

Alfa Motnosti. Vrednost 1,0 označuje motnost, vrednost 0,0 pa popolno preglednost.
DiffuseColor Barva snovi predmeta, ki ga želite prikazati. Predstavljajte barve v RGB. Senčenje materiala se odraža glede na stanje svetlobe.
EmissiveColor Oddana barva predmeta, ki ga želite prikazati. Predstavljajte barve v RGB. Ker gre za barvo, ki oddaja lastno svetlobo, se barva doda, ne da bi nanjo vplivala svetloba.
SpecularColor Barva odseva predmeta, ki ga želite prikazati. Predstavljajte barve v RGB. Glede na smer in pogled svetlobe se bo zdelo, da se material odbija.
SpecularPower Intenzivnost odboja predmeta, ki ga želite prikazati. Višja kot je vrednost, manjša je površina.

Slika materialne spremembe

Spodnja slika prikazuje različne vrednosti materiala.

Začetno stanje

To je stanje takoj po nalaganju podatkov vzorčnega modela.

初期状態

Alfa 1
Difuzna (rdeča) 0.8
Difuzna (zelena) 0.8
Difuzna (modra) 0
Emisivna (rdeča) 0
Emisivno (zeleno) 0
Emisivno (modro) 0
Zrcalna (rdeča) 0
Zrcalna (zelena) 0
Zrcalna (modra) 0
SpecularPower 5

Sprememba motnosti (Alfa)

Takrat spremenite motnost. Modra barva ozadja je rahlo vidna.

不透明度(Alpha)変更

Alfa 0.31
Difuzna (rdeča) 0.8
Difuzna (zelena) 0.8
Difuzna (modra) 0
Emisivna (rdeča) 0
Emisivno (zeleno) 0
Emisivno (modro) 0
Zrcalna (rdeča) 0
Zrcalna (zelena) 0
Zrcalna (modra) 0
SpecularPower 5

Razpršene spremembe

Barva snovi se spremeni, da postane modrikasta.

Diffuse 変更

Alfa 1
Difuzna (rdeča) 0.05
Difuzna (zelena) 0.71
Difuzna (modra) 1
Emisivna (rdeča) 0
Emisivno (zeleno) 0
Emisivno (modro) 0
Zrcalna (rdeča) 0
Zrcalna (zelena) 0
Zrcalna (modra) 0
SpecularPower 5

Opustitvene spremembe

Rdeči in modri elementi Emisive so maksimirani. Ne glede na stanje svetlobe se ohrani vsaj vijolično stanje.

Emissive 変更

Alfa 1
Difuzna (rdeča) 0.8
Difuzna (zelena) 0.8
Difuzna (modra) 0
Emisivna (rdeča) 1
Emisivno (zeleno) 0
Emisivno (modro) 1
Zrcalna (rdeča) 0
Zrcalna (zelena) 0
Zrcalna (modra) 0
SpecularPower 5

Zrcalne spremembe

Z nastavitvijo Specular bo material videti odsevno.

Specular 変更

Alfa 1
Difuzna (rdeča) 0.8
Difuzna (zelena) 0.8
Difuzna (modra) 0
Emisivna (rdeča) 0
Emisivno (zeleno) 0
Emisivno (modro) 0
Zrcalna (rdeča) 1
Zrcalna (zelena) 1
Zrcalna (modra) 1
SpecularPower 5

Sprememba specularPower

Spreminjanje funkcije SpecularPower spremeni obseg odsevne površine.

SpecularPower 変更

Alfa 1
Difuzna (rdeča) 0.8
Difuzna (zelena) 0.8
Difuzna (modra) 0
Emisivna (rdeča) 0
Emisivno (zeleno) 0
Emisivno (modro) 0
Zrcalna (rdeča) 1
Zrcalna (zelena) 1
Zrcalna (modra) 1
SpecularPower 20

polje

V polju so bistvene informacije, ki jih lahko nastavite na BasicEffect. Poleg tega ima parametre za izbiro menijev, ker pa je le parameter za delovanje, bom izpustil 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;

Pridobivanje materiala modela

Pridobi se vrednost materiala, nastavljenega v modelu kot začetna vrednost. V tem vzorcu je koda napisana ob predpostavki, da je v modelu nastavljen samo en učinek.

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

Nastavitev materiala

Vzorec nastavi vrednost za BasicEffect modela. Za "DiffuseColor", "EmissiveColor" in "SpecularColor", nastavljeno v vektor3, ne v barvni strukturi. Določite elemente rdeče za X, zelene za Y in modre za Z z z vrednostmi 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 vzorcu je koda, kot sta koda delovanja materiala in prikaz nizov vrednosti, vendar obstajajo deli, ki niso neposredno povezani z BasicMaterialom, zato bom razlago izpustil. Vzorec lahko prenesete ali si ogledate celotno kodo.

BasicEffect.Alpha lastnost

Dobi in nastavi motnost. Določite vrednost v obsegu 0,0 ~ 1,0. pluti Pridobite, nastavite

BasicEffect.DiffuseColor lastnost

Dobi in nastavi razpršeno barvo. X je rdeča, Y zelena, Z modra in vsaka vrednost je v območju 0,0 ~ 1,0. Vektor3 Pridobite, nastavite

BasicEffect.EmissiveColor lastnost

Dobi in nastavi oddano barvo. X je rdeča, Y zelena, Z modra in vsaka vrednost je v območju 0,0 ~ 1,0. Vektor3 Pridobite, nastavite

BasicEffect.SpecularColor lastnost

Dobi in nastavi odsevno barvo. X je rdeča, Y zelena, Z modra in vsaka vrednost je v območju 0,0 ~ 1,0. Vektor3 Pridobite, nastavite

BasicEffect.SpecularPower lastnost

Dobi in nastavi intenzivnost refleksije. Vrednost je določena kot 0,0~. pluti Pridobite, nastavite

Vse kode

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