Beautify addon
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EdgeFusion {
|
||||
|
||||
public class ContactUsWindow : EditorWindow {
|
||||
const string OnlineGuidesUrl = "https://kronnect.com/guides";
|
||||
const string SupportUrl = "https://kronnect.com/support";
|
||||
const string YoutubeUrl = "https://youtube.com/@kronnect";
|
||||
const string TwitterUrl = "https://twitter.com/kronnect";
|
||||
const string KronnectUrl = "https://assetstore.unity.com/publishers/15018?aid=1101lGsd";
|
||||
const string ReferralInfo = "?aid=1101lGsd&pubref=edgefusion";
|
||||
Texture2D kronnectLogo, welcomeBanner;
|
||||
GUIStyle headerStyle, bannerStyle;
|
||||
|
||||
readonly List<AssetCategory> assetCategories = new List<AssetCategory>
|
||||
{
|
||||
new AssetCategory
|
||||
{
|
||||
name = "Image Effects",
|
||||
assets = new List<Asset>
|
||||
{
|
||||
new Asset { name = "Beautify 3 - Advanced Post Processing", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/beautify-3-advanced-post-processing-233073" },
|
||||
new Asset { name = "Frame Pack for Beautify", url = "https://assetstore.unity.com/packages/2d/gui/frame-pack-204058" },
|
||||
new Asset { name = "LUT Pack for Beautify", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/lut-pack-for-beautify-202502" },
|
||||
new Asset { name = "Beautify HDRP", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/beautify-hdrp-165411" },
|
||||
new Asset { name = "Cloud Shadows FX", url = "https://assetstore.unity.com/packages/vfx/shaders/cloud-shadows-fx-267702" },
|
||||
new Asset { name = "Dynamic Fog & Mist 2", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/dynamic-fog-mist-2-48200" },
|
||||
new Asset { name = "Edge Fusion", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/edge-fusion-smooth-surface-contacts-334484" },
|
||||
new Asset { name = "Global Snow 2", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/global-snow-2-248191" },
|
||||
new Asset { name = "Luma Based Ambient Occlusion (SSAO 2D)", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/luma-based-ambient-occlusion-2-ssao-2d-249066" },
|
||||
new Asset { name = "Radiant Global Illumination", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/radiant-global-illumination-225934" },
|
||||
new Asset { name = "Shiny SSR 2", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/shiny-ssr-2-screen-space-reflections-188638" },
|
||||
new Asset { name = "Sun Flares HDRP", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/sun-flares-hdrp-171177" },
|
||||
new Asset { name = "Umbra Soft Shadows", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/umbra-soft-shadows-better-directional-contact-shadows-for-urp-282485" },
|
||||
new Asset { name = "Volumetric Fog & Mist 2", url = "https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/volumetric-fog-mist-2-162694" },
|
||||
new Asset { name = "Volumetric Lights 2", url = "https://assetstore.unity.com/packages/vfx/shaders/volumetric-lights-2-234539" },
|
||||
new Asset { name = "Volumetric Lights Set", url = "https://assetstore.unity.com/packages/3d/props/volumetric-lights-set-237873" },
|
||||
new Asset { name = "Volumetric Lights 2 HDRP", url = "https://assetstore.unity.com/packages/vfx/shaders/volumetric-lights-2-hdrp-243807" },
|
||||
}
|
||||
},
|
||||
new AssetCategory
|
||||
{
|
||||
name = "Tools & Shaders",
|
||||
assets = new List<Asset>
|
||||
{
|
||||
new Asset { name = "Compass Navigator Pro 2", url = "https://assetstore.unity.com/packages/tools/gui/compass-navigator-pro-2-273662" },
|
||||
new Asset { name = "Highlight Plus", url = "https://assetstore.unity.com/packages/vfx/shaders/highlight-plus-all-in-one-outline-selection-effects-134149" },
|
||||
new Asset { name = "Highlight Plus 2D", url = "https://assetstore.unity.com/packages/vfx/shaders/highlight-plus-2d-138383" },
|
||||
new Asset { name = "Liquid Volume 2", url = "https://assetstore.unity.com/packages/vfx/shaders/liquid-volume-2-249127" },
|
||||
new Asset { name = "Liquid Volume Pro 2", url = "https://assetstore.unity.com/packages/vfx/shaders/liquid-volume-pro-2-129967" },
|
||||
new Asset { name = "Liquid Volume Pro 2 HDRP", url = "https://assetstore.unity.com/packages/vfx/shaders/liquid-volume-pro-2-hdrp-253786" },
|
||||
new Asset { name = "Potions & Volumetric Liquid", url = "https://assetstore.unity.com/packages/slug/123474" },
|
||||
new Asset { name = "Shader Control", url = "https://assetstore.unity.com/packages/vfx/shaders/shader-control-74817" },
|
||||
new Asset { name = "Split Screen Pro", url = "https://assetstore.unity.com/packages/tools/camera/split-screen-pro-207149" },
|
||||
new Asset { name = "Skybox Plus", url = "https://assetstore.unity.com/packages/2d/environments/skybox-plus-182966" },
|
||||
new Asset { name = "Trails FX", url = "https://assetstore.unity.com/packages/vfx/shaders/trails-fx-146898" },
|
||||
new Asset { name = "Transitions Plus", url = "https://assetstore.unity.com/packages/tools/camera/transitions-plus-266067" },
|
||||
new Asset { name = "Tunnel FX 2", url = "https://assetstore.unity.com/packages/vfx/shaders/tunnel-fx-2-86544" },
|
||||
new Asset { name = "Voxel Play 3", url = "https://assetstore.unity.com/packages/tools/game-toolkits/voxel-play-3-310775" },
|
||||
new Asset { name = "Pirates of Voxel Play", url = "https://assetstore.unity.com/packages/tools/game-toolkits/pirates-of-voxel-play-189096" },
|
||||
new Asset { name = "X-Frame FPS Accelerator", url = "https://assetstore.unity.com/packages/tools/camera/x-frame-fps-accelerator-63965" }
|
||||
}
|
||||
},
|
||||
new AssetCategory
|
||||
{
|
||||
name = "Grids & Maps",
|
||||
assets = new List<Asset>
|
||||
{
|
||||
new Asset { name = "Grids 2D", url = "https://assetstore.unity.com/packages/tools/game-toolkits/grids-2d-59981" },
|
||||
new Asset { name = "Hexasphere Grid System", url = "https://assetstore.unity.com/packages/tools/modeling/hexasphere-grid-system-89112" },
|
||||
new Asset { name = "Terrain Grid System 2", url = "https://assetstore.unity.com/packages/tools/terrain/terrain-grid-system-2-244921" },
|
||||
new Asset { name = "World Map 2D Edition 2", url = "https://assetstore.unity.com/packages/tools/gui/world-map-2d-edition-2-151238" },
|
||||
new Asset { name = "World Map Globe Edition 2", url = "https://assetstore.unity.com/packages/tools/gui/world-map-globe-edition-2-150643" },
|
||||
new Asset { name = "World Map Strategy Kit 2", url = "https://assetstore.unity.com/packages/tools/game-toolkits/world-map-strategy-kit-2-150938" },
|
||||
new Asset { name = "World Maps & Weather Symbols", url = "https://assetstore.unity.com/packages/2d/textures-materials/world-flags-and-weather-symbols-69010" },
|
||||
new Asset { name = "Military Units 2D", url = "https://assetstore.unity.com/packages/2d/textures-materials/military-units-the-stylized-art-collection-187769" },
|
||||
new Asset { name = "Military Units 3D", url = "https://assetstore.unity.com/packages/3d/vehicles/military-units-3d-246876" },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void OnEnable () {
|
||||
kronnectLogo = Resources.Load<Texture2D>("kronnectLogo");
|
||||
welcomeBanner = Resources.Load<Texture2D>("welcomeBanner");
|
||||
}
|
||||
|
||||
void DrawHeader (string title) {
|
||||
if (headerStyle == null) {
|
||||
GUIStyle skurikenModuleTitleStyle = "ShurikenModuleTitle";
|
||||
headerStyle = new GUIStyle(skurikenModuleTitleStyle) {
|
||||
contentOffset = new Vector2(5f, -2f),
|
||||
normal = { textColor = Color.white },
|
||||
fixedHeight = 24,
|
||||
fontSize = 13
|
||||
};
|
||||
}
|
||||
|
||||
GUILayout.Label(title, headerStyle);
|
||||
}
|
||||
|
||||
void OnGUI () {
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(10);
|
||||
|
||||
DrawHeader("Online Resources");
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
if (GUILayout.Button("Asset Documentation", EditorStyles.linkLabel)) {
|
||||
Application.OpenURL(OnlineGuidesUrl);
|
||||
}
|
||||
if (GUILayout.Button("Support & Community", EditorStyles.linkLabel)) {
|
||||
Application.OpenURL(SupportUrl);
|
||||
}
|
||||
if (GUILayout.Button("YouTube Channel", EditorStyles.linkLabel)) {
|
||||
Application.OpenURL(YoutubeUrl);
|
||||
}
|
||||
if (GUILayout.Button("X / Twitter", EditorStyles.linkLabel)) {
|
||||
Application.OpenURL(TwitterUrl);
|
||||
}
|
||||
if (GUILayout.Button("Kronnect Asset Store", EditorStyles.linkLabel)) {
|
||||
Application.OpenURL(KronnectUrl);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
if (bannerStyle == null) {
|
||||
bannerStyle = new GUIStyle(GUI.skin.button);
|
||||
bannerStyle.normal.background = welcomeBanner;
|
||||
bannerStyle.normal.scaledBackgrounds = new[] { welcomeBanner };
|
||||
}
|
||||
const float width = 1100 / 2;
|
||||
const float height = 200 / 2;
|
||||
|
||||
if (GUILayout.Button("", bannerStyle, GUILayout.Width(width), GUILayout.Height(height))) {
|
||||
Application.OpenURL(KronnectUrl);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
DrawHeader("Kronnect Assets");
|
||||
|
||||
GUIStyle textStyle = new GUIStyle(EditorStyles.wordWrappedLabel) {
|
||||
fontSize = 11
|
||||
};
|
||||
GUILayout.Label("Thank you for using this asset!\nWe invite you to explore more assets and complete your collection by visiting the affiliated links below to the Asset Store:", textStyle);
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
foreach (var category in assetCategories) {
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Label(category.name, EditorStyles.boldLabel);
|
||||
foreach (var asset in category.assets) {
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
if (GUILayout.Button(asset.name, EditorStyles.linkLabel)) {
|
||||
Application.OpenURL(asset.url + ReferralInfo);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Close", GUILayout.Width(60))) {
|
||||
Close();
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.Label(new GUIContent(kronnectLogo), GUILayout.Width(100), GUILayout.Height(30));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(10);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void ShowScreen () {
|
||||
ContactUsWindow window = GetWindow<ContactUsWindow>(true, "Online Resources", true);
|
||||
window.minSize = window.maxSize = new Vector2(750, 640);
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class AssetCategory {
|
||||
public string name;
|
||||
public List<Asset> assets;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Asset {
|
||||
public string name;
|
||||
public string url;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 806f9c43fa6ac884c967fedf7fd3bf8d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "EdgeFusionEditor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:823cc7d3f7f1d438d9ad8413a6147ef0",
|
||||
"GUID:3eae0364be2026648bf74846acb8a731",
|
||||
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
|
||||
"GUID:f279941a09ad6a84abae8535f4c1e3fe"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c541b389c1ff8c4eb32767616e60357
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,489 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace EdgeFusion {
|
||||
|
||||
[CustomEditor(typeof(global::EdgeFusion.EdgeFusion))]
|
||||
public class EdgeFusionEditor : VolumeComponentEditor {
|
||||
|
||||
SerializedDataParameter blendLayers, renderingLayerFilter, blendWithOthers, specialGroupLayers, doubleSidedLayers, intensity, radius, distanceCompensation, enableIntraObjectFusion, normalThreshold, concavityTest, intraObjectFusionPerObject;
|
||||
SerializedDataParameter sampleCount, jitter, maxBlendDistance, binarySearchSteps, maxScreenRadius;
|
||||
SerializedDataParameter doubleSidedRenderingLayerFilter, specialGroupRenderingLayerFilter;
|
||||
SerializedDataParameter earlyExitHits, antiFlicker;
|
||||
SerializedDataParameter debugMode, depthDebugMultiplier, shadowProtection, noiseIntensity, noiseScale, noiseContrast;
|
||||
SerializedDataParameter compareMode, compareSameSide, comparePanning, compareLineAngle, compareLineWidth, compareLineColor;
|
||||
SerializedDataParameter msaaEdgeFixPower;
|
||||
SerializedProperty idExclusionPairs;
|
||||
|
||||
static readonly QualityPreset[] k_Presets = (QualityPreset[])Enum.GetValues(typeof(QualityPreset));
|
||||
static readonly int[] k_PresetValues = k_Presets
|
||||
.Select(p => (int)p)
|
||||
.ToArray();
|
||||
static PropertyInfo pipelineMsaaProperty;
|
||||
static Type cachedPipelineType;
|
||||
string[] presetNames;
|
||||
bool renderFeaturePresent;
|
||||
Terrain[] sceneTerrainsCache;
|
||||
bool hasEdgeFusionObjectInScene;
|
||||
const string k_AdditionalGroupsFoldoutKey = "EdgeFusion.AdditionalGroupsFoldout";
|
||||
bool showAdditionalGroups;
|
||||
bool msaaCameraActive;
|
||||
|
||||
public override void OnEnable () {
|
||||
|
||||
try {
|
||||
presetNames = k_Presets
|
||||
.Select(p => ObjectNames.NicifyVariableName(p.ToString()))
|
||||
.ToArray();
|
||||
var o = new PropertyFetcher<global::EdgeFusion.EdgeFusion>(serializedObject);
|
||||
blendLayers = Unpack(o.Find(x => x.blendLayers));
|
||||
renderingLayerFilter = Unpack(o.Find(x => x.renderingLayerFilter));
|
||||
blendWithOthers = Unpack(o.Find(x => x.blendWithOthers));
|
||||
specialGroupLayers = Unpack(o.Find(x => x.specialGroupLayers));
|
||||
doubleSidedLayers = Unpack(o.Find(x => x.doubleSidedLayers));
|
||||
doubleSidedRenderingLayerFilter = Unpack(o.Find(x => x.doubleSidedRenderingLayerFilter));
|
||||
specialGroupRenderingLayerFilter = Unpack(o.Find(x => x.specialGroupRenderingLayerFilter));
|
||||
intensity = Unpack(o.Find(x => x.intensity));
|
||||
radius = Unpack(o.Find(x => x.radius));
|
||||
distanceCompensation = Unpack(o.Find(x => x.distanceCompensation));
|
||||
enableIntraObjectFusion = Unpack(o.Find(x => x.enableIntraObjectFusion));
|
||||
intraObjectFusionPerObject = Unpack(o.Find(x => x.intraObjectFusionPerObject));
|
||||
normalThreshold = Unpack(o.Find(x => x.normalThreshold));
|
||||
concavityTest = Unpack(o.Find(x => x.concavityTest));
|
||||
sampleCount = Unpack(o.Find(x => x.sampleCount));
|
||||
jitter = Unpack(o.Find(x => x.jitter));
|
||||
maxBlendDistance = Unpack(o.Find(x => x.maxBlendDistance));
|
||||
binarySearchSteps = Unpack(o.Find(x => x.binarySearchSteps));
|
||||
earlyExitHits = Unpack(o.Find(x => x.earlyExitHits));
|
||||
antiFlicker = Unpack(o.Find(x => x.antiFlicker));
|
||||
debugMode = Unpack(o.Find(x => x.debugMode));
|
||||
depthDebugMultiplier = Unpack(o.Find(x => x.depthDebugMultiplier));
|
||||
msaaEdgeFixPower = Unpack(o.Find(x => x.msaaEdgeFixPower));
|
||||
shadowProtection = Unpack(o.Find(x => x.shadowProtection));
|
||||
maxScreenRadius = Unpack(o.Find(x => x.maxScreenRadius));
|
||||
noiseIntensity = Unpack(o.Find(x => x.noiseIntensity));
|
||||
noiseScale = Unpack(o.Find(x => x.noiseScale));
|
||||
noiseContrast = Unpack(o.Find(x => x.noiseContrast));
|
||||
compareMode = Unpack(o.Find(x => x.compareMode));
|
||||
compareSameSide = Unpack(o.Find(x => x.compareSameSide));
|
||||
comparePanning = Unpack(o.Find(x => x.comparePanning));
|
||||
compareLineAngle = Unpack(o.Find(x => x.compareLineAngle));
|
||||
compareLineWidth = Unpack(o.Find(x => x.compareLineWidth));
|
||||
compareLineColor = Unpack(o.Find(x => x.compareLineColor));
|
||||
idExclusionPairs = serializedObject.FindProperty("idExclusionPairs");
|
||||
renderFeaturePresent = IsEdgeFusionRenderFeaturePresent();
|
||||
// PORT NOTE (Unity 2022.3): FindObjectsByType does not exist before 2023.1; use the classic API.
|
||||
sceneTerrainsCache = UnityEngine.Object.FindObjectsOfType<Terrain>();
|
||||
showAdditionalGroups = EditorPrefs.GetBool(k_AdditionalGroupsFoldoutKey, false);
|
||||
msaaCameraActive = CameraUsesMsaa();
|
||||
hasEdgeFusionObjectInScene = SceneHasEdgeFusionObject();
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
|
||||
int blendLayersValue = blendLayers.overrideState.boolValue ? blendLayers.value.intValue : -1;
|
||||
int doubleSidedLayersValue = doubleSidedLayers.overrideState.boolValue ? doubleSidedLayers.value.intValue : 0;
|
||||
int specialGroupLayersValue = specialGroupLayers.overrideState.boolValue ? specialGroupLayers.value.intValue : 0;
|
||||
uint renderingLayerFilterValue = renderingLayerFilter.overrideState.boolValue ? (uint)renderingLayerFilter.value.intValue : uint.MaxValue;
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
if (!renderFeaturePresent) {
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.HelpBox("Edge Fusion Render Feature is not added to the current URP Renderer. The effect will not be visible.", MessageType.Error);
|
||||
if (GUILayout.Button("Select Current URP Renderer", GUILayout.Height(20))) {
|
||||
SelectCurrentURPRenderer();
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Online Resources & Support")) {
|
||||
ContactUsWindow.ShowScreen();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.LabelField("Object Selection", EditorStyles.boldLabel);
|
||||
PropertyField(blendLayers);
|
||||
PropertyField(renderingLayerFilter, new GUIContent("Rendering Layer Filter"));
|
||||
|
||||
// Only show "Blend With Others" if something is excluded (otherwise it has no effect)
|
||||
bool somethingExcluded = blendLayersValue != -1 || renderingLayerFilterValue != uint.MaxValue;
|
||||
if (somethingExcluded) {
|
||||
PropertyField(blendWithOthers, new GUIContent("Blend With Others", "When enabled, visible geometry not selected by any layer setting will also blend with marked objects."));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(4);
|
||||
using (var foldoutScope = new EditorGUI.ChangeCheckScope()) {
|
||||
showAdditionalGroups = EditorGUILayout.Foldout(showAdditionalGroups, "Additional Object Groups", true);
|
||||
if (foldoutScope.changed) {
|
||||
EditorPrefs.SetBool(k_AdditionalGroupsFoldoutKey, showAdditionalGroups);
|
||||
}
|
||||
}
|
||||
|
||||
if (showAdditionalGroups) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
EditorGUILayout.LabelField("Double-Sided Objects", EditorStyles.miniLabel);
|
||||
PropertyField(doubleSidedLayers, new GUIContent("Layers"));
|
||||
PropertyField(doubleSidedRenderingLayerFilter, new GUIContent("Rendering Layer Filter"));
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
EditorGUILayout.LabelField("Special Group (vertex displacement, animated vegetation)", EditorStyles.miniLabel);
|
||||
PropertyField(specialGroupLayers, new GUIContent("Layers"));
|
||||
PropertyField(specialGroupRenderingLayerFilter, new GUIContent("Rendering Layer Filter"));
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
if (specialGroupLayers.overrideState.boolValue && specialGroupLayersValue == -1) {
|
||||
EditorGUILayout.HelpBox("Special Group selection should only include objects with custom vertex shaders.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
if ((blendLayersValue & doubleSidedLayersValue) != 0) {
|
||||
EditorGUILayout.HelpBox("Layers included in Double-Sided Layers are automatically excluded from Blend Layers.", MessageType.Info);
|
||||
}
|
||||
if (((blendLayersValue & specialGroupLayersValue) != 0) || ((doubleSidedLayersValue & specialGroupLayersValue) != 0)) {
|
||||
EditorGUILayout.HelpBox("Layers included in Special Group Layers are automatically excluded from Blend Layers and Double-Sided Layers.", MessageType.Info);
|
||||
}
|
||||
int effectiveBlendForTerrain = (blendLayersValue & ~doubleSidedLayersValue) & ~specialGroupLayersValue;
|
||||
CheckTerrainBlendLayers(effectiveBlendForTerrain, renderingLayerFilterValue);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("ID Exclusions", EditorStyles.boldLabel);
|
||||
DrawIdExclusionPairs(blendLayersValue, renderingLayerFilterValue);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Blending", EditorStyles.boldLabel);
|
||||
PropertyField(intensity);
|
||||
PropertyField(radius);
|
||||
PropertyField(distanceCompensation, new GUIContent("Distance Compensation", "Scales the effective radius proportionally with distance from the camera. Keeps a small radius up close while increasing it for distant objects."));
|
||||
PropertyField(maxScreenRadius);
|
||||
PropertyField(enableIntraObjectFusion);
|
||||
if (enableIntraObjectFusion.value.boolValue) {
|
||||
EditorGUI.indentLevel++;
|
||||
PropertyField(normalThreshold);
|
||||
PropertyField(concavityTest);
|
||||
PropertyField(intraObjectFusionPerObject, new GUIContent("Per Object", "When enabled, intra-object fusion only runs on renderers that have an Edge Fusion Object component with the effect allowed; fill-pass normals are skipped."));
|
||||
if (intraObjectFusionPerObject.value.boolValue && !hasEdgeFusionObjectInScene) {
|
||||
EditorGUILayout.HelpBox("Add 'Edge Fusion Object' component to the gameobjects you want to control intra-object fusion.", MessageType.Warning);
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
PropertyField(shadowProtection);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Noise", EditorStyles.boldLabel);
|
||||
PropertyField(noiseIntensity);
|
||||
if (noiseIntensity.value.floatValue > 0) {
|
||||
EditorGUI.indentLevel++;
|
||||
PropertyField(noiseScale, new GUIContent("Scale"));
|
||||
PropertyField(noiseContrast, new GUIContent("Contrast"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
PropertyField(jitter);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Performance", EditorStyles.boldLabel);
|
||||
if (GUILayout.Button("Tips", GUILayout.Width(50), GUILayout.Height(18))) {
|
||||
Application.OpenURL("https://kronnect.com/guides/edge-fusion-performance-tips/");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
PropertyField(sampleCount);
|
||||
int currentQuality = sampleCount.value.intValue;
|
||||
int selectedIndex = GetClosestPresetIndex(currentQuality);
|
||||
using (var cc = new EditorGUI.ChangeCheckScope()) {
|
||||
EditorGUI.BeginDisabledGroup(!sampleCount.overrideState.boolValue);
|
||||
int newIndex = EditorGUILayout.Popup(selectedIndex, presetNames ?? Array.Empty<string>(), GUILayout.Width(80f));
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if (cc.changed && newIndex >= 0 && newIndex < k_PresetValues.Length) {
|
||||
var selectedPreset = (QualityPreset)k_PresetValues[newIndex];
|
||||
sampleCount.value.intValue = k_PresetValues[newIndex];
|
||||
binarySearchSteps.value.intValue = GetBinarySearchStepsForPreset(selectedPreset);
|
||||
binarySearchSteps.overrideState.boolValue = true;
|
||||
earlyExitHits.value.intValue = GetEarlyExitHitsForPreset(selectedPreset);
|
||||
earlyExitHits.overrideState.boolValue = true;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
PropertyField(binarySearchSteps);
|
||||
PropertyField(earlyExitHits, new GUIContent("Early Exit Hits", "Stops searching edge position after n nearest edge hits"));
|
||||
PropertyField(antiFlicker, new GUIContent("Anti-Flicker", "Stabilises the blending when two edge candidates are near-tie in distance. Averages them with a soft-argmin so edgeUV moves continuously instead of snapping between winners. Helps in any scene with sub-pixel motion between frames (VR, slow camera motion, animated objects, FPS mouse look, camera shake). Disable to match the classic pick-one behaviour."));
|
||||
PropertyField(maxBlendDistance);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Debug", EditorStyles.boldLabel);
|
||||
PropertyField(debugMode);
|
||||
if (debugMode.overrideState.boolValue && debugMode.value.intValue == (int)DebugMode.Depth) {
|
||||
EditorGUI.indentLevel++;
|
||||
PropertyField(depthDebugMultiplier, new GUIContent("Depth Multiplier"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
if (debugMode.overrideState.boolValue && debugMode.value.intValue == (int)DebugMode.SpecialGroup && (!specialGroupLayers.overrideState.boolValue || specialGroupLayersValue == 0)) {
|
||||
EditorGUILayout.HelpBox("Special Group is not executing because Special Group Layers is set to Nothing.", MessageType.Warning);
|
||||
}
|
||||
|
||||
PropertyField(compareMode, new GUIContent("Compare Mode"));
|
||||
if (compareMode.value.boolValue) {
|
||||
EditorGUI.indentLevel++;
|
||||
PropertyField(compareSameSide, new GUIContent("Same Side"));
|
||||
if (compareSameSide.value.boolValue) {
|
||||
PropertyField(comparePanning, new GUIContent("Panning"));
|
||||
}
|
||||
else {
|
||||
PropertyField(compareLineAngle, new GUIContent("Line Angle"));
|
||||
}
|
||||
PropertyField(compareLineWidth, new GUIContent("Line Width"));
|
||||
PropertyField(compareLineColor, new GUIContent("Line Color"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (msaaCameraActive) {
|
||||
PropertyField(msaaEdgeFixPower, new GUIContent("MSAA Edge Fix Amount", "When using MSAA in forward pass and certain blending layers configuration, you can use this option to reduce MSAA edge artifacts due to multi-sampling."));
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void CheckTerrainBlendLayers (int blendLayerMask, uint renderingLayerMaskValue) {
|
||||
if (sceneTerrainsCache == null || sceneTerrainsCache.Length == 0) return;
|
||||
|
||||
bool hasTerrainWithDrawInstanced = false;
|
||||
bool hasTerrainWithoutDrawInstanced = false;
|
||||
|
||||
uint rlMask = renderingLayerMaskValue;
|
||||
foreach (var terrain in sceneTerrainsCache) {
|
||||
if (terrain == null) continue;
|
||||
bool selectedByBlendLayers = IsLayerInMask(terrain.gameObject.layer, blendLayerMask);
|
||||
bool selectedByRenderingLayers = (rlMask == uint.MaxValue) || ((terrain.renderingLayerMask & rlMask) != 0);
|
||||
bool consideredForBlend = selectedByBlendLayers && selectedByRenderingLayers;
|
||||
if (!consideredForBlend) continue;
|
||||
|
||||
if (terrain.drawInstanced) {
|
||||
hasTerrainWithDrawInstanced = true;
|
||||
}
|
||||
else {
|
||||
hasTerrainWithoutDrawInstanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTerrainWithDrawInstanced) {
|
||||
EditorGUILayout.HelpBox(
|
||||
"Terrain has Draw Instanced option enabled which is not compatible with Edge Fusion. However, you can exclude it from blending layers or rendering layers as a workaround which is also faster.",
|
||||
MessageType.Error
|
||||
);
|
||||
}
|
||||
else if (hasTerrainWithoutDrawInstanced) {
|
||||
EditorGUILayout.HelpBox(
|
||||
"For best performance, you can exclude terrain objects from blending (via Blend Layers or Rendering Layers).",
|
||||
MessageType.Warning
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsLayerInMask (int layer, int layerMask) {
|
||||
return ((layerMask & (1 << layer)) != 0);
|
||||
}
|
||||
|
||||
static readonly string[] exclusionIdNames = BuildExclusionIdNames();
|
||||
|
||||
bool SceneHasEdgeFusionObject () {
|
||||
// PORT NOTE (Unity 2022.3): FindObjectsByType does not exist before 2023.1; use the classic API.
|
||||
return UnityEngine.Object.FindObjectsOfType<EdgeFusionObject>().Length > 0;
|
||||
}
|
||||
|
||||
static string[] BuildExclusionIdNames () {
|
||||
var names = new string[32];
|
||||
for (int i = 0; i < 30; i++) {
|
||||
names[i] = $"ID {i + 1}";
|
||||
}
|
||||
names[30] = "ID 31 (Terrain)";
|
||||
names[31] = "ID 32 (Special Group)";
|
||||
return names;
|
||||
}
|
||||
|
||||
void DrawIdExclusionPairs (int blendLayersValue, uint renderingLayerFilterValue) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(15f);
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
EditorGUILayout.LabelField("Exclusion Pairs", EditorStyles.miniLabel);
|
||||
|
||||
bool usesTerrain = false;
|
||||
for (int i = 0; i < idExclusionPairs.arraySize; i++) {
|
||||
var element = idExclusionPairs.GetArrayElementAtIndex(i);
|
||||
var enabledProp = element.FindPropertyRelative("enabled");
|
||||
var idA = element.FindPropertyRelative("idA");
|
||||
var idB = element.FindPropertyRelative("idB");
|
||||
|
||||
if (enabledProp.boolValue && (idA.intValue == 31 || idB.intValue == 31)) usesTerrain = true;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
enabledProp.boolValue = EditorGUILayout.Toggle(enabledProp.boolValue, GUILayout.Width(16));
|
||||
EditorGUI.BeginDisabledGroup(!enabledProp.boolValue);
|
||||
idA.intValue = EditorGUILayout.Popup(idA.intValue - 1, exclusionIdNames) + 1;
|
||||
EditorGUILayout.LabelField("↔", GUILayout.Width(20));
|
||||
idB.intValue = EditorGUILayout.Popup(idB.intValue - 1, exclusionIdNames) + 1;
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if (GUILayout.Button("×", GUILayout.Width(20))) {
|
||||
idExclusionPairs.DeleteArrayElementAtIndex(i);
|
||||
i--;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("+ Add Exclusion Pair")) {
|
||||
idExclusionPairs.InsertArrayElementAtIndex(idExclusionPairs.arraySize);
|
||||
var newElement = idExclusionPairs.GetArrayElementAtIndex(idExclusionPairs.arraySize - 1);
|
||||
newElement.FindPropertyRelative("enabled").boolValue = true;
|
||||
newElement.FindPropertyRelative("idA").intValue = 1;
|
||||
newElement.FindPropertyRelative("idB").intValue = 31;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
bool terrainIncludedInBlend = blendLayersValue == -1 && renderingLayerFilterValue == uint.MaxValue;
|
||||
if (usesTerrain && terrainIncludedInBlend) {
|
||||
EditorGUILayout.HelpBox(
|
||||
"You are excluding Terrain (ID 31) but Blend Layers and Rendering Layer Filter include everything. " +
|
||||
"For terrain to receive ID 31, it must be excluded from Blend Layers or Rendering Layer Filter so it goes through the fill pass.",
|
||||
MessageType.Warning
|
||||
);
|
||||
}
|
||||
|
||||
if (idExclusionPairs.arraySize > 0) {
|
||||
EditorGUILayout.HelpBox(
|
||||
"IDs 1-30: Set via EdgeFusionObject component\n" +
|
||||
"ID 31: Terrain (objects not in Blend Layers)\n" +
|
||||
"ID 32: Special Group objects",
|
||||
MessageType.Info
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static int GetClosestPresetIndex (int sampleCount) {
|
||||
int closestIndex = 0;
|
||||
int smallestDelta = int.MaxValue;
|
||||
for (int i = 0; i < k_PresetValues.Length; i++) {
|
||||
int delta = Mathf.Abs(k_PresetValues[i] - sampleCount);
|
||||
if (delta < smallestDelta) {
|
||||
smallestDelta = delta;
|
||||
closestIndex = i;
|
||||
}
|
||||
}
|
||||
return closestIndex;
|
||||
}
|
||||
|
||||
static int GetBinarySearchStepsForPreset (QualityPreset preset) {
|
||||
switch (preset) {
|
||||
case QualityPreset.VeryLow: return 2;
|
||||
case QualityPreset.Low: return 4;
|
||||
case QualityPreset.Medium: return 5;
|
||||
case QualityPreset.High: return 7;
|
||||
case QualityPreset.VeryHigh: return 8;
|
||||
default: return 7;
|
||||
}
|
||||
}
|
||||
|
||||
static int GetEarlyExitHitsForPreset (QualityPreset preset) {
|
||||
switch (preset) {
|
||||
case QualityPreset.VeryLow: return 1;
|
||||
case QualityPreset.Low: return 2;
|
||||
case QualityPreset.Medium: return 3;
|
||||
case QualityPreset.High: return 4;
|
||||
case QualityPreset.VeryHigh: return 5;
|
||||
default: return 5;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsEdgeFusionRenderFeaturePresent () {
|
||||
return GetCurrentURPRendererData() != null && CheckRendererForEdgeFusion(GetCurrentURPRendererData());
|
||||
}
|
||||
|
||||
UnityEngine.Object GetCurrentURPRendererData () {
|
||||
var pipeline = UnityEngine.Rendering.GraphicsSettings.currentRenderPipeline;
|
||||
if (pipeline == null) return null;
|
||||
|
||||
var serializedAsset = new SerializedObject(pipeline);
|
||||
var rendererDataList = serializedAsset.FindProperty("m_RendererDataList");
|
||||
if (rendererDataList == null || !rendererDataList.isArray || rendererDataList.arraySize == 0) return null;
|
||||
|
||||
var defaultRendererIndex = serializedAsset.FindProperty("m_DefaultRendererIndex");
|
||||
int index = defaultRendererIndex != null ? defaultRendererIndex.intValue : 0;
|
||||
if (index < 0 || index >= rendererDataList.arraySize) return null;
|
||||
|
||||
var rendererDataProperty = rendererDataList.GetArrayElementAtIndex(index);
|
||||
return rendererDataProperty.objectReferenceValue;
|
||||
}
|
||||
|
||||
bool CheckRendererForEdgeFusion (UnityEngine.Object rendererData) {
|
||||
if (rendererData == null) return false;
|
||||
|
||||
var serializedRenderer = new SerializedObject(rendererData);
|
||||
var featuresProperty = serializedRenderer.FindProperty("m_RendererFeatures");
|
||||
if (featuresProperty == null || !featuresProperty.isArray) return false;
|
||||
|
||||
for (int i = 0; i < featuresProperty.arraySize; i++) {
|
||||
var featureProperty = featuresProperty.GetArrayElementAtIndex(i);
|
||||
var feature = featureProperty.objectReferenceValue;
|
||||
if (feature != null && feature.GetType().Name == "EdgeFusionRenderFeature") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SelectCurrentURPRenderer () {
|
||||
var rendererData = GetCurrentURPRendererData();
|
||||
if (rendererData != null) {
|
||||
Selection.activeObject = rendererData;
|
||||
EditorGUIUtility.PingObject(rendererData);
|
||||
}
|
||||
}
|
||||
|
||||
static bool CameraUsesMsaa () {
|
||||
if (TryGetPipelineMsaaSamples(GraphicsSettings.currentRenderPipeline, out int pipelineSamples) && pipelineSamples > 1) {
|
||||
return true;
|
||||
}
|
||||
foreach (Camera cam in Camera.allCameras) {
|
||||
if (cam == null || !cam.allowMSAA) continue;
|
||||
if (cam.targetTexture != null) {
|
||||
if (cam.targetTexture.antiAliasing > 1) return true;
|
||||
}
|
||||
else if (QualitySettings.antiAliasing > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool TryGetPipelineMsaaSamples (RenderPipelineAsset pipeline, out int samples) {
|
||||
samples = 0;
|
||||
if (pipeline == null) return false;
|
||||
var type = pipeline.GetType();
|
||||
if (type != cachedPipelineType) {
|
||||
cachedPipelineType = type;
|
||||
pipelineMsaaProperty = type.GetProperty("msaaSampleCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
}
|
||||
if (pipelineMsaaProperty != null && pipelineMsaaProperty.PropertyType == typeof(int)) {
|
||||
samples = (int)pipelineMsaaProperty.GetValue(pipeline);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c98b9d430534f2048b7fd84249cf6125
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,96 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EdgeFusion {
|
||||
|
||||
[CustomEditor(typeof(EdgeFusionObject))]
|
||||
public class EdgeFusionObjectEditor : Editor {
|
||||
SerializedProperty overrideRadius;
|
||||
SerializedProperty customRadius;
|
||||
SerializedProperty overrideObjectId;
|
||||
SerializedProperty customObjectId;
|
||||
SerializedProperty useRandomId;
|
||||
SerializedProperty randomIdPerChild;
|
||||
SerializedProperty disallowIntraObjectFusion;
|
||||
SerializedProperty includeMode;
|
||||
SerializedProperty childLayerMask;
|
||||
|
||||
void OnEnable () {
|
||||
overrideRadius = serializedObject.FindProperty("overrideRadius");
|
||||
customRadius = serializedObject.FindProperty("customRadius");
|
||||
overrideObjectId = serializedObject.FindProperty("overrideObjectId");
|
||||
customObjectId = serializedObject.FindProperty("customObjectId");
|
||||
useRandomId = serializedObject.FindProperty("useRandomId");
|
||||
randomIdPerChild = serializedObject.FindProperty("randomIdPerChild");
|
||||
disallowIntraObjectFusion = serializedObject.FindProperty("disallowIntraObjectFusion");
|
||||
includeMode = serializedObject.FindProperty("includeMode");
|
||||
childLayerMask = serializedObject.FindProperty("childLayerMask");
|
||||
EdgeFusionObject edgeFusionObject = (EdgeFusionObject)target;
|
||||
edgeFusionObject.Refresh();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Optional Override", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.PropertyField(overrideObjectId, new GUIContent("Override Object ID"));
|
||||
if (overrideObjectId.boolValue) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(useRandomId, new GUIContent("Use Random ID", "Use a random Object ID, instead of an Id derived from object position"));
|
||||
if (useRandomId.boolValue && includeMode.intValue == (int)IncludeMode.IncludeChildren) {
|
||||
EditorGUILayout.PropertyField(randomIdPerChild, new GUIContent("Random Id Per Child", "Assign a different random ID to each child renderer"));
|
||||
}
|
||||
if (!useRandomId.boolValue) {
|
||||
EditorGUILayout.PropertyField(customObjectId, new GUIContent("Custom Object ID", "0 = auto. >0 overrides the auto-generated ID. Objects sharing the same ID are considered the same for inter-object detection."));
|
||||
if (customObjectId.intValue <= 0) {
|
||||
EditorGUILayout.HelpBox("Custom Object ID must be greater than 0.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(overrideRadius, new GUIContent("Override Radius"));
|
||||
if (overrideRadius.boolValue) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(customRadius, new GUIContent("Custom Radius", "Custom blend radius in meters (0 = disables blending for this object)"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(disallowIntraObjectFusion, new GUIContent("Disallow Intra-Object Fusion", "Disable intra-object fusion for this object/children while keeping inter-object fusion."));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Inclusion", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(includeMode, new GUIContent("Include Mode"));
|
||||
|
||||
if (includeMode.intValue == (int)IncludeMode.IncludeChildren) {
|
||||
EditorGUILayout.PropertyField(childLayerMask, new GUIContent("Child Layer Mask"));
|
||||
}
|
||||
|
||||
if (!serializedObject.isEditingMultipleObjects) {
|
||||
EdgeFusionObject edgeFusionObject = (EdgeFusionObject)target;
|
||||
Material invalidMaterial = edgeFusionObject.nonInstancingMaterial;
|
||||
if (invalidMaterial != null) {
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.HelpBox($"Material '{invalidMaterial.name}' does not support GPU instancing.", MessageType.Warning);
|
||||
if (GUILayout.Button("Select Material", EditorStyles.linkLabel)) {
|
||||
Selection.activeObject = invalidMaterial;
|
||||
EditorGUIUtility.PingObject(invalidMaterial);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < targets.Length; i++) {
|
||||
EdgeFusionObject edgeFusionObject = (EdgeFusionObject)targets[i];
|
||||
if (edgeFusionObject.nonInstancingMaterial != null) {
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.HelpBox("Some selected objects use materials that do not support GPU instancing.", MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83616b2fc8a9f764d9290e84c7e1b5e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4042a265c63b614e80c25998e440a47
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1ace189099e25c4ba86243c9d9c58e0
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cce82a93703f33d47918c4bc452af9ed
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user