您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
191 行
7.4 KiB
191 行
7.4 KiB
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Experimental.Rendering.HDPipeline;
|
|
|
|
using System.Linq;
|
|
|
|
namespace UnityEditor.Experimental.Rendering.HDPipeline
|
|
{
|
|
public class TerrainLitGUI : LitGUI
|
|
{
|
|
private class StylesLayer
|
|
{
|
|
public readonly GUIContent layersText = new GUIContent("Inputs");
|
|
public readonly GUIContent layerMapMaskText = new GUIContent("Layer Mask", "Layer mask");
|
|
public readonly GUIContent useHeightBasedBlendText = new GUIContent("Use Height Based Blend", "Layer will be blended with the underlying layer based on the height.");
|
|
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
|
|
}
|
|
|
|
static StylesLayer s_Styles = null;
|
|
private static StylesLayer styles { get { if (s_Styles == null) s_Styles = new StylesLayer(); return s_Styles; } }
|
|
|
|
public TerrainLitGUI()
|
|
{
|
|
m_PropertySuffixes[0] = "0";
|
|
m_PropertySuffixes[1] = "1";
|
|
m_PropertySuffixes[2] = "2";
|
|
m_PropertySuffixes[3] = "3";
|
|
}
|
|
|
|
// Layer options
|
|
MaterialProperty useHeightBasedBlend = null;
|
|
const string kUseHeightBasedBlend = "_UseHeightBasedBlend";
|
|
|
|
// Density/opacity mode
|
|
MaterialProperty[] opacityAsDensity = new MaterialProperty[kMaxLayerCount];
|
|
const string kOpacityAsDensity = "_OpacityAsDensity";
|
|
|
|
// Height blend
|
|
MaterialProperty heightTransition = null;
|
|
const string kHeightTransition = "_HeightTransition";
|
|
|
|
bool m_UseHeightBasedBlend;
|
|
|
|
protected override void FindMaterialProperties(MaterialProperty[] props)
|
|
{
|
|
useHeightBasedBlend = FindProperty(kUseHeightBasedBlend, props);
|
|
heightTransition = FindProperty(kHeightTransition, props);
|
|
|
|
for (int i = 0; i < kMaxLayerCount; ++i)
|
|
{
|
|
// Density/opacity mode
|
|
opacityAsDensity[i] = FindProperty(string.Format("{0}{1}", kOpacityAsDensity, i), props);
|
|
}
|
|
}
|
|
|
|
// We use the user data to save a string that represent the referenced lit material
|
|
// so we can keep reference during serialization
|
|
void DoLayeringInputGUI()
|
|
{
|
|
EditorGUI.indentLevel++;
|
|
GUILayout.Label(styles.layersText, EditorStyles.boldLabel);
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = useHeightBasedBlend.hasMixedValue;
|
|
m_UseHeightBasedBlend = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend.floatValue > 0.0f);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
useHeightBasedBlend.floatValue = m_UseHeightBasedBlend ? 1.0f : 0.0f;
|
|
}
|
|
|
|
if (m_UseHeightBasedBlend)
|
|
{
|
|
EditorGUI.indentLevel++;
|
|
m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
|
|
bool DoLayersGUI(AssetImporter materialImporter)
|
|
{
|
|
bool layerChanged = false;
|
|
|
|
GUI.changed = false;
|
|
|
|
DoLayeringInputGUI();
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
layerChanged |= GUI.changed;
|
|
GUI.changed = false;
|
|
|
|
return layerChanged;
|
|
}
|
|
|
|
protected override bool ShouldEmissionBeEnabled(Material mat)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
protected override void SetupMaterialKeywordsAndPassInternal(Material material)
|
|
{
|
|
SetupMaterialKeywordsAndPass(material);
|
|
}
|
|
|
|
static public void SetupLayersMappingKeywords(Material material)
|
|
{
|
|
const string kLayerMappingPlanar = "_LAYER_MAPPING_PLANAR";
|
|
const string kLayerMappingTriplanar = "_LAYER_MAPPING_TRIPLANAR";
|
|
|
|
for (int i = 0; i < kMaxLayerCount; ++i)
|
|
{
|
|
string layerUVBaseParam = string.Format("{0}{1}", kUVBase, i);
|
|
UVBaseMapping layerUVBaseMapping = (UVBaseMapping)material.GetFloat(layerUVBaseParam);
|
|
string currentLayerMappingPlanar = string.Format("{0}{1}", kLayerMappingPlanar, i);
|
|
CoreUtils.SetKeyword(material, currentLayerMappingPlanar, layerUVBaseMapping == UVBaseMapping.Planar);
|
|
string currentLayerMappingTriplanar = string.Format("{0}{1}", kLayerMappingTriplanar, i);
|
|
CoreUtils.SetKeyword(material, currentLayerMappingTriplanar, layerUVBaseMapping == UVBaseMapping.Triplanar);
|
|
}
|
|
}
|
|
|
|
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change
|
|
static new public void SetupMaterialKeywordsAndPass(Material material)
|
|
{
|
|
SetupBaseLitKeywords(material);
|
|
SetupBaseLitMaterialPass(material);
|
|
|
|
// TODO: planar/triplannar supprt
|
|
//SetupLayersMappingKeywords(material);
|
|
|
|
for (int i = 0; i < kMaxLayerCount; ++i)
|
|
{
|
|
CoreUtils.SetKeyword(material, "_NORMALMAP" + i, material.GetTexture(kNormalMap + i) || material.GetTexture(kDetailMap + i));
|
|
|
|
CoreUtils.SetKeyword(material, "_MASKMAP" + i, material.GetTexture(kMaskMap + i));
|
|
|
|
CoreUtils.SetKeyword(material, "_HEIGHTMAP" + i, material.GetTexture(kHeightMap + i));
|
|
|
|
CoreUtils.SetKeyword(material, "_THICKNESSMAP" + i, material.GetTexture(kThicknessMap + i));
|
|
}
|
|
|
|
bool useHeightBasedBlend = material.GetFloat(kUseHeightBasedBlend) != 0.0f;
|
|
CoreUtils.SetKeyword(material, "_HEIGHT_BASED_BLEND", useHeightBasedBlend);
|
|
}
|
|
|
|
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
|
|
{
|
|
FindBaseMaterialProperties(props);
|
|
FindMaterialProperties(props);
|
|
|
|
m_MaterialEditor = materialEditor;
|
|
// We should always do this call at the beginning
|
|
m_MaterialEditor.serializedObject.Update();
|
|
|
|
Material material = m_MaterialEditor.target as Material;
|
|
AssetImporter materialImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material.GetInstanceID()));
|
|
|
|
bool optionsChanged = false;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
BaseMaterialPropertiesGUI();
|
|
EditorGUILayout.Space();
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
optionsChanged = true;
|
|
}
|
|
|
|
bool layerChanged = DoLayersGUI(materialImporter);
|
|
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.LabelField(StylesBaseUnlit.advancedText, EditorStyles.boldLabel);
|
|
// NB RenderQueue editor is not shown on purpose: we want to override it based on blend mode
|
|
EditorGUI.indentLevel++;
|
|
m_MaterialEditor.EnableInstancingField();
|
|
EditorGUI.indentLevel--;
|
|
|
|
if (layerChanged || optionsChanged)
|
|
{
|
|
foreach (var obj in m_MaterialEditor.targets)
|
|
{
|
|
SetupMaterialKeywordsAndPassInternal((Material)obj);
|
|
}
|
|
}
|
|
|
|
// We should always do this call at the end
|
|
m_MaterialEditor.serializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
} // namespace UnityEditor
|