浏览代码

Merge trunk

/main
Patrick Fournier 7 年前
当前提交
de93c238
共有 1065 个文件被更改,包括 1455 次插入936 次删除
  1. 2
      .gitignore
  2. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Assets/IGraphAsset.cs
  3. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Assets/SerializableGraphAsset.cs
  4. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/Edge.cs
  5. 4
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/NodeUtils.cs
  6. 92
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraph.cs
  7. 15
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraphObject.cs
  8. 5
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableNode.cs
  9. 18
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableSlot.cs
  10. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SlotType.cs
  11. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/DrawState.cs
  12. 21
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/GraphChange.cs
  13. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/GraphDrawingData.cs
  14. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IEdge.cs
  15. 10
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IGraph.cs
  16. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IGraphObject.cs
  17. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/INode.cs
  18. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IOnAssetEnabled.cs
  19. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/ISlot.cs
  20. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/SlotReference.cs
  21. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/IntegrationTests/SerializationTests.cs
  22. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/UnitTests/SerializedGraphTests.cs
  23. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/DictionaryPool.cs
  24. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/ListPool.cs
  25. 8
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/Logging.cs
  26. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/ObjectPool.cs
  27. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/PooledObject.cs
  28. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/QueuePool.cs
  29. 51
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/SerializationHelper.cs
  30. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/StackPool.cs
  31. 4
      MaterialGraphProject/Assets/NewNodes/Editor/ChannelBlendNode.cs
  32. 2
      MaterialGraphProject/Assets/NewNodes/Editor/CommonMatrixType.cs
  33. 2
      MaterialGraphProject/Assets/NewNodes/Editor/ConstantType.cs
  34. 3
      MaterialGraphProject/Assets/NewNodes/Editor/FractalNode.cs
  35. 4
      MaterialGraphProject/Assets/NewNodes/Editor/FunctionNAddNode.cs
  36. 4
      MaterialGraphProject/Assets/NewNodes/Editor/FunctionNInNOut.cs
  37. 7
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/BlendModeNode.cs
  38. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/BlendModesEnum.cs
  39. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ColorBalanceNode.cs
  40. 9
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ConstantsNode.cs
  41. 17
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/GradientNode.cs
  42. 97
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/HeightToNormalNode.cs
  43. 5
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/LightProbeNode.cs
  44. 7
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ParallaxNode.cs
  45. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/RadialShearNode.cs
  46. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/RandomRangeNode.cs
  47. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ReciprocalSqrtNode.cs
  48. 5
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ReflectionProbeNode.cs
  49. 7
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/SamplerStateNode.cs
  50. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ScaleOffsetNode.cs
  51. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/TangentToWorldNode.cs
  52. 39
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/TextureSamplerNode.cs
  53. 8
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/TransformNode.cs
  54. 6
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/UVTriPlanar.cs
  55. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/AACheckerBoard3dNode.cs
  56. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/AACheckerBoardNode.cs
  57. 7
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/MultiLayerParallaxNode.cs
  58. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/POMNode.cs
  59. 4
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/ScatterNode.cs
  60. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/SphereWarpNode.cs
  61. 4
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/SphericalIndentationNode.cs
  62. 4
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/ToggleNode.cs
  63. 5
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/VertexNormalNode.cs
  64. 537
      MaterialGraphProject/Assets/PartyPreview.ShaderGraph
  65. 3
      MaterialGraphProject/Assets/PartyPreview.ShaderGraph.meta
  66. 4
      MaterialGraphProject/Assets/SRP.meta
  67. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline.meta
  68. 2
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Camera/CameraSwitcher.cs
  69. 82
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Camera/FreeCamera.cs
  70. 19
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/CommandBufferPool.cs
  71. 107
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugActionManager.cs
  72. 14
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugItemHandler.cs
  73. 6
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugItemUI.cs
  74. 3
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuManager.cs
  75. 56
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuState.cs
  76. 3
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuUI.cs
  77. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuUpdater.cs
  78. 14
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugPanel.cs
  79. 39
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugPanelUI.cs
  80. 1
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Debugging.cs
  81. 13
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Editor/DebugMenuEditor.cs
  82. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateBool.cs
  83. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateColor.cs
  84. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateFloat.cs
  85. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateInt.cs
  86. 4
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateUInt.cs
  87. 2
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderGenerator/Editor/CSharpToHLSL.cs
  88. 193
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl
  89. 26
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl
  90. 46
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl
  91. 29
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl
  92. 13
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/EntityLighting.hlsl
  93. 8
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Fibonacci.hlsl
  94. 174
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  95. 9
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl
  96. 9
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Shadow.hlsl
  97. 310
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  98. 46
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowSampling.hlsl
  99. 10
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl
  100. 32
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Wind.hlsl

2
.gitignore


MaterialGraphProject/Library
MaterialGraphProject/obj
MaterialGraphProject/MaterialGraphProject.CSharp.csproj
MaterialGraphProject/MaterialGraphProject.sln.DotSettings.user
*.csproj
MaterialGraphProject/MaterialGraphProject.sln
MaterialGraphProject/Temp

.DS_Store
MaterialGraphProject/Assets/_MingWai/New Custom Texture.asset.meta
MaterialGraphProject/Packages/*
MaterialGraphProject/GeneratedShader.shader
!MaterialGraphProject/Packages/manifest.json

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Assets/IGraphAsset.cs


namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
}

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Assets/SerializableGraphAsset.cs


namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
}

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/Edge.cs


using System;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public class Edge : IEdge

4
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/NodeUtils.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.MaterialGraph;
using UnityEditor.ShaderGraph;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public class SlotConfigurationException : Exception
{

92
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraph.cs


using System.Reflection;
using System.Runtime.InteropServices;
using NUnit.Framework;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public class SerializableGraph : IGraph, ISerializationCallbackReceiver

[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
List<INode> m_AddedNodes = new List<INode>();
[NonSerialized]
List<INode> m_RemovedNodes = new List<INode>();
[NonSerialized]
List<IEdge> m_AddedEdges = new List<IEdge>();
[NonSerialized]
List<IEdge> m_RemovedEdges = new List<IEdge>();
public IEnumerable<INode> addedNodes
{
get { return m_AddedNodes; }
}
public IEnumerable<INode> removedNodes
{
get { return m_RemovedNodes; }
}
public IEnumerable<IEdge> addedEdges
{
get { return m_AddedEdges; }
}
public IEnumerable<IEdge> removedEdges
{
get { return m_RemovedEdges; }
}
public IGraphObject owner { get; set; }
public virtual void ClearChanges()
{
m_AddedNodes.Clear();
m_RemovedNodes.Clear();
m_AddedEdges.Clear();
m_RemovedEdges.Clear();
}
public IEnumerable<T> GetNodes<T>() where T : INode
{
return m_Nodes.Values.OfType<T>();

{
m_Nodes.Add(node.guid, node);
node.owner = this;
NotifyChange(new NodeAddedGraphChange(node));
m_AddedNodes.Add(node);
}
public virtual void RemoveNode(INode node)

m_Nodes.Remove(node.guid);
NotifyChange(new NodeRemovedGraphChange(node));
m_RemovedNodes.Add(node);
ValidateGraph();
}

return;
m_Nodes.Remove(node.guid);
NotifyChange(new NodeRemovedGraphChange(node));
m_RemovedNodes.Add(node);
}
void AddEdgeToNodeEdges(IEdge edge)

return new Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo>();
}
public virtual IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef)
{
if (fromSlotRef == null || toSlotRef == null)
return null;

var newEdge = new Edge(outputSlot, inputSlot);
m_Edges.Add(newEdge);
NotifyChange(new EdgeAddedGraphChange(newEdge));
m_AddedEdges.Add(newEdge);
return newEdge;
}
public virtual IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
{
var newEdge = ConnectNoValidate(fromSlotRef, toSlotRef);
ValidateGraph();
return newEdge;
}

if (m_NodeEdges.TryGetValue(e.outputSlot.nodeGuid, out outputNodeEdges))
outputNodeEdges.Remove(e);
NotifyChange(new EdgeRemovedGraphChange(e));
m_RemovedEdges.Add(e);
}
public INode GetNodeFromGuid(Guid guid)

m_SerializableEdges = null;
foreach (var edge in m_Edges)
AddEdgeToNodeEdges(edge);
OnEnable();
ValidateGraph();
}
public virtual void ValidateGraph()

//manually modifies serialized data
//of if they delete a node in the inspector
//debug view.
foreach (var edge in edges.ToArray())
//debug view.
foreach (var edge in edges.ToArray())
{
var outputNode = GetNodeFromGuid(edge.outputSlot.nodeGuid);
var inputNode = GetNodeFromGuid(edge.inputSlot.nodeGuid);

removedNodeEdges.Add(edge);
}
foreach (var edge in removedNodeEdges)
RemoveEdge(edge);
RemoveEdgeNoValidate(edge);
}
// Remove all nodes and re-add them.

foreach (var node in m_Nodes.Values)
removedNodeGuids.Add(node.guid);
foreach (var nodeGuid in removedNodeGuids)
RemoveNode(m_Nodes[nodeGuid]);
RemoveNodeNoValidate(m_Nodes[nodeGuid]);
ValidateGraph();
AddNode(node);
AddNodeNoValidate(node);
}
// Add edges from other graph which don't exist in this one.

Connect(edge.outputSlot, edge.inputSlot);
ConnectNoValidate(edge.outputSlot, edge.inputSlot);
ValidateGraph();
}
public void OnEnable()

node.OnEnable();
}
}
public OnGraphChange onChange { get; set; }
public IGraphObject owner { get; set; }
protected void NotifyChange(GraphChange change)
{
if (onChange != null)
onChange(change);
}
}
}

15
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraphObject.cs


using System;
using UnityEditor;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public class SerializableGraphObject : ScriptableObject, IGraphObject, ISerializationCallbackReceiver
{

m_DeserializedGraph = deserializedGraph; // graph.ReplaceWith(m_DeserializedGraph);
}
void Validate()
{
if (graph != null)
{
graph.OnEnable();
graph.ValidateGraph();
}
}
Validate();
Undo.undoRedoPerformed += UndoRedoPerformed;
UndoRedoPerformed();
}

5
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public class SerializableNode : INode, ISerializationCallbackReceiver

{}
public OnNodeModified onModified { get; set; }
public OnNodeReplaced onReplaced { get; set; }
public IEnumerable<T> GetInputSlots<T>() where T : ISlot
{

18
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableSlot.cs


using System;
using System.Linq;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public class SerializableSlot : ISlot

unchecked
{
return (m_Id * 397) ^ (owner != null ? owner.GetHashCode() : 0);
}
}
public bool isConnected
{
get
{
// node and graph respectivly
if (owner == null || owner.owner == null)
return false;
var graph = owner.owner;
var edges = graph.GetEdges(slotReference);
return edges.Any();
}
}
}

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SlotType.cs


namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public enum SlotType
{

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/DrawState.cs


using System;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public struct DrawState

21
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/GraphChange.cs


using System;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public abstract class GraphChange {}

}
public IEdge edge { get; private set; }
}
public static class GraphChangeExtensions
{
public static void Match(this GraphChange change,
Action<NodeAddedGraphChange> nodeAdded = null,
Action<NodeRemovedGraphChange> nodeRemoved = null,
Action<EdgeAddedGraphChange> edgeAdded = null,
Action<EdgeRemovedGraphChange> edgeRemoved = null)
{
if (change is NodeAddedGraphChange && nodeAdded != null)
nodeAdded((NodeAddedGraphChange)change);
else if (change is NodeRemovedGraphChange && nodeRemoved != null)
nodeRemoved((NodeRemovedGraphChange)change);
else if (change is EdgeAddedGraphChange && edgeAdded != null)
edgeAdded((EdgeAddedGraphChange)change);
else if (change is EdgeRemovedGraphChange && edgeRemoved != null)
edgeRemoved((EdgeRemovedGraphChange)change);
}
}
}

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/GraphDrawingData.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public class GraphDrawingData : ISerializationCallbackReceiver

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IEdge.cs


using System;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public interface IEdge : IEquatable<IEdge>
{

10
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IGraph.cs


using System;
using System.Collections.Generic;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
public delegate void OnGraphChange(GraphChange change);
public interface IGraph : IOnAssetEnabled
{
IEnumerable<T> GetNodes<T>() where T : INode;

IEnumerable<IEdge> GetEdges(SlotReference s);
void ValidateGraph();
void ReplaceWith(IGraph other);
OnGraphChange onChange { get; set; }
IEnumerable<INode> addedNodes { get; }
IEnumerable<INode> removedNodes { get; }
IEnumerable<IEdge> addedEdges { get; }
IEnumerable<IEdge> removedEdges { get; }
void ClearChanges();
}
}

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IGraphObject.cs


namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public interface IGraphObject
{

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/INode.cs


using System;
using System.Collections.Generic;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public enum ModificationScope
{

public interface INode
{
OnNodeModified onModified { get; set; }
OnNodeReplaced onReplaced { get; set; }
IGraph owner { get; set; }
Guid guid { get; }
Guid RewriteGuid();

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/IOnAssetEnabled.cs


namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public interface IOnAssetEnabled
{

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/ISlot.cs


using System;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public interface ISlot : IEquatable<ISlot>
{

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Interfaces/SlotReference.cs


using System;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
[Serializable]
public class SlotReference : ISerializationCallbackReceiver, IEquatable<SlotReference>

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/IntegrationTests/SerializationTests.cs


using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEditor.Graphing.IntegrationTests
{

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/UnitTests/SerializedGraphTests.cs


using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEditor.Graphing.UnitTests
{

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/DictionaryPool.cs


using System.Collections.Generic;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public static class DictionaryPool<TKey, TValue>
{

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/ListPool.cs


using System.Collections.Generic;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public static class ListPool<T>
{

8
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/Logging.cs


using System;
using UnityEngine;
using Object = System.Object;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
public void LogFormat(LogType logType, Object context, string format, params object[] args)
public void LogFormat(LogType logType, UnityEngine.Object context, string format, params object[] args)
public void LogException(Exception exception, Object context)
public void LogException(Exception exception, UnityEngine.Object context)
{
Console.WriteLine("{0} - {1}", context, exception);
}

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/ObjectPool.cs


using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
class ObjectPool<T> where T : new()
{

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/PooledObject.cs


using System;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public class PooledObject<T> : IDisposable where T : new()
{

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/QueuePool.cs


using System.Collections.Generic;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public static class QueuePool<T>
{

51
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/SerializationHelper.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public static class SerializationHelper
{

[SerializeField]
public string fullName;
[SerializeField]
public string assemblyName;
return !string.IsNullOrEmpty(fullName) && !string.IsNullOrEmpty(assemblyName);
}
public string SearchString()
{
if (!IsValid())
return string.Empty;
return string.Format("{0}, {1}", fullName, assemblyName);
}
public string SearchStringTestable()
{
if (!IsValid())
return string.Empty;
return string.Format("{0}, {1}-testable", fullName, assemblyName);
return !string.IsNullOrEmpty(fullName);
}
}

{
return new TypeSerializationInfo
{
fullName = type.FullName,
assemblyName = type.Assembly.GetName().Name
fullName = type.FullName
private static Type GetTypeFromSerializedString(TypeSerializationInfo typeInfo)
static Type GetTypeFromSerializedString(TypeSerializationInfo typeInfo)
var res = Type.GetType(typeInfo.SearchString());
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
var type = assembly.GetType(typeInfo.fullName);
if (type != null)
return type;
}
// if we are using a 'testable' dll.
if (res == null)
res = Type.GetType(typeInfo.SearchStringTestable());
return res;
return null;
}
public static JSONSerializedElement Serialize<T>(T item)

};
}
private static TypeSerializationInfo DoTypeRemap(TypeSerializationInfo info, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper)
static TypeSerializationInfo DoTypeRemap(TypeSerializationInfo info, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper)
{
TypeSerializationInfo foundInfo;
if (remapper.TryGetValue(info, out foundInfo))

throw new ArgumentException(string.Format("Can not deserialize {0}, it is invalid", item));
TypeSerializationInfo info = item.typeInfo;
info.fullName = info.fullName.Replace("UnityEngine.MaterialGraph", "UnityEditor.ShaderGraph");
info.fullName = info.fullName.Replace("UnityEngine.Graphing", "UnityEditor.Graphing");
info.assemblyName = "Assembly-CSharp-Editor";
throw new ArgumentException(string.Format("Can not deserialize ({0}, {1}), type is invalid", info.assemblyName, info.fullName));
throw new ArgumentException(string.Format("Can not deserialize ({0}), type is invalid", info.fullName));
T instance;
try

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Util/StackPool.cs


using System.Collections.Generic;
namespace UnityEngine.Graphing
namespace UnityEditor.Graphing
{
public static class StackPool<T>
{

4
MaterialGraphProject/Assets/NewNodes/Editor/ChannelBlendNode.cs


using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
/* [Title("Art/ChannelBlend")]
public class ChannelBlend : FunctionNInNOut, IGeneratesFunction

2
MaterialGraphProject/Assets/NewNodes/Editor/CommonMatrixType.cs


namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
public enum CommonMatrixType
{

2
MaterialGraphProject/Assets/NewNodes/Editor/ConstantType.cs


namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
public enum ConstantType
{

3
MaterialGraphProject/Assets/NewNodes/Editor/FractalNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Procedural/Fractal")]
public class FractalNode : CodeFunctionNode

4
MaterialGraphProject/Assets/NewNodes/Editor/FunctionNAddNode.cs


using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
/* [Title("Math/Advanced/Adder")]
public class AddManyNode : FunctionNInNOut, IGeneratesFunction

4
MaterialGraphProject/Assets/NewNodes/Editor/FunctionNInNOut.cs


using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
/* public abstract class FunctionNInNOut : AbstractMaterialNode, IGeneratesBodyCode
{

7
MaterialGraphProject/Assets/NewNodes/Editor/Keep/BlendModeNode.cs


using System.Reflection;
using UnityEditor.MaterialGraph.Drawing.Controls;
using UnityEngine.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Art/BlendMode")]
public class BlendModeNode : CodeFunctionNode

2
MaterialGraphProject/Assets/NewNodes/Editor/Keep/BlendModesEnum.cs


namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
public enum BlendModesEnum
{

3
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ColorBalanceNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Art/Adjustments/ColorBalance")]
public class ColorBalanceNode : CodeFunctionNode

9
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ConstantsNode.cs


using System.Collections.Generic;
using UnityEditor.MaterialGraph.Drawing.Controls;
using UnityEngine.MaterialGraph;
using UnityEngine.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.ShaderGraph;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Math/Constants")]
public class ConstantsNode : AbstractMaterialNode, IGeneratesBodyCode

17
MaterialGraphProject/Assets/NewNodes/Editor/Keep/GradientNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.MaterialGraph.Drawing.Controls;
using UnityEngine.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
Gradient m_Gradient;
Gradient m_Gradient = new Gradient();
[SerializeField]
Vector4[] m_SerializableColorKeys = { new Vector4(1f, 1f, 1f, 0f), new Vector4(0f, 0f, 0f, 1f), };

AddSlot(new Vector1MaterialSlot(BOutputSlotId, k_BOutputSlotName, k_BOutputSlotName, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(AOutputSlotId, k_AOutputSlotName, k_AOutputSlotName, SlotType.Output, 0));
RemoveSlotsNameNotMatching(new[] { TimeInputSlotId, RGBAOutputSlotId, ROutputSlotId, GOutputSlotId, BOutputSlotId, AOutputSlotId });
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
m_SerializableAlphaKeys = null;
m_SerializableColorKeys = null;
m_Gradient.SetKeys(colorKeys, alphaKeys);
}

97
MaterialGraphProject/Assets/NewNodes/Editor/Keep/HeightToNormalNode.cs


using System.Linq;
using JetBrains.Annotations;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
public class HeightToNormalNode : CodeFunctionNode
public class HeightToNormalNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
public const int TextureInput = 0;
public const int TexCoordInput = 1;
public const int TexOffsetInput = 2;
public const int StrengthInput = 3;
public const int NormalOutput = 4;
const string TextureInputName = "Texture";
const string TexCoordInputName = "UV";
const string TexOffsetInputName = "Offset";
const string StrengthInputName = "Strength";
const string NormalOutputName = "Normal";
UpdateNodeAfterDeserialization();
protected override MethodInfo GetFunctionToConvert()
public sealed override void UpdateNodeAfterDeserialization()
return GetType().GetMethod("Unity_HeightToNormal", BindingFlags.Static | BindingFlags.NonPublic);
AddSlot(new Texture2DMaterialSlot(TextureInput, TextureInputName, TextureInputName, SlotType.Input));
AddSlot(new Vector2MaterialSlot(TexCoordInput, TexCoordInputName, TexCoordInputName, SlotType.Input, Vector2.zero));
AddSlot(new Vector1MaterialSlot(TexOffsetInput, TexOffsetInputName, TexOffsetInputName, SlotType.Input, 0.005f));
AddSlot(new Vector1MaterialSlot(StrengthInput, StrengthInputName, StrengthInputName, SlotType.Input, 8f));
AddSlot(new Vector3MaterialSlot(NormalOutput, NormalOutputName, NormalOutputName, SlotType.Output, Vector3.zero));
static string Unity_HeightToNormal(
[Slot(0, Binding.None)] Texture2D heightmap,
[Slot(1, Binding.MeshUV0)] Vector1 texCoord,
[Slot(2, Binding.None, 0.005f, 0, 0, 0)] Vector1 texOffset,
[Slot(3, Binding.None, 8f, 0, 0, 0)] Vector1 strength,
[Slot(4, Binding.None)] out Vector1 normal)
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
return
@"
{
float2 offsetU = float2(texCoord.x + texOffset, texCoord.y);
float2 offsetV = float2(texCoord.x, texCoord.y + texOffset);
var textureInput = GetSlotValue(TextureInput, generationMode);
var texCoordInput = RequiresMeshUV(UVChannel.uv0)
? string.Format("{0}.xy", UVChannel.uv0.GetUVName())
: GetSlotValue(TexCoordInput, generationMode);
var texOffsetInput = GetSlotValue(TexOffsetInput, generationMode);
var strengthInput = GetSlotValue(StrengthInput, generationMode);
var normalOutput = GetVariableNameForSlot(NormalOutput);
visitor.AddShaderChunk(string.Format("{0}3 {1};", precision, normalOutput), true);
visitor.AddShaderChunk("{", false);
visitor.Indent();
{
visitor.AddShaderChunk(string.Format("{0}2 offsetU = float2({1}.x + {2}, {1}.y);", precision, texCoordInput, texOffsetInput), true);
visitor.AddShaderChunk(string.Format("{0}2 offsetV = float2({1}.x, {1}.y + {2});", precision, texCoordInput, texOffsetInput), true);
float normalSample = 0;
float uSample = 0;
float vSample = 0;
visitor.AddShaderChunk(string.Format("{0} normalSample = UNITY_SAMPLE_TEX2D({1}, {2});", precision, textureInput, texCoordInput), true);
visitor.AddShaderChunk(string.Format("{0} uSample = UNITY_SAMPLE_TEX2D({1}, offsetU);", precision, textureInput), true);
visitor.AddShaderChunk(string.Format("{0} vSample = UNITY_SAMPLE_TEX2D({1}, offsetV);", precision, textureInput), true);
#ifdef UNITY_COMPILER_HLSL
normalSample = heightmap.Sample(my_linear_repeat_sampler, texCoord).r;
uSample = heightmap.Sample(my_linear_repeat_sampler, offsetU).r;
vSample = heightmap.Sample(my_linear_repeat_sampler, offsetV).r;
#endif
visitor.AddShaderChunk(string.Format("{0}3 va = float3(1, 0, (uSample - normalSample) * {1});", precision, strengthInput), true);
visitor.AddShaderChunk(string.Format("{0}3 vb = float3(0, 1, (vSample - normalSample) * {1});", precision, strengthInput), true);
visitor.AddShaderChunk(string.Format("{0} = cross(va, vb);", normalOutput), true);
}
visitor.Deindent();
visitor.AddShaderChunk("}", false);
}
float uMinusNormal = uSample - normalSample;
float vMinusNormal = vSample - normalSample;
public override bool hasPreview
{
get { return true; }
}
uMinusNormal = uMinusNormal * strength;
vMinusNormal = vMinusNormal * strength;
public bool RequiresMeshUV(UVChannel channel)
{
if (channel != UVChannel.uv0)
{
return false;
}
float3 va = float3(1, 0, uMinusNormal);
float3 vb = float3(0, 1, vMinusNormal);
var uvSlot = FindInputSlot<MaterialSlot>(TexCoordInput);
if (uvSlot == null)
return true;
normals = cross(va, vb);
}
";
var edges = owner.GetEdges(uvSlot.slotReference).ToList();
return edges.Count == 0;
}
}
}

5
MaterialGraphProject/Assets/NewNodes/Editor/Keep/LightProbeNode.cs


using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Input/Scene Data/Light Probe")]
public class LightProbeNode : CodeFunctionNode

7
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ParallaxNode.cs


using UnityEngine.Graphing;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/Parallax")]

return GetFunctionName() + " (" +
inputValue1 + ", " +
channel.GetUVName() + ", " +
ShaderGeneratorNames.TangentSpaceViewDirection + ")";
CoordinateSpace.View.ToVariableName(InterpolatorType.Tangent) + ")";
}
public bool RequiresMeshUV(UVChannel channel)

3
MaterialGraphProject/Assets/NewNodes/Editor/Keep/RadialShearNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/RadialShearNode")]
public class RadialShearNode : CodeFunctionNode

3
MaterialGraphProject/Assets/NewNodes/Editor/Keep/RandomRangeNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Math/Range/RandomRange")]
public class RandomRangeNode : CodeFunctionNode

2
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ReciprocalSqrtNode.cs


using System.Reflection;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Math/Advanced/Reciprocal Square Root")]
public class ReciprocalSqrtNode : CodeFunctionNode

5
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ReflectionProbeNode.cs


using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Input/Scene Data/Reflection Probe")]
public class ReflectionProbeNode : CodeFunctionNode

7
MaterialGraphProject/Assets/NewNodes/Editor/Keep/SamplerStateNode.cs


using System;
using UnityEditor.MaterialGraph.Drawing.Controls;
using UnityEngine.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Input/Texture/Sampler State")]
public class SamplerStateNode : AbstractMaterialNode

3
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ScaleOffsetNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/ScaleOffset")]
public class ScaleOffsetNode : CodeFunctionNode

3
MaterialGraphProject/Assets/NewNodes/Editor/Keep/TangentToWorldNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Math/Vector/TangentToWorld")]
public class TangentToWorldNode : CodeFunctionNode

39
MaterialGraphProject/Assets/NewNodes/Editor/Keep/TextureSamplerNode.cs


using System.Linq;
using System.Reflection;
using UnityEngine.Graphing;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Texture/Sample 2D")]
public class Sample2DTexture : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV

AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0));
AddSlot(new Texture2DMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName, SlotType.Input));
AddSlot(new Vector2MaterialSlot(UVInput, kUVInputName, kUVInputName, SlotType.Input, Vector4.zero));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.uv0));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInput, SamplerInput });
}

{
//Texture input slot
var textureSlot = FindInputSlot<MaterialSlot>(TextureInputId);
var edgesTexture = owner.GetEdges(textureSlot.slotReference);
// if no texture connected return nothing
if (!edgesTexture.Any())
{
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(OutputSlotRGBAId) + " = " + precision + "4(0,0,0,0);", true);
return;
}
//UV input slot
var uvSlot = FindInputSlot<MaterialSlot>(UVInput);
var uvName = string.Format("{0}.xy", UVChannel.uv0.GetUVName());
var edgesUV = owner.GetEdges(uvSlot.slotReference);
if (edgesUV.Any())
uvName = GetSlotValue(UVInput, generationMode);
var uvName = GetSlotValue(UVInput, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);

public bool RequiresMeshUV(UVChannel channel)
{
if (channel != UVChannel.uv0)
{
var uvSlot = FindInputSlot<MaterialSlot>(UVInput) as UVMaterialSlot;
if (uvSlot == null)
}
var uvSlot = FindInputSlot<MaterialSlot>(UVInput);
if (uvSlot == null)
return true;
if (uvSlot.isConnected)
return false;
var edges = owner.GetEdges(uvSlot.slotReference).ToList();
return edges.Count == 0;
return uvSlot.RequiresMeshUV(channel);
}
}
}

8
MaterialGraphProject/Assets/NewNodes/Editor/Keep/TransformNode.cs


using UnityEngine.Graphing;
using System.Collections.Generic;
using UnityEditor.MaterialGraph.Drawing.Controls;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Math/Vector/Transform")]
public class TransformNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireTangent, IMayRequireBitangent, IMayRequireNormal

6
MaterialGraphProject/Assets/NewNodes/Editor/Keep/UVTriPlanar.cs


using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
/* [Title("UV/Tri-Planar Mapping")]
public class UVTriPlanar : FunctionNInNOut, IGeneratesFunction, IMayRequireNormal, IMayRequireWorldPosition

/*
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/Tri-Planar Mapping")]
public class UVTriPlanar : FunctionNInNOut, IGeneratesFunction, IMayRequireNormal, IMayRequireWorldPosition

3
MaterialGraphProject/Assets/NewNodes/Editor/Kill/AACheckerBoard3dNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Procedural/AACheckerboard3d")]
public class AACheckerboard3dNode : CodeFunctionNode

3
MaterialGraphProject/Assets/NewNodes/Editor/Kill/AACheckerBoardNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Procedural/AACheckerboard")]
public class AACheckerboardNode : CodeFunctionNode

7
MaterialGraphProject/Assets/NewNodes/Editor/Kill/MultiLayerParallaxNode.cs


using UnityEngine.Graphing;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/MultiLayerParallax")]
public class MultiLayerParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirection

layerCountValue + ", " +
texValue + ", " +
UVChannel.uv0.GetUVName() + ", " +
ShaderGeneratorNames.TangentSpaceViewDirection + ")";
CoordinateSpace.View.ToVariableName(InterpolatorType.Tangent) + ")";
}
public bool RequiresMeshUV(UVChannel channel)

3
MaterialGraphProject/Assets/NewNodes/Editor/Kill/POMNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/ParallaxOcclusionMapping")]
public class ParallaxOcclusionMappingNode : CodeFunctionNode

4
MaterialGraphProject/Assets/NewNodes/Editor/Kill/ScatterNode.cs


using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
/* [Title("Procedural/Scatter")]
public class ScatterNode : FunctionNInNOut, IGeneratesFunction

3
MaterialGraphProject/Assets/NewNodes/Editor/Kill/SphereWarpNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/SphereWarpNode")]
public class SphereWarpNode : CodeFunctionNode

4
MaterialGraphProject/Assets/NewNodes/Editor/Kill/SphericalIndentationNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("UV/SphericalIndentation")]
public class SphericalIndentationNode : CodeFunctionNode

4
MaterialGraphProject/Assets/NewNodes/Editor/Kill/ToggleNode.cs


using UnityEngine.Graphing;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
/* [Title("Input/Toggle")]
public class ToggleNode : PropertyNode, IGeneratesBodyCode

5
MaterialGraphProject/Assets/NewNodes/Editor/Kill/VertexNormalNode.cs


using UnityEngine.Graphing;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEngine.MaterialGraph
namespace UnityEditor.ShaderGraph
{
[Title("Input/Geometry/Vertex Normal")]
public class VertexNormalNode : AbstractMaterialNode

537
MaterialGraphProject/Assets/PartyPreview.ShaderGraph
文件差异内容过多而无法显示
查看文件

3
MaterialGraphProject/Assets/PartyPreview.ShaderGraph.meta


externalObjects: {}
defaultTextures: []
nonModifiableTextures:
- Texture_507A46B3: {fileID: 2800000, guid: e2e7994f2c9b58f40aaebdaabbbd0ad8, type: 3}
- Texture_507A46B3: {fileID: 2800000, guid: a653bbc25cc7e4794829cf7b1184abcb, type: 3}
- Texture_E2350D28: {fileID: 2800000, guid: 7296f51323ae9485a9c834c4e3d722ed, type: 3}
userData:
assetBundleName:
assetBundleVariant:

4
MaterialGraphProject/Assets/SRP.meta


fileFormatVersion: 2
guid: c29d1b9487ffd4a729adcbe0f197a3f4
guid: 612579e2db831754e87f0b4b938dbfaf
timeCreated: 1505274236
timeCreated: 1504184175
licenseType: Pro
DefaultImporter:
externalObjects: {}

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline.meta


fileFormatVersion: 2
guid: fd470011795144262bf5aa4bf5f396a1
guid: 22c204b70537f8d46a054fa00bf16298
timeCreated: 1505274236
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:

2
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Camera/CameraSwitcher.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering

82
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Camera/FreeCamera.cs


using System.Collections.Generic;
[ExecuteInEditMode]
public float m_MoveSpeed = 50.0f;
public float m_MoveSpeed = 10.0f;
public float m_Turbo = 10.0f;
private static string kMouseX = "Mouse X";

private static string kVertical = "Vertical";
private static string kHorizontal = "Horizontal";
private string[] m_RequiredInputAxes = { kMouseX, kMouseY, kRightStickX, kRightStickY, kVertical, kHorizontal };
private bool m_Valid = true;
m_Valid = Debugging.CheckRequiredInputAxisMapping(m_RequiredInputAxes);
RegisterInputs();
}
void RegisterInputs()
{
#if UNITY_EDITOR
List <InputManagerEntry> inputEntries = new List<InputManagerEntry>();
// Add new bindings
inputEntries.Add(new InputManagerEntry { name = kRightStickX, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Fourth, sensitivity = 1.0f, gravity = 1.0f, deadZone = 0.2f });
inputEntries.Add(new InputManagerEntry { name = kRightStickY, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Fifth, sensitivity = 1.0f, gravity = 1.0f, deadZone = 0.2f, invert = true });
InputRegistering.RegisterInputs(inputEntries);
#endif
if (m_Valid)
float inputRotateAxisX = 0.0f;
float inputRotateAxisY = 0.0f;
if (Input.GetMouseButton(1))
float inputRotateAxisX = 0.0f;
float inputRotateAxisY = 0.0f;
if (Input.GetMouseButton(1))
{
inputRotateAxisX = Input.GetAxis(kMouseX) * m_LookSpeedMouse;
inputRotateAxisY = Input.GetAxis(kMouseY) * m_LookSpeedMouse;
}
inputRotateAxisX += (Input.GetAxis(kRightStickX) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisY += (Input.GetAxis(kRightStickY) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisX = Input.GetAxis(kMouseX) * m_LookSpeedMouse;
inputRotateAxisY = Input.GetAxis(kMouseY) * m_LookSpeedMouse;
}
inputRotateAxisX += (Input.GetAxis(kRightStickX) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisY += (Input.GetAxis(kRightStickY) * m_LookSpeedController * Time.deltaTime);
float inputVertical = Input.GetAxis(kVertical);
float inputHorizontal = Input.GetAxis(kHorizontal);
float inputVertical = Input.GetAxis(kVertical);
float inputHorizontal = Input.GetAxis(kHorizontal);
bool moved = inputRotateAxisX != 0.0f || inputRotateAxisY != 0.0f || inputVertical != 0.0f || inputHorizontal != 0.0f;
if (moved)
{
float rotationX = transform.localEulerAngles.x;
float newRotationY = transform.localEulerAngles.y + inputRotateAxisX;
bool moved = inputRotateAxisX != 0.0f || inputRotateAxisY != 0.0f || inputVertical != 0.0f || inputHorizontal != 0.0f;
if (moved)
{
float rotationX = transform.localEulerAngles.x;
float newRotationY = transform.localEulerAngles.y + inputRotateAxisX;
// Weird clamping code due to weird Euler angle mapping...
float newRotationX = (rotationX - inputRotateAxisY);
if (rotationX <= 90.0f && newRotationX >= 0.0f)
newRotationX = Mathf.Clamp(newRotationX, 0.0f, 90.0f);
if (rotationX >= 270.0f)
newRotationX = Mathf.Clamp(newRotationX, 270.0f, 360.0f);
// Weird clamping code due to weird Euler angle mapping...
float newRotationX = (rotationX - inputRotateAxisY);
if (rotationX <= 90.0f && newRotationX >= 0.0f)
newRotationX = Mathf.Clamp(newRotationX, 0.0f, 90.0f);
if (rotationX >= 270.0f)
newRotationX = Mathf.Clamp(newRotationX, 270.0f, 360.0f);
transform.localRotation = Quaternion.Euler(newRotationX, newRotationY, transform.localEulerAngles.z);
transform.localRotation = Quaternion.Euler(newRotationX, newRotationY, transform.localEulerAngles.z);
float moveSpeed = Time.deltaTime * m_MoveSpeed;
if (Input.GetMouseButton(1))
moveSpeed *= Input.GetKey(KeyCode.LeftShift) ? m_Turbo : 1.0f;
else
moveSpeed *= Input.GetAxis("Fire1") > 0.0f ? m_Turbo : 1.0f;
transform.position += transform.forward * moveSpeed * inputVertical;
transform.position += transform.right * moveSpeed * inputHorizontal;
}
float moveSpeed = Time.deltaTime * m_MoveSpeed;
if (Input.GetMouseButton(1))
moveSpeed *= Input.GetKey(KeyCode.LeftShift) ? m_Turbo : 1.0f;
else
moveSpeed *= Input.GetAxis("Fire1") > 0.0f ? m_Turbo : 1.0f;
transform.position += transform.forward * moveSpeed * inputVertical;
transform.position += transform.right * moveSpeed * inputHorizontal;
}
}
}

19
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/CommandBufferPool.cs


namespace UnityEngine.Experimental.Rendering
{
internal class ObjectPool<T> where T : new()
class ObjectPool<T> where T : new()
private readonly Stack<T> m_Stack = new Stack<T>();
private readonly UnityAction<T> m_ActionOnGet;
private readonly UnityAction<T> m_ActionOnRelease;
readonly Stack<T> m_Stack = new Stack<T>();
readonly UnityAction<T> m_ActionOnGet;
readonly UnityAction<T> m_ActionOnRelease;
public int countAll { get; private set; }
public int countActive { get { return countAll - countInactive; } }

m_Stack.Push(element);
}
}
private static ObjectPool<CommandBuffer> m_BufferPool = new ObjectPool<CommandBuffer>(null, x => x.Clear());
static ObjectPool<CommandBuffer> s_BufferPool = new ObjectPool<CommandBuffer>(null, x => x.Clear());
var cmd = m_BufferPool.Get();
var cmd = s_BufferPool.Get();
var cmd = m_BufferPool.Get();
var cmd = s_BufferPool.Get();
cmd.name = name;
return cmd;
}

m_BufferPool.Release(buffer);
s_BufferPool.Release(buffer);
}
}
}

107
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugActionManager.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering

persistent.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.MakePersistent, persistent);
AddAction(DebugAction.MoveVertical, new DebugActionDesc { axisTrigger = kDPadVertical, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.2f });
AddAction(DebugAction.MoveHorizontal, new DebugActionDesc { axisTrigger = kDPadHorizontal, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.2f });
AddAction(DebugAction.MoveVertical, new DebugActionDesc { axisTrigger = kDPadVertical, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.4f });
AddAction(DebugAction.MoveHorizontal, new DebugActionDesc { axisTrigger = kDPadHorizontal, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.4f });
}
DebugActionManager()

void RegisterInputs()
{
#if UNITY_EDITOR
// Grab reference to input manager
var currentSelection = UnityEditor.Selection.activeObject;
UnityEditor.EditorApplication.ExecuteMenuItem("Edit/Project Settings/Input");
var inputManager = UnityEditor.Selection.activeObject;
// Wrap in serialized object
var soInputManager = new UnityEditor.SerializedObject(inputManager);
var spAxes = soInputManager.FindProperty("m_Axes");
List <InputManagerEntry > inputEntries = new List<InputManagerEntry>();
new InputManagerEntry { name = kEnableDebugBtn1, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left ctrl", altBtnPositive = "joystick button 8" }.WriteEntry(spAxes);
new InputManagerEntry { name = kEnableDebugBtn2, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "backspace", altBtnPositive = "joystick button 9" }.WriteEntry(spAxes);
inputEntries.Add(new InputManagerEntry { name = kEnableDebugBtn1, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left ctrl", altBtnPositive = "joystick button 8" });
inputEntries.Add(new InputManagerEntry { name = kEnableDebugBtn2, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "backspace", altBtnPositive = "joystick button 9" });
inputEntries.Add(new InputManagerEntry { name = kDebugNextBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page down", altBtnPositive = "joystick button 5" });
inputEntries.Add(new InputManagerEntry { name = kDebugPreviousBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page up", altBtnPositive = "joystick button 4" });
new InputManagerEntry { name = kDebugNextBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page down", altBtnPositive = "joystick button 5" }.WriteEntry(spAxes);
new InputManagerEntry { name = kDebugPreviousBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page up", altBtnPositive = "joystick button 4" }.WriteEntry(spAxes);
new InputManagerEntry { name = kDPadHorizontal, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right", btnNegative = "left", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f }.WriteEntry(spAxes);
new InputManagerEntry { name = kDPadHorizontal, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Sixth, btnPositive = "right", btnNegative = "left", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f }.WriteEntry(spAxes);
new InputManagerEntry { name = kDPadVertical, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "up", btnNegative = "down", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f }.WriteEntry(spAxes);
new InputManagerEntry { name = kDPadVertical, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Seventh, btnPositive = "up", btnNegative = "down", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f }.WriteEntry(spAxes);
inputEntries.Add(new InputManagerEntry { name = kDPadHorizontal, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right", btnNegative = "left", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kDPadHorizontal, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Sixth, btnPositive = "right", btnNegative = "left", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kDPadVertical, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "up", btnNegative = "down", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kDPadVertical, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Seventh, btnPositive = "up", btnNegative = "down", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kValidateBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "return", altBtnPositive = "joystick button 0" });
inputEntries.Add(new InputManagerEntry { name = kPersistentBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right shift", altBtnPositive = "joystick button 2" });
new InputManagerEntry { name = kValidateBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "return", altBtnPositive = "joystick button 0" }.WriteEntry(spAxes);
new InputManagerEntry { name = kPersistentBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right shift", altBtnPositive = "joystick button 2" }.WriteEntry(spAxes);
// Commit
soInputManager.ApplyModifiedProperties();
UnityEditor.Selection.activeObject = currentSelection;
InputRegistering.RegisterInputs(inputEntries);
#if UNITY_EDITOR
class InputManagerEntry
{
public enum Kind { KeyOrButton, Mouse, Axis }
public enum Axis { X, Y, Third, Fourth, Fifth, Sixth, Seventh, Eigth }
public enum Joy { All, First, Second }
public string name = "";
public string desc = "";
public string btnNegative = "";
public string btnPositive = "";
public string altBtnNegative = "";
public string altBtnPositive = "";
public float gravity = 0.0f;
public float deadZone = 0.0f;
public float sensitivity = 0.0f;
public bool snap = false;
public bool invert = false;
public Kind kind = Kind.Axis;
public Axis axis = Axis.X;
public Joy joystick = Joy.All;
bool InputAlreadyRegistered(string name, Kind kind, UnityEditor.SerializedProperty spAxes)
{
for (var i = 0; i < spAxes.arraySize; ++i )
{
var spAxis = spAxes.GetArrayElementAtIndex(i);
var axisName = spAxis.FindPropertyRelative("m_Name").stringValue;
var kindValue = spAxis.FindPropertyRelative("type").intValue;
if (axisName == name && (int)kind == kindValue)
return true;
}
return false;
}
public void WriteEntry(UnityEditor.SerializedProperty spAxes)
{
if(InputAlreadyRegistered(name, kind, spAxes))
return;
spAxes.InsertArrayElementAtIndex(spAxes.arraySize);
var spAxis = spAxes.GetArrayElementAtIndex(spAxes.arraySize - 1);
spAxis.FindPropertyRelative("m_Name").stringValue = name;
spAxis.FindPropertyRelative("descriptiveName").stringValue = desc;
spAxis.FindPropertyRelative("negativeButton").stringValue = btnNegative;
spAxis.FindPropertyRelative("altNegativeButton").stringValue = altBtnNegative;
spAxis.FindPropertyRelative("positiveButton").stringValue = btnPositive;
spAxis.FindPropertyRelative("altPositiveButton").stringValue = altBtnPositive;
spAxis.FindPropertyRelative("gravity").floatValue = gravity;
spAxis.FindPropertyRelative("dead").floatValue = deadZone;
spAxis.FindPropertyRelative("sensitivity").floatValue = sensitivity;
spAxis.FindPropertyRelative("snap").boolValue = snap;
spAxis.FindPropertyRelative("invert").boolValue = invert;
spAxis.FindPropertyRelative("type").intValue = (int)kind;
spAxis.FindPropertyRelative("axis").intValue = (int)axis;
spAxis.FindPropertyRelative("joyNum").intValue = (int)joystick;
}
}
#endif
}
}

14
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugItemHandler.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using System;

m_DebugItem = item;
}
// Method user needs to override for specific value clamping.
public virtual void ClampValues(Func<object> getter, Action<object> setter) {}
// Method user needs to override for specific value validation.
public virtual void ValidateValues(Func<object> getter, Action<object> setter) {}
// Method that will create UI items for runtime debug menu.
public abstract DebugItemUI BuildGUI(GameObject parent);

public void OnEditorGUI()
{
if (m_DebugItem.runtimeOnly)
return;
if(OnEditorGUIImpl())
{
DebugMenuUI.changed = true;

m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
setter(Mathf.Clamp((float)getter(), m_Min, m_Max));
}

m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
setter(Math.Min(m_Max, Math.Max(m_Min, (uint)getter())));
}

6
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugItemUI.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

protected DebugItem m_DebugItem = null;
public bool dynamicDisplay { get { return (m_DebugItem.flags & DebugItemFlag.DynamicDisplay) != 0; } }
public DebugItem debugItem { get { return m_DebugItem; } }
protected DebugItemUI(DebugItem debugItem)
{

3
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuManager.cs


using System;
using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

if(m_DebugMenuState != null && m_DebugMenuStateDirty)
{
m_DebugMenuStateDirty = false;
m_DebugMenuState.UpdateAllDebugItems();
m_DebugMenuState.ReInitializeDebugItemStates();
}
m_DebugMenuUI.Update();

56
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuState.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
[Serializable]
public abstract class DebugItemState
: ScriptableObject
{

#if UNITY_EDITOR
UnityEditor.Undo.undoRedoPerformed += OnUndoRedoPerformed;
#endif
DebugMenuManager.instance.SetDebugMenuState(this);
}
public void OnDisable()
{
DebugMenuManager.instance.SetDebugMenuState(null);
#if UNITY_EDITOR
UnityEditor.Undo.undoRedoPerformed -= OnUndoRedoPerformed;
#endif
}
public void ReInitializeDebugItemStates()
{
CleanUp();
// Populate item states
DebugMenuManager dmm = DebugMenuManager.instance;
for (int panelIdx = 0; panelIdx < dmm.panelCount; ++panelIdx)

if (debugItemState == null)
{
debugItemState = item.handler.CreateDebugItemState();
debugItemState.hideFlags = HideFlags.DontSave;
debugItemState.Initialize(item);
debugItemState.SetValue(item.GetValue());
AddDebugItemState(debugItemState);
if (debugItemState != null)
{
debugItemState.hideFlags = HideFlags.DontSave;
debugItemState.Initialize(item);
debugItemState.SetValue(item.GetValue());
AddDebugItemState(debugItemState);
}
else
{
Debug.LogWarning(String.Format("DebugItemState for item {0} of type {1} is not provided.\nDid you implement CreateDebugItemState in your custom Handler?", item.name, item.type));
}
DebugMenuManager.instance.SetDebugMenuState(this);
UpdateAllDebugItems();
public void OnDisable()
private void CleanUp()
#if UNITY_EDITOR
UnityEditor.Undo.undoRedoPerformed -= OnUndoRedoPerformed;
#endif
foreach (var item in m_ItemStateList)
{
Object.DestroyImmediate(item);
}
m_ItemStateList.Clear();
foreach(var item in m_ItemStateList)
{
Object.DestroyImmediate(item);
}
CleanUp();
}
void OnUndoRedoPerformed()

#endif
}
public void AddDebugItemState(DebugItemState state)
private void AddDebugItemState(DebugItemState state)
{
m_ItemStateList.Add(state);
}

return m_ItemStateList.Find(x => x.itemName == item.name && x.panelName == item.panelName);
}
public void UpdateAllDebugItems()
private void UpdateAllDebugItems()
{
foreach (var itemState in m_ItemStateList)
{

3
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuUI.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugMenuUpdater.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

14
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugPanel.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using System;

public enum DebugItemFlag
{
None,
DynamicDisplay,
EditorOnly
None = 0,
DynamicDisplay = 1 << 0,
EditorOnly = 1 << 1,
RuntimeOnly = 1 << 2
}
public class DebugItem

public DebugItemHandler handler { get { return m_Handler; } }
public DebugItemFlag flags { get { return m_Flags; } }
public bool readOnly { get { return m_Setter == null; } }
public bool editorOnly { get { return (flags & DebugItemFlag.EditorOnly) != 0; } }
public bool runtimeOnly { get { return (flags & DebugItemFlag.RuntimeOnly) != 0; } }
public DebugItem(string name, string panelName, Type type, Func<object> getter, Action<object> setter, DebugItemFlag flags = DebugItemFlag.None, DebugItemHandler handler = null)
{

if(m_Setter != null)
{
m_Setter(value);
m_Handler.ClampValues(m_Getter, m_Setter);
m_Handler.ValidateValues(m_Getter, m_Setter);
}
if (record && OnItemDirty != null)

39
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/DebugPanelUI.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using System;

GameObject.Destroy(child.gameObject);
}
m_ItemsUI.Clear();
protected void AddDebugItemUI(DebugItem item, GameObject parent)
{
#if UNITY_EDITOR
// We don't want runtime only items even in the "player" debug menu if we are in the editor.
if (item.runtimeOnly)
return;
#endif
if(item.editorOnly)
return;
DebugItemUI itemUI = item.handler.BuildGUI(parent);
if(itemUI == null)
{
Debug.LogWarning(String.Format("DebugItemUI not provided for item {0} of type {1}.\n Did you implement BuildGUI for your custom Handler?", item.name, item.type));
}
else
{
m_ItemsUI.Add(itemUI);
}
}
m_ItemsUI.Clear();
if(!((item.flags & DebugItemFlag.EditorOnly) != 0))
{
DebugItemHandler handler = item.handler; // Should never be null, we have at least the default handler
m_ItemsUI.Add(handler.BuildGUI(parent));
}
AddDebugItemUI(item, parent);
}
}

{
if (m_SelectedItem != -1)
{
return m_DebugPanel.GetDebugItem(m_SelectedItem);
return m_ItemsUI[m_SelectedItem].debugItem;
}
return null;

public void OnMoveHorizontal(float value)
{
if (m_SelectedItem != -1 && !m_DebugPanel.GetDebugItem(m_SelectedItem).readOnly)
if (m_SelectedItem != -1 && !m_ItemsUI[m_SelectedItem].debugItem.readOnly)
{
if (value > 0.0f)
m_ItemsUI[m_SelectedItem].OnIncrement();

public void OnValidate()
{
if (m_SelectedItem != -1 && !m_DebugPanel.GetDebugItem(m_SelectedItem).readOnly)
if (m_SelectedItem != -1 && !m_ItemsUI[m_SelectedItem].debugItem.readOnly)
m_ItemsUI[m_SelectedItem].OnValidate();
}

1
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Debugging.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

13
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Editor/DebugMenuEditor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
using UnityEditor;
namespace UnityEngine.Experimental.Rendering

{
DebugItemState debugItemState = m_DebugMenuState.FindDebugItemState(item);
UnityEditor.Undo.RecordObject(debugItemState, "DebugMenu State Update");
debugItemState.SetValue(item.GetValue());
EditorUtility.SetDirty(m_DebugMenuState);
if(debugItemState != null)
{
UnityEditor.Undo.RecordObject(debugItemState, "DebugMenu State Update");
debugItemState.SetValue(item.GetValue());
EditorUtility.SetDirty(m_DebugMenuState);
}
}
void OnGUI()

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateBool.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateColor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateFloat.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateInt.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

4
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/Debugging/Serialization/DebugItemStateUInt.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
namespace UnityEngine.Experimental.Rendering
{

2
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderGenerator/Editor/CSharpToHLSL.cs


guard = "_" + guard;
writer.Write("//\n");
writer.Write("// This file was automatically generated from " + it.Key + ". Please don't edit by hand.\n");
writer.Write("// This file was automatically generated. Please don't edit by hand.\n");
writer.Write("//\n\n");
writer.Write("#ifndef " + guard + "\n");
writer.Write("#define " + guard + "\n");

193
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl


}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 19, 29.
float G_MaskingSmithGGX(float NdotV, float VdotH, float roughness)
float G_MaskingSmithGGX(float NdotV, float roughness)
{
// G1(V, H) = HeavisideStep(VdotH) / (1 + Λ(V)).
// Λ(V) = -0.5 + 0.5 * sqrt(1 + 1 / a²).

// Assume that (VdotH > 0), e.i. (acos(LdotV) < Pi).
float hs = VdotH > 0.0 ? 1.0 : 0.0;
return hs / (0.5 + 0.5 * sqrt(1.0 + a2 * (1.0 / z2 - 1.0)));
return 1 / (0.5 + 0.5 * sqrt(1.0 + a2 * (1.0 / z2 - 1.0)));
// Note that we pass 1.0 instead of 'VdotH' since the multiplication will already clamp.
return D_GGX(NdotH, roughness) * G_MaskingSmithGGX(NdotV, 1.0, roughness) * VdotH / NdotV;
return D_GGX(NdotH, roughness) * G_MaskingSmithGGX(NdotV, roughness) * VdotH / NdotV;
}
// Precompute part of lambdaV
float GetSmithJointGGXPartLambdaV(float NdotV, float roughness)
{
float a2 = roughness * roughness;
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
// Note: V = G / (4 * NdotL * NdotV)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float partLambdaV)
float a2 = roughness * roughness;
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
// G = 1 / (1 + lambda_v + lambda_l);
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5
// G = 1 / (1 + lambda_v + lambda_l);
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
float lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
// Reorder code to be more optimal:
float lambdaV = NdotL * partLambdaV;
float lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l));

// Precompute part of lambdaV
float GetSmithJointGGXLambdaV(float NdotV, float roughness)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
float a = roughness;
float a2 = a * a;
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
float partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
return V_SmithJointGGX(NdotL, NdotV, roughness, partLambdaV);
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float lambdaV)
// Inline D_GGX() * V_SmithJointGGX() together for better code generation.
float DV_SmithJointGGX(float NdotH, float NdotL, float NdotV, float roughness, float partLambdaV)
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
lambdaV *= NdotL;
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
float2 D = float2(a2, f * f); // Fraction without the constant (1/Pi)
float lambdaV = NdotL * partLambdaV;
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l));
return 0.5 / (lambdaV + lambdaL);
float2 G = float2(1, lambdaV + lambdaL); // Fraction without the constant (0.5)
return (INV_PI * 0.5) * (D.x * G.x) / (D.y * G.y);
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness)
float DV_SmithJointGGX(float NdotH, float NdotL, float NdotV, float roughness)
float a = roughness;
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
float lambdaV = NdotL * (NdotV * (1 - a) + a);
float lambdaL = NdotV * (NdotL * (1 - a) + a);
return 0.5 / (lambdaV + lambdaL);
float partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
return DV_SmithJointGGX(NdotH, NdotL, NdotV, roughness, partLambdaV);
// Precompute part of LambdaV
float GetSmithJointGGXApproxLambdaV(float NdotV, float roughness)
// Precompute a part of LambdaV.
// Note on this linear approximation.
// Exact for roughness values of 0 and 1. Also, exact when the cosine is 0 or 1.
// Otherwise, the worst case relative error is around 10%.
// https://www.desmos.com/calculator/wtp8lnjutx
float GetSmithJointGGXPartLambdaVApprox(float NdotV, float roughness)
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness, float lambdaV)
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness, float partLambdaV)
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
lambdaV *= NdotL;
float lambdaV = NdotL * partLambdaV;
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness)
{
float partLambdaV = GetSmithJointGGXPartLambdaVApprox(NdotV, roughness);
return V_SmithJointGGXApprox(NdotL, NdotV, roughness, partLambdaV);
}
float f = TdotH * TdotH / (roughnessT * roughnessT) + BdotH * BdotH / (roughnessB * roughnessB) + NdotH * NdotH;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float f = TdotH * TdotH / aT2 + BdotH * BdotH / aB2 + NdotH * NdotH;
return 1.0 / (roughnessT * roughnessB * f * f);
}

}
float GetSmithJointGGXAnisoPartLambdaV(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
{
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
}
// Note: V = G / (4 * NdotL * NdotV)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float partLambdaV)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float lambdaV = NdotL * sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float lambdaV = NdotL * partLambdaV;
float GetSmithJointGGXAnisoLambdaV(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB, partLambdaV);
float V_SmithJointGGXAnisoLambdaV(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float lambdaV)
// Inline D_GGXAniso() * V_SmithJointGGXAniso() together for better code generation.
float DV_SmithJointGGXAniso(float TdotH, float BdotH, float NdotH,
float TdotV, float BdotV, float NdotV,
float TdotL, float BdotL, float NdotL,
float roughnessT, float roughnessB, float partLambdaV)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
lambdaV *= NdotL;
float f = TdotH * TdotH / aT2 + BdotH * BdotH / aB2 + NdotH * NdotH;
float2 D = float2(1, roughnessT * roughnessB * f * f); // Fraction without the constant (1/Pi)
float lambdaV = NdotL * partLambdaV;
return 0.5 / (lambdaV + lambdaL);
float2 G = float2(1, lambdaV + lambdaL); // Fraction without the constant (0.5)
return (INV_PI * 0.5) * (D.x * G.x) / (D.y * G.y);
}
float DV_SmithJointGGXAniso(float TdotH, float BdotH, float NdotH,
float TdotV, float BdotV, float NdotV,
float TdotL, float BdotL, float NdotL,
float roughnessT, float roughnessB)
{
float partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return DV_SmithJointGGXAniso(TdotH, BdotH, NdotH,
TdotV, BdotV, NdotV,
TdotL, BdotL, NdotL,
roughnessT, roughnessB, partLambdaV);
}
//-----------------------------------------------------------------------------

return INV_PI;
}
float DisneyDiffuseNoPI(float NdotV, float NdotL, float LdotH, float perceptualRoughness)
float DisneyDiffuseNoPI(float NdotV, float NdotL, float LdotV, float perceptualRoughness)
float fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
// (2 * LdotH * LdotH) = 1 + LdotV
// float fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
float fd90 = 0.5 + (perceptualRoughness + perceptualRoughness * LdotV);
float viewScatter = F_Schlick(1.0, fd90, NdotV);
float viewScatter = F_Schlick(1.0, fd90, NdotV);
return lightScatter * viewScatter;
// Normalize the BRDF for polar view angles of up to (Pi/4).
// We use the worst case of (roughness = albedo = 1), and, for each view angle,
// integrate (brdf * cos(theta_light)) over all light directions.
// The resulting value is for (theta_view = 0), which is actually a little bit larger
// than the value of the integral for (theta_view = Pi/4).
// Hopefully, the compiler folds the constant together with (1/Pi).
return rcp(1.03571) * (lightScatter * viewScatter);
float DisneyDiffuse(float NdotV, float NdotL, float LdotH, float perceptualRoughness)
float DisneyDiffuse(float NdotV, float NdotL, float LdotV, float perceptualRoughness)
return INV_PI * DisneyDiffuseNoPI(NdotV, NdotL, LdotH, perceptualRoughness);
return INV_PI * DisneyDiffuseNoPI(NdotV, NdotL, LdotV, perceptualRoughness);
float3 DiffuseGGXNoPI(float3 albedo, float NdotV, float NdotL, float NdotH, float LdotV, float perceptualRoughness)
float3 DiffuseGGXNoPI(float3 albedo, float NdotV, float NdotL, float NdotH, float LdotV, float roughness)
float facing = 0.5 + 0.5 * LdotV;
float rough = facing * (0.9 - 0.4 * facing) * ((0.5 + NdotH) / NdotH);
float facing = 0.5 + 0.5 * LdotV; // (LdotH)^2
float rough = facing * (0.9 - 0.4 * facing) * (0.5 / NdotH + 1);
float smooth = transmitL * transmitV * 1.05; // Normalize F_t over the hemisphere
float single = lerp(smooth, rough, perceptualRoughness); // Rescaled by PI
// This constant is picked s.t. setting perceptualRoughness, albedo and all angles to 1
// allows us to match the Lambertian and the Disney Diffuse models. Original value: 0.1159.
float multiple = perceptualRoughness * (0.079577 * PI); // Rescaled by PI
float smooth = transmitL * transmitV * 1.05; // Normalize F_t over the hemisphere
float single = lerp(smooth, rough, roughness); // Rescaled by PI
float multiple = roughness * (0.1159 * PI); // Rescaled by PI
float3 DiffuseGGX(float3 albedo, float NdotV, float NdotL, float NdotH, float LdotV, float perceptualRoughness)
float3 DiffuseGGX(float3 albedo, float NdotV, float NdotL, float NdotH, float LdotV, float roughness)
return INV_PI * DiffuseGGXNoPI(albedo, NdotV, NdotL, NdotH, LdotV, perceptualRoughness);
return INV_PI * DiffuseGGXNoPI(albedo, NdotV, NdotL, NdotH, LdotV, roughness);
}
#endif // UNITY_BSDF_INCLUDED

26
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl


// The reason is that for compute shader we need to guarantee that the layout of CBs is consistent across kernels. Something that we can't control with the global namespace (uniforms get optimized out if not used, modifying the global CBuffer layout per kernel)
// Structure definition that are share between C# and hlsl.
// These structures need to be align on float4 to respectect various packing rules from sahder language.
// These structures need to be align on float4 to respect various packing rules from sahder language.
// This mean that these structure need to be padded.
// Do not use "in", only "out" or "inout" as califier, not "inline" keyword either, useless.

return x * x;
}
// Acos in 14 cycles.
// Ref: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
float FastACos(float inX)
// Input [0, 1] and output [0, PI/2]
// 9 VALU
float FastACosPos(float inX)
return res;
}
// Ref: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
// Input [-1, 1] and output [0, PI]
// 12 VALU
float FastACos(float inX)
{
float res = FastACosPos(inX);
return (inX >= 0) ? res : PI - res; // Undo range reduction
}

float3 FastSign(float x)
{
return saturate(x * FLT_MAX) * 2.0 - 1.0;
}
// Orthonormalize the basis vectors using the Gram-Schmidt process.
// We assume that the length of the surface normal is sufficiently close to 1.
// return orthonormalize tangent
float3 Orthonormalize(float3 tangent, float3 normal)
{
return normalize(tangent - dot(tangent, normal) * normal);
}
// ----------------------------------------------------------------------------

46
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl


}
// Ref: Moving Frostbite to PBR - Gotanda siggraph 2011
float GetSpecularOcclusion(float NdotV, float ambientOcclusion, float roughness)
// Return specular occlusion based on ambient occlusion (usually get from SSAO) and view/roughness info
float GetSpecularOcclusionFromAmbientOcclusion(float NdotV, float ambientOcclusion, float roughness)
}
// ref: Practical Realtime Strategies for Accurate Indirect Occlusion
// Update ambient occlusion to colored ambient occlusion based on statitics of how light is bouncing in an object and with the albedo of the object
float3 GTAOMultiBounce(float visibility, float3 albedo)
{
float3 a = 2.0404 * albedo - 0.3324;
float3 b = -4.7951 * albedo + 0.6417;
float3 c = 2.7552 * albedo + 0.6903;
float x = visibility;
return max(x, ((x * a + b) * x + c) * x);
}
// Based on Oat and Sander's 2008 technique
// Area/solidAngle of intersection of two cone
float SphericalCapIntersectionSolidArea(float cosC1, float cosC2, float cosB)
{
float r1 = FastACos(cosC1);
float r2 = FastACos(cosC2);
float rd = FastACos(cosB);
float area = 0.0;
if (rd <= max(r1, r2) - min(r1, r2))
{
// One cap is completely inside the other
area = TWO_PI - TWO_PI * max(cosC1, cosC2);
}
else if (rd >= r1 + r2)
{
// No intersection exists
area = 0.0;
}
else
{
float diff = abs(r1 - r2);
float den = r1 + r2 - diff;
float x = 1.0 - saturate((rd - diff) / den);
area = smoothstep(0.0, 1.0, x);
area *= TWO_PI - TWO_PI * max(cosC1, cosC2);
}
return area;
}
//-----------------------------------------------------------------------------

29
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl


// Convert anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) to roughness
void ConvertAnisotropyToRoughness(float roughness, float anisotropy, out float roughnessT, out float roughnessB)
{
// (0 <= anisotropy <= 1), therefore (0 <= anisoAspect <= 1)
// The 0.9 factor limits the aspect ratio to 10:1.
float anisoAspect = sqrt(1.0 - 0.9 * anisotropy);
roughnessT = roughness / anisoAspect; // Distort along tangent (rougher)
roughnessB = roughness * anisoAspect; // Straighten along bitangent (smoother)
}
// Ref: Donald Revie - Implementing Fur Using Deferred Shading (GPU Pro 2)
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to the normal.
// The returned normal is NOT normalized.
float3 ComputeGrainNormal(float3 grainDir, float3 V)
{
float3 B = cross(-V, grainDir);
return cross(B, grainDir);
}
// Fake anisotropic by distorting the normal.
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to N.
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction)
float3 GetAnisotropicModifiedNormal(float3 grainDir, float3 N, float3 V, float anisotropy)
{
float3 grainNormal = ComputeGrainNormal(grainDir, V);
// TODO: test whether normalizing 'grainNormal' is worth it.
return normalize(lerp(N, grainNormal, anisotropy));
// Use the parametrization of Sony Imageworks.
// Ref: Revisiting Physically Based Shading at Imageworks, p. 15.
roughnessT = roughness * (1 + anisotropy);
roughnessB = roughness * (1 - anisotropy);
}
//-----------------------------------------------------------------------------

13
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/EntityLighting.hlsl


}
// This sample a 3D volume storing SH
// Volume is store as 3D texture with 4 R, G, B, X set of 4 coefficient store atlas in same 3D texture. X unused.
// TODO: the packing here is innefficient as we will fetch values far away from each other and they may not fit into the cache
// Suggest we pack only RGB not X and continuous
float3 SampleProbeVolumeSH4(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float4x4 WorldToTexture, float texelSizeX)
// Volume is store as 3D texture with 4 R, G, B, X set of 4 coefficient store atlas in same 3D texture. X is use for occlusion.
// TODO: the packing here is inefficient as we will fetch values far away from each other and they may not fit into the cache - Suggest we pack only RGB continuously
// TODO: The calcul of texcoord could be perform with a single matrix multicplication calcualted on C++ side that will fold probeVolumeMin and probeVolumeSizeInv into it and handle the identity case, no reasons to do it in C++ (ask Ionut about it)
// It should also handle the camera relative path (if the render pipeline use it)
float3 SampleProbeVolumeSH4(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float4x4 WorldToTexture,
float transformToLocal, float texelSizeX, float3 probeVolumeMin, float3 probeVolumeSizeInv)
float3 texCoord = mul(WorldToTexture, float4(positionWS, 1.0)).xyz;
float3 position = (transformToLocal == 1.0f) ? mul(WorldToTexture, float4(positionWS, 1.0)).xyz : positionWS;
float3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
// Each component is store in the same texture 3D. Each use one quater on the x axis
// Here we get R component then increase by step size (0.25) to get other component. This assume 4 component
// but last one is not used.

8
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Fibonacci.hlsl


return float2(i / fibN1 + (0.5f / fibN1), frac(i * (fibN2 / fibN1)));
}
#define GOLDEN_RATIO 1.6180339887498948482
// Replaces the Fibonacci sequence in Fibonacci2dSeq() with the Golden ratio.
float2 Golden2dSeq(int i, float n)
{
return float2(i / n + (0.5f / n), frac(i * rcp(GOLDEN_RATIO)));
}
static const int k_FibonacciSeq[] = {
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181
};

174
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


#include "BSDF.hlsl"
#include "Sampling.hlsl"
// TODO: We need to change this hard limit!
#ifndef UNITY_SPECCUBE_LOD_STEPS
#define UNITY_SPECCUBE_LOD_STEPS 6
#endif

// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution.
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness)
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness, uint mipMapCount)
return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
return perceptualRoughness * mipMapCount;
}
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness)
{
return PerceptualRoughnessToMipmapLevel(perceptualRoughness, UNITY_SPECCUBE_LOD_STEPS);
}
// The *accurate* version of the non-linear remapping. It works by

return saturate(1.7 / 1.4 - sqrt(2.89 / 1.96 - (2.8 / 1.96) * perceptualRoughness));
}
//-----------------------------------------------------------------------------
// Anisotropic image based lighting
//-----------------------------------------------------------------------------
// Ref: Donald Revie - Implementing Fur Using Deferred Shading (GPU Pro 2)
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to the normal.
// The returned normal is NOT normalized.
float3 ComputeGrainNormal(float3 grainDir, float3 V)
{
float3 B = cross(grainDir, V);
return cross(B, grainDir);
}
// Fake anisotropy by distorting the normal (non-negative anisotropy values only).
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to N.
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction)
float3 GetAnisotropicModifiedNormal(float3 grainDir, float3 N, float3 V, float anisotropy)
{
float3 grainNormal = ComputeGrainNormal(grainDir, V);
return normalize(lerp(N, grainNormal, anisotropy));
}
// Ref: "Moving Frostbite to PBR", p. 69.
float3 GetSpecularDominantDir(float3 N, float3 R, float roughness, float NdotV)
{

return lerp(N, R, lerpFactor);
}
//-----------------------------------------------------------------------------
// Anisotropic image based lighting
//-----------------------------------------------------------------------------
// To simulate the streching of highlight at grazing angle for IBL we shrink the roughness
// which allow to fake an anisotropic specular lobe.
// Ref: http://www.frostbite.com/2015/08/stochastic-screen-space-reflections/ - slide 84

// Compute { localL = reflect(-localV, localH) }
float3 localL = -localV + 2.0 * VdotH * localH;
NdotL = localL.z;
L = mul(localL, localToWorld);
}
// Ref: "A Simpler and Exact Sampling Routine for the GGX Distribution of Visible Normals".
void SampleVisibleAnisoGGXDir(float2 u, float3 V, float3x3 localToWorld,
float roughnessT, float roughnessB,
out float3 L,
out float NdotL,
out float NdotH,
out float VdotH,
bool VeqN = false)
{
float3 localV = mul(V, transpose(localToWorld));
// Construct an orthonormal basis around the stretched view direction.
float3x3 viewToLocal;
if (VeqN)
{
viewToLocal = k_identity3x3;
}
else
{
viewToLocal[2] = normalize(float3(roughnessT * localV.x, roughnessB * localV.y, localV.z));
viewToLocal[0] = (viewToLocal[2].z < 0.9999) ? normalize(cross(viewToLocal[2], float3(0, 0, 1))) : float3(1, 0, 0);
viewToLocal[1] = cross(viewToLocal[0], viewToLocal[2]);
}
// Compute a sample point with polar coordinates (r, phi).
float r = sqrt(u.x);
float b = viewToLocal[2].z + 1;
float a = rcp(b);
float c = (u.y < a) ? u.y * b : 1 + (u.y * b - 1) / viewToLocal[2].z;
float phi = PI * c;
float p1 = r * cos(phi);
float p2 = r * sin(phi) * ((u.y < a) ? 1 : viewToLocal[2].z);
// Unstretch.
float3 viewH = normalize(float3(roughnessT * p1, roughnessB * p2, sqrt(1 - p1 * p1 - p2 * p2)));
VdotH = viewH.z;
float3 localH = mul(viewH, viewToLocal);
NdotH = localH.z;
// Compute { localL = reflect(-localV, localH) }
float3 localL = -localV + 2 * VdotH * localH;
NdotL = localL.z;
L = mul(localL, localToWorld);

float3 N,
float roughness,
float index, // Current MIP level minus one
float lastMipLevel,
float invOmegaP,
uint sampleCount, // Must be a Fibonacci number
bool prefilter,

// Bias samples towards the mirror direction to reduce variance.
// This will have a side effect of making the reflection sharper.
// Ref: Stochastic Screen-Space Reflections, p. 67.
const float bias = 0.5 * roughness;
#ifndef USE_KARIS_APPROXIMATION
float NdotV = 1; // N == V
float partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
#endif
float3 lightInt = float3(0.0, 0.0, 0.0);
float cbsdfInt = 0.0;

float3 L;
float NdotL, NdotH, VdotH;
bool isValid;
float NdotL, NdotH, LdotH;
L = mul(localL, localToWorld);
NdotL = localL.z;
isValid = true;
L = mul(localL, localToWorld);
NdotL = localL.z;
LdotH = sqrt(0.5 + 0.5 * NdotL);
u.x = lerp(u.x, 0.0, bias);
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH, true);
// Note: if (N == V), all of the microsurface normals are visible.
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, LdotH, true);
isValid = NdotL > 0.0;
if (NdotL <= 0) continue; // Note that some samples will have 0 contribution
}
float mipLevel;

// in order to reduce the variance.
// Ref: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
//
// pdf = D * NdotH * jacobian, where jacobian = 1.0 / (4* LdotH).
//
// Since L and V are symmetric around H, LdotH == VdotH.
// Since we pre-integrate the result for the normal direction,
// N == V and then NdotH == LdotH. Therefore, the BRDF's pdf
// can be simplified:
// pdf = D * NdotH / (4 * LdotH) = D * 0.25;
//
// - OmegaS : Solid angle associated with the sample
// - OmegaP : Solid angle associated with the texel of the cubemap
// - OmegaS: Solid angle associated with the sample
// - OmegaP: Solid angle associated with the texel of the cubemap
float omegaS;

}
else
{
float pdf = D_GGX(NdotH, roughness) * 0.25;
// TODO: check the accuracy of the sample's solid angle fit for GGX.
omegaS = rcp(sampleCount) / pdf;
// float PDF = D * NdotH * Jacobian, where Jacobian = 1 / (4 * LdotH).
// Since (N == V), NdotH == LdotH.
float pdf = 0.25 * D_GGX(NdotH, roughness);
// TODO: improve the accuracy of the sample's solid angle fit for GGX.
omegaS = rcp(sampleCount) * rcp(pdf);
// invOmegaP is precomputed on CPU and provide as a parameter of the function
// 'invOmegaP' is precomputed on CPU and provided as a parameter to the function.
mipLevel = 0.5 * log2(omegaS * invOmegaP);
const float mipBias = roughness;
mipLevel = 0.5 * log2(omegaS * invOmegaP) + mipBias;
if (isValid)
{
// Bias the MIP map level to compensate for the importance sampling bias.
// This will blur the reflection.
// TODO: find a more accurate MIP bias function.
mipLevel = lerp(mipLevel, lastMipLevel, bias);
// TODO: use a Gaussian-like filter to generate the MIP pyramid.
float3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;
// TODO: use a Gaussian-like filter to generate the MIP pyramid.
float3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;
// The goal of this function is to use Monte-Carlo integration to find
// X = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// Note: Integral{CBSDF(L, N, V) dL} is given by the FDG texture.
// CBSDF = F * D * G * NdotL / (4 * NdotL * NdotV) = F * D * G / (4 * NdotV).
// PDF = D * NdotH / (4 * LdotH).
// Weight = CBSDF / PDF = F * G * LdotH / (NdotV * NdotH).
// Since we perform filtering with the assumption that (V == N),
// (LdotH == NdotH) && (NdotV == 1) && (Weight == F * G).
// Therefore, after the Monte Carlo expansion of the integrals,
// X = Sum(Radiance(L) * Weight) / Sum(Weight) = Sum(Radiance(L) * F * G) / Sum(F * G).
// Our goal is to use Monte-Carlo integration with importance sampling to evaluate
// X(V) = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// CBSDF = F * D * G * NdotL / (4 * NdotL * NdotV) = F * D * G / (4 * NdotV).
// PDF = D * NdotH / (4 * LdotH).
// Weight = CBSDF / PDF = F * G * LdotH / (NdotV * NdotH).
// Since we perform filtering with the assumption that (V == N),
// (LdotH == NdotH) && (NdotV == 1) && (Weight == F * G).
// We use the approximation of Brian Karis from "Real Shading in Unreal Engine 4":
// Weight ≈ NdotL, which produces nearly identical results in practice.
#ifndef USE_KARIS_APPROXIMATION
// The choice of the Fresnel factor does not appear to affect the result.
float F = 1; // F_Schlick(F0, LdotH);
float V = V_SmithJointGGX(NdotL, NdotV, roughness, partLambdaV);
float G = V * NdotL * NdotV; // 4 cancels out
lightInt += NdotL * val;
cbsdfInt += NdotL;
}
lightInt += F * G * val;
cbsdfInt += F * G;
#else
// Use the approximation from "Real Shading in Unreal Engine 4": Weight ≈ NdotL.
lightInt += NdotL * val;
cbsdfInt += NdotL;
#endif
}
return float4(lightInt / cbsdfInt, 1.0);

9
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl


// it return the offset to apply to the UVSet provide in PerPixelHeightDisplacementParam
// viewDirTS is view vector in texture space matching the UVSet
// ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
float2 ParallaxOcclusionMapping(float lod, float lodThreshold, int numSteps, float3 viewDirTS, float maxHeight, PerPixelHeightDisplacementParam ppdParam, out float outHeight)
float2 ParallaxOcclusionMapping(float lod, float lodThreshold, int numSteps, float3 viewDirTS, PerPixelHeightDisplacementParam ppdParam, out float outHeight)
// TODO: explain this factor! Necessary to achieve parity between tessellation and POM w.r.t. height.
maxHeight *= 0.1;
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;

// float2 parallaxDir = normalize(Out.viewDirTS.xy);
// float2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) * maxHeight;
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z);
float2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
// Do a first step before the loop to init all value correctly

// Secant method to affine the search
// Ref: Faster Relief Mapping Using the Secant Method - Eric Risser
for (int i = 0; i < 5; ++i)
for (int i = 0; i < 3; ++i)
{
// intersectionHeight is the height [0..1] for the intersection between view ray and heightfield line
float intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);

9
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Shadow.hlsl


#ifndef SHADOW_HLSL
#ifndef SHADOW_HLSL
#define SHADOW_HLSL
//
// Shadow master include header.

#define SHADOW_SUPPORTS_DYNAMIC_INDEXING 0 // only on >= sm 5.1
#define SHADOW_OPTIMIZE_REGISTER_USAGE 0 // redefine this as 1 in your ShadowContext.hlsl to optimize for register usage over instruction count
#include "../../../Core/Shadow/ShadowBase.cs.hlsl" // ShadowData definition, auto generated (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)

// Shadow context definition and initialization, i.e. resource binding (project header, must be kept in sync with C# runtime)
#define SHADOW_CONTEXT_INCLUDE
#include "../../ShadowIncludes.inl"
#include "../../ShadowIncludes.hlsl"
//#include "ShadowContext.hlsl"
// helper function to extract shadowmap data from the ShadowData struct
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out float slice )

// include project specific shadow dispatcher. If this file is not empty, it MUST define which default shadows it's overriding
#define SHADOW_DISPATCH_INCLUDE
#include "../../ShadowIncludes.inl"
#include "../../ShadowIncludes.hlsl"
//#include "ShadowDispatch.hlsl"
// if shadow dispatch is empty we'll fall back to default shadow sampling implementations
#ifndef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL

310
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


// calc TCs
float2 posTC = posNDC * 0.5 + 0.5;
closestSampleNDC = (floor(posTC * sd.textureSize.zw) + 0.5) * sd.texelSizeRcp.zw * 2.0 - 1.0.xx;
return (posTC * sd.scaleOffset.xy + sd.scaleOffset.zw) * sd.textureSize.xy;
return uint2( (posTC * sd.scaleOffset.xy + sd.scaleOffset.zw) * sd.textureSize.xy );
}
int EvalShadow_GetCubeFaceID( float3 dir )

//
#define kMaxShadowCascades 4
#define SHADOW_REPEAT_CASCADE( _x ) _x, _x, _x, _x
int EvalShadow_GetSplitSphereIndexForDirshadows( float3 positionWS, float4 dirShadowSplitSpheres[4], out float relDistance )
{

payloadOffset++;
float4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
float border = borders[shadowSplitIndex];
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// normal based bias

// Be careful of this code, we need it here before the if statement otherwise the compiler screws up optimizing dirShadowSplitSpheres VGPRs away
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz );
float3 wposDir = normalize( -splitSphere + positionWS );
float cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
// sample the texture
uint texIdx, sampIdx;
float slice;

UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
float border = borders[shadowSplitIndex];
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
float shadow1 = 1.0;
float shadow1 = 1.0;
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex - 1];
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[shadowSplitIndex].xyz );
float3 wposDir = normalize( -splitSphere.xyz + positionWS );
float cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
[branch]
if( alpha > 0.0 )
{
sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];

UnpackShadowmapId( sd.id, slice );
[branch]
if( all( abs( posNDC.xy ) <= (1.0 - sd.texelSizeRcp.zw * 0.5) ) )
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}

}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
uint orig_payloadOffset = payloadOffset; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
\
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
shadowSplitIndex++; \
float shadow1 = 1.0; \
if( shadowSplitIndex < kMaxShadowCascades ) \
{ \
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex - 1]; \
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[shadowSplitIndex].xyz ); \
float3 wposDir = normalize( -splitSphere.xyz + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
shadow1 = shadow; \
\
[branch] \
if( alpha > 0.0 ) \
{ \
sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, false ); \
/* sample the texture */ \
UnpackShadowmapId( sd.id, slice ); \
\
if( all( abs( posNDC.xy ) <= (1.0 - sd.texelSizeRcp.zw * 0.5) ) ) \
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
} \
} \
shadow = lerp( shadow, shadow1, alpha ); \
return shadow; \
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
uint orig_payloadOffset = payloadOffset; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* Be careful of this code, we need it here before the if statement otherwise the compiler screws up optimizing dirShadowSplitSpheres VGPRs away */ \
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz ); \
float3 wposDir = normalize( -splitSphere + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
float shadow1 = 1.0; \
\
shadowSplitIndex++; \
if( shadowSplitIndex < kMaxShadowCascades ) \
{ \
shadow1 = shadow; \
\
if( alpha > 0.0 ) \
{ \
sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, false ); \
/* sample the texture */ \
UnpackShadowmapId( sd.id, slice ); \
\
[branch] \
if( all( abs( posNDC.xy ) <= (1.0 - sd.texelSizeRcp.zw * 0.5) ) ) \
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
} \
} \
shadow = lerp( shadow, shadow1, alpha ); \
return shadow; \
} \
\
float EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Blend( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
float4 dirShadowSplitSpheres[kMaxShadowCascades];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
float relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );

float3 posNDC;
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
if( shadowSplitIndex < (kMaxShadowCascades-1) )
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 );
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( 3, shadowSplitIndex + 1 )].xyz );
float3 wposDir = normalize( -splitSphere + positionWS );
float cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
if( shadowSplitIndex < nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) )
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex];
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[shadowSplitIndex+1].xyz );
float3 wposDir = normalize( -splitSphere.xyz + positionWS );
float cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
if( step( EvalShadow_hash12( posTC.xy ), alpha ) )
{
shadowSplitIndex++;
sd = shadowContext.shadowDatas[index + 2 + shadowSplitIndex];
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex+1] * sd.texelSizeRcp.zw, sd.normalBias );
posTC = EvalShadow_GetTexcoords( sd, positionWS );
}
sd = shadowContext.shadowDatas[index + 1 + nextSplit];
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[nextSplit] * sd.texelSizeRcp.zw, sd.normalBias );
posTC = EvalShadow_GetTexcoords( sd, positionWS );
}
// sample the texture
uint texIdx, sampIdx;

return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha );
}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
if( shadowSplitIndex < (kMaxShadowCascades-1) ) \
{ \
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex]; \
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[shadowSplitIndex+1].xyz ); \
float3 wposDir = normalize( -splitSphere.xyz + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
if( step( EvalShadow_hash12( posTC.xy ), alpha ) ) \
{ \
sd = shadowContext.shadowDatas[index + 2 + shadowSplitIndex]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex+1] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
} \
} \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha ); \
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 ); \
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[nextSplit].xyz ); \
float3 wposDir = normalize( -splitSphere + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
if( shadowSplitIndex != nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) ) \
{ \
sd = shadowContext.shadowDatas[index + 1 + nextSplit]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[nextSplit] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
} \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha ); \
} \
\
float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Dither( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

float4 closestWS = mul( closestNDC, sd.shadowToWorld );
return closestWS.xyz / closestWS.w;
}
float3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, Texture2DArray tex, float3 positionWS, float3 normalWS, int index, float4 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
float relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );
if( shadowSplitIndex < 0 )
return 1.0;
float4 scales = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
float4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
float4 closestNDC = { 0,0,0,1 };
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
// load the texel
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, slice, 0 ).x;
// reconstruct depth position
float4 closestWS = mul( closestNDC, sd.shadowToWorld );
return closestWS.xyz / closestWS.w;
}

46
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowSampling.hlsl


float2 fetchesUV[9];
SampleShadow_ComputeSamples_Tent_5x5(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
for (int i = 0; i < 9; i++)
for( int i = 0; i < 9; i++ )
return shadow;
}

float2 fetchesUV[16];
SampleShadow_ComputeSamples_Tent_7x7(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
for (int i = 0; i < 16; i++)
#if SHADOW_OPTIMIZE_REGISTER_USAGE == 1
int i;
[loop]
for( i = 0; i < 1; i++ )
{
shadow += fetchesWeights[ 0] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 0].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 1] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 1].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 2] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 2].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 3] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 3].xy, coord.z ), slice ).x;
}
[loop]
for( i = 0; i < 1; i++ )
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 4] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 4].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 5] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 5].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 6] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 6].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 7] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 7].xy, coord.z ), slice ).x;
[loop]
for( i = 0; i < 1; i++ )
{
shadow += fetchesWeights[ 8] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 8].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 9] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[ 9].xy, coord.z ), slice ).x;
shadow += fetchesWeights[10] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[10].xy, coord.z ), slice ).x;
shadow += fetchesWeights[11] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[11].xy, coord.z ), slice ).x;
}
[loop]
for( i = 0; i < 1; i++ )
{
shadow += fetchesWeights[12] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[12].xy, coord.z ), slice ).x;
shadow += fetchesWeights[13] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[13].xy, coord.z ), slice ).x;
shadow += fetchesWeights[14] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[14].xy, coord.z ), slice ).x;
shadow += fetchesWeights[15] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[15].xy, coord.z ), slice ).x;
}
#else
for( int i = 0; i < 16; i++ )
{
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
#endif
return shadow;
}

10
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl


return exp(-opticalDepth);
}
float TransmittanceIntegralOverHomogeneousInterval(float extinction, float start, float end)
{
return (exp(-extinction * start) - exp(-extinction * end)) / extinction;
}
float3 OpticalDepthHomogeneous(float3 extinction, float intervalLength)
{
return extinction * intervalLength;

{
return exp(-opticalDepth);
}
float3 TransmittanceIntegralOverHomogeneousInterval(float3 extinction, float start, float end)
{
return (exp(-extinction * start) - exp(-extinction * end)) / extinction;
}
float IsotropicPhaseFunction()

32
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/Core/ShaderLibrary/Wind.hlsl


void ApplyWind( inout float3 worldPos,
inout float3 worldNormal,
float3 rootWP,
float stiffness,
float drag,
float shiverDrag,
float shiverDirectionality,
float initialBend,
float shiverMask,
float4 time)
void ApplyWindDisplacement( inout float3 positionWS,
float3 normalWS,
float3 rootWP,
float stiffness,
float drag,
float shiverDrag,
float shiverDirectionality,
float initialBend,
float shiverMask,
float4 time)
WindData wind = GetAnalyticalWind(worldPos, rootWP, drag, shiverDrag, initialBend, time);
WindData wind = GetAnalyticalWind(positionWS, rootWP, drag, shiverDrag, initialBend, time);
if(wind.Strength > 0.0f)
if (wind.Strength > 0.0f)
float att = AttenuateTrunk(distance(worldPos, rootWP), stiffness);
float att = AttenuateTrunk(distance(positionWS, rootWP), stiffness);
worldPos = Rotate(rootWP, worldPos, rotAxis, (wind.Strength) * 0.001 * att);
positionWS = Rotate(rootWP, positionWS, rotAxis, (wind.Strength) * 0.001 * att);
float3 shiverDirection = normalize(lerp(worldNormal, normalize(wind.Direction + wind.ShiverDirection), shiverDirectionality));
worldPos += wind.ShiverStrength * shiverDirection * shiverMask;
float3 shiverDirection = normalize(lerp(normalWS, normalize(wind.Direction + wind.ShiverDirection), shiverDirectionality));
positionWS += wind.ShiverStrength * shiverDirection * shiverMask;
}
}

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存