Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogEditor.cs
2024-08-26 23:07:20 +03:00

270 lines
14 KiB
C#

using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEditorInternal;
using UnityEditor.Rendering;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering.HighDefinition
{
[CanEditMultipleObjects]
[CustomEditor(typeof(LocalVolumetricFog))]
class LocalVolumetricFogEditor : Editor
{
internal const EditMode.SceneViewEditMode k_EditShape = EditMode.SceneViewEditMode.ReflectionProbeBox;
internal const EditMode.SceneViewEditMode k_EditBlend = EditMode.SceneViewEditMode.GridBox;
Editor m_MaterialEditor;
static HierarchicalBox s_ShapeBox;
internal static HierarchicalBox s_BlendBox;
SerializedLocalVolumetricFog m_SerializedLocalVolumetricFog;
void OnEnable()
{
m_SerializedLocalVolumetricFog = new SerializedLocalVolumetricFog(serializedObject);
if (s_ShapeBox == null || s_ShapeBox.Equals(null))
{
s_ShapeBox = new HierarchicalBox(LocalVolumetricFogUI.Styles.k_GizmoColorBase, LocalVolumetricFogUI.Styles.k_BaseHandlesColor);
s_ShapeBox.monoHandle = false;
}
if (s_BlendBox == null || s_BlendBox.Equals(null))
{
s_BlendBox = new HierarchicalBox(LocalVolumetricFogUI.Styles.k_GizmoColorBase, InfluenceVolumeUI.k_HandlesColor, parent: s_ShapeBox);
}
}
void OnDisable()
{
CoreUtils.Destroy(m_MaterialEditor);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
if (!HDRenderPipeline.currentAsset?.currentPlatformRenderPipelineSettings.supportVolumetrics ?? false)
{
HDEditorUtils.QualitySettingsHelpBox("The current HDRP Asset does not support volumetric fog.", MessageType.Error,
HDRenderPipelineUI.ExpandableGroup.Lighting, HDRenderPipelineUI.ExpandableLighting.Volumetric, "m_RenderPipelineSettings.supportVolumetrics");
}
LocalVolumetricFogUI.Inspector.Draw(m_SerializedLocalVolumetricFog, this);
m_SerializedLocalVolumetricFog.Apply();
if ((LocalVolumetricFogMaskMode)m_SerializedLocalVolumetricFog.maskMode.intValue == LocalVolumetricFogMaskMode.Material
&& m_SerializedLocalVolumetricFog.materialMask.objectReferenceValue is Material mat)
{
// Update material target
if (m_MaterialEditor == null || m_MaterialEditor.target != mat)
Editor.CreateCachedEditor(mat, typeof(MaterialEditor), ref m_MaterialEditor);
// Draw material UI
using (new EditorGUI.DisabledScope((mat.hideFlags & HideFlags.NotEditable) != 0))
{
m_MaterialEditor.DrawHeader();
m_MaterialEditor.OnInspectorGUI();
}
}
}
static Vector3 CenterBlendLocalPosition(LocalVolumetricFog localVolumetricFog)
{
if (localVolumetricFog.parameters.m_EditorAdvancedFade)
{
Vector3 size = localVolumetricFog.parameters.size;
Vector3 posBlend = localVolumetricFog.parameters.m_EditorPositiveFade;
posBlend.x *= size.x;
posBlend.y *= size.y;
posBlend.z *= size.z;
Vector3 negBlend = localVolumetricFog.parameters.m_EditorNegativeFade;
negBlend.x *= size.x;
negBlend.y *= size.y;
negBlend.z *= size.z;
Vector3 localPosition = (negBlend - posBlend) * 0.5f;
return localPosition;
}
else
return Vector3.zero;
}
static Vector3 BlendSize(LocalVolumetricFog localVolumetricFog)
{
Vector3 size = localVolumetricFog.parameters.size;
if (localVolumetricFog.parameters.m_EditorAdvancedFade)
{
Vector3 blendSize = (Vector3.one - localVolumetricFog.parameters.m_EditorPositiveFade - localVolumetricFog.parameters.m_EditorNegativeFade);
blendSize.x *= size.x;
blendSize.y *= size.y;
blendSize.z *= size.z;
return blendSize;
}
else
return size - localVolumetricFog.parameters.m_EditorUniformFade * 2f * Vector3.one;
}
[DrawGizmo(GizmoType.Selected | GizmoType.Active)]
static void DrawGizmosSelected(LocalVolumetricFog localVolumetricFog, GizmoType gizmoType)
{
if (s_BlendBox == null || s_BlendBox.Equals(null)
|| s_ShapeBox == null || s_ShapeBox.Equals(null))
return;
using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, Vector3.one)))
{
// Blend box
s_BlendBox.center = CenterBlendLocalPosition(localVolumetricFog);
s_BlendBox.size = BlendSize(localVolumetricFog);
Color baseColor = localVolumetricFog.parameters.albedo;
baseColor.a = 8 / 255f;
s_BlendBox.baseColor = baseColor;
s_BlendBox.DrawHull(EditMode.editMode == k_EditBlend);
// Bounding box.
s_ShapeBox.center = Vector3.zero;
s_ShapeBox.size = localVolumetricFog.parameters.size;
s_ShapeBox.DrawHull(EditMode.editMode == k_EditShape);
}
}
void OnSceneGUI()
{
//Note: for each handle to be independent when multi-selecting LocalVolumetricFog,
//We cannot rely hereon SerializedLocalVolumetricFog which is the collection of
//selected LocalVolumetricFog. Thus code is almost the same of the UI.
LocalVolumetricFog localVolumetricFog = target as LocalVolumetricFog;
switch (EditMode.editMode)
{
case k_EditBlend:
using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, Vector3.one)))
{
//contained must be initialized in all case
s_ShapeBox.center = Vector3.zero;
s_ShapeBox.size = localVolumetricFog.parameters.size;
Color baseColor = localVolumetricFog.parameters.albedo;
baseColor.a = 8 / 255f;
s_BlendBox.baseColor = baseColor;
s_BlendBox.monoHandle = !localVolumetricFog.parameters.m_EditorAdvancedFade;
s_BlendBox.center = CenterBlendLocalPosition(localVolumetricFog);
s_BlendBox.size = BlendSize(localVolumetricFog);
EditorGUI.BeginChangeCheck();
s_BlendBox.DrawHandle();
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(localVolumetricFog, L10n.Tr("Change Local Volumetric Fog Blend"));
if (localVolumetricFog.parameters.m_EditorAdvancedFade)
{
//work in local space to compute the change on positiveFade and negativeFade
Vector3 newCenterBlendLocalPosition = s_BlendBox.center;
Vector3 halfSize = s_BlendBox.size * 0.5f;
Vector3 size = localVolumetricFog.parameters.size;
Vector3 posFade = newCenterBlendLocalPosition + halfSize;
posFade.x = 0.5f - posFade.x / size.x;
posFade.y = 0.5f - posFade.y / size.y;
posFade.z = 0.5f - posFade.z / size.z;
Vector3 negFade = newCenterBlendLocalPosition - halfSize;
negFade.x = 0.5f + negFade.x / size.x;
negFade.y = 0.5f + negFade.y / size.y;
negFade.z = 0.5f + negFade.z / size.z;
localVolumetricFog.parameters.m_EditorPositiveFade = posFade;
localVolumetricFog.parameters.m_EditorNegativeFade = negFade;
}
else
{
float uniformDistance = (s_ShapeBox.size.x - s_BlendBox.size.x) * 0.5f;
float max = Mathf.Min(s_ShapeBox.size.x, s_ShapeBox.size.y, s_ShapeBox.size.z) * 0.5f;
localVolumetricFog.parameters.m_EditorUniformFade = Mathf.Clamp(uniformDistance, 0f, max);
}
}
}
break;
case k_EditShape:
//important: if the origin of the handle's space move along the handle,
//handles displacement will appears as moving two time faster.
using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, localVolumetricFog.transform.rotation, Vector3.one)))
{
//contained must be initialized in all case
s_ShapeBox.center = Quaternion.Inverse(localVolumetricFog.transform.rotation) * localVolumetricFog.transform.position;
s_ShapeBox.size = localVolumetricFog.parameters.size;
Vector3 previousSize = localVolumetricFog.parameters.size;
Vector3 previousPositiveFade = localVolumetricFog.parameters.m_EditorPositiveFade;
Vector3 previousNegativeFade = localVolumetricFog.parameters.m_EditorNegativeFade;
EditorGUI.BeginChangeCheck();
s_ShapeBox.DrawHandle();
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObjects(new Object[] { localVolumetricFog, localVolumetricFog.transform }, L10n.Tr("Change Local Volumetric Fog Bounding Box"));
Vector3 newSize = s_ShapeBox.size;
localVolumetricFog.parameters.size = newSize;
Vector3 newPositiveFade = new Vector3(
newSize.x < 0.00001 ? 0 : previousPositiveFade.x * previousSize.x / newSize.x,
newSize.y < 0.00001 ? 0 : previousPositiveFade.y * previousSize.y / newSize.y,
newSize.z < 0.00001 ? 0 : previousPositiveFade.z * previousSize.z / newSize.z
);
Vector3 newNegativeFade = new Vector3(
newSize.x < 0.00001 ? 0 : previousNegativeFade.x * previousSize.x / newSize.x,
newSize.y < 0.00001 ? 0 : previousNegativeFade.y * previousSize.y / newSize.y,
newSize.z < 0.00001 ? 0 : previousNegativeFade.z * previousSize.z / newSize.z
);
for (int axeIndex = 0; axeIndex < 3; ++axeIndex)
{
if (newPositiveFade[axeIndex] + newNegativeFade[axeIndex] > 1)
{
float overValue = (newPositiveFade[axeIndex] + newNegativeFade[axeIndex] - 1f) * 0.5f;
newPositiveFade[axeIndex] -= overValue;
newNegativeFade[axeIndex] -= overValue;
if (newPositiveFade[axeIndex] < 0)
{
newNegativeFade[axeIndex] += newPositiveFade[axeIndex];
newPositiveFade[axeIndex] = 0f;
}
if (newNegativeFade[axeIndex] < 0)
{
newPositiveFade[axeIndex] += newNegativeFade[axeIndex];
newNegativeFade[axeIndex] = 0f;
}
}
}
localVolumetricFog.parameters.m_EditorPositiveFade = newPositiveFade;
localVolumetricFog.parameters.m_EditorNegativeFade = newNegativeFade;
//update normal mode blend
float max = Mathf.Min(newSize.x, newSize.y, newSize.z) * 0.5f;
float newUniformFade = Mathf.Clamp(localVolumetricFog.parameters.m_EditorUniformFade, 0f, max);
localVolumetricFog.parameters.m_EditorUniformFade = newUniformFade;
//update engine used percents
if (localVolumetricFog.parameters.m_EditorAdvancedFade)
{
localVolumetricFog.parameters.positiveFade = newPositiveFade;
localVolumetricFog.parameters.negativeFade = newNegativeFade;
}
else
{
localVolumetricFog.parameters.positiveFade =
localVolumetricFog.parameters.negativeFade = new Vector3(
1.0f - (newSize.x > 0.00000001 ? (newSize.x - newUniformFade) / newSize.x : 0f),
1.0f - (newSize.y > 0.00000001 ? (newSize.y - newUniformFade) / newSize.y : 0f),
1.0f - (newSize.z > 0.00000001 ? (newSize.z - newUniformFade) / newSize.z : 0f));
}
Vector3 delta = localVolumetricFog.transform.rotation * s_ShapeBox.center - localVolumetricFog.transform.position;
localVolumetricFog.transform.position += delta;
}
}
break;
}
}
}
}