您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

200 行
8.5 KiB

namespace UnityEngine.Experimental.Rendering
{
[RequireComponent(typeof(Light))]
public class AdditionalShadowData : MonoBehaviour
{
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
// We can't rely on Unity for our additional data, we need to version it ourself.
[SerializeField]
float m_Version = 1.0f;
#pragma warning restore 414
public const int DefaultShadowResolution = 512;
public int shadowResolution = DefaultShadowResolution;
public static int GetShadowResolution(AdditionalShadowData shadowData)
{
if (shadowData != null)
return shadowData.shadowResolution;
else
return DefaultShadowResolution;
}
[Range(0.0f, 1.0f)]
public float shadowDimmer = 1.0f;
public float shadowFadeDistance = 10000.0f;
// Contact shadows
public bool enableContactShadows = false;
[Range(0.0f, 1.0f)]
public float contactShadowLength = 0.0f;
[Range(0.0f, 1.0f)]
public float contactShadowDistanceScaleFactor = 0.5f;
public float contactShadowMaxDistance = 50.0f;
public float contactShadowFadeDistance = 5.0f;
[Range(4, 64)]
public uint contactShadowSampleCount = 8;
// shadow related parameters
[System.Serializable]
public struct ShadowData
{
public int format;
public int[] data;
};
[HideInInspector, SerializeField]
private int shadowCascadeCount = 4;
[HideInInspector, SerializeField]
private float[] shadowCascadeRatios = new float[3] { 0.05f, 0.2f, 0.3f };
[HideInInspector, SerializeField]
private float[] shadowCascadeBorders = new float[4] { 0.2f, 0.2f, 0.2f, 0.2f };
[HideInInspector, SerializeField]
private int shadowAlgorithm;
[HideInInspector, SerializeField]
private int shadowVariant;
[HideInInspector, SerializeField]
private int shadowPrecision;
[HideInInspector, SerializeField]
private ShadowData shadowData;
[HideInInspector, SerializeField]
private ShadowData[] shadowDatas = new ShadowData[0];
public int cascadeCount { get { return shadowCascadeCount; } }
public void GetShadowCascades(out int cascadeCount, out float[] cascadeRatios, out float[] cascadeBorders) { cascadeCount = shadowCascadeCount; cascadeRatios = shadowCascadeRatios; cascadeBorders = shadowCascadeBorders; }
public void SetShadowCascades(int cascadeCount, float[] cascadeRatios, float[] cascadeBorders) { shadowCascadeCount = cascadeCount; shadowCascadeRatios = cascadeRatios; shadowCascadeBorders = cascadeBorders; }
public void GetShadowAlgorithm(out int algorithm, out int variant, out int precision) { algorithm = shadowAlgorithm; variant = shadowVariant; precision = shadowPrecision; }
public void SetShadowAlgorithm(int algorithm, int variant, int precision, int format, int[] data)
{
shadowAlgorithm = algorithm;
shadowVariant = variant;
shadowPrecision = precision;
shadowData.format = format;
shadowData.data = data;
int idx = FindShadowData(format);
if (idx < 0)
{
idx = shadowDatas.Length;
ShadowData[] tmp = new ShadowData[idx + 1];
for (int i = 0; i < idx; ++i)
tmp[i] = shadowDatas[i];
shadowDatas = tmp;
}
shadowDatas[idx].format = format;
shadowDatas[idx].data = data != null ? data : new int[0];
}
// Load a specific shadow data. Returns null if requested data is not present.
public int[] GetShadowData(int shadowDataFormat)
{
if (shadowData.format == shadowDataFormat)
return shadowData.data;
int idx = FindShadowData(shadowDataFormat);
return idx >= 0 ? shadowDatas[idx].data : null;
}
// Returns the currently set shadow data and format. Can return null.
public int[] GetShadowData(out int shadowDataFormat)
{
shadowDataFormat = shadowData.format;
return shadowData.data;
}
#if UNITY_EDITOR
public void CompactShadowData()
{
shadowDatas = new ShadowData[0];
UnityEditor.EditorUtility.SetDirty(this);
}
#endif
private int FindShadowData(int shadowDataFormat)
{
for (int i = 0; i < shadowDatas.Length; ++i)
{
if (shadowDatas[i].format == shadowDataFormat)
return i;
}
return -1;
}
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(AdditionalShadowData))]
[UnityEditor.CanEditMultipleObjects]
public class AdditionalShadowDataEditor : UnityEditor.Editor
{
static ShadowRegistry m_ShadowRegistry;
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
UnityEditor.SerializedProperty m_ShadowAlgorithm;
UnityEditor.SerializedProperty m_ShadowVariant;
UnityEditor.SerializedProperty m_ShadowData;
UnityEditor.SerializedProperty m_ShadowDatas;
#pragma warning restore 414
UnityEditor.SerializedProperty m_ShadowCascadeCount;
UnityEditor.SerializedProperty m_ShadowCascadeRatios;
UnityEditor.SerializedProperty m_ShadowCascadeBorders;
public static void SetRegistry( ShadowRegistry registry ) { m_ShadowRegistry = registry; }
void OnEnable()
{
m_ShadowAlgorithm = serializedObject.FindProperty( "shadowAlgorithm" );
m_ShadowVariant = serializedObject.FindProperty( "shadowVariant" );
m_ShadowData = serializedObject.FindProperty( "shadowData" );
m_ShadowDatas = serializedObject.FindProperty( "shadowDatas" );
m_ShadowCascadeCount = serializedObject.FindProperty( "shadowCascadeCount" );
m_ShadowCascadeRatios = serializedObject.FindProperty( "shadowCascadeRatios" );
m_ShadowCascadeBorders = serializedObject.FindProperty( "shadowCascadeBorders" );
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if( m_ShadowRegistry == null )
return;
AdditionalShadowData asd = (AdditionalShadowData) target;
if( asd == null )
return;
UnityEditor.EditorGUI.BeginChangeCheck();
m_ShadowRegistry.Draw( asd.gameObject.GetComponent<Light>() );
serializedObject.Update();
// cascade code
if( asd.gameObject.GetComponent<Light>().type == LightType.Directional )
{
UnityEditor.EditorGUI.BeginChangeCheck();
UnityEditor.EditorGUILayout.PropertyField( m_ShadowCascadeCount );
if( UnityEditor.EditorGUI.EndChangeCheck() )
{
const int kMaxCascades = (int) ShadowAtlas.k_MaxCascadesInShader; // depending on where you look this is either 32 or 4, so we're limiting it to 4 for now
int newcnt = m_ShadowCascadeCount.intValue <= 0 ? 1 : (m_ShadowCascadeCount.intValue > kMaxCascades ? kMaxCascades : m_ShadowCascadeCount.intValue);
m_ShadowCascadeCount.intValue = newcnt;
m_ShadowCascadeRatios.arraySize = newcnt-1;
m_ShadowCascadeBorders.arraySize = newcnt;
}
UnityEditor.EditorGUI.indentLevel++;
for( int i = 0; i < m_ShadowCascadeRatios.arraySize; i++ )
{
UnityEditor.EditorGUILayout.Slider( m_ShadowCascadeRatios.GetArrayElementAtIndex( i ), 0.0f, 1.0f, new GUIContent( "Cascade " + i ) );
}
for (int i = 0; i < m_ShadowCascadeBorders.arraySize; i++)
{
UnityEditor.EditorGUILayout.Slider( m_ShadowCascadeBorders.GetArrayElementAtIndex( i ), 0.0f, 1.0f, new GUIContent( "Transition " + i ) );
}
UnityEditor.EditorGUI.indentLevel--;
}
if( UnityEditor.EditorGUI.EndChangeCheck() )
{
UnityEditor.EditorUtility.SetDirty( asd );
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
UnityEditor.SceneView.RepaintAll();
}
serializedObject.ApplyModifiedProperties();
}
}
#endif
}