Flatkit 추가 및 설정
This commit is contained in:
58
Assets/FlatKit/Shaders/Editor/MaterialPropertyExtensions.cs
Normal file
58
Assets/FlatKit/Shaders/Editor/MaterialPropertyExtensions.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace FlatKit.Editor {
|
||||
internal static class MaterialPropertyExtensions {
|
||||
public static ShaderPropertyType GetShaderPropertyType(this MaterialProperty property) {
|
||||
#if UNITY_6000_2_OR_NEWER
|
||||
return property.propertyType;
|
||||
#else
|
||||
return property.type switch {
|
||||
MaterialProperty.PropType.Color => ShaderPropertyType.Color,
|
||||
MaterialProperty.PropType.Vector => ShaderPropertyType.Vector,
|
||||
MaterialProperty.PropType.Float => ShaderPropertyType.Float,
|
||||
MaterialProperty.PropType.Range => ShaderPropertyType.Range,
|
||||
MaterialProperty.PropType.Texture => ShaderPropertyType.Texture,
|
||||
_ => ShaderPropertyType.Float,
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
public static ShaderPropertyFlags GetShaderPropertyFlags(this MaterialProperty property) {
|
||||
#if UNITY_6000_2_OR_NEWER
|
||||
return property.propertyFlags;
|
||||
#else
|
||||
var flags = ShaderPropertyFlags.None;
|
||||
if ((property.flags & MaterialProperty.PropFlags.HideInInspector) != 0) {
|
||||
flags |= ShaderPropertyFlags.HideInInspector;
|
||||
}
|
||||
|
||||
if ((property.flags & MaterialProperty.PropFlags.NoScaleOffset) != 0) {
|
||||
flags |= ShaderPropertyFlags.NoScaleOffset;
|
||||
}
|
||||
|
||||
if ((property.flags & MaterialProperty.PropFlags.PerRendererData) != 0) {
|
||||
flags |= ShaderPropertyFlags.PerRendererData;
|
||||
}
|
||||
|
||||
if ((property.flags & MaterialProperty.PropFlags.Normal) != 0) {
|
||||
flags |= ShaderPropertyFlags.Normal;
|
||||
}
|
||||
|
||||
if ((property.flags & MaterialProperty.PropFlags.HDR) != 0) {
|
||||
flags |= ShaderPropertyFlags.HDR;
|
||||
}
|
||||
|
||||
if ((property.flags & MaterialProperty.PropFlags.Gamma) != 0) {
|
||||
flags |= ShaderPropertyFlags.Gamma;
|
||||
}
|
||||
|
||||
if ((property.flags & MaterialProperty.PropFlags.NonModifiableTextureData) != 0) {
|
||||
flags |= ShaderPropertyFlags.NonModifiableTextureData;
|
||||
}
|
||||
|
||||
return flags;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d3efcc567a614203b135261649ee197
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
126
Assets/FlatKit/Shaders/Editor/ObjectOutlineEditorUtils.cs
Normal file
126
Assets/FlatKit/Shaders/Editor/ObjectOutlineEditorUtils.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using FlatKit;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public static class ObjectOutlineEditorUtils {
|
||||
private static readonly GUIStyle RichHelpBoxStyle = new(EditorStyles.helpBox) { richText = true };
|
||||
|
||||
public static void SetActive(Material material, bool active) {
|
||||
// Work directly with the active URP Renderer Data to avoid dependency on a Camera context.
|
||||
var rendererData = GetRendererData();
|
||||
if (rendererData == null) {
|
||||
const string m = "<b>ScriptableRendererData</b> is required to manage per-object outlines.\n" +
|
||||
"Please assign a <b>URP Asset</b> in the Graphics settings.";
|
||||
EditorGUILayout.LabelField(m, RichHelpBoxStyle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find existing feature on the renderer data.
|
||||
var feature = rendererData.rendererFeatures
|
||||
.FirstOrDefault(f => f != null && f.GetType() == typeof(ObjectOutlineRendererFeature));
|
||||
|
||||
// Create feature on demand when enabling outlines.
|
||||
if (feature == null && active) {
|
||||
feature = ScriptableObject.CreateInstance<ObjectOutlineRendererFeature>();
|
||||
feature.name = "Flat Kit Per Object Outline";
|
||||
AddRendererFeature(rendererData, feature);
|
||||
|
||||
var addedMsg = $"<color=grey>[Flat Kit]</color> <b>Added</b> <color=green>{feature.name}</color> Renderer " +
|
||||
$"Feature to <b>{rendererData.name}</b>.";
|
||||
Debug.Log(addedMsg, rendererData);
|
||||
}
|
||||
|
||||
// If disabling and there's no feature, nothing to do.
|
||||
if (feature == null) return;
|
||||
|
||||
// Register/unregister the material and check usage.
|
||||
if (feature is not ObjectOutlineRendererFeature outlineFeature) {
|
||||
Debug.LogError("ObjectOutlineRendererFeature not found");
|
||||
return;
|
||||
}
|
||||
|
||||
var featureIsUsed = outlineFeature.RegisterMaterial(material, active);
|
||||
|
||||
// Remove the feature asset if no materials are using it anymore.
|
||||
if (!featureIsUsed) {
|
||||
RemoveRendererFeature(rendererData, feature);
|
||||
var removedMsg = $"<color=grey>[Flat Kit]</color> <b>Removed</b> <color=green>{feature.name}</color> Renderer " +
|
||||
$"Feature from <b>{rendererData.name}</b> because no materials are using it.";
|
||||
Debug.Log(removedMsg, rendererData);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddRendererFeature(ScriptableRendererData rendererData, ScriptableRendererFeature feature) {
|
||||
// Save the asset as a sub-asset.
|
||||
AssetDatabase.AddObjectToAsset(feature, rendererData);
|
||||
rendererData.rendererFeatures.Add(feature);
|
||||
rendererData.SetDirty();
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private static void RemoveRendererFeature(ScriptableRendererData rendererData, ScriptableRendererFeature feature) {
|
||||
rendererData.rendererFeatures.Remove(feature);
|
||||
rendererData.SetDirty();
|
||||
|
||||
// Remove the asset.
|
||||
AssetDatabase.RemoveObjectFromAsset(feature);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
[CanBeNull]
|
||||
private static ScriptableRenderer GetRenderer(Camera camera) {
|
||||
if (!camera) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var additionalCameraData = camera.GetComponent<UniversalAdditionalCameraData>();
|
||||
if (!additionalCameraData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var renderer = additionalCameraData.scriptableRenderer;
|
||||
return renderer;
|
||||
}
|
||||
|
||||
private static List<ScriptableRendererFeature> GetRendererFeatures(ScriptableRenderer renderer) {
|
||||
var property =
|
||||
typeof(ScriptableRenderer).GetProperty("rendererFeatures", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (property == null) return null;
|
||||
var features = property.GetValue(renderer) as List<ScriptableRendererFeature>;
|
||||
return features;
|
||||
}
|
||||
|
||||
internal static ScriptableRendererData GetRendererData() {
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
var srpAsset = GraphicsSettings.defaultRenderPipeline;
|
||||
#else
|
||||
var srpAsset = GraphicsSettings.renderPipelineAsset;
|
||||
#endif
|
||||
if (srpAsset == null) {
|
||||
const string m = "<b>Flat Kit</b> No SRP asset found. Please assign a URP Asset in the Graphics settings " +
|
||||
"to enable per-object outlines.";
|
||||
Debug.LogError(m);
|
||||
return null;
|
||||
}
|
||||
|
||||
var field = typeof(UniversalRenderPipelineAsset).GetField("m_RendererDataList",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var rendererDataList = (ScriptableRendererData[])field!.GetValue(srpAsset);
|
||||
|
||||
var rendererData = rendererDataList.FirstOrDefault();
|
||||
if (rendererData == null) {
|
||||
Debug.LogError("No ScriptableRendererData found");
|
||||
return null;
|
||||
}
|
||||
|
||||
return rendererData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b52ec40d323041e7b931cd4b15ec8306
|
||||
timeCreated: 1720322479
|
||||
1026
Assets/FlatKit/Shaders/Editor/StylizedSurfaceEditor.cs
Normal file
1026
Assets/FlatKit/Shaders/Editor/StylizedSurfaceEditor.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bde8f608f6b473fb5938a0a218648cf
|
||||
timeCreated: 1551041742
|
||||
320
Assets/FlatKit/Shaders/Editor/TerrainEditor.cs
Normal file
320
Assets/FlatKit/Shaders/Editor/TerrainEditor.cs
Normal file
@@ -0,0 +1,320 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace FlatKit {
|
||||
public class TerrainEditor : StylizedSurfaceEditor, ITerrainLayerCustomUI {
|
||||
private class StylesLayer
|
||||
{
|
||||
public readonly GUIContent warningHeightBasedBlending = new GUIContent("Height-based blending is disabled if you have more than four TerrainLayer materials!");
|
||||
|
||||
public readonly GUIContent enableHeightBlend = new GUIContent("Enable Height-based Blend", "Blend terrain layers based on height values.");
|
||||
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
|
||||
public readonly GUIContent enableInstancedPerPixelNormal = new GUIContent("Enable Per-pixel Normal", "Enable per-pixel normal when the terrain uses instanced rendering.");
|
||||
|
||||
public readonly GUIContent diffuseTexture = new GUIContent("Diffuse");
|
||||
public readonly GUIContent colorTint = new GUIContent("Color Tint");
|
||||
public readonly GUIContent opacityAsDensity = new GUIContent("Opacity as Density", "Enable Density Blend (if unchecked, opacity is used as Smoothness)");
|
||||
public readonly GUIContent normalMapTexture = new GUIContent("Normal Map");
|
||||
public readonly GUIContent normalScale = new GUIContent("Normal Scale");
|
||||
public readonly GUIContent maskMapTexture = new GUIContent("Mask", "R: Metallic\nG: AO\nB: Height\nA: Smoothness");
|
||||
public readonly GUIContent maskMapTextureWithoutHeight = new GUIContent("Mask Map", "R: Metallic\nG: AO\nA: Smoothness");
|
||||
public readonly GUIContent channelRemapping = new GUIContent("Channel Remapping");
|
||||
public readonly GUIContent defaultValues = new GUIContent("Channel Default Values");
|
||||
public readonly GUIContent metallic = new GUIContent("R: Metallic");
|
||||
public readonly GUIContent ao = new GUIContent("G: AO");
|
||||
public readonly GUIContent height = new GUIContent("B: Height");
|
||||
public readonly GUIContent heightParametrization = new GUIContent("Parametrization");
|
||||
public readonly GUIContent heightAmplitude = new GUIContent("Amplitude (cm)");
|
||||
public readonly GUIContent heightBase = new GUIContent("Base (cm)");
|
||||
public readonly GUIContent heightMin = new GUIContent("Min (cm)");
|
||||
public readonly GUIContent heightMax = new GUIContent("Max (cm)");
|
||||
public readonly GUIContent heightCm = new GUIContent("B: Height (cm)");
|
||||
public readonly GUIContent smoothness = new GUIContent("A: Smoothness");
|
||||
}
|
||||
|
||||
static StylesLayer s_Styles = null;
|
||||
|
||||
private static StylesLayer styles {
|
||||
get {
|
||||
if (s_Styles == null) s_Styles = new StylesLayer();
|
||||
return s_Styles;
|
||||
}
|
||||
}
|
||||
|
||||
// Height blend params
|
||||
MaterialProperty enableHeightBlend = null;
|
||||
const string kEnableHeightBlend = "_EnableHeightBlend";
|
||||
|
||||
MaterialProperty heightTransition = null;
|
||||
const string kHeightTransition = "_HeightTransition";
|
||||
|
||||
// Per-pixel Normal (while instancing)
|
||||
MaterialProperty enableInstancedPerPixelNormal = null;
|
||||
const string kEnableInstancedPerPixelNormal = "_EnableInstancedPerPixelNormal";
|
||||
|
||||
private bool m_ShowChannelRemapping = false;
|
||||
enum HeightParametrization
|
||||
{
|
||||
Amplitude,
|
||||
MinMax
|
||||
};
|
||||
private HeightParametrization m_HeightParametrization = HeightParametrization.Amplitude;
|
||||
|
||||
private static bool DoesTerrainUseMaskMaps(TerrainLayer[] terrainLayers)
|
||||
{
|
||||
for (int i = 0; i < terrainLayers.Length; ++i)
|
||||
{
|
||||
if (terrainLayers[i].maskMapTexture != null)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void FindMaterialProperties(MaterialProperty[] props)
|
||||
{
|
||||
enableHeightBlend = FindProperty(kEnableHeightBlend, props, false);
|
||||
heightTransition = FindProperty(kHeightTransition, props, false);
|
||||
enableInstancedPerPixelNormal = FindProperty(kEnableInstancedPerPixelNormal, props, false);
|
||||
}
|
||||
|
||||
static public void SetupMaterialKeywords(Material material)
|
||||
{
|
||||
bool enableHeightBlend = (material.HasProperty(kEnableHeightBlend) && material.GetFloat(kEnableHeightBlend) > 0);
|
||||
CoreUtils.SetKeyword(material, "_TERRAIN_BLEND_HEIGHT", enableHeightBlend);
|
||||
|
||||
bool enableInstancedPerPixelNormal = material.GetFloat(kEnableInstancedPerPixelNormal) > 0.0f;
|
||||
CoreUtils.SetKeyword(material, "_TERRAIN_INSTANCED_PERPIXEL_NORMAL", enableInstancedPerPixelNormal);
|
||||
}
|
||||
|
||||
static public bool TextureHasAlpha(Texture2D inTex)
|
||||
{
|
||||
if (inTex != null)
|
||||
{
|
||||
return GraphicsFormatUtility.HasAlphaChannel(GraphicsFormatUtility.GetGraphicsFormat(inTex.format, true));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties) {
|
||||
base.OnGUI(materialEditorIn, properties);
|
||||
FindMaterialProperties(properties);
|
||||
|
||||
bool optionsChanged = false;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
if (enableHeightBlend != null)
|
||||
{
|
||||
//EditorGUI.indentLevel++;
|
||||
materialEditorIn.ShaderProperty(enableHeightBlend, styles.enableHeightBlend);
|
||||
if (enableHeightBlend.floatValue > 0)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.HelpBox(styles.warningHeightBasedBlending.text, MessageType.Info);
|
||||
materialEditorIn.ShaderProperty(heightTransition, styles.heightTransition);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
//EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
optionsChanged = true;
|
||||
}
|
||||
|
||||
bool enablePerPixelNormalChanged = false;
|
||||
|
||||
// Since Instanced Per-pixel normal is actually dependent on instancing enabled or not, it is not
|
||||
// important to check it in the GUI. The shader will make sure it is enabled/disabled properly.s
|
||||
if (enableInstancedPerPixelNormal != null)
|
||||
{
|
||||
//EditorGUI.indentLevel++;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
materialEditorIn.ShaderProperty(enableInstancedPerPixelNormal, styles.enableInstancedPerPixelNormal);
|
||||
enablePerPixelNormalChanged = EditorGUI.EndChangeCheck();
|
||||
//EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (optionsChanged || enablePerPixelNormalChanged)
|
||||
{
|
||||
foreach (var obj in materialEditorIn.targets)
|
||||
{
|
||||
SetupMaterialKeywords((Material)obj);
|
||||
}
|
||||
}
|
||||
|
||||
// We should always do this call at the end
|
||||
materialEditorIn.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain terrain)
|
||||
{
|
||||
var terrainLayers = terrain.terrainData.terrainLayers;
|
||||
|
||||
// Don't use the member field enableHeightBlend as ShaderGUI.OnGUI might not be called if the material UI is folded.
|
||||
// heightblend shouldn't be available if we are in multi-pass mode, because it is guaranteed to be broken.
|
||||
bool heightBlendAvailable = (terrainLayers.Length <= 4);
|
||||
bool heightBlend = heightBlendAvailable && terrain.materialTemplate.HasProperty(kEnableHeightBlend) && (terrain.materialTemplate.GetFloat(kEnableHeightBlend) > 0);
|
||||
|
||||
terrainLayer.diffuseTexture = EditorGUILayout.ObjectField(styles.diffuseTexture, terrainLayer.diffuseTexture, typeof(Texture2D), false) as Texture2D;
|
||||
TerrainLayerUtility.ValidateDiffuseTextureUI(terrainLayer.diffuseTexture);
|
||||
|
||||
var diffuseRemapMin = terrainLayer.diffuseRemapMin;
|
||||
var diffuseRemapMax = terrainLayer.diffuseRemapMax;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
bool enableDensity = false;
|
||||
if (terrainLayer.diffuseTexture != null)
|
||||
{
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
rect.y += 16 + 4;
|
||||
rect.width = EditorGUIUtility.labelWidth + 64;
|
||||
rect.height = 16;
|
||||
|
||||
++EditorGUI.indentLevel;
|
||||
|
||||
var diffuseTint = new Color(diffuseRemapMax.x, diffuseRemapMax.y, diffuseRemapMax.z);
|
||||
diffuseTint = EditorGUI.ColorField(rect, styles.colorTint, diffuseTint, true, false, false);
|
||||
diffuseRemapMax.x = diffuseTint.r;
|
||||
diffuseRemapMax.y = diffuseTint.g;
|
||||
diffuseRemapMax.z = diffuseTint.b;
|
||||
diffuseRemapMin.x = diffuseRemapMin.y = diffuseRemapMin.z = 0;
|
||||
|
||||
if (!heightBlend)
|
||||
{
|
||||
rect.y = rect.yMax + 2;
|
||||
enableDensity = EditorGUI.Toggle(rect, styles.opacityAsDensity, diffuseRemapMin.w > 0);
|
||||
}
|
||||
|
||||
--EditorGUI.indentLevel;
|
||||
}
|
||||
diffuseRemapMax.w = 1;
|
||||
diffuseRemapMin.w = enableDensity ? 1 : 0;
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
terrainLayer.diffuseRemapMin = diffuseRemapMin;
|
||||
terrainLayer.diffuseRemapMax = diffuseRemapMax;
|
||||
}
|
||||
|
||||
// Display normal map UI
|
||||
terrainLayer.normalMapTexture = EditorGUILayout.ObjectField(styles.normalMapTexture, terrainLayer.normalMapTexture, typeof(Texture2D), false) as Texture2D;
|
||||
TerrainLayerUtility.ValidateNormalMapTextureUI(terrainLayer.normalMapTexture, TerrainLayerUtility.CheckNormalMapTextureType(terrainLayer.normalMapTexture));
|
||||
|
||||
if (terrainLayer.normalMapTexture != null)
|
||||
{
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
rect.y += 16 + 4;
|
||||
rect.width = EditorGUIUtility.labelWidth + 64;
|
||||
rect.height = 16;
|
||||
|
||||
++EditorGUI.indentLevel;
|
||||
terrainLayer.normalScale = EditorGUI.FloatField(rect, styles.normalScale, terrainLayer.normalScale);
|
||||
--EditorGUI.indentLevel;
|
||||
}
|
||||
|
||||
// Display the mask map UI and the remap controls
|
||||
terrainLayer.maskMapTexture = EditorGUILayout.ObjectField(heightBlend ? styles.maskMapTexture : styles.maskMapTextureWithoutHeight, terrainLayer.maskMapTexture, typeof(Texture2D), false) as Texture2D;
|
||||
TerrainLayerUtility.ValidateMaskMapTextureUI(terrainLayer.maskMapTexture);
|
||||
|
||||
var maskMapRemapMin = terrainLayer.maskMapRemapMin;
|
||||
var maskMapRemapMax = terrainLayer.maskMapRemapMax;
|
||||
var smoothness = terrainLayer.smoothness;
|
||||
var metallic = terrainLayer.metallic;
|
||||
|
||||
++EditorGUI.indentLevel;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_ShowChannelRemapping = EditorGUILayout.Foldout(m_ShowChannelRemapping, terrainLayer.maskMapTexture != null ? s_Styles.channelRemapping : s_Styles.defaultValues);
|
||||
|
||||
if (m_ShowChannelRemapping)
|
||||
{
|
||||
if (terrainLayer.maskMapTexture != null)
|
||||
{
|
||||
float min, max;
|
||||
min = maskMapRemapMin.x; max = maskMapRemapMax.x;
|
||||
EditorGUILayout.MinMaxSlider(s_Styles.metallic, ref min, ref max, 0, 1);
|
||||
maskMapRemapMin.x = min; maskMapRemapMax.x = max;
|
||||
|
||||
min = maskMapRemapMin.y; max = maskMapRemapMax.y;
|
||||
EditorGUILayout.MinMaxSlider(s_Styles.ao, ref min, ref max, 0, 1);
|
||||
maskMapRemapMin.y = min; maskMapRemapMax.y = max;
|
||||
|
||||
if (heightBlend)
|
||||
{
|
||||
EditorGUILayout.LabelField(styles.height);
|
||||
++EditorGUI.indentLevel;
|
||||
m_HeightParametrization = (HeightParametrization)EditorGUILayout.EnumPopup(styles.heightParametrization, m_HeightParametrization);
|
||||
if (m_HeightParametrization == HeightParametrization.Amplitude)
|
||||
{
|
||||
// (height - heightBase) * amplitude
|
||||
float amplitude = Mathf.Max(maskMapRemapMax.z - maskMapRemapMin.z, Mathf.Epsilon); // to avoid divide by zero
|
||||
float heightBase = maskMapRemapMin.z / amplitude;
|
||||
amplitude = EditorGUILayout.FloatField(styles.heightAmplitude, amplitude * 100) / 100;
|
||||
heightBase = EditorGUILayout.FloatField(styles.heightBase, heightBase * 100) / 100;
|
||||
maskMapRemapMin.z = heightBase * amplitude;
|
||||
maskMapRemapMax.z = (1.0f - heightBase) * amplitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskMapRemapMin.z = EditorGUILayout.FloatField(styles.heightMin, maskMapRemapMin.z * 100) / 100;
|
||||
maskMapRemapMax.z = EditorGUILayout.FloatField(styles.heightMax, maskMapRemapMax.z * 100) / 100;
|
||||
}
|
||||
--EditorGUI.indentLevel;
|
||||
}
|
||||
|
||||
min = maskMapRemapMin.w; max = maskMapRemapMax.w;
|
||||
EditorGUILayout.MinMaxSlider(s_Styles.smoothness, ref min, ref max, 0, 1);
|
||||
maskMapRemapMin.w = min; maskMapRemapMax.w = max;
|
||||
}
|
||||
else
|
||||
{
|
||||
metallic = EditorGUILayout.Slider(s_Styles.metallic, metallic, 0, 1);
|
||||
// AO and Height are still exclusively controlled via the maskRemap controls
|
||||
// metallic and smoothness have their own values as fields within the LayerData.
|
||||
maskMapRemapMax.y = EditorGUILayout.Slider(s_Styles.ao, maskMapRemapMax.y, 0, 1);
|
||||
if (heightBlend)
|
||||
{
|
||||
maskMapRemapMax.z = EditorGUILayout.FloatField(s_Styles.heightCm, maskMapRemapMax.z * 100) / 100;
|
||||
}
|
||||
|
||||
// There's a possibility that someone could slide max below the existing min value
|
||||
// so we'll just protect against that by locking the min value down a little bit.
|
||||
// In the case of height (Z), we are trying to set min to no lower than zero value unless
|
||||
// max goes negative. Zero is a good sensible value for the minimum. For AO (Y), we
|
||||
// don't need this extra protection step because the UI blocks us from going negative
|
||||
// anyway. In both cases, pushing the slider below the min value will lock them together,
|
||||
// but min will be "left behind" if you go back up.
|
||||
maskMapRemapMin.y = Mathf.Min(maskMapRemapMin.y, maskMapRemapMax.y);
|
||||
maskMapRemapMin.z = Mathf.Min(Mathf.Max(0, maskMapRemapMin.z), maskMapRemapMax.z);
|
||||
|
||||
if (TextureHasAlpha(terrainLayer.diffuseTexture))
|
||||
{
|
||||
GUIStyle warnStyle = new GUIStyle(GUI.skin.label);
|
||||
warnStyle.wordWrap = true;
|
||||
GUILayout.Label("Smoothness is controlled by diffuse alpha channel", warnStyle);
|
||||
}
|
||||
else
|
||||
smoothness = EditorGUILayout.Slider(s_Styles.smoothness, smoothness, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
terrainLayer.maskMapRemapMin = maskMapRemapMin;
|
||||
terrainLayer.maskMapRemapMax = maskMapRemapMax;
|
||||
terrainLayer.smoothness = smoothness;
|
||||
terrainLayer.metallic = metallic;
|
||||
}
|
||||
--EditorGUI.indentLevel;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
TerrainLayerUtility.TilingSettingsUI(terrainLayer);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/FlatKit/Shaders/Editor/TerrainEditor.cs.meta
Normal file
3
Assets/FlatKit/Shaders/Editor/TerrainEditor.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17bd6c3b6c7c433c897e5a36eba47b46
|
||||
timeCreated: 1645650454
|
||||
157
Assets/FlatKit/Shaders/Editor/Tooltips.cs
Normal file
157
Assets/FlatKit/Shaders/Editor/Tooltips.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FlatKit.StylizedSurface {
|
||||
public static class Tooltips {
|
||||
// @formatter:off
|
||||
public static readonly Dictionary<string, string> Map = new Dictionary<string, string> {
|
||||
{ "Color", "Primary color of the material. This color is usually the most visible." }, {
|
||||
"Cel Shading Mode", "Lets you choose how the coloring/shading is applied.\n" +
|
||||
"- 'None' uses only flat Color parameter above, no primary cel is added;\n" +
|
||||
"- 'Single' adds a primary cel layer;\n" +
|
||||
"- 'Steps' works with a special texture for adding as many cels as there are in the texture;\n" +
|
||||
"- 'Curve' works with a special texture, but unlike 'Steps', it uses a smooth interpolated one."
|
||||
},
|
||||
{ "Color Shaded", "Color of the cel layer. Usually it is the dark part of cel shaded objects." },
|
||||
{ "Self Shading Size", "How much of the object is covered with the cel layer." }, {
|
||||
"Edge Size",
|
||||
"How smooth the transition between cel layers is. Values to the left mean 'sharper', values to the right are 'smoother'."
|
||||
}, {
|
||||
"Localized Shading",
|
||||
"Can also be called the \"flatness\" value. Defines how spread out the shading is across " +
|
||||
"the object. The value of 0 distributes the color transition gradually across the whole " +
|
||||
"object. The value of 1 makes shading fully flat."
|
||||
},
|
||||
{ "Enable Extra Cel Layer", "If one cel is not enough, here's another one." }, {
|
||||
"Enable Specular",
|
||||
"Toggle specular highlight on/off. Specular is a highlight that appears on shiny surfaces, " +
|
||||
"like metal or glass. It is kind of a glare effect."
|
||||
},
|
||||
{ "Specular Color", "Color of specular highlight. Usually it is white or very bright." }, {
|
||||
"Specular Size",
|
||||
"How big the specular highlight is. Values to the left mean 'smaller', values to the right are 'bigger'."
|
||||
}, {
|
||||
"Specular Edge Smoothness",
|
||||
"How smooth or sharp the specular highlight is. Values to the left mean 'sharper', values to the right are 'smoother'."
|
||||
}, {
|
||||
"Enable Rim",
|
||||
"Enables a rim highlight on the edges of the object. It can be used as a pseudo-outline layer or even as an additional color layer."
|
||||
},
|
||||
{ "Rim Color", "Color of the rim highlight. Usually it is bright." }, {
|
||||
"Light Align",
|
||||
"Position of the rim highlight that depends on light direction. Use this to move the rim part on the mesh."
|
||||
},
|
||||
{ "Rim Size", "How big the rim highlight is." }, {
|
||||
"Rim Edge Smoothness",
|
||||
"How smooth or sharp the rim part is. Values to the left mean 'sharper', values to the right are 'smoother'."
|
||||
},
|
||||
|
||||
// Height gradient.
|
||||
{
|
||||
"Enable Height Gradient",
|
||||
"Height gradient enables a color overlay that gradually changes across the vertical axis."
|
||||
},
|
||||
{ "Gradient Color", "Sets the color of the gradient overlay part." }, {
|
||||
"[DR_GRADIENT_ON]Space", "Whether the gradient should be in World or Local space.\n" +
|
||||
"- World space means that the `Center` parameter is relative to the world origin.\n" +
|
||||
"- Local space means that the `Center` parameter is relative to the object's pivot point."
|
||||
},
|
||||
{ "Center X", "X coordinate of the middle gradient point." },
|
||||
{ "Center Y", "Y coordinate of the middle gradient point." },
|
||||
{ "Size", "How stretched the gradient is." },
|
||||
{ "Gradient Angle", "Rotates the gradient on the mesh." },
|
||||
|
||||
// Outline.
|
||||
{ "Enable Outline", "Enables an outline layer on the material." },
|
||||
{ "[DR_OUTLINE_ON]Width", "Thickness of the outline." },
|
||||
{ "[DR_OUTLINE_ON]Color", "Color of the outline." }, {
|
||||
"[DR_OUTLINE_ON]Scale", "Controls a way of stretching the model uniformly. This is used rarely, " +
|
||||
"typically on symmetrical objects when the model can't have smooth normals."
|
||||
}, {
|
||||
"[DR_OUTLINE_ON]Smooth Normals", "Processes the mesh and creates a copy of it with smoothed normals " +
|
||||
"baked into a UV channel.\nPlease see our online documentation " +
|
||||
"(https://flatkit.dustyroom.com) for more details."
|
||||
}, {
|
||||
"[DR_OUTLINE_ON]Depth Offset", "Pushes the outline further from the camera. Use this if you are seeing " +
|
||||
"outlines intersecting the object."
|
||||
}, {
|
||||
"[DR_OUTLINE_ON]Space", "Whether the outline should be in Clip (aka Screen) or Local space. Different " +
|
||||
"objects require different space, so try both."
|
||||
}, {
|
||||
"Camera Distance Impact", "How much the distance between the object and the camera influences the " +
|
||||
"outline width. This is useful for making outlines thinner on distant objects."
|
||||
}, {
|
||||
"Enable Vertex Colors", "Uses mesh vertex color in object's appearance.\n" +
|
||||
"Vertex colors are colors that are stored in the mesh itself. They can be painted in 3D " +
|
||||
"modeling software like Blender or Maya. Vertex colors are usually used for additional " +
|
||||
"color layers."
|
||||
}, {
|
||||
"Light Color Contribution",
|
||||
"How much the color of real-time lights (directional, point or spot) influences the color of the object.\n" +
|
||||
"Has no effect when the lighting is baked as that color is already included in the lightmap and/or light probes."
|
||||
}, {
|
||||
"Point / Spot Light Edge",
|
||||
"Sharpness of the transition between lit and unlit parts of the surface when using point or spot lights."
|
||||
}, {
|
||||
"Override Light Direction",
|
||||
"Enables overriding of light direction. Use it when you want to re-align the shaded part for the current material only."
|
||||
},
|
||||
{ "Pitch", "Moves the shaded part across world-space X coordinate" },
|
||||
{ "Yaw", "Moves the shaded part across world-space Y coordinate" },
|
||||
|
||||
// Shadows.
|
||||
{
|
||||
"Mode", "Use this menu to let the current material receive shadows.\n" +
|
||||
"- 'Multiply' parameter multiplies black shadow over existing colors of shading;\n" +
|
||||
"- 'Color' parameter applies freely colored shadow over existing colors of shading."
|
||||
},
|
||||
{ "Power", "How opaque the received shadows are." },
|
||||
{ "[_UNITYSHADOWMODE_COLOR]Color", "Color of the received shadows." }, {
|
||||
"Sharpness",
|
||||
"How smooth or sharp the received shadows are. Values to the left mean 'sharper', values to the right are 'smoother'."
|
||||
},
|
||||
{
|
||||
"Shadow Occlusion",
|
||||
"Mask received Unity shadows in areas where normals face away from the light. Useful to " +
|
||||
"remove shadows that 'go through' objects."
|
||||
},
|
||||
|
||||
// Texture maps.
|
||||
{ "Albedo", "Main texture of the material. It is also known as 'Diffuse'." },
|
||||
{
|
||||
"Mix Into Shading",
|
||||
"Uses the main texture when calculating lighting and shading colors. When disabled, the Environment Lighting of the scene has a greater impact on the material."
|
||||
},
|
||||
{ "Texture Impact", "How opaque or transparent the texture is." },
|
||||
{
|
||||
"Blending Mode", "Select which blending mode to use for the texture:\n" +
|
||||
"-'Add' adds the texture to the existing colors of shading;\n" +
|
||||
"-'Multiply' multiplies the texture over the existing colors of shading;\n" +
|
||||
"-'Interpolate' (only Detail Map) blends the texture with the existing colors of shading."
|
||||
},
|
||||
{
|
||||
"Detail Map",
|
||||
"A texture that is used to add small details to the surface. There is no principal difference " +
|
||||
"between this texture and the main one, except that it is usually smaller and has more details."
|
||||
},
|
||||
{ "Detail Color", "The color to be applied to the detail map." },
|
||||
{ "Detail Impact", "How visible the detail map is." },
|
||||
|
||||
{ "Normal Map", "Also known as 'Bump Map'. This texture contains normals applied to the surface." }, {
|
||||
"Emission Map", "A texture representing the parts of the object that emit light. It is usually used for " +
|
||||
"glowing signs, screens, lights, etc."
|
||||
}, {
|
||||
"Emission Color",
|
||||
"The color of the emitted light. Note that this is an HDR value. When combined with Bloom " +
|
||||
"post-processing, it can be used to create a glowing effect."
|
||||
},
|
||||
{ "Base Alpha Cutoff", "Allows controlling which pixels to render based on the texture alpha values." }, {
|
||||
"Surface Type",
|
||||
"Whether the object is opaque or transparent. This defines the render queue of the material."
|
||||
},
|
||||
{ "Render Faces", "Whether to render the Front, Back or both faces of the mesh." },
|
||||
{ "Alpha Clipping", "Allows controlling which pixels to render based on the texture alpha values." },
|
||||
{ "Enable GPU Instancing", "GPU Instancing allows rendering many copies of the same mesh at once." },
|
||||
};
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
3
Assets/FlatKit/Shaders/Editor/Tooltips.cs.meta
Normal file
3
Assets/FlatKit/Shaders/Editor/Tooltips.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00e8e0985db344a089f2cb512edbcd4a
|
||||
timeCreated: 1604769966
|
||||
Reference in New Issue
Block a user