AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
StandardShaderGUI.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License.
3 
4 using System;
5 using UnityEditor;
6 using UnityEngine;
7 
8 namespace HoloToolkit.Unity
9 {
13  public class StandardShaderGUI : ShaderGUI
14  {
15  public enum RenderingMode
16  {
17  Opaque,
18  TransparentCutout,
19  Transparent,
20  PremultipliedTransparent,
21  Additive,
22  Custom
23  }
24 
25  public enum CustomRenderingMode
26  {
27  Opaque,
28  TransparentCutout,
29  Transparent
30  }
31 
32  public enum AlbedoAlphaMode
33  {
34  Transparency,
35  Metallic,
36  Smoothness
37  }
38 
39  public enum DepthWrite
40  {
41  Off,
42  On
43  }
44 
45  public static class Styles
46  {
47  public static string primaryMapsTitle = "Main Maps";
48  public static string renderingOptionsTitle = "Rendering Options";
49  public static string advancedOptionsTitle = "Advanced Options";
50  public static string fluentOptionsTitle = "Fluent Options";
51  public static string renderTypeName = "RenderType";
52  public static string renderingModeName = "_Mode";
53  public static string customRenderingModeName = "_CustomMode";
54  public static string sourceBlendName = "_SrcBlend";
55  public static string destinationBlendName = "_DstBlend";
56  public static string blendOperationName = "_BlendOp";
57  public static string depthTestName = "_ZTest";
58  public static string depthWriteName = "_ZWrite";
59  public static string colorWriteMaskName = "_ColorWriteMask";
60  public static string alphaTestOnName = "_ALPHATEST_ON";
61  public static string alphaBlendOnName = "_ALPHABLEND_ON";
62  public static string disableAlbedoMapName = "_DISABLE_ALBEDO_MAP";
63  public static string albedoMapAlphaMetallicName = "_METALLIC_TEXTURE_ALBEDO_CHANNEL_A";
64  public static string albedoMapAlphaSmoothnessName = "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A";
65  public static readonly string[] renderingModeNames = Enum.GetNames(typeof(RenderingMode));
66  public static readonly string[] customRenderingModeNames = Enum.GetNames(typeof(CustomRenderingMode));
67  public static readonly string[] albedoAlphaModeNames = Enum.GetNames(typeof(AlbedoAlphaMode));
68  public static readonly string[] depthWriteNames = Enum.GetNames(typeof(DepthWrite));
69  public static GUIContent sourceBlend = new GUIContent("Source Blend", "Blend Mode of Newly Calculated Color");
70  public static GUIContent destinationBlend = new GUIContent("Destination Blend", "Blend Mode of Existing Color");
71  public static GUIContent blendOperation = new GUIContent("Blend Operation", "Operation for Blending New Color With Existing Color");
72  public static GUIContent depthTest = new GUIContent("Depth Test", "How Should Depth Testing Be Performed.");
73  public static GUIContent depthWrite = new GUIContent("Depth Write", "Controls Whether Pixels From This Object Are Written to the Depth Buffer");
74  public static GUIContent colorWriteMask = new GUIContent("Color Write Mask", "Color Channel Writing Mask");
75  public static GUIContent cullMode = new GUIContent("Cull Mode", "Triangle Culling Mode");
76  public static GUIContent renderQueueOverride = new GUIContent("Render Queue Override", "Manually Override the Render Queue");
77  public static GUIContent albedo = new GUIContent("Albedo", "Albedo (RGB) and Transparency (A)");
78  public static GUIContent alphaCutoff = new GUIContent("Alpha Cutoff", "Threshold for Alpha Cutoff");
79  public static GUIContent metallic = new GUIContent("Metallic", "Metallic Value");
80  public static GUIContent smoothness = new GUIContent("Smoothness", "Smoothness Value");
81  public static GUIContent enableNormalMap = new GUIContent("Normal Map", "Enable Normal Map");
82  public static GUIContent normalMap = new GUIContent("Normal Map");
83  public static GUIContent enableEmission = new GUIContent("Emission", "Enable Emission");
84  public static GUIContent emissiveColor = new GUIContent("Color");
85  public static GUIContent directionalLight = new GUIContent("Directional Light", "Affected by Unity Directional Light");
86  public static GUIContent specularHighlights = new GUIContent("Specular Highlights", "Calculate Specular Highlights");
87  public static GUIContent reflections = new GUIContent("Reflections", "Calculate Glossy Reflections");
88  public static GUIContent refraction = new GUIContent("Refraction", "Calculate Refraction");
89  public static GUIContent refractiveIndex = new GUIContent("Refractive Index", "Ratio of Indices of Refraction at the Surface Interface");
90  public static GUIContent rimLight = new GUIContent("Rim Light", "Enable Rim/Edge Lighting");
91  public static GUIContent rimColor = new GUIContent("Color", "Rim Highlight Color");
92  public static GUIContent rimPower = new GUIContent("Power", "Rim Highlight Saturation");
93  public static GUIContent clippingPlane = new GUIContent("Clipping Plane", "Enable Clipping Against a Plane");
94  public static GUIContent clipPlane = new GUIContent("Plane", "Plane To Clip Against");
95  public static GUIContent clippingPlaneBorder = new GUIContent("Border", "Enable a Border Along the Clipping Plane");
96  public static GUIContent clippingPlaneBorderWidth = new GUIContent("Width", "Width of the Clipping Plane Border");
97  public static GUIContent clippingPlaneBorderColor = new GUIContent("Color", "Interpolated Color of the Clipping Plane Border");
98  public static GUIContent nearPlaneFade = new GUIContent("Near Plane Fade", "Objects Disappear (Turn to Black) as the Camera Nears Them");
99  public static GUIContent fadeBeginDistance = new GUIContent("Fade Begin", "Distance From Camera to Begin Fade In");
100  public static GUIContent fadeCompleteDistance = new GUIContent("Fade Complete", "Distance From Camera When Fade is Fully In");
101  public static GUIContent hoverLight = new GUIContent("Hover Light", "Enable utilization of a Hover Light");
102  public static GUIContent enableHoverColorOverride = new GUIContent("Override Color", "Override Global Hover Color");
103  public static GUIContent hoverLightOpaque = new GUIContent("Hover Light Opaque", "Enable Hover Light on Transparent Pixels");
104  public static GUIContent enableHoverColorOpaqueOverride = new GUIContent("Override Color", "Override Opaque Hover Color");
105  public static GUIContent hoverColorOpaqueOverride = new GUIContent("Color", "Override Hover Color for Transparent Pixels");
106  public static GUIContent hoverColorOverride = new GUIContent("Color", "Override Hover Color");
107  public static GUIContent roundCorners = new GUIContent("Round Corners", "(Assumes UVs Specify Borders)");
108  public static GUIContent roundCornerRadius = new GUIContent("Unit Radius", "Rounded Rectangle Corner Unit Sphere Radius");
109  public static GUIContent roundCornerMargin = new GUIContent("Margin %", "Distance From Geometry Edge");
110  public static GUIContent borderLight = new GUIContent("Border Light", "Enable Border Lighting (Assumes UVs Specify Borders)");
111  public static GUIContent borderLightUsesHoverColor = new GUIContent("Use Hover Color", "Border Color Comes From Hover Light");
112  public static GUIContent borderLightOpaque = new GUIContent("Opaque Borders", "Borders Override Alpha Value to Appear Opaque");
113  public static GUIContent borderWidth = new GUIContent("Width %", "Uniform Width Along Border as a % of the Smallest XYZ Dimension");
114  public static GUIContent borderMinValue = new GUIContent("Min Value", "Minimum Border Saturation");
115  public static GUIContent edgeSmoothingValue = new GUIContent("Edge Smoothing Value", "Smooths Edges When Round Corners and Transparency Is Enabled");
116  public static GUIContent innerGlow = new GUIContent("Inner Glow", "Enable Inner Glow (Assumes UVs Specify Borders)");
117  public static GUIContent innerGlowColor = new GUIContent("Color", "Inner Glow Color (RGB) and Intensity (A)");
118  public static GUIContent environmentColoring = new GUIContent("Environment Coloring", "Change Color Based on View");
119  public static GUIContent environmentColorThreshold = new GUIContent("Threshold", "Threshold When Environment Coloring Should Appear Based on Surface Normal");
120  public static GUIContent environmentColorIntensity = new GUIContent("Intensity", "Intensity (or Brightness) of the Environment Coloring");
121  public static GUIContent environmentColorX = new GUIContent("X-Axis Color", "Color Along the World Space X-Axis");
122  public static GUIContent environmentColorY = new GUIContent("Y-Axis Color", "Color Along the World Space Y-Axis");
123  public static GUIContent environmentColorZ = new GUIContent("Z-Axis Color", "Color Along the World Space Z-Axis");
124  }
125 
126  protected bool initialized;
127 
128  protected MaterialProperty renderingMode;
129  protected MaterialProperty customRenderingMode;
130  protected MaterialProperty sourceBlend;
131  protected MaterialProperty destinationBlend;
132  protected MaterialProperty blendOperation;
133  protected MaterialProperty depthTest;
134  protected MaterialProperty depthWrite;
135  protected MaterialProperty colorWriteMask;
136  protected MaterialProperty cullMode;
137  protected MaterialProperty renderQueueOverride;
138  protected MaterialProperty albedoMap;
139  protected MaterialProperty albedoColor;
140  protected MaterialProperty albedoAlphaMode;
141  protected MaterialProperty alphaCutoff;
142  protected MaterialProperty enableNormalMap;
143  protected MaterialProperty normalMap;
144  protected MaterialProperty enableEmission;
145  protected MaterialProperty emissiveColor;
146  protected MaterialProperty metallic;
147  protected MaterialProperty smoothness;
148  protected MaterialProperty directionalLight;
149  protected MaterialProperty specularHighlights;
150  protected MaterialProperty reflections;
151  protected MaterialProperty refraction;
152  protected MaterialProperty refractiveIndex;
153  protected MaterialProperty rimLight;
154  protected MaterialProperty rimColor;
155  protected MaterialProperty rimPower;
156  protected MaterialProperty clippingPlane;
157  protected MaterialProperty clipPlane;
158  protected MaterialProperty clippingPlaneBorder;
159  protected MaterialProperty clippingPlaneBorderWidth;
160  protected MaterialProperty clippingPlaneBorderColor;
161  protected MaterialProperty nearPlaneFade;
162  protected MaterialProperty fadeBeginDistance;
163  protected MaterialProperty fadeCompleteDistance;
164  protected MaterialProperty hoverLight;
165  protected MaterialProperty enableHoverColorOverride;
166  protected MaterialProperty hoverLightOpaque;
167  protected MaterialProperty enableHoverColorOpaqueOverride;
168  protected MaterialProperty hoverColorOverrideOpaque;
169  protected MaterialProperty hoverColorOverride;
170  protected MaterialProperty roundCorners;
171  protected MaterialProperty roundCornerRadius;
172  protected MaterialProperty roundCornerMargin;
173  protected MaterialProperty borderLight;
174  protected MaterialProperty borderLightUsesHoverColor;
175  protected MaterialProperty borderLightOpaque;
176  protected MaterialProperty borderWidth;
177  protected MaterialProperty borderMinValue;
178  protected MaterialProperty edgeSmoothingValue;
179  protected MaterialProperty innerGlow;
180  protected MaterialProperty innerGlowColor;
181  protected MaterialProperty environmentColoring;
182  protected MaterialProperty environmentColorThreshold;
183  protected MaterialProperty environmentColorIntensity;
184  protected MaterialProperty environmentColorX;
185  protected MaterialProperty environmentColorY;
186  protected MaterialProperty environmentColorZ;
187 
188  protected void FindProperties(MaterialProperty[] props)
189  {
190  renderingMode = FindProperty(Styles.renderingModeName, props);
191  customRenderingMode = FindProperty(Styles.customRenderingModeName, props);
192  sourceBlend = FindProperty(Styles.sourceBlendName, props);
193  destinationBlend = FindProperty(Styles.destinationBlendName, props);
194  blendOperation = FindProperty(Styles.blendOperationName, props);
195  depthTest = FindProperty(Styles.depthTestName, props);
196  depthWrite = FindProperty(Styles.depthWriteName, props);
197  colorWriteMask = FindProperty(Styles.colorWriteMaskName, props);
198  cullMode = FindProperty("_CullMode", props);
199  renderQueueOverride = FindProperty("_RenderQueueOverride", props);
200  albedoMap = FindProperty("_MainTex", props);
201  albedoColor = FindProperty("_Color", props);
202  albedoAlphaMode = FindProperty("_AlbedoAlphaMode", props);
203  alphaCutoff = FindProperty("_Cutoff", props);
204  metallic = FindProperty("_Metallic", props);
205  smoothness = FindProperty("_Smoothness", props);
206  enableNormalMap = FindProperty("_EnableNormalMap", props);
207  normalMap = FindProperty("_NormalMap", props);
208  enableEmission = FindProperty("_EnableEmission", props);
209  emissiveColor = FindProperty("_EmissiveColor", props);
210  directionalLight = FindProperty("_DirectionalLight", props);
211  specularHighlights = FindProperty("_SpecularHighlights", props);
212  reflections = FindProperty("_Reflections", props);
213  refraction = FindProperty("_Refraction", props);
214  refractiveIndex = FindProperty("_RefractiveIndex", props);
215  rimLight = FindProperty("_RimLight", props);
216  rimColor = FindProperty("_RimColor", props);
217  rimPower = FindProperty("_RimPower", props);
218  clippingPlane = FindProperty("_ClippingPlane", props);
219  clipPlane = FindProperty("_ClipPlane", props);
220  clippingPlaneBorder = FindProperty("_ClippingPlaneBorder", props);
221  clippingPlaneBorderWidth = FindProperty("_ClippingPlaneBorderWidth", props);
222  clippingPlaneBorderColor = FindProperty("_ClippingPlaneBorderColor", props);
223  nearPlaneFade = FindProperty("_NearPlaneFade", props);
224  fadeBeginDistance = FindProperty("_FadeBeginDistance", props);
225  fadeCompleteDistance = FindProperty("_FadeCompleteDistance", props);
226  hoverLight = FindProperty("_HoverLight", props);
227  enableHoverColorOverride = FindProperty("_EnableHoverColorOverride", props);
228  hoverColorOverride = FindProperty("_HoverColorOverride", props);
229  hoverLightOpaque = FindProperty("_HoverLightOpaque", props);
230  enableHoverColorOpaqueOverride = FindProperty("_EnableHoverColorOpaqueOverride", props);
231  hoverColorOverrideOpaque = FindProperty("_HoverColorOpaqueOverride", props);
232  roundCorners = FindProperty("_RoundCorners", props);
233  roundCornerRadius = FindProperty("_RoundCornerRadius", props);
234  roundCornerMargin = FindProperty("_RoundCornerMargin", props);
235  borderLight = FindProperty("_BorderLight", props);
236  borderLightUsesHoverColor = FindProperty("_BorderLightUsesHoverColor", props);
237  borderLightOpaque = FindProperty("_BorderLightOpaque", props);
238  borderWidth = FindProperty("_BorderWidth", props);
239  borderMinValue = FindProperty("_BorderMinValue", props);
240  edgeSmoothingValue = FindProperty("_EdgeSmoothingValue", props);
241  innerGlow = FindProperty("_InnerGlow", props);
242  innerGlowColor = FindProperty("_InnerGlowColor", props);
243  environmentColoring = FindProperty("_EnvironmentColoring", props);
244  environmentColorThreshold = FindProperty("_EnvironmentColorThreshold", props);
245  environmentColorIntensity = FindProperty("_EnvironmentColorIntensity", props);
246  environmentColorX = FindProperty("_EnvironmentColorX", props);
247  environmentColorY = FindProperty("_EnvironmentColorY", props);
248  environmentColorZ = FindProperty("_EnvironmentColorZ", props);
249  }
250 
251  public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
252  {
253  Material material = (Material)materialEditor.target;
254 
255  FindProperties(props);
256  Initialize(material);
257 
258  RenderingModeOptions(materialEditor);
259  MainMapOptions(materialEditor, material);
260  RenderingOptions(materialEditor, material);
261  FluentOptions(materialEditor, material);
262  AdvancedOptions(materialEditor, material);
263  }
264 
265  public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
266  {
267  // Cache old shader properties with potentially different names than the new shader.
268  float? smoothness = GetFloatProperty(material, "_Glossiness");
269  float? diffuse = GetFloatProperty(material, "_UseDiffuse");
270  float? specularHighlights = GetFloatProperty(material, "_SpecularHighlights");
271  float? normalMap = null;
272  Texture normalMapTexture = material.GetTexture("_BumpMap");
273  float? emission = null;
274  Color? emissionColor = GetColorProperty(material, "_EmissionColor");
275  float? reflections = null;
276  float? rimLighting = null;
277  Vector4? textureScaleOffset = null;
278  float? cullMode = GetFloatProperty(material, "_Cull");
279 
280  if (oldShader)
281  {
282  if (oldShader.name.Contains("Standard"))
283  {
284  normalMap = material.IsKeywordEnabled("_NORMALMAP") ? 1.0f : 0.0f;
285  emission = material.IsKeywordEnabled("_EMISSION") ? 1.0f : 0.0f;
286  reflections = GetFloatProperty(material, "_GlossyReflections");
287  }
288  else if (oldShader.name.Contains("Fast Configurable"))
289  {
290  normalMap = material.IsKeywordEnabled("_USEBUMPMAP_ON") ? 1.0f : 0.0f;
291  emission = GetFloatProperty(material, "_UseEmissionColor");
292  reflections = GetFloatProperty(material, "_UseReflections");
293  rimLighting = GetFloatProperty(material, "_UseRimLighting");
294  textureScaleOffset = GetVectorProperty(material, "_TextureScaleOffset");
295  }
296  }
297 
298  base.AssignNewShaderToMaterial(material, oldShader, newShader);
299 
300  // Apply old shader properties to the new shader.
301  SetFloatProperty(material, null, "_Smoothness", smoothness);
302  SetFloatProperty(material, "_DIRECTIONAL_LIGHT", "_DirectionalLight", diffuse);
303  SetFloatProperty(material, "_SPECULAR_HIGHLIGHTS", "_SpecularHighlights", specularHighlights);
304  SetFloatProperty(material, "_NORMAL_MAP", "_EnableNormalMap", normalMap);
305 
306  if (normalMapTexture)
307  {
308  material.SetTexture("_NormalMap", normalMapTexture);
309  }
310 
311  SetFloatProperty(material, "_EMISSION", "_EnableEmission", emission);
312  SetColorProperty(material, "_EmissiveColor", emissionColor);
313  SetFloatProperty(material, "_REFLECTIONS", "_Reflections", reflections);
314  SetFloatProperty(material, "_RIM_LIGHT", "_RimLight", rimLighting);
315  SetVectorProperty(material, "_MainTex_ST", textureScaleOffset);
316  SetFloatProperty(material, null, "_CullMode", cullMode);
317 
318  // Setup the rendering mode based on the old shader.
319  if (oldShader == null || !oldShader.name.Contains("Legacy Shaders/"))
320  {
321  SetupMaterialWithRenderingMode(material, (RenderingMode)material.GetFloat(Styles.renderingModeName), CustomRenderingMode.Opaque, -1);
322  }
323  else
324  {
325  RenderingMode mode = RenderingMode.Opaque;
326 
327  if (oldShader.name.Contains("/Transparent/Cutout/"))
328  {
329  mode = RenderingMode.TransparentCutout;
330  }
331  else if (oldShader.name.Contains("/Transparent/"))
332  {
333  mode = RenderingMode.Transparent;
334  }
335 
336  material.SetFloat(Styles.renderingModeName, (float)mode);
337 
338  MaterialChanged(material);
339  }
340  }
341 
342  protected void Initialize(Material material)
343  {
344  if (!initialized)
345  {
346  MaterialChanged(material);
347  initialized = true;
348  }
349  }
350 
351  protected void MaterialChanged(Material material)
352  {
353  SetupMaterialWithAlbedo(material, albedoMap, albedoAlphaMode);
354  SetupMaterialWithRenderingMode(material, (RenderingMode)renderingMode.floatValue, (CustomRenderingMode)customRenderingMode.floatValue, (int)renderQueueOverride.floatValue);
355  }
356 
357  protected void RenderingModeOptions(MaterialEditor materialEditor)
358  {
359  EditorGUI.BeginChangeCheck();
360 
361  EditorGUI.showMixedValue = renderingMode.hasMixedValue;
362  RenderingMode mode = (RenderingMode)renderingMode.floatValue;
363  EditorGUI.BeginChangeCheck();
364  mode = (RenderingMode)EditorGUILayout.Popup(renderingMode.displayName, (int)mode, Styles.renderingModeNames);
365 
366  if (EditorGUI.EndChangeCheck())
367  {
368  materialEditor.RegisterPropertyChangeUndo(renderingMode.displayName);
369  renderingMode.floatValue = (float)mode;
370  }
371 
372  EditorGUI.showMixedValue = false;
373 
374  if (EditorGUI.EndChangeCheck())
375  {
376  UnityEngine.Object[] targets = renderingMode.targets;
377 
378  foreach (UnityEngine.Object target in targets)
379  {
380  MaterialChanged((Material)target);
381  }
382  }
383 
384  if ((RenderingMode)renderingMode.floatValue == RenderingMode.Custom)
385  {
386  EditorGUI.indentLevel += 2;
387  customRenderingMode.floatValue = EditorGUILayout.Popup(customRenderingMode.displayName, (int)customRenderingMode.floatValue, Styles.customRenderingModeNames);
388  materialEditor.ShaderProperty(sourceBlend, Styles.sourceBlend);
389  materialEditor.ShaderProperty(destinationBlend, Styles.destinationBlend);
390  materialEditor.ShaderProperty(blendOperation, Styles.blendOperation);
391  materialEditor.ShaderProperty(depthTest, Styles.depthTest);
392  depthWrite.floatValue = EditorGUILayout.Popup(depthWrite.displayName, (int)depthWrite.floatValue, Styles.depthWriteNames);
393  materialEditor.ShaderProperty(colorWriteMask, Styles.colorWriteMask);
394  EditorGUI.indentLevel -= 2;
395  }
396 
397  materialEditor.ShaderProperty(cullMode, Styles.cullMode);
398  }
399 
400  protected void MainMapOptions(MaterialEditor materialEditor, Material material)
401  {
402  GUILayout.Label(Styles.primaryMapsTitle, EditorStyles.boldLabel, new GUILayoutOption[0]);
403 
404  materialEditor.TexturePropertySingleLine(Styles.albedo, albedoMap, albedoColor);
405 
406  EditorGUI.indentLevel += 2;
407 
408  albedoAlphaMode.floatValue = EditorGUILayout.Popup(albedoAlphaMode.displayName, (int)albedoAlphaMode.floatValue, Styles.albedoAlphaModeNames);
409 
410  if ((RenderingMode)renderingMode.floatValue == RenderingMode.TransparentCutout)
411  {
412  materialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoff.text);
413  }
414 
415  if ((AlbedoAlphaMode)albedoAlphaMode.floatValue != AlbedoAlphaMode.Metallic)
416  {
417  materialEditor.ShaderProperty(metallic, Styles.metallic);
418  }
419 
420  if ((AlbedoAlphaMode)albedoAlphaMode.floatValue != AlbedoAlphaMode.Smoothness)
421  {
422  materialEditor.ShaderProperty(smoothness, Styles.smoothness);
423  }
424 
425  SetupMaterialWithAlbedo(material, albedoMap, albedoAlphaMode);
426 
427  EditorGUI.indentLevel -= 2;
428 
429  if (PropertyEnabled(directionalLight) ||
430  PropertyEnabled(reflections) ||
431  PropertyEnabled(rimLight) ||
432  PropertyEnabled(environmentColoring))
433  {
434  materialEditor.ShaderProperty(enableNormalMap, Styles.enableNormalMap);
435 
436  if (PropertyEnabled(enableNormalMap))
437  {
438  materialEditor.TexturePropertySingleLine(Styles.normalMap, normalMap);
439  }
440  }
441 
442  materialEditor.ShaderProperty(enableEmission, Styles.enableEmission);
443 
444  if (PropertyEnabled(enableEmission))
445  {
446  materialEditor.ShaderProperty(emissiveColor, Styles.emissiveColor, 2);
447  }
448 
449  EditorGUILayout.Space();
450  materialEditor.TextureScaleOffsetProperty(albedoMap);
451  }
452 
453  protected void RenderingOptions(MaterialEditor materialEditor, Material material)
454  {
455  EditorGUILayout.Space();
456  GUILayout.Label(Styles.renderingOptionsTitle, EditorStyles.boldLabel, new GUILayoutOption[0]);
457 
458  materialEditor.ShaderProperty(directionalLight, Styles.directionalLight);
459 
460  if (PropertyEnabled(directionalLight))
461  {
462  materialEditor.ShaderProperty(specularHighlights, Styles.specularHighlights, 2);
463  }
464 
465  materialEditor.ShaderProperty(reflections, Styles.reflections);
466 
467  if (PropertyEnabled(reflections))
468  {
469  materialEditor.ShaderProperty(refraction, Styles.refraction, 2);
470 
471  if (PropertyEnabled(refraction))
472  {
473  materialEditor.ShaderProperty(refractiveIndex, Styles.refractiveIndex, 4);
474  }
475  }
476 
477  materialEditor.ShaderProperty(rimLight, Styles.rimLight);
478 
479  if (PropertyEnabled(rimLight))
480  {
481  materialEditor.ShaderProperty(rimColor, Styles.rimColor, 2);
482  materialEditor.ShaderProperty(rimPower, Styles.rimPower, 2);
483  }
484 
485  materialEditor.ShaderProperty(clippingPlane, Styles.clippingPlane);
486 
487  if (PropertyEnabled(clippingPlane))
488  {
489  materialEditor.ShaderProperty(clipPlane, Styles.clipPlane, 2);
490  materialEditor.ShaderProperty(clippingPlaneBorder, Styles.clippingPlaneBorder, 2);
491 
492  if (PropertyEnabled(clippingPlaneBorder))
493  {
494  materialEditor.ShaderProperty(clippingPlaneBorderWidth, Styles.clippingPlaneBorderWidth, 4);
495  materialEditor.ShaderProperty(clippingPlaneBorderColor, Styles.clippingPlaneBorderColor, 4);
496  }
497  }
498 
499  materialEditor.ShaderProperty(nearPlaneFade, Styles.nearPlaneFade);
500 
501  if (PropertyEnabled(nearPlaneFade))
502  {
503  materialEditor.ShaderProperty(fadeBeginDistance, Styles.fadeBeginDistance, 2);
504  materialEditor.ShaderProperty(fadeCompleteDistance, Styles.fadeCompleteDistance, 2);
505  }
506  }
507 
508  protected void FluentOptions(MaterialEditor materialEditor, Material material)
509  {
510  EditorGUILayout.Space();
511  GUILayout.Label(Styles.fluentOptionsTitle, EditorStyles.boldLabel, new GUILayoutOption[0]);
512  RenderingMode mode = (RenderingMode)renderingMode.floatValue;
513  CustomRenderingMode customMode = (CustomRenderingMode)customRenderingMode.floatValue;
514 
515  materialEditor.ShaderProperty(hoverLight, Styles.hoverLight);
516 
517  if (PropertyEnabled(hoverLight))
518  {
519  materialEditor.ShaderProperty(enableHoverColorOverride, Styles.enableHoverColorOverride, 2);
520 
521  if (PropertyEnabled(enableHoverColorOverride))
522  {
523  materialEditor.ShaderProperty(hoverColorOverride, Styles.hoverColorOverride, 4);
524  }
525 
526  if (mode == RenderingMode.Transparent || (mode == RenderingMode.Custom && customMode == CustomRenderingMode.Transparent))
527  {
528  materialEditor.ShaderProperty(hoverLightOpaque, Styles.hoverLightOpaque, 2);
529  }
530 
531  if (PropertyEnabled(hoverLightOpaque))
532  {
533  materialEditor.ShaderProperty(enableHoverColorOpaqueOverride, Styles.enableHoverColorOpaqueOverride, 4);
534 
535  if (PropertyEnabled(enableHoverColorOpaqueOverride))
536  {
537  materialEditor.ShaderProperty(hoverColorOverrideOpaque, Styles.hoverColorOpaqueOverride, 6);
538  }
539  }
540  }
541 
542  materialEditor.ShaderProperty(roundCorners, Styles.roundCorners);
543 
544  if (PropertyEnabled(roundCorners))
545  {
546  materialEditor.ShaderProperty(roundCornerRadius, Styles.roundCornerRadius, 2);
547  materialEditor.ShaderProperty(roundCornerMargin, Styles.roundCornerMargin, 2);
548  }
549 
550  materialEditor.ShaderProperty(borderLight, Styles.borderLight);
551 
552  if (PropertyEnabled(borderLight))
553  {
554  if (PropertyEnabled(hoverLight))
555  {
556  materialEditor.ShaderProperty(borderLightUsesHoverColor, Styles.borderLightUsesHoverColor, 2);
557  }
558 
559  if (mode == RenderingMode.TransparentCutout || mode == RenderingMode.Transparent ||
560  (mode == RenderingMode.Custom && customMode == CustomRenderingMode.TransparentCutout) ||
561  (mode == RenderingMode.Custom && customMode == CustomRenderingMode.Transparent))
562  {
563  materialEditor.ShaderProperty(borderLightOpaque, Styles.borderLightOpaque, 2);
564  }
565 
566  materialEditor.ShaderProperty(borderWidth, Styles.borderWidth, 2);
567 
568  if (!PropertyEnabled(borderLightOpaque))
569  {
570  materialEditor.ShaderProperty(borderMinValue, Styles.borderMinValue, 2);
571  }
572  }
573 
574  if (PropertyEnabled(roundCorners) || PropertyEnabled(borderLight))
575  {
576  materialEditor.ShaderProperty(edgeSmoothingValue, Styles.edgeSmoothingValue);
577  }
578 
579  materialEditor.ShaderProperty(innerGlow, Styles.innerGlow);
580 
581  if (PropertyEnabled(innerGlow))
582  {
583  materialEditor.ShaderProperty(innerGlowColor, Styles.innerGlowColor, 2);
584  }
585 
586  materialEditor.ShaderProperty(environmentColoring, Styles.environmentColoring);
587 
588  if (PropertyEnabled(environmentColoring))
589  {
590  materialEditor.ShaderProperty(environmentColorThreshold, Styles.environmentColorThreshold, 2);
591  materialEditor.ShaderProperty(environmentColorIntensity, Styles.environmentColorIntensity, 2);
592  materialEditor.ShaderProperty(environmentColorX, Styles.environmentColorX, 2);
593  materialEditor.ShaderProperty(environmentColorY, Styles.environmentColorY, 2);
594  materialEditor.ShaderProperty(environmentColorZ, Styles.environmentColorZ, 2);
595  }
596  }
597 
598  protected void AdvancedOptions(MaterialEditor materialEditor, Material material)
599  {
600  EditorGUILayout.Space();
601  GUILayout.Label(Styles.advancedOptionsTitle, EditorStyles.boldLabel, new GUILayoutOption[0]);
602 
603  EditorGUI.BeginChangeCheck();
604 
605  materialEditor.ShaderProperty(renderQueueOverride, Styles.renderQueueOverride);
606 
607  if (EditorGUI.EndChangeCheck())
608  {
609  MaterialChanged(material);
610  }
611 
612  // Show the RenderQueueField but do not allow users to directly manipulate it. That is done via the renderQueueOverride.
613  GUI.enabled = false;
614  materialEditor.RenderQueueField();
615 
616  // When round corner or border light features are used, enable instancing to disable batching. Static and dynamic
617  // batching will normalize the object scale, which breaks border related features.
618  GUI.enabled = !PropertyEnabled(roundCorners) && !PropertyEnabled(borderLight);
619 
620  if (!GUI.enabled && !material.enableInstancing)
621  {
622  material.enableInstancing = true;
623  }
624 
625  materialEditor.EnableInstancingField();
626  }
627 
628  protected static void SetupMaterialWithAlbedo(Material material, MaterialProperty albedoMap, MaterialProperty albedoAlphaMode)
629  {
630  if (albedoMap.textureValue)
631  {
632  material.DisableKeyword(Styles.disableAlbedoMapName);
633  }
634  else
635  {
636  material.EnableKeyword(Styles.disableAlbedoMapName);
637  }
638 
639  switch ((AlbedoAlphaMode)albedoAlphaMode.floatValue)
640  {
641  case AlbedoAlphaMode.Transparency:
642  {
643  material.DisableKeyword(Styles.albedoMapAlphaMetallicName);
644  material.DisableKeyword(Styles.albedoMapAlphaSmoothnessName);
645  }
646  break;
647 
648  case AlbedoAlphaMode.Metallic:
649  {
650  material.EnableKeyword(Styles.albedoMapAlphaMetallicName);
651  material.DisableKeyword(Styles.albedoMapAlphaSmoothnessName);
652  }
653  break;
654 
655  case AlbedoAlphaMode.Smoothness:
656  {
657  material.DisableKeyword(Styles.albedoMapAlphaMetallicName);
658  material.EnableKeyword(Styles.albedoMapAlphaSmoothnessName);
659  }
660  break;
661  }
662  }
663 
664  protected static void SetupMaterialWithRenderingMode(Material material, RenderingMode mode, CustomRenderingMode customMode, int renderQueueOverride)
665  {
666  switch (mode)
667  {
668  case RenderingMode.Opaque:
669  {
670  material.SetOverrideTag(Styles.renderTypeName, Styles.renderingModeNames[(int)RenderingMode.Opaque]);
671  material.SetInt(Styles.customRenderingModeName, (int)CustomRenderingMode.Opaque);
672  material.SetInt(Styles.sourceBlendName, (int)UnityEngine.Rendering.BlendMode.One);
673  material.SetInt(Styles.destinationBlendName, (int)UnityEngine.Rendering.BlendMode.Zero);
674  material.SetInt(Styles.blendOperationName, (int)UnityEngine.Rendering.BlendOp.Add);
675  material.SetInt(Styles.depthTestName, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
676  material.SetInt(Styles.depthWriteName, (int)DepthWrite.On);
677  material.SetInt(Styles.colorWriteMaskName, (int)UnityEngine.Rendering.ColorWriteMask.All);
678  material.DisableKeyword(Styles.alphaTestOnName);
679  material.DisableKeyword(Styles.alphaBlendOnName);
680  material.renderQueue = (renderQueueOverride >= 0) ? renderQueueOverride : (int)UnityEngine.Rendering.RenderQueue.Geometry;
681  }
682  break;
683 
684  case RenderingMode.TransparentCutout:
685  {
686  material.SetOverrideTag(Styles.renderTypeName, Styles.renderingModeNames[(int)RenderingMode.TransparentCutout]);
687  material.SetInt(Styles.customRenderingModeName, (int)CustomRenderingMode.TransparentCutout);
688  material.SetInt(Styles.sourceBlendName, (int)UnityEngine.Rendering.BlendMode.One);
689  material.SetInt(Styles.destinationBlendName, (int)UnityEngine.Rendering.BlendMode.Zero);
690  material.SetInt(Styles.blendOperationName, (int)UnityEngine.Rendering.BlendOp.Add);
691  material.SetInt(Styles.depthTestName, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
692  material.SetInt(Styles.depthWriteName, (int)DepthWrite.On);
693  material.SetInt(Styles.colorWriteMaskName, (int)UnityEngine.Rendering.ColorWriteMask.All);
694  material.EnableKeyword(Styles.alphaTestOnName);
695  material.DisableKeyword(Styles.alphaBlendOnName);
696  material.renderQueue = (renderQueueOverride >= 0) ? renderQueueOverride : (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
697  }
698  break;
699 
700  case RenderingMode.Transparent:
701  {
702  material.SetOverrideTag(Styles.renderTypeName, Styles.renderingModeNames[(int)RenderingMode.Transparent]);
703  material.SetInt(Styles.customRenderingModeName, (int)CustomRenderingMode.Transparent);
704  material.SetInt(Styles.sourceBlendName, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
705  material.SetInt(Styles.destinationBlendName, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
706  material.SetInt(Styles.blendOperationName, (int)UnityEngine.Rendering.BlendOp.Add);
707  material.SetInt(Styles.depthTestName, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
708  material.SetInt(Styles.depthWriteName, (int)DepthWrite.Off);
709  material.SetInt(Styles.colorWriteMaskName, (int)UnityEngine.Rendering.ColorWriteMask.All);
710  material.DisableKeyword(Styles.alphaTestOnName);
711  material.EnableKeyword(Styles.alphaBlendOnName);
712  material.renderQueue = (renderQueueOverride >= 0) ? renderQueueOverride : (int)UnityEngine.Rendering.RenderQueue.Transparent;
713  }
714  break;
715 
716  case RenderingMode.PremultipliedTransparent:
717  {
718  material.SetOverrideTag(Styles.renderTypeName, Styles.renderingModeNames[(int)RenderingMode.Transparent]);
719  material.SetInt(Styles.customRenderingModeName, (int)CustomRenderingMode.Transparent);
720  material.SetInt(Styles.sourceBlendName, (int)UnityEngine.Rendering.BlendMode.One);
721  material.SetInt(Styles.destinationBlendName, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
722  material.SetInt(Styles.blendOperationName, (int)UnityEngine.Rendering.BlendOp.Add);
723  material.SetInt(Styles.depthTestName, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
724  material.SetInt(Styles.depthWriteName, (int)DepthWrite.Off);
725  material.SetInt(Styles.colorWriteMaskName, (int)UnityEngine.Rendering.ColorWriteMask.All);
726  material.DisableKeyword(Styles.alphaTestOnName);
727  material.EnableKeyword(Styles.alphaBlendOnName);
728  material.renderQueue = (renderQueueOverride >= 0) ? renderQueueOverride : (int)UnityEngine.Rendering.RenderQueue.Transparent;
729  }
730  break;
731 
732  case RenderingMode.Additive:
733  {
734  material.SetOverrideTag(Styles.renderTypeName, Styles.renderingModeNames[(int)RenderingMode.Transparent]);
735  material.SetInt(Styles.customRenderingModeName, (int)CustomRenderingMode.Transparent);
736  material.SetInt(Styles.sourceBlendName, (int)UnityEngine.Rendering.BlendMode.One);
737  material.SetInt(Styles.destinationBlendName, (int)UnityEngine.Rendering.BlendMode.One);
738  material.SetInt(Styles.blendOperationName, (int)UnityEngine.Rendering.BlendOp.Add);
739  material.SetInt(Styles.depthTestName, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
740  material.SetInt(Styles.depthWriteName, (int)DepthWrite.Off);
741  material.SetInt(Styles.colorWriteMaskName, (int)UnityEngine.Rendering.ColorWriteMask.All);
742  material.DisableKeyword(Styles.alphaTestOnName);
743  material.EnableKeyword(Styles.alphaBlendOnName);
744  material.renderQueue = (renderQueueOverride >= 0) ? renderQueueOverride : (int)UnityEngine.Rendering.RenderQueue.Transparent;
745  }
746  break;
747 
748  case RenderingMode.Custom:
749  {
750  material.SetOverrideTag(Styles.renderTypeName, Styles.customRenderingModeNames[(int)customMode]);
751  // _SrcBlend, _DstBlend, _BlendOp, _ZTest, _ZWrite, _ColorWriteMask are controlled by UI.
752 
753  switch (customMode)
754  {
755  case CustomRenderingMode.Opaque:
756  {
757 
758  material.DisableKeyword(Styles.alphaTestOnName);
759  material.DisableKeyword(Styles.alphaBlendOnName);
760  }
761  break;
762 
763  case CustomRenderingMode.TransparentCutout:
764  {
765  material.EnableKeyword(Styles.alphaTestOnName);
766  material.DisableKeyword(Styles.alphaBlendOnName);
767  }
768  break;
769 
770  case CustomRenderingMode.Transparent:
771  {
772  material.DisableKeyword(Styles.alphaTestOnName);
773  material.EnableKeyword(Styles.alphaBlendOnName);
774  }
775  break;
776  }
777 
778  material.renderQueue = (renderQueueOverride >= 0) ? renderQueueOverride : material.renderQueue;
779  }
780  break;
781  }
782  }
783 
784  protected static bool PropertyEnabled(MaterialProperty property)
785  {
786  return (property.floatValue != 0.0f);
787  }
788 
789  protected static float? GetFloatProperty(Material material, string propertyName)
790  {
791  if (material.HasProperty(propertyName))
792  {
793  return material.GetFloat(propertyName);
794  }
795 
796  return null;
797  }
798 
799  protected static Vector4? GetVectorProperty(Material material, string propertyName)
800  {
801  if (material.HasProperty(propertyName))
802  {
803  return material.GetVector(propertyName);
804  }
805 
806  return null;
807  }
808 
809  protected static Color? GetColorProperty(Material material, string propertyName)
810  {
811  if (material.HasProperty(propertyName))
812  {
813  return material.GetColor(propertyName);
814  }
815 
816  return null;
817  }
818 
819  protected static void SetFloatProperty(Material material, string keywordName, string propertyName, float? propertyValue)
820  {
821  if (propertyValue.HasValue)
822  {
823  if (keywordName != null)
824  {
825  if (propertyValue.Value != 0.0f)
826  {
827  material.EnableKeyword(keywordName);
828  }
829  else
830  {
831  material.DisableKeyword(keywordName);
832  }
833  }
834 
835  material.SetFloat(propertyName, propertyValue.Value);
836  }
837  }
838 
839  protected static void SetVectorProperty(Material material, string propertyName, Vector4? propertyValue)
840  {
841  if (propertyValue.HasValue)
842  {
843  material.SetVector(propertyName, propertyValue.Value);
844  }
845  }
846 
847  protected static void SetColorProperty(Material material, string propertyName, Color? propertyValue)
848  {
849  if (propertyValue.HasValue)
850  {
851  material.SetColor(propertyName, propertyValue.Value);
852  }
853  }
854  }
855 }
void MainMapOptions(MaterialEditor materialEditor, Material material)
void AdvancedOptions(MaterialEditor materialEditor, Material material)
static void SetVectorProperty(Material material, string propertyName, Vector4? propertyValue)
static bool PropertyEnabled(MaterialProperty property)
static readonly string [] renderingModeNames
override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
A custom shader inspector for the "MixedRealityToolkit/Standard" shader.
static void SetFloatProperty(Material material, string keywordName, string propertyName, float? propertyValue)
void RenderingOptions(MaterialEditor materialEditor, Material material)
static void SetColorProperty(Material material, string propertyName, Color? propertyValue)
static float GetFloatProperty(Material material, string propertyName)
static Color GetColorProperty(Material material, string propertyName)
static readonly string [] customRenderingModeNames
static void SetupMaterialWithAlbedo(Material material, MaterialProperty albedoMap, MaterialProperty albedoAlphaMode)
static readonly string [] albedoAlphaModeNames
static Vector4 GetVectorProperty(Material material, string propertyName)
void MaterialChanged(Material material)
void FluentOptions(MaterialEditor materialEditor, Material material)
static void SetupMaterialWithRenderingMode(Material material, RenderingMode mode, CustomRenderingMode customMode, int renderQueueOverride)
void FindProperties(MaterialProperty[] props)
override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
void RenderingModeOptions(MaterialEditor materialEditor)