306 lines
18 KiB
C#
306 lines
18 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.Rendering.Universal;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace ShinySSRR {
|
|
|
|
[CustomEditor(typeof(Reflections))]
|
|
public class ReflectionsEditor : Editor {
|
|
|
|
SerializedProperty ignore, scope, layerMask, nameFilter, subMeshMask;
|
|
SerializedProperty smoothness, metallic, perSubMeshSmoothness, subMeshSettings;
|
|
SerializedProperty materialSmoothnessMapPropertyName, materialSmoothnessIntensityPropertyName, materialReflectivityPropertyName;
|
|
SerializedProperty smoothnessSource, customSmoothnessMap;
|
|
SerializedProperty normalSource, normalMap, normalMapStrength, materialNormalMapPropertyName, materialNormalMapScalePropertyName;
|
|
SerializedProperty occlusionSource, occlusionMap, occlusionStrength, materialOcclusionMapPropertyName, materialOcclusionStrengthPropertyName;
|
|
SerializedProperty fresnel, fuzzyness, contactHardening;
|
|
SerializedProperty overrideGlobalSettings;
|
|
SerializedProperty sampleCount, maxRayLength, thickness, binarySearchIterations, refineThickness, thicknessFine, decay, jitter;
|
|
SerializedProperty uvDistortionSpeed, skyboxMultiplier;
|
|
Volume shinyVolume;
|
|
Reflections ssr;
|
|
|
|
private void OnEnable() {
|
|
ignore = serializedObject.FindProperty("ignore");
|
|
scope = serializedObject.FindProperty("scope");
|
|
layerMask = serializedObject.FindProperty("layerMask");
|
|
nameFilter = serializedObject.FindProperty("nameFilter");
|
|
subMeshMask = serializedObject.FindProperty("subMeshMask");
|
|
smoothness = serializedObject.FindProperty("smoothness");
|
|
metallic = serializedObject.FindProperty("metallic");
|
|
smoothnessSource = serializedObject.FindProperty("smoothnessSource");
|
|
customSmoothnessMap = serializedObject.FindProperty("customSmoothnessMap");
|
|
materialSmoothnessMapPropertyName = serializedObject.FindProperty("materialSmoothnessMapPropertyName");
|
|
materialSmoothnessIntensityPropertyName = serializedObject.FindProperty("materialSmoothnessIntensityPropertyName");
|
|
materialReflectivityPropertyName = serializedObject.FindProperty("materialReflectivityPropertyName");
|
|
perSubMeshSmoothness = serializedObject.FindProperty("perSubMeshSmoothness");
|
|
subMeshSettings = serializedObject.FindProperty("subMeshSettings");
|
|
normalSource = serializedObject.FindProperty("normalSource");
|
|
normalMap = serializedObject.FindProperty("normalMap");
|
|
normalMapStrength = serializedObject.FindProperty("normalMapStrength");
|
|
materialNormalMapPropertyName = serializedObject.FindProperty("materialNormalMapPropertyName");
|
|
materialNormalMapScalePropertyName = serializedObject.FindProperty("materialNormalMapScalePropertyName");
|
|
occlusionSource = serializedObject.FindProperty("occlusionSource");
|
|
occlusionMap = serializedObject.FindProperty("occlusionMap");
|
|
occlusionStrength = serializedObject.FindProperty("occlusionStrength");
|
|
materialOcclusionMapPropertyName = serializedObject.FindProperty("materialOcclusionMapPropertyName");
|
|
materialOcclusionStrengthPropertyName = serializedObject.FindProperty("materialOcclusionStrengthPropertyName");
|
|
fresnel = serializedObject.FindProperty("fresnel");
|
|
fuzzyness = serializedObject.FindProperty("fuzzyness");
|
|
contactHardening = serializedObject.FindProperty("contactHardening");
|
|
overrideGlobalSettings = serializedObject.FindProperty("overrideGlobalSettings");
|
|
sampleCount = serializedObject.FindProperty("sampleCount");
|
|
maxRayLength = serializedObject.FindProperty("maxRayLength");
|
|
binarySearchIterations = serializedObject.FindProperty("binarySearchIterations");
|
|
thickness = serializedObject.FindProperty("thickness");
|
|
refineThickness = serializedObject.FindProperty("refineThickness");
|
|
thicknessFine = serializedObject.FindProperty("thicknessFine");
|
|
decay = serializedObject.FindProperty("decay");
|
|
jitter = serializedObject.FindProperty("jitter");
|
|
uvDistortionSpeed = serializedObject.FindProperty("uvDistortionSpeed");
|
|
skyboxMultiplier = serializedObject.FindProperty("skyboxMultiplier");
|
|
|
|
ssr = (Reflections)target;
|
|
Reflections.currentEditingReflections = ssr;
|
|
FindShinySSRRVolume();
|
|
}
|
|
|
|
private void OnDisable() {
|
|
Reflections.currentEditingReflections = null;
|
|
}
|
|
|
|
void FindShinySSRRVolume() {
|
|
Volume[] vols = Misc.FindObjectsOfType<Volume>(true);
|
|
foreach (Volume volume in vols) {
|
|
if (volume.sharedProfile != null && volume.sharedProfile.Has<ShinyScreenSpaceRaytracedReflections>()) {
|
|
shinyVolume = volume;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public override void OnInspectorGUI() {
|
|
|
|
UniversalRenderPipelineAsset pipe = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
|
|
if (pipe == null) {
|
|
EditorGUILayout.HelpBox("Universal Rendering Pipeline asset is not set in 'Project Settings / Graphics or Quality' !", MessageType.Error);
|
|
EditorGUILayout.Separator();
|
|
GUI.enabled = false;
|
|
} else if (!ShinySSRR.installed) {
|
|
EditorGUILayout.HelpBox("Shiny SSR Render Feature must be added to the rendering pipeline renderer.", MessageType.Error);
|
|
if (GUILayout.Button("Go to Universal Rendering Pipeline Asset")) {
|
|
Selection.activeObject = pipe;
|
|
}
|
|
EditorGUILayout.Separator();
|
|
GUI.enabled = false;
|
|
} else {
|
|
EditorGUILayout.BeginVertical(GUI.skin.box);
|
|
|
|
if (shinyVolume != null) {
|
|
if (GUILayout.Button("Show Volume Settings")) {
|
|
Selection.SetActiveObjectWithContext(shinyVolume, null);
|
|
GUIUtility.ExitGUI();
|
|
}
|
|
} else if (pipe != null) {
|
|
if (GUILayout.Button("Show URP Renderer Settings")) {
|
|
var so = new SerializedObject(pipe);
|
|
var prop = so.FindProperty("m_RendererDataList");
|
|
if (prop != null && prop.arraySize > 0) {
|
|
var o = prop.GetArrayElementAtIndex(0);
|
|
if (o != null) {
|
|
Selection.SetActiveObjectWithContext(o.objectReferenceValue, null);
|
|
GUIUtility.ExitGUI();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
// ensure submesh array size matches materials count
|
|
Reflections refl = (Reflections)target;
|
|
if (refl.ssrRenderers != null && refl.ssrRenderers.Count == 1 && refl.ssrRenderers[0].originalMaterials != null) {
|
|
List<Material> materials = refl.ssrRenderers[0].originalMaterials;
|
|
if (refl.subMeshSettings == null) {
|
|
refl.subMeshSettings = new SubMeshSettingsData[materials.Count];
|
|
} else if (refl.subMeshSettings.Length < materials.Count) {
|
|
System.Array.Resize(ref refl.subMeshSettings, materials.Count);
|
|
}
|
|
}
|
|
Reflections.currentEditingReflections = refl;
|
|
|
|
serializedObject.Update();
|
|
|
|
EditorGUILayout.PropertyField(ignore);
|
|
if (!ignore.boolValue) {
|
|
|
|
if (refl.renderers?.Count == 0) {
|
|
if (scope.intValue == (int)Scope.OnlyThisObject) {
|
|
EditorGUILayout.HelpBox("No renderers found on this gameobject. Switch to 'Include Children' or add this script to another object which contains a renderer.", MessageType.Warning);
|
|
} else {
|
|
EditorGUILayout.HelpBox("No renderers found under this gameobject.", MessageType.Warning);
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.PropertyField(scope);
|
|
if (scope.intValue == (int)Scope.IncludeChildren || scope.intValue == (int)Scope.AllObjectsInLayer) {
|
|
EditorGUI.indentLevel++;
|
|
EditorGUILayout.PropertyField(layerMask);
|
|
EditorGUILayout.PropertyField(nameFilter);
|
|
EditorGUILayout.PropertyField(subMeshMask);
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
|
|
EditorGUILayout.PropertyField(smoothnessSource);
|
|
bool usesMaterialSmoothness = smoothnessSource.intValue == (int)SmoothnessSource.Material;
|
|
EditorGUI.indentLevel++;
|
|
switch (smoothnessSource.intValue) {
|
|
case (int)SmoothnessSource.Material:
|
|
EditorGUILayout.LabelField("Default values (used only if not present in the material):", EditorStyles.miniLabel);
|
|
EditorGUILayout.PropertyField(customSmoothnessMap, new GUIContent("Smoothness Map (A)"));
|
|
EditorGUILayout.PropertyField(metallic);
|
|
EditorGUILayout.PropertyField(smoothness);
|
|
break;
|
|
case (int)SmoothnessSource.Custom:
|
|
EditorGUILayout.PropertyField(customSmoothnessMap, new GUIContent("Smoothness Map (A)"));
|
|
if (!perSubMeshSmoothness.boolValue) {
|
|
EditorGUILayout.PropertyField(metallic);
|
|
EditorGUILayout.PropertyField(smoothness);
|
|
}
|
|
EditorGUILayout.PropertyField(perSubMeshSmoothness, new GUIContent("Per SubMesh Values"));
|
|
if (perSubMeshSmoothness.boolValue) {
|
|
EditorGUILayout.PropertyField(subMeshSettings, new GUIContent("Intensities"), true);
|
|
}
|
|
break;
|
|
}
|
|
EditorGUI.indentLevel--;
|
|
|
|
EditorGUILayout.PropertyField(normalSource);
|
|
bool usesMaterialNormal = normalSource.intValue == (int)NormalSource.Material;
|
|
if (ShinySSRR.isDeferredActive && !usesMaterialNormal) {
|
|
EditorGUILayout.HelpBox("In deferred rendering path, Reflections scripts will use material normal maps always.", MessageType.Info);
|
|
usesMaterialNormal = true;
|
|
}
|
|
|
|
EditorGUI.indentLevel++;
|
|
switch (normalSource.intValue) {
|
|
case (int)NormalSource.ScreenSpaceNormals:
|
|
if (ShinySSRR.isDeferredActive) {
|
|
EditorGUILayout.HelpBox("This option should not be used in deferred rendering.", MessageType.Warning);
|
|
} else if (!ShinySSRR.isUsingScreenSpaceNormals) {
|
|
EditorGUILayout.HelpBox("Screen Space Normals option must be enabled in the Shiny SSR Render Feature.", MessageType.Warning);
|
|
if (GUILayout.Button("Go to Universal Rendering Pipeline Asset")) {
|
|
Selection.activeObject = pipe;
|
|
}
|
|
EditorGUILayout.Separator();
|
|
}
|
|
break;
|
|
case (int)NormalSource.Material:
|
|
EditorGUILayout.LabelField("Default values (used only if not present in the material):", EditorStyles.miniLabel);
|
|
EditorGUILayout.PropertyField(normalMap);
|
|
EditorGUILayout.PropertyField(normalMapStrength);
|
|
break;
|
|
case (int)NormalSource.Custom:
|
|
EditorGUILayout.PropertyField(normalMap);
|
|
EditorGUILayout.PropertyField(normalMapStrength);
|
|
break;
|
|
}
|
|
EditorGUI.indentLevel--;
|
|
|
|
EditorGUILayout.PropertyField(occlusionSource);
|
|
bool usesMaterialOcclusion = occlusionSource.intValue == (int)OcclusionSource.Material;
|
|
EditorGUI.indentLevel++;
|
|
switch (occlusionSource.intValue) {
|
|
case (int)OcclusionSource.Material:
|
|
EditorGUILayout.LabelField("Default values (used only if not present in the material):", EditorStyles.miniLabel);
|
|
EditorGUILayout.PropertyField(occlusionMap);
|
|
EditorGUILayout.PropertyField(occlusionStrength);
|
|
break;
|
|
case (int)OcclusionSource.Custom:
|
|
EditorGUILayout.PropertyField(occlusionMap);
|
|
EditorGUILayout.PropertyField(occlusionStrength);
|
|
break;
|
|
}
|
|
EditorGUI.indentLevel--;
|
|
|
|
if (usesMaterialSmoothness || perSubMeshSmoothness.boolValue || usesMaterialNormal || usesMaterialOcclusion) {
|
|
EditorGUILayout.Separator();
|
|
EditorGUILayout.LabelField("Material Property Names", EditorStyles.miniBoldLabel);
|
|
if (usesMaterialSmoothness || perSubMeshSmoothness.boolValue) {
|
|
EditorGUILayout.PropertyField(materialSmoothnessMapPropertyName, new GUIContent("Smoothness Map", "The material property name for the smoothness map"));
|
|
EditorGUILayout.PropertyField(materialReflectivityPropertyName, new GUIContent("Metallic", "The material property name for the metallic intensity"));
|
|
EditorGUILayout.PropertyField(materialSmoothnessIntensityPropertyName, new GUIContent("Smoothness", "The material property name for the smoothness intensity"));
|
|
}
|
|
if (usesMaterialNormal) {
|
|
EditorGUILayout.PropertyField(materialNormalMapPropertyName, new GUIContent("NormalMap", "The material property name for the normal map"));
|
|
EditorGUILayout.PropertyField(materialNormalMapScalePropertyName, new GUIContent("NormalMap Strength", "The material property name for the normal map strength or scale"));
|
|
}
|
|
if (usesMaterialOcclusion) {
|
|
EditorGUILayout.PropertyField(materialOcclusionMapPropertyName, new GUIContent("Occlusion Map", "The material property name for the occlusion map"));
|
|
EditorGUILayout.PropertyField(materialOcclusionStrengthPropertyName, new GUIContent("Occlusion Strength", "The material property name for the occlusion strength"));
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.PropertyField(overrideGlobalSettings, new GUIContent("Override Volume Settings"));
|
|
if (overrideGlobalSettings.boolValue) {
|
|
EditorGUI.indentLevel++;
|
|
EditorGUILayout.BeginHorizontal();
|
|
EditorGUILayout.LabelField("Apply Quality Preset:", GUILayout.Width(EditorGUIUtility.labelWidth));
|
|
if (GUILayout.Button("Fast")) {
|
|
ApplyRaytracingPreset(RaytracingPreset.Fast);
|
|
}
|
|
if (GUILayout.Button("Medium")) {
|
|
ApplyRaytracingPreset(RaytracingPreset.Medium);
|
|
}
|
|
if (GUILayout.Button("High")) {
|
|
ApplyRaytracingPreset(RaytracingPreset.High);
|
|
}
|
|
if (GUILayout.Button("Superb")) {
|
|
ApplyRaytracingPreset(RaytracingPreset.Superb);
|
|
}
|
|
if (GUILayout.Button("Ultra")) {
|
|
ApplyRaytracingPreset(RaytracingPreset.Ultra);
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.PropertyField(sampleCount);
|
|
EditorGUILayout.PropertyField(maxRayLength);
|
|
EditorGUILayout.PropertyField(thickness);
|
|
EditorGUILayout.PropertyField(binarySearchIterations);
|
|
EditorGUILayout.PropertyField(refineThickness);
|
|
if (refineThickness.boolValue) {
|
|
EditorGUILayout.PropertyField(thicknessFine);
|
|
}
|
|
EditorGUILayout.PropertyField(jitter);
|
|
EditorGUILayout.PropertyField(fresnel);
|
|
EditorGUILayout.PropertyField(decay);
|
|
EditorGUILayout.PropertyField(fuzzyness, new GUIContent("Fuzziness"));
|
|
EditorGUILayout.PropertyField(contactHardening);
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.PropertyField(uvDistortionSpeed);
|
|
EditorGUILayout.PropertyField(skyboxMultiplier);
|
|
|
|
float multiplierValue = skyboxMultiplier.floatValue;
|
|
if (multiplierValue < 1f) {
|
|
ShinyScreenSpaceRaytracedReflections globalSettings = VolumeManager.instance?.stack?.GetComponent<ShinyScreenSpaceRaytracedReflections>();
|
|
if (globalSettings != null && globalSettings.skyboxIntensity.value <= 0f) {
|
|
EditorGUILayout.HelpBox("Skybox Intensity is zero in the global settings, so this multiplier has no effect.", MessageType.Warning);
|
|
}
|
|
}
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
|
|
void ApplyRaytracingPreset(RaytracingPreset preset) {
|
|
ssr.ApplyRaytracingPreset(preset);
|
|
EditorUtility.SetDirty(ssr);
|
|
}
|
|
|
|
}
|
|
} |