Матеріали BasicEffect

Сторінка оновлюється :
Дата створення сторінки :

зведення

Маніпулюйте параметрами, пов'язаними з матеріальною частиною BasicEffect, щоб побачити, як виглядає модель.

Робоче середовище

Передумови

Підтримувані версії XNA
  • 4.0
Підтримувані платформи
  • Windows (XP SP2 або новішої версії, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Потрібна версія вершинного шейдера Windows 2.0
Потрібна версія піксельного шейдера для Windows 2.0

Робоче середовище

платформа
  • Вікна 7
  • Xbox 360
  • Windows Phone 7

Як працювати зі зразком

Працює клавіатураXbox 360 контролермиша сенсорна
Виберіть параметри, які потрібно змінити ↑、↓ Ліва палиця ↑, ↓ Ліва кнопка -
Зміна параметрів ←、→ Лівий стік ←, → ←→ Перетягування -

речовина

Що таке BasicEffect?

У XNA, якщо ви хочете відобразити 3D-полігони, вам потрібно написати шейдерну програму, щоб намалювати їх і вирішити, як їх намалювати. Для цього створіть окремий файл ефектів, напишіть програму, прочитайте її як клас ефектів (Effect) і запустіть шейдерну програму.

Однак є багато випадків, коли вам не потрібен спеціальний ефект малювання, і навіть у таких випадках Effect необхідний, тому морочитися з реалізацією шейдерної програми напрочуд громіздко.

Тому базові параметри, такі як матеріали та світло, заздалегідь готуються як властивості, щоб з ефектами можна було легко впоратися «BasicEffect». Це дуже просто, тому що вам не потрібно створювати файл ефектів, ви можете впоратися з цим, просто створивши екземпляр класу.

Навіть якщо ви завантажуєте дані моделі з вмісту, BasicEffect встановлено за замовчуванням, тому вам навіть не потрібно створювати екземпляр.

матеріал

Матеріал в основному відноситься до характеристик матеріалу речовини і використовується для визначення кольору, ступеня відбиття та міцності речовини. Оскільки з'явилася можливість самостійно висловлювати його в шейдерних програмах, визначення матеріалу може мати приблизний сенс без фіксації, але BasicEffect має такі параметри:

Альфа Непрозорість. Значення 1,0 вказує на непрозорість, а 0,0 — на повну прозорість.
Дифузний колір Колір речовини об'єкта, що відображається. Представлення кольорів у RGB. Затінення матеріалу відбивається в залежності від стану світла.
EmissiveColor (Емісійний колір) Випромінюваний колір об'єкта, який потрібно відобразити. Представлення кольорів у RGB. Оскільки це колір, який випромінює власне світло, колір додається без впливу світла.
Дзеркальний колір Колір відображення об'єкта, що відображається. Представлення кольорів у RGB. Залежно від напрямку та точки зору світла матеріал буде здаватися відбитим.
Дзеркальна потужність Інтенсивність відображення об'єкта, що відображається. Чим вище значення, тим менша площа відбивається.

Образ матеріальних змін

На зображенні нижче показані різні значення матеріалу.

Початковий стан

Це стан відразу після завантаження зразка даних моделі.

初期状態

Альфа 1
Дифузний (червоний) 0.8
Дифузний (зелений) 0.8
Дифузний (синій) 0
Емісійний (червоний) 0
Емісійний (зелений) 0
Емісійний (синій) 0
Дзеркальний (червоний) 0
Дзеркальний (зелений) 0
Дзеркальний (синій) 0
Дзеркальна потужність 5

Зміна непрозорості (альфа)

Це коли ви змінюєте непрозорість. Слабо помітний синій колір фону.

不透明度(Alpha)変更

Альфа 0.31
Дифузний (червоний) 0.8
Дифузний (зелений) 0.8
Дифузний (синій) 0
Емісійний (червоний) 0
Емісійний (зелений) 0
Емісійний (синій) 0
Дзеркальний (червоний) 0
Дзеркальний (зелений) 0
Дзеркальний (синій) 0
Дзеркальна потужність 5

Дифузні модифікації

Колір речовини змінюють, роблячи його синюватим.

Diffuse 変更

Альфа 1
Дифузний (червоний) 0.05
Дифузний (зелений) 0.71
Дифузний (синій) 1
Емісійний (червоний) 0
Емісійний (зелений) 0
Емісійний (синій) 0
Дзеркальний (червоний) 0
Дзеркальний (зелений) 0
Дзеркальний (синій) 0
Дзеркальна потужність 5

Емісійні модифікації

Червоні та сині елементи Emissive максимізовані. Незалежно від стану світла, принаймні фіолетовий стан зберігається.

Emissive 変更

Альфа 1
Дифузний (червоний) 0.8
Дифузний (зелений) 0.8
Дифузний (синій) 0
Емісійний (червоний) 1
Емісійний (зелений) 0
Емісійний (синій) 1
Дзеркальний (червоний) 0
Дзеркальний (зелений) 0
Дзеркальний (синій) 0
Дзеркальна потужність 5

Дзеркальні зміни

Встановивши Дзеркальний, матеріал буде виглядати світловідбиваючим.

Specular 変更

Альфа 1
Дифузний (червоний) 0.8
Дифузний (зелений) 0.8
Дифузний (синій) 0
Емісійний (червоний) 0
Емісійний (зелений) 0
Емісійний (синій) 0
Дзеркальний (червоний) 1
Дзеркальний (зелений) 1
Дзеркальний (синій) 1
Дзеркальна потужність 5

Модифікація SpecularPower

Зміна SpecularPower змінює діапазон відбивної поверхні.

SpecularPower 変更

Альфа 1
Дифузний (червоний) 0.8
Дифузний (зелений) 0.8
Дифузний (синій) 0
Емісійний (червоний) 0
Емісійний (зелений) 0
Емісійний (синій) 0
Дзеркальний (червоний) 1
Дзеркальний (зелений) 1
Дзеркальний (синій) 1
Дзеркальна потужність 20

поле

Поле містить суттєву інформацію, для якої слід встановити значення BasicEffect. Крім того, в ньому є параметри для вибору меню, але так як це тільки параметр для роботи, то подробиці опустим.

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

Вилучення матеріалу моделі

Витягується значення матеріалу, встановленого в моделі як початкове значення. У цьому зразку код пишеться на основі припущення, що в моделі встановлено лише один ефект.

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

Налаштування матеріалу

Зразок встановлює значення для BasicEffect моделі. Для "DiffuseColor", "EmissiveColor" та "SpecularColor" встановлено у Vector3, а не у структурі Color. Вкажіть елементи червоного для X, зеленого для Y та синього для Z зі значеннями 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;
    }
}

У зразку є такий код, як код роботи з матеріалом і рядкове відображення значень, але є частини, які не мають прямого відношення до BasicMaterial, тому пояснення я опустим. Ви можете завантажити зразок або ознайомитися з повним кодом.

BasicEffect.Alpha власність

Отримує і встановлює непрозорість. Вкажіть значення в діапазоні 0.0~1.0. плавати отримати, встановити

BasicEffect.DiffuseColor власність

Отримує і встановлює розсіяний колір. X - червоний, Y - зелений, Z - синій, і кожне значення знаходиться в діапазоні 0.0 ~ 1.0. Вектор3 отримати, встановити

BasicEffect.EmissiveColor власність

Отримує і встановлює випромінюваний колір. X - червоний, Y - зелений, Z - синій, і кожне значення знаходиться в діапазоні 0.0 ~ 1.0. Вектор3 отримати, встановити

BasicEffect.SpecularColor власність

Отримує і встановлює відбитий колір. X - червоний, Y - зелений, Z - синій, і кожне значення знаходиться в діапазоні 0.0 ~ 1.0. Вектор3 отримати, встановити

BasicEffect.SpecularPower власність

Отримує і встановлює інтенсивність відображення. Значення вказано як 0.0~. плавати отримати, встановити

Всі коди

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