Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
MaterialShaderPlugin.cs
Go to the documentation of this file.
1 using System.Collections.Generic;
2 using System.Linq;
3 
4 using SiliconStudio.Paradox.DataModel;
5 using SiliconStudio.Paradox.Effects.Data;
6 using SiliconStudio.Paradox.Graphics;
7 using SiliconStudio.Paradox.Shaders;
8 using SiliconStudio.Paradox.Shaders.Compiler;
9 
10 namespace SiliconStudio.Paradox.Effects
11 {
12  public class MaterialShaderPlugin : ShaderPlugin<RenderPassPlugin>
13  {
15  {
16  Flags |= EffectPluginFlags.StaticPermutation;
17  }
18 
20  {
21  object permutation;
22  if (permutations.TryGetValue(EffectMeshDataPermutation.Key, out permutation))
23  {
24  return new MaterialShaderPluginPermutationKey((Mesh)permutation);
25  }
26 
27  return null;
28  }
29 
30  public override void SetupShaders(EffectMesh effectMesh)
31  {
32  var permutationKey = new MaterialShaderPluginPermutationKey(effectMesh.MeshData);
33 
34  // Determines the max number of bones from the currect graphics profile
35  int defaultSkinningMaxBones = GraphicsDevice.Features.Profile <= GraphicsProfile.Level_9_3 ? 56 : 200;
36 
37  if (permutationKey.SkinningPosition)
38  {
39  DefaultShaderPass.Macros.Add(new ShaderMacro("SkinningMaxBones", defaultSkinningMaxBones));
40  BasicShaderPlugin.ApplyMixinClass(DefaultShaderPass.Shader, new ShaderClassSource("TransformationSkinning"), true);
41  }
42 
43  if (permutationKey.SkinningNormal)
44  BasicShaderPlugin.ApplyMixinClass(DefaultShaderPass.Shader, new ShaderClassSource("NormalSkinning"), true);
45  if (permutationKey.SkinningTangent)
46  BasicShaderPlugin.ApplyMixinClass(DefaultShaderPass.Shader, new ShaderClassSource("TangentSkinning"), true);
47 
48  if (permutationKey.AlbedoMaterial != null)
49  BasicShaderPlugin.ApplyMixinClass(DefaultShaderPass.Shader, permutationKey.AlbedoMaterial, true);
50  }
51 
52  public override void SetupResources(EffectMesh effectMesh)
53  {
54  if (effectMesh.MeshData.Material.Parameters.Get(EffectData.NeedAlphaBlending))
55  {
56  effectMesh.Parameters.Set(BlendStateKey, GraphicsDevice.BlendStates.NonPremultiplied);
57  }
58  }
59 
60  private class MaterialShaderPluginPermutationKey
61  {
62  public MaterialShaderPluginPermutationKey(Mesh meshData)
63  {
64  if (meshData.Draw == null)
65  return;
66 
67  var subMeshData = meshData.Draw; //Data[Mesh.StandardSubMeshData];
68 
69  NeedAlphaBlending = meshData.EffectParameters.Get(EffectData.NeedAlphaBlending);
70  AlbedoMaterial = meshData.EffectParameters.Get(EffectData.AlbedoMaterial);
71 
72  var vertexElementUsages = new HashSet<string>(subMeshData
73  .VertexBuffers
74  .SelectMany(x => x.Declaration.VertexElements)
75  .Select(x => x.SemanticAsText));
76 
77  if (vertexElementUsages.Contains("BLENDWEIGHT"))
78  {
79  SkinningPosition = true;
80  if (vertexElementUsages.Contains("NORMAL"))
81  SkinningNormal = true;
82  if (vertexElementUsages.Contains("TANGENT"))
83  SkinningTangent = true;
84  }
85  }
86 
87  public ShaderMixinSource AlbedoMaterial { get; set; }
88  public bool NeedAlphaBlending { get; set; }
89  public bool SkinningPosition { get; set; }
90  public bool SkinningNormal { get; set; }
91  public bool SkinningTangent { get; set; }
92 
93  protected bool Equals(MaterialShaderPluginPermutationKey other)
94  {
95  return ShaderSourceComparer.Default.Equals(AlbedoMaterial, other.AlbedoMaterial)
96  && SkinningPosition.Equals(other.SkinningPosition)
97  && SkinningNormal.Equals(other.SkinningNormal)
98  && SkinningTangent.Equals(other.SkinningTangent)
99  && NeedAlphaBlending.Equals(other.NeedAlphaBlending);
100  }
101 
102  public override bool Equals(object obj)
103  {
104  if (ReferenceEquals(null, obj)) return false;
105  if (ReferenceEquals(this, obj)) return true;
106  if (obj.GetType() != typeof(MaterialShaderPluginPermutationKey)) return false;
107  return Equals((MaterialShaderPluginPermutationKey)obj);
108  }
109 
110  public override int GetHashCode()
111  {
112  unchecked
113  {
114  int hashCode = (AlbedoMaterial != null ? ShaderSourceComparer.Default.GetHashCode(AlbedoMaterial) : 0);
115  hashCode = (hashCode * 397) ^ SkinningPosition.GetHashCode();
116  hashCode = (hashCode * 397) ^ SkinningNormal.GetHashCode();
117  hashCode = (hashCode * 397) ^ SkinningTangent.GetHashCode();
118  hashCode = (hashCode * 397) ^ NeedAlphaBlending.GetHashCode();
119  return hashCode;
120  }
121  }
122  }
123  }
124 }
SiliconStudio.Paradox.Shaders.ShaderMacro ShaderMacro
A mixin performing a combination of ShaderClassSource and other mixins.
override void SetupShaders(EffectMesh effectMesh)
static readonly ParameterKey< bool > NeedAlphaBlending
Definition: MeshData.cs:22
Flags
Enumeration of the new Assimp's flags.
override bool Equals(object against)
Determines whether the specified System.Object is equal to this instance.
override void SetupResources(EffectMesh effectMesh)
object GenerateEffectKey(Dictionary< ParameterKey, object > permutations)