ライトの修正。独自形式をMMDに近づけ、質感、処理速度が向上
@@ -172,7 +172,7 @@ | ||
172 | 172 | public override void Draw(GameTime gameTime) |
173 | 173 | { |
174 | 174 | Draw(); |
175 | - base.Draw(gameTime); | |
175 | + //base.Draw(gameTime); | |
176 | 176 | } |
177 | 177 | /// <summary> |
178 | 178 | /// モデルの描画 |
@@ -215,6 +215,10 @@ | ||
215 | 215 | |
216 | 216 | private void ModelDraw(GraphicsDevice graphics, string EffectTechniqueName) |
217 | 217 | { |
218 | +#if TRACE | |
219 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
220 | + mmdXNA.TimeRular.BeginMark(1, "ModelDraw-Prepare", Color.PaleGreen); | |
221 | +#endif | |
218 | 222 | //ビューとプロジェクション取得 |
219 | 223 | Matrix view = mmdXNA.Camera.GetViewMatrix(); |
220 | 224 | Matrix projection = mmdXNA.Camera.GetProjectionMatrix(graphics); |
@@ -223,12 +227,13 @@ | ||
223 | 227 | translationTexture.Flip(); |
224 | 228 | faceTexture.Flip(); |
225 | 229 | |
230 | + //TODO: GetSkinRotation、GetSkinTranslationがボトルネック。原因はO(200)程度の処理量…… | |
226 | 231 | //スキンアニメーション用テクスチャ |
227 | 232 | rotationTexture.Texture.SetData<Quaternion>(BoneManager.GetSkinRotation()); |
228 | 233 | translationTexture.Texture.SetData<Vector4>(BoneManager.GetSkinTranslation()); |
229 | 234 | //フェイステクスチャ |
230 | 235 | faceTexture.Texture.SetData<Vector4>(FaceManager.GetFaceTranslation()); |
231 | - | |
236 | + | |
232 | 237 | Vector2 textureSize = new Vector2(rotationTexture.Texture.Width, |
233 | 238 | rotationTexture.Texture.Height); |
234 | 239 | //フェイステクスチャのサイズ |
@@ -235,30 +240,42 @@ | ||
235 | 240 | Vector2 faceTextureSize = new Vector2(faceTexture.Texture.Width, faceTexture.Texture.Height); |
236 | 241 | |
237 | 242 | //ライティング設定の取得 |
238 | - Vector3[] LightVectors, LightColors; | |
239 | - mmdXNA.LightManager.GetParameters(out LightVectors, out LightColors); | |
243 | + Vector3 LightVector, LightColor; | |
244 | + mmdXNA.LightManager.GetParameters(out LightVector, out LightColor); | |
240 | 245 | //モデルのCullModeを変更 |
241 | 246 | CullMode mode = graphics.RenderState.CullMode; |
242 | 247 | graphics.RenderState.CullMode = CullMode.None; |
243 | - | |
248 | + | |
249 | +#if TRACE | |
250 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
251 | + { | |
252 | + mmdXNA.TimeRular.EndMark(1, "ModelDraw-Prepare"); | |
253 | + mmdXNA.TimeRular.BeginMark(1, "ModelDraw-Core", Color.RosyBrown); | |
254 | + } | |
255 | +#endif | |
244 | 256 | foreach (ModelMesh mesh in ModelData.ModelData.Meshes) |
245 | 257 | { |
246 | - foreach (Effect effect in mesh.Effects) | |
258 | +#if TRACE | |
259 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
260 | + mmdXNA.TimeRular.BeginMark(2, "ModelDraw-SetData", Color.RosyBrown);//メモ:この中の実行コードが時間くってる | |
261 | +#endif | |
262 | + foreach (Effect effect in mesh.Effects)//メモ:エフェクト17回ループで処理時間食ってる | |
247 | 263 | { |
264 | + mmdXNA.TimeRular.BeginMark(3, "ModelDraw-SetData1", Color.RosyBrown); | |
265 | + | |
266 | + | |
248 | 267 | //エフェクトルーチン。調整が必要 |
249 | 268 | //テクニックセット |
250 | 269 | effect.CurrentTechnique = effect.Techniques[EffectTechniqueName]; |
251 | - //ライティングセット(すげーアホなコード書いてるが、ToStringするとGC発生しちゃうのでやむなく……) | |
252 | - effect.Parameters["DirLight0Direction"].SetValue(LightVectors[0]); | |
253 | - effect.Parameters["DirLight0DiffuseColor"].SetValue(LightColors[0]); | |
254 | - //effect.Parameters["DirLight0SpecularColor"].SetValue(LightSpeculars[0]); | |
255 | - effect.Parameters["DirLight1Direction"].SetValue(LightVectors[1]); | |
256 | - effect.Parameters["DirLight1DiffuseColor"].SetValue(LightColors[1]); | |
257 | - //effect.Parameters["DirLight1SpecularColor"].SetValue(LightSpeculars[1]); | |
258 | - effect.Parameters["DirLight2Direction"].SetValue(LightVectors[2]); | |
259 | - effect.Parameters["DirLight2DiffuseColor"].SetValue(LightColors[2]); | |
260 | - //effect.Parameters["DirLight2SpecularColor"].SetValue(LightSpeculars[2]); | |
270 | + //ライティングセット | |
271 | + effect.Parameters["AmbientLightColor"].SetValue(mmdXNA.LightManager.AmbientLight.ToVector3()); | |
272 | + effect.Parameters["DirLight0Direction"].SetValue(LightVector); | |
273 | + effect.Parameters["DirLight0DiffuseColor"].SetValue(LightColor); | |
261 | 274 | |
275 | + mmdXNA.TimeRular.EndMark(3, "ModelDraw-SetData1"); | |
276 | + mmdXNA.TimeRular.BeginMark(3, "ModelDraw-SetData2", Color.RosyBrown); | |
277 | + | |
278 | + | |
262 | 279 | //ボーン設定 |
263 | 280 | effect.Parameters["BoneRotationTexture"].SetValue( |
264 | 281 | rotationTexture.Texture); |
@@ -269,6 +286,11 @@ | ||
269 | 286 | //表情設定 |
270 | 287 | effect.Parameters["FaceTranslationTexture"].SetValue(faceTexture.Texture); |
271 | 288 | effect.Parameters["FaceTextureSize"].SetValue(faceTextureSize); |
289 | + | |
290 | + mmdXNA.TimeRular.EndMark(3, "ModelDraw-SetData2"); | |
291 | + mmdXNA.TimeRular.BeginMark(3, "ModelDraw-SetData3", Color.RosyBrown); | |
292 | + | |
293 | + | |
272 | 294 | //トゥーンライティング設定 |
273 | 295 | effect.Parameters["UseToonLighting"].SetValue(UseToon ? 1.0f : 0.0f); |
274 | 296 | effect.Parameters["ToonThresholds"].SetValue(ToonThresholds); |
@@ -278,10 +300,30 @@ | ||
278 | 300 | effect.Parameters["World"].SetValue(World); |
279 | 301 | effect.Parameters["View"].SetValue(view); |
280 | 302 | effect.Parameters["Projection"].SetValue(projection); |
303 | + | |
304 | + mmdXNA.TimeRular.EndMark(3, "ModelDraw-SetData3"); | |
281 | 305 | |
282 | 306 | } |
307 | +#if TRACE | |
308 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
309 | + { | |
310 | + mmdXNA.TimeRular.EndMark(2, "ModelDraw-SetData"); | |
311 | + mmdXNA.TimeRular.BeginMark(2, "ModelDraw-Draw", Color.RoyalBlue); | |
312 | + } | |
313 | +#endif | |
283 | 314 | mesh.Draw(); |
315 | +#if TRACE | |
316 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
317 | + mmdXNA.TimeRular.EndMark(2, "ModelDraw-Draw"); | |
318 | +#endif | |
284 | 319 | } |
320 | +#if TRACE | |
321 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
322 | + { | |
323 | + mmdXNA.TimeRular.EndMark(1, "ModelDraw-Core"); | |
324 | + mmdXNA.TimeRular.BeginMark(1, "ModelDraw-After", Color.OrangeRed); | |
325 | + } | |
326 | +#endif | |
285 | 327 | //CullModeの変更を戻す |
286 | 328 | graphics.RenderState.CullMode = mode; |
287 | 329 | //アクセサリの描画 |
@@ -296,6 +338,11 @@ | ||
296 | 338 | } |
297 | 339 | } |
298 | 340 | } |
341 | +#if TRACE | |
342 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
343 | + mmdXNA.TimeRular.EndMark(1, "ModelDraw-After"); | |
344 | +#endif | |
345 | + | |
299 | 346 | } |
300 | 347 | |
301 | 348 | } |
@@ -12,29 +12,48 @@ | ||
12 | 12 | /// </summary> |
13 | 13 | public class MMDLightManager |
14 | 14 | { |
15 | - const int NumLight = 3; | |
16 | - Vector3[] m_dir = new Vector3[NumLight], m_color = new Vector3[NumLight], m_spec = new Vector3[NumLight]; | |
15 | + //const int NumLight = 3; | |
16 | + //Vector3[] m_dir = new Vector3[NumLight], m_color = new Vector3[NumLight], m_spec = new Vector3[NumLight]; | |
17 | 17 | |
18 | 18 | /// <summary> |
19 | + /// 環境光の色 | |
20 | + /// </summary> | |
21 | + /// <remarks>MMDにおける照明色はこの項目が相当</remarks> | |
22 | + public Color AmbientLight = new Color(154, 154, 154); | |
23 | + | |
24 | + /// <summary> | |
19 | 25 | /// キーライト |
20 | 26 | /// </summary> |
21 | - public MMDLight KeyLight = new MMDLight(new Vector3(1, -1, 1), | |
22 | - new Color(154, 145, 106)); | |
27 | + /// <remarks>MMDの照明方向はこの項目が相当</remarks> | |
28 | + public MMDLight KeyLight = new MMDLight(new Vector3(-0.5f, -1f, -0.5f), new Color(80, 80, 80), LightType.DirectionalLight);//new Color(154, 154, 154)); | |
29 | + | |
30 | + | |
31 | + internal void GetParameters(out Vector3 dir, out Vector3 color) | |
32 | + { | |
33 | + KeyLight.SetParameters(out dir, out color); | |
34 | + } | |
35 | + | |
36 | + | |
37 | + //TODO: 1.1aには削除 | |
38 | + #region MMDのライトアニメーションに合わせるため、廃止 | |
23 | 39 | /// <summary> |
24 | 40 | /// フィルライト |
25 | 41 | /// </summary> |
42 | + [Obsolete("Lightに統合", true)] | |
26 | 43 | public MMDLight FillLight = new MMDLight(new Vector3(-1, 1, -1), |
27 | - new Color(148, 139, 103)); | |
44 | + new Color(148, 139, 103),LightType.DirectionalLight); | |
28 | 45 | /// <summary> |
29 | 46 | /// バックライト |
30 | 47 | /// </summary> |
48 | + [Obsolete("Lightに統合", true)] | |
31 | 49 | public MMDLight BackLight = new MMDLight(new Vector3(-1, -1, -1), |
32 | - new Color(82, 92, 100)); | |
50 | + new Color(82, 92, 100), LightType.DirectionalLight); | |
33 | 51 | /// <summary> |
34 | 52 | /// ライト |
35 | 53 | /// </summary> |
36 | 54 | /// <param name="i">0=キー、1=フィル、2=バック</param> |
37 | 55 | /// <returns>ライト構造体</returns> |
56 | + [Obsolete("Lightを使用して下さい", true)] | |
38 | 57 | public MMDLight this[int i] |
39 | 58 | { |
40 | 59 | get |
@@ -54,14 +73,8 @@ | ||
54 | 73 | |
55 | 74 | |
56 | 75 | |
57 | - internal void GetParameters(out Vector3[] dir, out Vector3[] color) | |
58 | - { | |
59 | - dir = m_dir; | |
60 | - color = m_color; | |
61 | - for (int i = 0; i < 3; i++) | |
62 | - { | |
63 | - this[i].SetParameters(out dir[i], out color[i]); | |
64 | - } | |
65 | - } | |
76 | + | |
77 | + #endregion | |
78 | + | |
66 | 79 | } |
67 | 80 | } |
@@ -8,8 +8,22 @@ | ||
8 | 8 | namespace MikuMikuDance.XNA.Stages |
9 | 9 | { |
10 | 10 | /// <summary> |
11 | - /// ライト | |
11 | + /// ライトの種別 | |
12 | 12 | /// </summary> |
13 | + public enum LightType | |
14 | + { | |
15 | + /// <summary> | |
16 | + /// ディレクショナルライト | |
17 | + /// </summary> | |
18 | + DirectionalLight = 0, | |
19 | + /// <summary> | |
20 | + /// スポットライト(未実装) | |
21 | + /// </summary> | |
22 | + SpotLight = 1, | |
23 | + } | |
24 | + /// <summary> | |
25 | + /// ライトクラス | |
26 | + /// </summary> | |
13 | 27 | public struct MMDLight |
14 | 28 | { |
15 | 29 | /// <summary> |
@@ -20,10 +34,17 @@ | ||
20 | 34 | /// カラー |
21 | 35 | /// </summary> |
22 | 36 | public Color Color; |
23 | - internal MMDLight(Vector3 dir, Color color) | |
37 | + | |
38 | + /// <summary> | |
39 | + /// ライトの種別 | |
40 | + /// </summary> | |
41 | + public LightType Type; | |
42 | + | |
43 | + internal MMDLight(Vector3 dir, Color color, LightType type) | |
24 | 44 | { |
25 | 45 | Direction = dir; |
26 | 46 | Color = color; |
47 | + Type = type; | |
27 | 48 | } |
28 | 49 | internal void SetParameters(out Vector3 dir, out Vector3 color) |
29 | 50 | { |
@@ -23,6 +23,10 @@ | ||
23 | 23 | /// このモデルに適応するワールド座標系 |
24 | 24 | /// </summary> |
25 | 25 | public Matrix World { get; set; } |
26 | + /// <summary> | |
27 | + /// MikuMikuDanceXNA.TimeRularをこのアクセサリが呼び出すかどうか | |
28 | + /// </summary> | |
29 | + public bool UseTimeRular { get; set; } | |
26 | 30 | |
27 | 31 | /// <summary> |
28 | 32 | /// コンストラクタ |
@@ -37,6 +41,7 @@ | ||
37 | 41 | this.mmd = mmd; |
38 | 42 | ModelData = model; |
39 | 43 | World = world; |
44 | + UseTimeRular = true; | |
40 | 45 | game.Components.Add(this); |
41 | 46 | } |
42 | 47 | /// <summary> |
@@ -48,7 +53,7 @@ | ||
48 | 53 | //親がいない場合は自分で描画する。親がいる場合は親のタイミングで描画される |
49 | 54 | if (parent == null) |
50 | 55 | Draw(Matrix.Identity); |
51 | - base.Draw(gameTime); | |
56 | + //base.Draw(gameTime); | |
52 | 57 | } |
53 | 58 | /// <summary> |
54 | 59 | /// 内部描画ルーチン |
@@ -56,36 +61,48 @@ | ||
56 | 61 | /// <param name="baseTransform">基準トランスフォーム</param> |
57 | 62 | internal void Draw(Matrix baseTransform) |
58 | 63 | { |
64 | +#if TRACE | |
65 | + if (mmd.TimeRular != null && UseTimeRular) | |
66 | + { | |
67 | + mmd.TimeRular.BeginMark(1, "AccessoryDraw", Color.Red); | |
68 | + mmd.TimeRular.BeginMark(2, "AccessoryDraw-Prepare", Color.Gray); | |
69 | + } | |
70 | +#endif | |
59 | 71 | //アクセサリ描画用に設定 |
60 | 72 | Game.GraphicsDevice.RenderState.AlphaBlendEnable = true; |
61 | 73 | Game.GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add; |
62 | 74 | Game.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha; |
63 | 75 | Game.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha; |
76 | + Game.GraphicsDevice.RenderState.AlphaTestEnable = true; | |
77 | + Game.GraphicsDevice.RenderState.ReferenceAlpha = 1; | |
78 | + Game.GraphicsDevice.RenderState.AlphaFunction = CompareFunction.GreaterEqual; | |
79 | + | |
64 | 80 | //モデルのCullModeを変更 |
65 | 81 | CullMode mode = Game.GraphicsDevice.RenderState.CullMode; |
66 | - Game.GraphicsDevice.RenderState.CullMode = CullMode.None; | |
67 | - //ステージの描画 | |
82 | + Game.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; | |
83 | +#if TRACE | |
84 | + if (mmd.TimeRular != null && UseTimeRular) | |
85 | + { | |
86 | + mmd.TimeRular.EndMark(2, "AccessoryDraw-Prepare"); | |
87 | + mmd.TimeRular.BeginMark(2, "AccessoryDraw-Core", Color.Green); | |
88 | + } | |
89 | +#endif | |
90 | + //アクセサリの描画 | |
68 | 91 | foreach (ModelMesh mesh in ModelData.Meshes) |
69 | 92 | { |
70 | 93 | foreach (BasicEffect effect in mesh.Effects) |
71 | 94 | { |
72 | 95 | effect.LightingEnabled = true; |
73 | - //effect.EnableDefaultLighting(); | |
96 | + effect.AmbientLightColor = mmd.LightManager.AmbientLight.ToVector3(); | |
74 | 97 | effect.DirectionalLight0.Direction = mmd.LightManager.KeyLight.Direction; |
75 | 98 | effect.DirectionalLight0.Direction.Normalize(); |
76 | - effect.DirectionalLight0.DiffuseColor = mmd.LightManager.KeyLight.Color.ToVector3(); | |
77 | - effect.DirectionalLight0.SpecularColor = Vector3.Zero; | |
99 | + effect.DirectionalLight0.DiffuseColor = mmd.LightManager.KeyLight.Color.ToVector3();//new Vector3(0.2f, 0.2f, 0.2f); | |
100 | + effect.DirectionalLight0.SpecularColor = mmd.LightManager.KeyLight.Color.ToVector3(); | |
78 | 101 | effect.DirectionalLight0.Enabled = true; |
102 | + effect.DirectionalLight1.Enabled = false; | |
103 | + effect.DirectionalLight2.Enabled = false; | |
104 | + effect.PreferPerPixelLighting = true; | |
79 | 105 | |
80 | - effect.DirectionalLight1.Direction = mmd.LightManager.FillLight.Direction; | |
81 | - effect.DirectionalLight1.DiffuseColor = mmd.LightManager.FillLight.Color.ToVector3(); | |
82 | - effect.DirectionalLight1.SpecularColor = Vector3.Zero; | |
83 | - effect.DirectionalLight1.Enabled = true; | |
84 | - effect.DirectionalLight2.Direction = mmd.LightManager.BackLight.Direction; | |
85 | - effect.DirectionalLight2.DiffuseColor = mmd.LightManager.BackLight.Color.ToVector3(); | |
86 | - effect.DirectionalLight2.SpecularColor = Vector3.Zero; | |
87 | - effect.DirectionalLight2.Enabled = true; | |
88 | - | |
89 | 106 | effect.World = baseTransform * World; |
90 | 107 | effect.View = mmd.Camera.GetViewMatrix(); |
91 | 108 | effect.Projection = mmd.Camera.GetProjectionMatrix(Game.GraphicsDevice); |
@@ -97,8 +114,15 @@ | ||
97 | 114 | Game.GraphicsDevice.RenderState.AlphaBlendEnable = false; |
98 | 115 | //CullModeの変更を戻す |
99 | 116 | Game.GraphicsDevice.RenderState.CullMode = mode; |
100 | - | |
101 | 117 | |
118 | +#if TRACE | |
119 | + if (mmd.TimeRular != null && UseTimeRular) | |
120 | + { | |
121 | + mmd.TimeRular.EndMark(2, "AccessoryDraw-Core"); | |
122 | + mmd.TimeRular.EndMark(1, "AccessoryDraw"); | |
123 | + } | |
124 | +#endif | |
125 | + | |
102 | 126 | } |
103 | 127 | |
104 | 128 | } |