Materials d'efecte bàsic

Pàgina actualitzada :
Data de creació de la pàgina :

resum

Manipuleu els paràmetres relacionats amb la part material del BasicEffect per veure com es veu el model.

Entorn operatiu

Prerequisits

Versions XNA compatibles
  • 4.0
Plataformes suportades
  • Windows (XP SP2 o posterior, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Windows Requerit Versió Vertex Shader 2.0
Windows requereix la versió de Pixel Shader 2.0

Entorn operatiu

plataforma
  • Finestres 7
  • Xbox 360
  • Windows Phone 7

Com treballar amb la mostra

tàctil
Funciona amb el teclat del controlador de l'Xbox 360 amb el ratolí
Seleccioneu els paràmetres que vulgueu canviar ↑、↓ Pal esquerre ↑, ↓ Botó esquerre -
Canvi de paràmetres ←、→ Pal esquerre ←, → ←→ Arrossegar -

substància

Què és BasicEffect?

En XNA, si voleu visualitzar polígons 3D, heu d'escriure un programa shader per dibuixar-los i decidir com dibuixar-los. Per fer-ho, creeu un fitxer d'efectes separat, escriviu un programa, llegiu-lo com a classe d'efectes (Efecte) i executeu el programa shader.

No obstant això, hi ha molts casos en què no necessiteu un efecte de dibuix especial i, fins i tot en aquests casos, és necessari un efecte, de manera que és sorprenentment molest molestar-se a implementar un programa shader.

Per tant, els paràmetres bàsics com els materials i les llums es preparen com a propietats per endavant perquè els efectes es puguin manejar fàcilment "BasicEffect". És molt fàcil perquè no cal crear un fitxer d'efectes, es pot gestionar simplement creant una instància de la classe.

Fins i tot si carregueu dades del model des del contingut, BasicEffect s'estableix per defecte, de manera que ni tan sols cal crear una instància.

material

El material es refereix principalment a les característiques del material d'una substància i s'utilitza per especificar el color, el grau de reflexió i la força de la substància. Com que s'ha fet possible expressar-lo independentment en programes shader, la definició d'un material pot tenir un significat aproximat sense ser fixat, però BasicEffect té els següents paràmetres:

Alfa Opacitat. Un valor d'1,0 indica opacitat i un valor de 0,0 representa una transparència completa.
DifuseColor El color de la substància de l'objecte que es mostrarà. Representeu els colors en RGB. L'ombra del material es reflecteix en funció de l'estat de la llum.
EmissiuColor El color emès de l'objecte a mostrar. Representeu els colors en RGB. Com que és un color que emet llum pròpia, s'afegeix el color sense que la llum es vegi afectat.
SpecularColor El color del reflex de l'objecte a mostrar. Representeu els colors en RGB. Depenent de la direcció i el punt de vista de la llum, el material semblarà reflectit.
Poder especular La intensitat de la reflexió de l'objecte a mostrar. Com més gran sigui el valor, més petita serà l'àrea reflectida.

Imatge del canvi material

La imatge següent mostra els diferents valors del material.

Estat inicial

Aquest és l'estat immediatament després de carregar les dades del model d'exemple.

初期状態

Alfa 1
Difús (Vermell) 0.8
Difús (Verd) 0.8
Difús (Blau) 0
Emissiu (Vermell) 0
Emissiu (Verd) 0
Emissiu (blau) 0
Especular (Vermell) 0
Especular (Verd) 0
Especular (Blau) 0
Poder especular 5

Canvi d'opacitat (alfa)

És llavors quan canvies l'opacitat. El color blau del fons és dèbilment visible.

不透明度(Alpha)変更

Alfa 0.31
Difús (Vermell) 0.8
Difús (Verd) 0.8
Difús (Blau) 0
Emissiu (Vermell) 0
Emissiu (Verd) 0
Emissiu (blau) 0
Especular (Vermell) 0
Especular (Verd) 0
Especular (Blau) 0
Poder especular 5

Modificacions difuses

Es canvia el color de la substància per fer-la blavosa.

Diffuse 変更

Alfa 1
Difús (Vermell) 0.05
Difús (Verd) 0.71
Difús (Blau) 1
Emissiu (Vermell) 0
Emissiu (Verd) 0
Emissiu (blau) 0
Especular (Vermell) 0
Especular (Verd) 0
Especular (Blau) 0
Poder especular 5

Modificacions emissives

Es maximitzen els elements vermells i blaus de l'Emissiu. Independentment de l'estat de la llum, almenys es manté l'estat morat.

Emissive 変更

Alfa 1
Difús (Vermell) 0.8
Difús (Verd) 0.8
Difús (Blau) 0
Emissiu (Vermell) 1
Emissiu (Verd) 0
Emissiu (blau) 1
Especular (Vermell) 0
Especular (Verd) 0
Especular (Blau) 0
Poder especular 5

Canvis especulars

En configurar Specular, el material apareixerà reflectiu.

Specular 変更

Alfa 1
Difús (Vermell) 0.8
Difús (Verd) 0.8
Difús (Blau) 0
Emissiu (Vermell) 0
Emissiu (Verd) 0
Emissiu (blau) 0
Especular (Vermell) 1
Especular (Verd) 1
Especular (Blau) 1
Poder especular 5

Modificació especular

Canviant el poder especular canvia el rang de la superfície reflectant.

SpecularPower 変更

Alfa 1
Difús (Vermell) 0.8
Difús (Verd) 0.8
Difús (Blau) 0
Emissiu (Vermell) 0
Emissiu (Verd) 0
Emissiu (blau) 0
Especular (Vermell) 1
Especular (Verd) 1
Especular (Blau) 1
Poder especular 20

camp

El camp té informació material per establir a BasicEffect. A més, té paràmetres per seleccionar menús, però com que només és un paràmetre per al funcionament, ometreé els detalls.

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

Recuperació del material del model

Es recupera el valor del material establert en el model com a valor inicial. En aquesta mostra, el codi s'escriu en el supòsit que només hi ha un efecte establert en el 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;
    }
}

Configuració del material

La mostra estableix un valor per a l'efecte bàsic del model. Per a "DiffuseColor", "EmissiveColor" i "SpecularColor", definiu-lo en un Vector3, no en una estructura de color. Especifiqueu els elements de vermell per a X, verd per a Y i blau per a Z amb valors de 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;
    }
}

A la mostra, hi ha codi com el codi d'operació material i la visualització de la cadena de valors, però hi ha parts que no estan directament relacionades amb BasicMaterial, de manera que ometri l'explicació. Podeu descarregar la mostra o consultar el codi complet.

BasicEffect.Alpha propietat

Aconsegueix i estableix l'opacitat. Especifiqueu un valor en l'interval de 0.0~1.0. flotar obtenir, establir

BasicEffect.DiffuseColor propietat

Obté i estableix el color difús. X és vermell, Y és verd, Z és blau i cada valor es troba en el rang 0.0 ~ 1.0. Vector3 obtenir, establir

BasicEffect.EmissiveColor propietat

Obté i estableix el color emès. X és vermell, Y és verd, Z és blau i cada valor es troba en el rang 0.0 ~ 1.0. Vector3 obtenir, establir

BasicEffect.SpecularColor propietat

Obté i estableix el color reflectit. X és vermell, Y és verd, Z és blau i cada valor es troba en el rang 0.0 ~ 1.0. Vector3 obtenir, establir

BasicEffect.SpecularPower propietat

Aconsegueix i fixa la intensitat de la reflexió. El valor s'especifica com a 0.0~. flotar obtenir, establir

Tots els codis

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