浏览代码

Merge branch '2018.1' into projects/TheLastStand

/projects-TheLastStand
John Parsaie 7 年前
当前提交
40539650
共有 42 个文件被更改,包括 718 次插入361 次删除
  1. 12
      ScriptableRenderPipeline/Core/CoreRP/CoreUtils.cs
  2. 8
      ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugManager.cs
  3. 259
      ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorUtils.cs
  4. 14
      ScriptableRenderPipeline/Core/CoreRP/Editor/Debugging/DebugWindow.cs
  5. 18
      ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs
  6. 23
      ScriptableRenderPipeline/Core/CoreRP/TextureCache.cs
  7. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  8. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl
  9. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/MaterialDebug.cs
  10. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs
  11. 143
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs
  12. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraUI.cs
  13. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs
  14. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.Styles.cs
  15. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs
  16. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.Drawers.cs
  17. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.cs
  18. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/FrameSettingsUI.cs
  19. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  20. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset
  21. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Light/HDAdditionalLightData.cs
  22. 105
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  23. 39
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopSettings.cs
  24. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Shadow.hlsl
  25. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/ShadowContext.hlsl
  26. 33
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightUtils.cs
  27. 23
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbeCache.cs
  28. 25
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCache.cs
  29. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/MRTBufferManager.cs
  30. 21
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/GBufferManager.cs
  31. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/GGXConvolution/RuntimeFilterIBL.cs
  32. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  33. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/MaterialUtilities.hlsl
  34. 103
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/FrameSettings.cs
  35. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassForward.hlsl
  36. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs
  37. 33
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightAssetEditor.cs
  38. 3
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  39. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl
  40. 13
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl
  41. 16
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl
  42. 4
      Tests/Scripts/Editor/GraphicTests/Framework/TestFrameworkCustomBuild.cs

12
ScriptableRenderPipeline/Core/CoreRP/CoreUtils.cs


return temp;
}
public static string GetTextureAutoName(int width, int height, TextureFormat format, TextureDimension dim = TextureDimension.None, string name = "", bool mips = false, int depth = 0)
{
string temp;
if(depth == 0)
temp = string.Format("{0}x{1}_{2}{3}", width, height, format, mips ? "_Mips" : "");
else
temp = string.Format("{0}x{1}x{2}_{3}{4}", width, height, depth, format, mips ? "_Mips" : "");
temp = String.Format("{0}_{1}_{2}", name == "" ? "Texture" : name, (dim == TextureDimension.None) ? "" : dim.ToString(), temp);
return temp;
}
public static void ClearCubemap(CommandBuffer cmd, RenderTexture renderTexture, Color clearColor, bool clearMips = false)
{
int mipCount = 1;

8
ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugManager.cs


{
get
{
var uiManager = UnityObject.FindObjectOfType<DebugUIHandlerCanvas>();
// Might be needed to update the reference after domain reload
if (uiManager != null)
{
m_Root = uiManager.gameObject;
}
return m_Root != null && m_Root.activeInHierarchy;
}
set

259
ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorUtils.cs


return value;
}
public static void DrawPopup(GUIContent label, SerializedProperty property, string[] options)
{
var mode = property.intValue;
EditorGUI.BeginChangeCheck();
if (mode >= options.Length)
Debug.LogError(string.Format("Invalid option while trying to set {0}", label.text));
mode = EditorGUILayout.Popup(label, mode, options);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(property.objectReferenceValue, property.name);
property.intValue = mode;
}
}
public static void DrawCascadeSplitGUI<T>(ref SerializedProperty shadowCascadeSplit)
{
float[] cascadePartitionSizes = null;
System.Type type = typeof(T);
if (type == typeof(float))
{
cascadePartitionSizes = new float[] { shadowCascadeSplit.floatValue };
}
else if (type == typeof(Vector3))
{
Vector3 splits = shadowCascadeSplit.vector3Value;
cascadePartitionSizes = new float[]
{
Mathf.Clamp(splits[0], 0.0f, 1.0f),
Mathf.Clamp(splits[1] - splits[0], 0.0f, 1.0f),
Mathf.Clamp(splits[2] - splits[1], 0.0f, 1.0f)
};
}
if (cascadePartitionSizes != null)
{
EditorGUI.BeginChangeCheck();
ShadowCascadeSplitGUI.HandleCascadeSliderGUI(ref cascadePartitionSizes);
if (EditorGUI.EndChangeCheck())
{
if (type == typeof(float))
shadowCascadeSplit.floatValue = cascadePartitionSizes[0];
else
{
Vector3 updatedValue = new Vector3();
updatedValue[0] = cascadePartitionSizes[0];
updatedValue[1] = updatedValue[0] + cascadePartitionSizes[1];
updatedValue[2] = updatedValue[1] + cascadePartitionSizes[2];
shadowCascadeSplit.vector3Value = updatedValue;
}
}
}
}
public static void RemoveMaterialKeywords(Material material)
{
material.shaderKeywords = null;

}
return data;
}
}
static class ShadowCascadeSplitGUI
{
private const int kSliderbarTopMargin = 2;
private const int kSliderbarHeight = 24;
private const int kSliderbarBottomMargin = 2;
private const int kPartitionHandleWidth = 2;
private const int kPartitionHandleExtraHitAreaWidth = 2;
private static readonly Color[] kCascadeColors =
{
new Color(0.5f, 0.5f, 0.6f, 1.0f),
new Color(0.5f, 0.6f, 0.5f, 1.0f),
new Color(0.6f, 0.6f, 0.5f, 1.0f),
new Color(0.6f, 0.5f, 0.5f, 1.0f),
};
// using a LODGroup skin
private static readonly GUIStyle s_CascadeSliderBG = "LODSliderRange";
private static readonly GUIStyle s_TextCenteredStyle = new GUIStyle(EditorStyles.whiteMiniLabel)
{
alignment = TextAnchor.MiddleCenter
};
// Internal struct to bundle drag information
private class DragCache
{
public int m_ActivePartition; // the cascade partition that we are currently dragging/resizing
public float m_NormalizedPartitionSize; // the normalized size of the partition (0.0f < size < 1.0f)
public Vector2 m_LastCachedMousePosition; // mouse position the last time we registered a drag or mouse down.
public DragCache(int activePartition, float normalizedPartitionSize, Vector2 currentMousePos)
{
m_ActivePartition = activePartition;
m_NormalizedPartitionSize = normalizedPartitionSize;
m_LastCachedMousePosition = currentMousePos;
}
};
private static DragCache s_DragCache;
private static readonly int s_CascadeSliderId = "s_CascadeSliderId".GetHashCode();
private static SceneView s_RestoreSceneView;
private static SceneView.CameraMode s_OldSceneDrawMode;
private static bool s_OldSceneLightingMode;
/**
* Static function to handle the GUI and User input related to the cascade slider.
*
* @param normalizedCascadePartition The array of partition sizes in the range 0.0f - 1.0f; expects ONE entry if cascades = 2, and THREE if cascades=4
* The last entry will be automatically determined by summing up the array, and doing 1.0f - sum
*/
public static void HandleCascadeSliderGUI(ref float[] normalizedCascadePartitions)
{
EditorGUILayout.LabelField("Cascade splits");
// get the inspector width since we need it while drawing the partition rects.
// Only way currently is to reserve the block in the layout using GetRect(), and then immediately drawing the empty box
// to match the call to GetRect.
// From this point on, we move to non-layout based code.
var sliderRect = GUILayoutUtility.GetRect(GUIContent.none
, s_CascadeSliderBG
, GUILayout.Height(kSliderbarTopMargin + kSliderbarHeight + kSliderbarBottomMargin)
, GUILayout.ExpandWidth(true));
GUI.Box(sliderRect, GUIContent.none);
float currentX = sliderRect.x;
float cascadeBoxStartY = sliderRect.y + kSliderbarTopMargin;
float cascadeSliderWidth = sliderRect.width - (normalizedCascadePartitions.Length * kPartitionHandleWidth);
Color origTextColor = GUI.color;
Color origBackgroundColor = GUI.backgroundColor;
int colorIndex = -1;
// setup the array locally with the last partition
float[] adjustedCascadePartitions = new float[normalizedCascadePartitions.Length + 1];
System.Array.Copy(normalizedCascadePartitions, adjustedCascadePartitions, normalizedCascadePartitions.Length);
adjustedCascadePartitions[adjustedCascadePartitions.Length - 1] = 1.0f - normalizedCascadePartitions.Sum();
// check for user input on any of the partition handles
// this mechanism gets the current event in the queue... make sure that the mouse is over our control before consuming the event
int sliderControlId = GUIUtility.GetControlID(s_CascadeSliderId, FocusType.Passive);
Event currentEvent = Event.current;
int hotPartitionHandleIndex = -1; // the index of any partition handle that we are hovering over or dragging
// draw each cascade partition
for (int i = 0; i < adjustedCascadePartitions.Length; ++i)
{
float currentPartition = adjustedCascadePartitions[i];
colorIndex = (colorIndex + 1) % kCascadeColors.Length;
GUI.backgroundColor = kCascadeColors[colorIndex];
float boxLength = (cascadeSliderWidth * currentPartition);
// main cascade box
Rect partitionRect = new Rect(currentX, cascadeBoxStartY, boxLength, kSliderbarHeight);
GUI.Box(partitionRect, GUIContent.none, s_CascadeSliderBG);
currentX += boxLength;
// cascade box percentage text
GUI.color = Color.white;
Rect textRect = partitionRect;
var cascadeText = string.Format("{0}\n{1:F1}%", i, currentPartition * 100.0f);
GUI.Label(textRect, cascadeText, s_TextCenteredStyle);
// no need to draw the partition handle for last box
if (i == adjustedCascadePartitions.Length - 1)
break;
// partition handle
GUI.backgroundColor = Color.black;
Rect handleRect = partitionRect;
handleRect.x = currentX;
handleRect.width = kPartitionHandleWidth;
GUI.Box(handleRect, GUIContent.none, s_CascadeSliderBG);
// we want a thin handle visually (since wide black bar looks bad), but a slightly larger
// hit area for easier manipulation
Rect handleHitRect = handleRect;
handleHitRect.xMin -= kPartitionHandleExtraHitAreaWidth;
handleHitRect.xMax += kPartitionHandleExtraHitAreaWidth;
if (handleHitRect.Contains(currentEvent.mousePosition))
hotPartitionHandleIndex = i;
// add regions to slider where the cursor changes to Resize-Horizontal
if (s_DragCache == null)
{
EditorGUIUtility.AddCursorRect(handleHitRect, MouseCursor.ResizeHorizontal, sliderControlId);
}
currentX += kPartitionHandleWidth;
}
GUI.color = origTextColor;
GUI.backgroundColor = origBackgroundColor;
EventType eventType = currentEvent.GetTypeForControl(sliderControlId);
switch (eventType)
{
case EventType.MouseDown:
if (hotPartitionHandleIndex >= 0)
{
s_DragCache = new DragCache(hotPartitionHandleIndex, normalizedCascadePartitions[hotPartitionHandleIndex], currentEvent.mousePosition);
if (GUIUtility.hotControl == 0)
GUIUtility.hotControl = sliderControlId;
currentEvent.Use();
// Switch active scene view into shadow cascades visualization mode, once we start
// tweaking cascade splits.
if (s_RestoreSceneView == null)
{
s_RestoreSceneView = SceneView.lastActiveSceneView;
if (s_RestoreSceneView != null)
{
s_OldSceneDrawMode = s_RestoreSceneView.cameraMode;
s_OldSceneLightingMode = s_RestoreSceneView.m_SceneLighting;
s_RestoreSceneView.cameraMode = SceneView.GetBuiltinCameraMode(DrawCameraMode.ShadowCascades);
}
}
}
break;
case EventType.MouseUp:
// mouseUp event anywhere should release the hotcontrol (if it belongs to us), drags (if any)
if (GUIUtility.hotControl == sliderControlId)
{
GUIUtility.hotControl = 0;
currentEvent.Use();
}
s_DragCache = null;
// Restore previous scene view drawing mode once we stop tweaking cascade splits.
if (s_RestoreSceneView != null)
{
s_RestoreSceneView.cameraMode = s_OldSceneDrawMode;
s_RestoreSceneView.m_SceneLighting = s_OldSceneLightingMode;
s_RestoreSceneView = null;
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl != sliderControlId)
break;
// convert the mouse movement to normalized cascade width. Make sure that we are safe to apply the delta before using it.
float delta = (currentEvent.mousePosition - s_DragCache.m_LastCachedMousePosition).x / cascadeSliderWidth;
bool isLeftPartitionHappy = ((adjustedCascadePartitions[s_DragCache.m_ActivePartition] + delta) > 0.0f);
bool isRightPartitionHappy = ((adjustedCascadePartitions[s_DragCache.m_ActivePartition + 1] - delta) > 0.0f);
if (isLeftPartitionHappy && isRightPartitionHappy)
{
s_DragCache.m_NormalizedPartitionSize += delta;
normalizedCascadePartitions[s_DragCache.m_ActivePartition] = s_DragCache.m_NormalizedPartitionSize;
if (s_DragCache.m_ActivePartition < normalizedCascadePartitions.Length - 1)
normalizedCascadePartitions[s_DragCache.m_ActivePartition + 1] -= delta;
GUI.changed = true;
}
s_DragCache.m_LastCachedMousePosition = currentEvent.mousePosition;
currentEvent.Use();
break;
}
}
}
}

14
ScriptableRenderPipeline/Core/CoreRP/Editor/Debugging/DebugWindow.cs


static Dictionary<Type, Type> s_WidgetStateMap; // DebugUI.Widget type -> DebugState type
static Dictionary<Type, DebugUIDrawer> s_WidgetDrawerMap; // DebugUI.Widget type -> DebugUIDrawer
bool m_IsActiveInPlayMode
{
get { return Application.isPlaying && DebugManager.instance.displayRuntimeUI; }
}
[DidReloadScripts]
static void OnEditorReload()
{

void Update()
{
if (m_IsActiveInPlayMode)
return;
int treeState = DebugManager.instance.GetState();
if (m_DebugTreeState != treeState || m_IsDirty)

{
if (s_Styles == null)
s_Styles = new Styles();
if (m_IsActiveInPlayMode)
{
EditorGUILayout.HelpBox("The editor debug window is disabled while the runtime one is active.", MessageType.Info);
return;
}
var panels = DebugManager.instance.panels;
int itemCount = panels.Count(x => !x.isRuntimeOnly && x.children.Count(w => !w.isRuntimeOnly) > 0);

18
ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs


// UI stuff
protected struct ValRange
{
GUIContent Name;
#if UNITY_EDITOR
GUIContent Name;
float ValMax;
#endif
float ValMax;
public ValRange( string name, float valMin, float valDef, float valMax, float valScale ) { Name = new GUIContent( name ); ValMin = valMin; ValDef = valDef; ValMax = valMax; ValScale = valScale; }
public ValRange( string name, float valMin, float valDef, float valMax, float valScale )
{
#if UNITY_EDITOR
Name = new GUIContent( name );
ValMin = valMin;
ValMax = valMax;
#endif
ValDef = valDef;
ValScale = valScale;
}
#if UNITY_EDITOR
public void Slider( ref int currentVal ) { currentVal = ShadowUtils.Asint( ValScale * UnityEditor.EditorGUILayout.Slider( Name, ShadowUtils.Asfloat( currentVal ) / ValScale, ValMin, ValMax ) ); }
#else

23
ScriptableRenderPipeline/Core/CoreRP/TextureCache.cs


{
private Texture2DArray m_Cache;
public TextureCache2D(string cacheName = "")
: base(cacheName)
{
}
public override void TransferToSlice(CommandBuffer cmd, int sliceIndex, Texture texture)
{
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);

m_Cache = new Texture2DArray(width, height, numTextures, format, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp
wrapMode = TextureWrapMode.Clamp,
name = CoreUtils.GetTextureAutoName(width, height, format, TextureDimension.Tex2DArray, depth: numTextures, name: m_CacheName)
};
return res;

private int m_CubeMipLevelPropName;
private int m_cubeSrcTexPropName;
public TextureCacheCubemap(string cacheName = "")
: base(cacheName)
{
}
public override void TransferToSlice(CommandBuffer cmd, int sliceIndex, Texture texture)
{
if (!TextureCache.supportsCubemapArrayTextures)

wrapMode = TextureWrapMode.Repeat,
wrapModeV = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0
anisoLevel = 0,
name = CoreUtils.GetTextureAutoName(panoWidthTop, panoHeightTop, format, TextureDimension.Tex2DArray, depth: numCubeMaps, name: m_CacheName)
};
m_NumPanoMipLevels = isMipMapped ? GetNumMips(panoWidthTop, panoHeightTop) : 1;

hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0 // It is important to set 0 here, else unity force anisotropy filtering
anisoLevel = 0, // It is important to set 0 here, else unity force anisotropy filtering
name = CoreUtils.GetTextureAutoName(width, width, format, TextureDimension.CubeArray, depth: numCubeMaps, name: m_CacheName)
};
}

public abstract class TextureCache
{
protected int m_NumMipLevels;
protected string m_CacheName;
public static bool isMobileBuildTarget
{

// assert(m_SliceArray[m_SortedIdxArray[q-1]].CountLRU>=m_SliceArray[m_SortedIdxArray[q]].CountLRU);
}
protected TextureCache()
protected TextureCache(string cacheName)
m_CacheName = cacheName;
m_NumTextures = 0;
m_NumMipLevels = 0;
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs


{
children =
{
new DebugUI.UIntField { displayName = "Shadow Atlas Index", getter = () => lightingDebugSettings.shadowMapIndex, setter = value => lightingDebugSettings.shadowAtlasIndex = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetShadowAtlasCount() - 1u }
new DebugUI.UIntField { displayName = "Shadow Atlas Index", getter = () => lightingDebugSettings.shadowAtlasIndex, setter = value => lightingDebugSettings.shadowAtlasIndex = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetShadowAtlasCount() - 1u }
}
});
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl


}
// 4. Display leading 0
#pragma warning(disable : 3557) // loop only executes for 0 iteration(s)
for (int i = 0; i < leading0; ++i)
if (leading0 > 0)
DrawCharacter('0', fontColor, currentUnormCoord, fixedUnormCoord, flipY, color, -1);
for (int i = 0; i < leading0; ++i)
{
DrawCharacter('0', fontColor, currentUnormCoord, fixedUnormCoord, flipY, color, -1);
}
#pragma warning(default : 3557)
// 5. Display sign
if (intValue < 0 || forceNegativeSign)

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/MaterialDebug.cs


VertexNormalWS,
VertexColor,
VertexColorAlpha,
Last,
// if you add more values here, fix the first entry of next enum
};
// Number must be contiguous

None = 0,
Depth = DebugViewVarying.Last,
Depth = DebugViewVarying.VertexColorAlpha + 1,
Last,
// if you add more values here, fix the first entry of next enum
}
// Number must be contiguous

None = 0,
Tessellation = DebugViewGbuffer.Last,
Tessellation = DebugViewGbuffer.BakeShadowMask3 + 1,
PixelDisplacement,
VertexDisplacement,
TessellationDisplacement,

Last,
}
}

32
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs


public float m_DrawDistance = 1000.0f;
public float m_FadeScale = 0.9f;
private Material m_OldMaterial = null;
public const int kInvalidIndex = -1;
private int m_CullIndex = kInvalidIndex;
private DecalSystem.DecalHandle m_Handle = null;
public int CullIndex
public DecalSystem.DecalHandle Handle
return this.m_CullIndex;
return this.m_Handle;
this.m_CullIndex = value;
this.m_Handle = value;
}
}

m_Material = hdrp != null ? hdrp.GetDefaultDecalMaterial() : null;
}
DecalSystem.instance.AddDecal(this);
}
public void Start()
{
DecalSystem.instance.AddDecal(this);
if(m_Handle != null)
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, m_Material);
DecalSystem.instance.RemoveDecal(this);
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = null;
}
// Declare the method signature of the delegate to call.

// handle material changes
if (m_OldMaterial != m_Material)
{
Material tempMaterial = m_Material;
m_Material = m_OldMaterial;
if(m_Material != null)
DecalSystem.instance.RemoveDecal(this);
m_Material = tempMaterial;
DecalSystem.instance.AddDecal(this);
if( m_Handle != null)
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, m_Material);
m_OldMaterial = m_Material;
// notify the editor that material has changed so it can update the shader foldout

{
DrawGizmo(true);
// if this object is selected there is a chance the transform was changed so update culling info
DecalSystem.instance.UpdateCachedData(this);
DecalSystem.instance.UpdateCachedData(transform, m_DrawDistance, m_FadeScale, m_Handle);
}
public void OnDrawGizmos()

143
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs


{
public class DecalSystem
{
public const int kInvalidIndex = -1;
public class DecalHandle
{
public DecalHandle(int index, int materialID)
{
m_MaterialID = materialID;
m_Index = index;
}
public static bool IsValid(DecalHandle handle)
{
if (handle == null)
return false;
if (handle.m_Index == kInvalidIndex)
return false;
return true;
}
public int m_MaterialID; // identifies decal set
public int m_Index; // identifies decal within the set
}
static DecalSystem m_Instance;
static public DecalSystem instance
{

{
if (m_DecalAtlas == null)
{
m_DecalAtlas = new TextureCache2D();
m_DecalAtlas = new TextureCache2D("DecalAtlas");
public Camera CurrentCamera
{

return res;
}
public void UpdateCachedData(DecalProjectorComponent decal)
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, DecalHandle handle)
m_CachedDecalToWorld[decal.CullIndex] = decal.transform.localToWorldMatrix;
int index = handle.m_Index;
m_CachedDecalToWorld[index] = transform.localToWorldMatrix;
Matrix4x4 decalRotation = Matrix4x4.Rotate(decal.transform.rotation);
Matrix4x4 decalRotation = Matrix4x4.Rotate(transform.rotation);
// z/y axis swap for normal to decal space, Unity is column major
float y0 = decalRotation.m01;
float y1 = decalRotation.m11;

decalRotation.m12 = y1;
decalRotation.m22 = y2;
m_CachedNormalToWorld[decal.CullIndex] = decalRotation;
m_CachedNormalToWorld[index] = decalRotation;
m_CachedDrawDistances[decal.CullIndex].x = decal.m_DrawDistance < instance.DrawDistance
? decal.m_DrawDistance
m_CachedDrawDistances[index].x = drawDistance < instance.DrawDistance
? drawDistance
m_CachedDrawDistances[decal.CullIndex].y = decal.m_FadeScale;
m_BoundingSpheres[decal.CullIndex] = GetDecalProjectBoundingSphere(m_CachedDecalToWorld[decal.CullIndex]);
m_CachedDrawDistances[index].y = fadeScale;
m_BoundingSpheres[index] = GetDecalProjectBoundingSphere(m_CachedDecalToWorld[index]);
public void AddDecal(DecalProjectorComponent decal)
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, int materialID)
if (m_DecalsCount == m_Decals.Length)
if (m_DecalsCount == m_Handles.Length)
DecalProjectorComponent[] newDecals = new DecalProjectorComponent[m_DecalsCount + kDecalBlockSize];
DecalHandle[] newHandles = new DecalHandle[m_DecalsCount + kDecalBlockSize];
BoundingSphere[] newSpheres = new BoundingSphere[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedTransforms = new Matrix4x4[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedNormalToWorld = new Matrix4x4[m_DecalsCount + kDecalBlockSize];

m_Decals.CopyTo(newDecals, 0);
m_Handles.CopyTo(newHandles, 0);
m_Decals = newDecals;
m_Handles = newHandles;
m_BoundingSpheres = newSpheres;
m_CachedDecalToWorld = newCachedTransforms;
m_CachedNormalToWorld = newCachedNormalToWorld;

m_Decals[m_DecalsCount] = decal;
m_Decals[m_DecalsCount].CullIndex = m_DecalsCount;
UpdateCachedData(m_Decals[m_DecalsCount]);
DecalHandle decalHandle = new DecalHandle(m_DecalsCount, materialID);
m_Handles[m_DecalsCount] = decalHandle;
UpdateCachedData(transform, drawDistance, fadeScale, decalHandle);
return decalHandle;
public void RemoveDecal(DecalProjectorComponent decal)
public void RemoveDecal(DecalHandle handle)
int removeAtIndex = decal.CullIndex;
int removeAtIndex = handle.m_Index;
m_Decals[removeAtIndex] = m_Decals[m_DecalsCount - 1]; // move the last decal in list
m_Decals[removeAtIndex].CullIndex = removeAtIndex;
m_Decals[m_DecalsCount - 1] = null;
m_Handles[removeAtIndex] = m_Handles[m_DecalsCount - 1]; // move the last decal in list
m_Handles[removeAtIndex].m_Index = removeAtIndex;
m_Handles[m_DecalsCount - 1] = null;
// update the bounding spheres array
// update cached data
decal.CullIndex = DecalProjectorComponent.kInvalidIndex;
handle.m_Index = kInvalidIndex;
}
public void BeginCull()

private void GetDecalVolumeDataAndBound(Matrix4x4 decalToWorld, Matrix4x4 worldToView)
{
var influenceX = decalToWorld.GetColumn(0) * 0.5f;
var influenceY = decalToWorld.GetColumn(1) * 0.5f;
var influenceZ = decalToWorld.GetColumn(2) * 0.5f;

normalToWorldBatch[instanceCount].m23 = m_NormalTexIndex;
normalToWorldBatch[instanceCount].m33 = m_MaskTexIndex;
// clustered forward data
m_DecalDatas[m_DecalDatasCount].worldToDecal = decalToWorldBatch[instanceCount].inverse;
m_DecalDatas[m_DecalDatasCount].normalToWorld = normalToWorldBatch[instanceCount];

void UpdateTextureCache(CommandBuffer cmd)
{
if (m_DiffuseTexture != null)
{
m_DiffuseTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_DiffuseTexture);
}
else
{
m_DiffuseTexIndex = -1;
}
if (m_NormalTexture != null)
{
m_NormalTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_NormalTexture);
}
else
{
m_NormalTexIndex = -1;
}
if (m_MaskTexture != null)
{
m_MaskTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_MaskTexture);
}
else
{
m_MaskTexIndex = -1;
}
m_DiffuseTexIndex = (m_DiffuseTexture != null) ? instance.TextureAtlas.FetchSlice(cmd, m_DiffuseTexture) : -1;
m_NormalTexIndex = (m_NormalTexture != null) ? instance.TextureAtlas.FetchSlice(cmd, m_NormalTexture) : -1;
m_MaskTexIndex = (m_MaskTexture != null) ? instance.TextureAtlas.FetchSlice(cmd, m_MaskTexture) : -1;
}
public void RemoveFromTextureCache()

private CullingGroup m_CullingGroup = null;
private BoundingSphere[] m_BoundingSpheres = new BoundingSphere[kDecalBlockSize];
private DecalProjectorComponent[] m_Decals = new DecalProjectorComponent[kDecalBlockSize];
private DecalHandle[] m_Handles = new DecalHandle[kDecalBlockSize];
private int[] m_ResultIndices = new int[kDecalBlockSize];
private int m_NumResults = 0;
private int m_DecalsCount = 0;

private int m_MaskTexIndex = -1;
}
public void AddDecal(DecalProjectorComponent decal)
{
if (decal.CullIndex != DecalProjectorComponent.kInvalidIndex) //do not add the same decal more than once
return;
if(!decal.IsValid())
return;
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, Material material)
{
int key = decal.m_Material.GetInstanceID();
int key = material.GetInstanceID();
decalSet = new DecalSet(decal.m_Material);
decalSet = new DecalSet(material);
decalSet.AddDecal(decal);
return decalSet.AddDecal(transform, drawDistance, fadeScale, key);
public void RemoveDecal(DecalProjectorComponent decal)
public void RemoveDecal(DecalHandle handle)
if (decal.CullIndex == DecalProjectorComponent.kInvalidIndex) // check if we have this decal
return;
if (!DecalHandle.IsValid(handle))
return;
int key = decal.m_Material.GetInstanceID();
int key = handle.m_MaterialID;
decalSet.RemoveDecal(decal);
decalSet.RemoveDecal(handle);
if (decalSet.Count == 0)
{
decalSet.RemoveFromTextureCache();

}
public void UpdateCachedData(DecalProjectorComponent decal)
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, DecalHandle handle)
if (decal.CullIndex == DecalProjectorComponent.kInvalidIndex) // check if we have this decal
if(!DecalHandle.IsValid(handle))
int key = decal.m_Material.GetInstanceID();
int key = handle.m_MaterialID;
decalSet.UpdateCachedData(decal);
decalSet.UpdateCachedData(transform, drawDistance, fadeScale, handle);
}
}

pair.Value.EndCull();
}
}
// need a better way than passing light loop here
public void RenderIntoDBuffer(CommandBuffer cmd)
{
if (m_DecalMesh == null)

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraUI.cs


Inspector = new []
{
SectionPrimarySettings,
SectionPhysicalSettings,
// Not used for now
//SectionPhysicalSettings,
SectionCaptureSettings,
SectionOutputSettings,
SectionXRSettings,

18
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs


public class HDRenderPipelineMenuItems
{
[MenuItem("Internal/HDRenderPipeline/Upgrade Scene Light Intensity to physical light unit", priority = CoreUtils.editMenuPriority2)]
//[MenuItem("Internal/HDRenderPipeline/Upgrade Scene Light Intensity to physical light unit", priority = CoreUtils.editMenuPriority2)]
static void UpgradeLightsPLU()
{
Light[] lights = Resources.FindObjectsOfTypeAll<Light>();

EditorSceneManager.MarkSceneDirty(scene);
}
[MenuItem("Internal/HDRenderPipeline/Add \"Additional Light-shadow Data\" (if not present)")]
//[MenuItem("Internal/HDRenderPipeline/Add \"Additional Light-shadow Data\" (if not present)")]
static void AddAdditionalLightData()
{
var lights = UnityObject.FindObjectsOfType(typeof(Light)) as Light[];

}
}
[MenuItem("Internal/HDRenderPipeline/Add \"Additional Camera Data\" (if not present)")]
//[MenuItem("Internal/HDRenderPipeline/Add \"Additional Camera Data\" (if not present)")]
static void AddAdditionalCameraData()
{
var cameras = UnityObject.FindObjectsOfType(typeof(Camera)) as Camera[];

}
// This script is a helper for the artists to re-synchronize all layered materials
[MenuItem("Internal/HDRenderPipeline/Synchronize all Layered materials")]
////[MenuItem("Internal/HDRenderPipeline/Synchronize all Layered materials")]
static void SynchronizeAllLayeredMaterial()
{
var materials = Resources.FindObjectsOfTypeAll<Material>();

}
}
[MenuItem("Internal/HDRenderPipeline/Update/Update diffusion profile")]
//[MenuItem("Internal/HDRenderPipeline/Update/Update diffusion profile")]
static void UpdateDiffusionProfile()
{
var matIds = AssetDatabase.FindAssets("t:DiffusionProfileSettings");

}
}
[MenuItem("Internal/HDRenderPipeline/Update/Update material for clear coat")]
//[MenuItem("Internal/HDRenderPipeline/Update/Update material for clear coat")]
static void UpdateMaterialForClearCoat()
{
try

}
}
[MenuItem("Internal/HDRenderPipeline/Update/Update material for subsurface")]
//[MenuItem("Internal/HDRenderPipeline/Update/Update material for subsurface")]
static void UpdateMaterialForSubsurface()
{
try

}
//
[MenuItem("Internal/HDRenderPipeline/Update/Update Height Maps parametrization")]
//[MenuItem("Internal/HDRenderPipeline/Update/Update Height Maps parametrization")]
static void UpdateHeightMapParametrization()
{
try

}
// Function used only to check performance of data with and without tessellation
[MenuItem("Internal/HDRenderPipeline/Test/Remove tessellation materials (not reversible)")]
//[MenuItem("Internal/HDRenderPipeline/Test/Remove tessellation materials (not reversible)")]
static void RemoveTessellationMaterials()
{
var materials = Resources.FindObjectsOfTypeAll<Material>();

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.Styles.cs


public readonly GUIContent indirectBounceShadowWarning = new GUIContent("Realtime indirect bounce shadowing is not supported for Spot and Point lights.");
// Additional light data
public readonly GUIContent directionalIntensity = new GUIContent("Intensity (Lux)", "");
public readonly GUIContent punctualIntensity = new GUIContent("Intensity (Lumen)", "");
public readonly GUIContent areaIntensity = new GUIContent("Intensity (Lumen)", "");
public readonly GUIContent directionalIntensity = new GUIContent("Intensity (Lux)", "Illuminance of the directional light at ground level in lux.");
public readonly GUIContent punctualIntensity = new GUIContent("Intensity (Lumen)", "Luminous power of the light in lumen. Spotlight are considered as point light with barndoor so match intensity of a point light.");
public readonly GUIContent areaIntensity = new GUIContent("Intensity (Lumen)", "Luminous power of the light in lumen.");
public readonly GUIContent maxSmoothness = new GUIContent("Max Smoothness", "Very low cost way of faking spherical area lighting. This will modify the roughness of the material lit. This is useful when the specular highlight is too small or too sharp.");
public readonly GUIContent affectDiffuse = new GUIContent("Affect Diffuse", "This will disable diffuse lighting for this light. Doesn't save performance, diffuse lighting is still computed.");

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs


if (EditorGUI.EndChangeCheck())
{
m_AdditionalLightData.fadeDistance.floatValue = Mathf.Max(m_AdditionalLightData.fadeDistance.floatValue, 0.01f);
((Light)target).SetLightDirty(); // Should be apply only to parameter that's affect GI, but make the code cleaner
}
}

var type = settings.lightType;
// Special case for multi-selection: don't resolve light shape or it'll corrupt lights
if (type.hasMultipleDifferentValues)
if (type.hasMultipleDifferentValues
|| m_AdditionalLightData.lightTypeExtent.hasMultipleDifferentValues)
{
m_LightShape = (LightShape)(-1);
return;

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.Drawers.cs


var blendDistance = p.blendDistancePositive.vector3Value.x;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = p.blendDistancePositive.hasMultipleDifferentValues;
blendDistance = EditorGUILayout.Slider(CoreEditorUtils.GetContent("Blend Distance|Area around the probe where it is blended with other probes. Only used in deferred probes."), blendDistance, 0, maxBlendDistance);
if (EditorGUI.EndChangeCheck())
{

var blendNormalDistance = p.blendNormalDistancePositive.vector3Value.x;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = p.blendNormalDistancePositive.hasMultipleDifferentValues;
blendNormalDistance = EditorGUILayout.Slider(CoreEditorUtils.GetContent("Blend Normal Distance|Area around the probe where the normals influence the probe. Only used in deferred probes."), blendNormalDistance, 0, maxBlendDistance);
if (EditorGUI.EndChangeCheck())
{

EditorGUI.showMixedValue = false;
EditorGUILayout.PropertyField(p.influenceSphereRadius, CoreEditorUtils.GetContent("Radius"));
EditorGUILayout.PropertyField(p.boxOffset, CoreEditorUtils.GetContent("Sphere Offset|The center of the sphere in which the reflections will be applied to objects. The value is relative to the position of the Game Object."));

{
EditorGUILayout.PropertyField(p.renderDynamicObjects, CoreEditorUtils.GetContent("Dynamic Objects|If enabled dynamic objects are also rendered into the cubemap"));
p.customBakedTexture.objectReferenceValue = EditorGUILayout.ObjectField(CoreEditorUtils.GetContent("Cubemap"), p.customBakedTexture.objectReferenceValue, typeof(Cubemap), false);
EditorGUI.showMixedValue = p.customBakedTexture.hasMultipleDifferentValues;
EditorGUI.BeginChangeCheck();
var customBakedTexture = EditorGUILayout.ObjectField(CoreEditorUtils.GetContent("Cubemap"), p.customBakedTexture.objectReferenceValue, typeof(Cubemap), false);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
p.customBakedTexture.objectReferenceValue = customBakedTexture;
}
static void Drawer_ModeSettingsRealtime(HDReflectionProbeUI s, SerializedHDReflectionProbe p, Editor owner)

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.cs


{
operations = 0;
SetModeTarget(data.mode.intValue);
SetShapeTarget(data.influenceShape.intValue);
SetModeTarget(data.mode.hasMultipleDifferentValues ? -1 : data.mode.intValue);
SetShapeTarget(data.influenceShape.hasMultipleDifferentValues ? -1 : data.influenceShape.intValue);
isSectionExpandedSeparateProjection.value = data.useSeparateProjectionVolume.boolValue;
base.Update();

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/FrameSettingsUI.cs


EditorGUILayout.PropertyField(p.enablePostprocess, _.GetContent("Enable Postprocess"));
}
static void Drawer_SectionRenderingSettings(FrameSettingsUI s, SerializedFrameSettings p, Editor owner)
{
EditorGUILayout.PropertyField(p.enableForwardRenderingOnly, _.GetContent("Enable Forward Rendering Only"));
EditorGUILayout.PropertyField(p.enableDepthPrepassWithDeferredRendering, _.GetContent("Enable Depth Prepass With Deferred Rendering"));
EditorGUILayout.PropertyField(p.enableAlphaTestOnlyInDeferredPrepass, _.GetContent("Enable Alpha Test Only In Deferred Prepass"));
EditorGUILayout.PropertyField(p.enableAsyncCompute, _.GetContent("Enable Async Compute"));
EditorGUILayout.PropertyField(p.enableOpaqueObjects, _.GetContent("Enable Opaque Objects"));
EditorGUILayout.PropertyField(p.enableTransparentObjects, _.GetContent("Enable Transparent Objects"));
EditorGUILayout.PropertyField(p.enableMSAA, _.GetContent("Enable MSAA"));
}
static void Drawer_FieldForwardRenderingOnly(FrameSettingsUI s, SerializedFrameSettings p, Editor owner)
{
EditorGUILayout.PropertyField(p.enableForwardRenderingOnly, _.GetContent("Enable Forward Rendering Only"));

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


m_DebugDisplaySettings.RegisterDebug();
#if UNITY_EDITOR
// We don't need the debug of Default camera at runtime (each camera have its own debug settings)
FrameSettings.RegisterDebug("Default Camera", m_Asset.GetFrameSettings());
// We don't need the debug of Scene View at runtime (each camera have its own debug settings)
FrameSettings.RegisterDebug("Scene View", m_Asset.GetFrameSettings());
#endif
InitializeRenderTextures();

m_SSSBufferManager.Cleanup();
m_SkyManager.Cleanup();
m_VolumetricLightingModule.Cleanup();
m_IBLFilterGGX.Cleanup();
DestroyRenderTextures();

SceneViewDrawMode.ResetDrawMode();
FrameSettings.UnRegisterDebug("Scene View");
#endif
}

Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera);
PushFullScreenDebugTextureMip(cmd, m_BufferPyramid.depthPyramid, m_BufferPyramid.GetPyramidLodCount(hdCamera), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, debugMode);
cmd.SetGlobalTexture(HDShaderIDs._PyramidDepthTexture, m_BufferPyramid.depthPyramid);
}
void RenderPostProcess(HDCamera hdcamera, CommandBuffer cmd, PostProcessLayer layer)

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset


supportSSAO: 1
supportSubsurfaceScattering: 1
supportForwardOnly: 0
enableUltraQualitySSS: 0
supportDBuffer: 1
supportMSAA: 0
msaaSampleCount: 1

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Light/HDAdditionalLightData.cs


{
// At first init we need to initialize correctly the default value
lightData.ConvertPhysicalLightIntensityToLightIntensity();
// Special treatment for Unity builtin area light. Change it to our rectangle light
var light = lightData.gameObject.GetComponent<Light>();
if (light.type == LightType.Area)
{
lightData.lightTypeExtent = LightTypeExtent.Rectangle;
}
}
}

105
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


atlasInit.shadowClearShader = resources.shadowClearShader;
atlasInit.shadowBlurMoments = resources.shadowBlurMoments;
/*
// Code kept here for reference if we want to add VSM/MSM later on
varianceInit.baseInit.shadowmapFormat = ShadowVariance.GetFormat( false, false, true );
varianceInit.baseInit.shadowmapFormat = ShadowVariance.GetFormat(false, false, true);
varianceInit2.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, true, false );
varianceInit2.baseInit.shadowmapFormat = ShadowVariance.GetFormat(true, true, false);
varianceInit3.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, false, true );
varianceInit3.baseInit.shadowmapFormat = ShadowVariance.GetFormat(true, false, true);
m_Shadowmaps = new ShadowmapBase[] { new ShadowAtlas(ref atlasInit), new ShadowVariance(ref varianceInit), new ShadowVariance(ref varianceInit2), new ShadowVariance(ref varianceInit3) };
*/
m_Shadowmaps = new ShadowmapBase[] { new ShadowVariance(ref varianceInit), new ShadowVariance(ref varianceInit2), new ShadowVariance(ref varianceInit3), new ShadowAtlas(ref atlasInit) };
m_Shadowmaps = new ShadowmapBase[] { new ShadowAtlas(ref atlasInit) };
ShadowContext.SyncDel syncer = (ShadowContext sc) =>
{

cb.SetGlobalBuffer(HDShaderIDs._ShadowDatasExp, s_ShadowDataBuffer);
cb.SetGlobalBuffer(HDShaderIDs._ShadowPayloads, s_ShadowPayloadBuffer);
// bind textures
cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_VSM_0, tex[0]);
cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_VSM_1, tex[1]);
cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_VSM_2, tex[2]);
cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_PCF, tex[3]);
cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_PCF, tex[0]);
// Code kept here for reference if we want to add VSM/MSM later on
//cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_VSM_0, tex[1]);
//cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_VSM_1, tex[2]);
//cb.SetGlobalTexture(HDShaderIDs._ShadowmapExp_VSM_2, tex[3])
// TODO: Currently samplers are hard coded in ShadowContext.hlsl, so we can't really set them here
};

{
if (m_Shadowmaps != null)
{
(m_Shadowmaps[0] as ShadowAtlas).Dispose();
(m_Shadowmaps[1] as ShadowAtlas).Dispose();
(m_Shadowmaps[2] as ShadowAtlas).Dispose();
(m_Shadowmaps[3] as ShadowAtlas).Dispose();
foreach(var shadowMap in m_Shadowmaps)
{
(shadowMap as ShadowAtlas).Dispose();
}
m_Shadowmaps = null;
}
m_ShadowMgr = null;

public static readonly Vector3 k_BoxCullingExtentThreshold = Vector3.one * 0.01f;
// Static keyword is required here else we get a "DestroyBuffer can only be called from the main thread"
static ComputeBuffer s_DirectionalLightDatas = null;
static ComputeBuffer s_LightDatas = null;
static ComputeBuffer s_EnvLightDatas = null;
static ComputeBuffer s_shadowDatas = null;
static ComputeBuffer s_DecalDatas = null;
ComputeBuffer m_DirectionalLightDatas = null;
ComputeBuffer m_LightDatas = null;
ComputeBuffer m_EnvLightDatas = null;
ComputeBuffer m_shadowDatas = null;
ComputeBuffer m_DecalDatas = null;
static Texture2DArray s_DefaultTexture2DArray;
static Cubemap s_DefaultTextureCube;
Texture2DArray m_DefaultTexture2DArray;
Cubemap m_DefaultTextureCube;
PlanarReflectionProbeCache m_ReflectionPlanarProbeCache;
ReflectionProbeCache m_ReflectionProbeCache;

for (int i = 0, c = Mathf.Max(1, hdAsset.renderPipelineSettings.lightLoopSettings.maxPlanarReflectionProbes); i < c; ++i)
m_Env2DCaptureVP.Add(Matrix4x4.identity);
s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_shadowDatas = new ComputeBuffer(k_MaxCascadeCount + k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
s_DecalDatas = new ComputeBuffer(k_MaxDecalsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DecalData)));
m_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
m_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
m_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
m_shadowDatas = new ComputeBuffer(k_MaxCascadeCount + k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
m_DecalDatas = new ComputeBuffer(k_MaxDecalsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DecalData)));
m_CookieTexArray = new TextureCache2D();
m_CookieTexArray = new TextureCache2D("Cookie");
m_CubeCookieTexArray = new TextureCacheCubemap();
m_CubeCookieTexArray = new TextureCacheCubemap("Cookie");
m_CubeCookieTexArray.AllocTextureArray(gLightLoopSettings.cubeCookieTexArraySize, gLightLoopSettings.pointCookieSize, TextureFormat.RGBA32, true, m_CubeToPanoMaterial);
TextureFormat probeCacheFormat = gLightLoopSettings.reflectionCacheCompressed ? TextureFormat.BC6H : TextureFormat.RGBAHalf;

int index = GetDeferredLightingMaterialIndex(outputSplitLighting, lightLoopTilePass, shadowMask, debugDisplay);
m_deferredLightingMaterial[index] = CoreUtils.CreateEngineMaterial(m_Resources.deferredShader);
m_deferredLightingMaterial[index].name = string.Format("{0}_{1}", m_Resources.deferredShader.name, index);
CoreUtils.SetKeyword(m_deferredLightingMaterial[index], "OUTPUT_SPLIT_LIGHTING", outputSplitLighting == 1);
CoreUtils.SelectKeyword(m_deferredLightingMaterial[index], "LIGHTLOOP_TILE_PASS", "LIGHTLOOP_SINGLE_PASS", lightLoopTilePass == 1);
CoreUtils.SetKeyword(m_deferredLightingMaterial[index], "SHADOWS_SHADOWMASK", shadowMask == 1);

}
}
s_DefaultTexture2DArray = new Texture2DArray(1, 1, 1, TextureFormat.ARGB32, false);
s_DefaultTexture2DArray.SetPixels32(new Color32[1] { new Color32(128, 128, 128, 128) }, 0);
s_DefaultTexture2DArray.Apply();
m_DefaultTexture2DArray = new Texture2DArray(1, 1, 1, TextureFormat.ARGB32, false);
m_DefaultTexture2DArray.hideFlags = HideFlags.HideAndDontSave;
m_DefaultTexture2DArray.name = CoreUtils.GetTextureAutoName(1, 1, TextureFormat.ARGB32, depth: 1, dim: TextureDimension.Tex2DArray, name: "LightLoopDefault");
m_DefaultTexture2DArray.SetPixels32(new Color32[1] { new Color32(128, 128, 128, 128) }, 0);
m_DefaultTexture2DArray.Apply();
s_DefaultTextureCube = new Cubemap(16, TextureFormat.ARGB32, false);
s_DefaultTextureCube.Apply();
m_DefaultTextureCube = new Cubemap(16, TextureFormat.ARGB32, false);
m_DefaultTextureCube.Apply();
InitShadowSystem(hdAsset, shadowSettings);
}

DeinitShadowSystem();
CoreUtils.SafeRelease(s_DirectionalLightDatas);
CoreUtils.SafeRelease(s_LightDatas);
CoreUtils.SafeRelease(s_EnvLightDatas);
CoreUtils.SafeRelease(s_shadowDatas);
CoreUtils.SafeRelease(s_DecalDatas);
CoreUtils.Destroy(m_DefaultTexture2DArray);
CoreUtils.Destroy(m_DefaultTextureCube);
CoreUtils.SafeRelease(m_DirectionalLightDatas);
CoreUtils.SafeRelease(m_LightDatas);
CoreUtils.SafeRelease(m_EnvLightDatas);
CoreUtils.SafeRelease(m_shadowDatas);
CoreUtils.SafeRelease(m_DecalDatas);
if (m_ReflectionProbeCache != null)
{

void UpdateDataBuffers()
{
s_DirectionalLightDatas.SetData(m_lightList.directionalLights);
s_LightDatas.SetData(m_lightList.lights);
s_EnvLightDatas.SetData(m_lightList.envLights);
s_shadowDatas.SetData(m_lightList.shadows);
s_DecalDatas.SetData(DecalSystem.m_DecalDatas, 0, 0, Math.Min(DecalSystem.m_DecalDatasCount, k_MaxDecalsOnScreen)); // don't add more than the size of the buffer
m_DirectionalLightDatas.SetData(m_lightList.directionalLights);
m_LightDatas.SetData(m_lightList.lights);
m_EnvLightDatas.SetData(m_lightList.envLights);
m_shadowDatas.SetData(m_lightList.shadows);
m_DecalDatas.SetData(DecalSystem.m_DecalDatas, 0, 0, Math.Min(DecalSystem.m_DecalDatasCount, k_MaxDecalsOnScreen)); // don't add more than the size of the buffer
// These two buffers have been set in Rebuild()
s_ConvexBoundsBuffer.SetData(m_lightList.bounds);

cmd.SetGlobalTexture(HDShaderIDs._Env2DTextures, m_ReflectionPlanarProbeCache.GetTexCache());
cmd.SetGlobalMatrixArray(HDShaderIDs._Env2DCaptureVP, m_Env2DCaptureVP);
cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, s_DirectionalLightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, m_DirectionalLightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._LightDatas, s_LightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._LightDatas, m_LightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._EnvLightDatas, s_EnvLightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._EnvLightDatas, m_EnvLightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._DecalDatas, s_DecalDatas);
cmd.SetGlobalBuffer(HDShaderIDs._DecalDatas, m_DecalDatas);
cmd.SetGlobalBuffer(HDShaderIDs._ShadowDatas, s_shadowDatas);
cmd.SetGlobalBuffer(HDShaderIDs._ShadowDatas, m_shadowDatas);
cmd.SetGlobalInt(HDShaderIDs._NumTileFtplX, GetNumTileFtplX(hdCamera));
cmd.SetGlobalInt(HDShaderIDs._NumTileFtplY, GetNumTileFtplY(hdCamera));

39
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopSettings.cs


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

// Setup by system
public bool isFptlEnabled = true;
static DebugUI.Widget[] s_DebugEntries;
public void CopyTo(LightLoopSettings lightLoopSettings)
{

aggregate.isFptlEnabled = !aggregateFrameSettings.enableForwardRenderingOnly || aggregate.enableFptlForForwardOpaque;
}
public static void RegisterDebug(string menuName, LightLoopSettings lightLoopSettings)
public static void RegisterDebug(LightLoopSettings lightLoopSettings, List<DebugUI.Widget> widgets)
s_DebugEntries = new DebugUI.Widget[]
widgets.AddRange(new []
new DebugUI.BoolField { displayName = "Enable Fptl for Forward Opaque", getter = () => lightLoopSettings.enableFptlForForwardOpaque, setter = value => lightLoopSettings.enableFptlForForwardOpaque = value },
new DebugUI.BoolField { displayName = "Enable Tile/Cluster", getter = () => lightLoopSettings.enableTileAndCluster, setter = value => lightLoopSettings.enableTileAndCluster = value },
new DebugUI.BoolField { displayName = "Enable Big Tile", getter = () => lightLoopSettings.enableBigTilePrepass, setter = value => lightLoopSettings.enableBigTilePrepass = value },
new DebugUI.BoolField { displayName = "Enable Compute Lighting", getter = () => lightLoopSettings.enableComputeLightEvaluation, setter = value => lightLoopSettings.enableComputeLightEvaluation = value },
new DebugUI.BoolField { displayName = "Enable Light Classification", getter = () => lightLoopSettings.enableComputeLightVariants, setter = value => lightLoopSettings.enableComputeLightVariants = value },
new DebugUI.BoolField { displayName = "Enable Material Classification", getter = () => lightLoopSettings.enableComputeMaterialVariants, setter = value => lightLoopSettings.enableComputeMaterialVariants = value }
};
var panel = DebugManager.instance.GetPanel(menuName, true);
panel.children.Add(s_DebugEntries);
}
public static void UnRegisterDebug(string menuName)
{
var panel = DebugManager.instance.GetPanel(menuName);
if (panel != null)
panel.children.Remove(s_DebugEntries);
new DebugUI.Container
{
displayName = "Lighting Settings",
children =
{
new DebugUI.BoolField { displayName = "Enable Fptl for Forward Opaque", getter = () => lightLoopSettings.enableFptlForForwardOpaque, setter = value => lightLoopSettings.enableFptlForForwardOpaque = value },
new DebugUI.BoolField { displayName = "Enable Tile/Cluster", getter = () => lightLoopSettings.enableTileAndCluster, setter = value => lightLoopSettings.enableTileAndCluster = value },
new DebugUI.BoolField { displayName = "Enable Big Tile", getter = () => lightLoopSettings.enableBigTilePrepass, setter = value => lightLoopSettings.enableBigTilePrepass = value },
new DebugUI.BoolField { displayName = "Enable Compute Lighting", getter = () => lightLoopSettings.enableComputeLightEvaluation, setter = value => lightLoopSettings.enableComputeLightEvaluation = value },
new DebugUI.BoolField { displayName = "Enable Light Classification", getter = () => lightLoopSettings.enableComputeLightVariants, setter = value => lightLoopSettings.enableComputeLightVariants = value },
new DebugUI.BoolField { displayName = "Enable Material Classification", getter = () => lightLoopSettings.enableComputeMaterialVariants, setter = value => lightLoopSettings.enableComputeMaterialVariants = value }
}
}
});
}
}
}

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Shadow.hlsl


//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
// directional
#define SHADOW_DISPATCH_DIR_TEX 3
#define SHADOW_DISPATCH_DIR_TEX 0
#define SHADOW_DISPATCH_DIR_SMP 0
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_5X5 // all cascades
#define SHADOW_DISPATCH_DIR_ALG_0 GPUSHADOWALGORITHM_PCF_TENT_7X7 // 1st cascade

// point
#define SHADOW_DISPATCH_POINT_TEX 3
#define SHADOW_DISPATCH_POINT_TEX 0
#define SHADOW_DISPATCH_SPOT_TEX 3
#define SHADOW_DISPATCH_SPOT_TEX 0
#define SHADOW_DISPATCH_PUNC_TEX 3
#define SHADOW_DISPATCH_PUNC_TEX 0
#define SHADOW_DISPATCH_PUNC_SMP 0
#define SHADOW_DISPATCH_PUNC_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/ShadowContext.hlsl


StructuredBuffer<ShadowData> _ShadowDatasExp;
StructuredBuffer<int4> _ShadowPayloads;
// Currently we only use the PCF atlas.
// Keeping all other bindings for reference and for future PC dynamic shadow configuration as it's harmless anyway.
sc.tex2DArray[0] = _ShadowmapExp_VSM_0;
sc.tex2DArray[1] = _ShadowmapExp_VSM_1;
sc.tex2DArray[2] = _ShadowmapExp_VSM_2;
sc.tex2DArray[3] = _ShadowmapExp_PCF;
sc.samplers[0] = sampler_ShadowmapExp_VSM_0;
sc.tex2DArray[0] = _ShadowmapExp_PCF;
sc.tex2DArray[1] = _ShadowmapExp_VSM_0;
sc.tex2DArray[2] = _ShadowmapExp_VSM_1;
sc.tex2DArray[3] = _ShadowmapExp_VSM_2;
sc.compSamplers[0] = sampler_ShadowmapExp_PCF;
sc.samplers[0] = sampler_ShadowmapExp_VSM_0;
sc.compSamplers[0] = sampler_ShadowmapExp_PCF;
return sc;
}

33
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightUtils.cs


// Physical light unit helper
// All light unit are in lumen (Luminous power)
// Punctual light (point, spot) are convert to candela (cd = lumens / steradian)
// Area light are convert to luminance (cd/(m^2*steradian)) with the following formulation: Luminous Power / (Area * PI * steradian)
// For our isotropic area lights which expect radiance(W / (sr* m^2)) in the shader:
// power = Integral{area, Integral{hemisphere, radiance * <N, L>}},
// power = area * Pi * radiance,
// radiance = power / (area * Pi).
// We use photometric unit, so radiance is luminance and power is luminous power
// Ref: Moving Frostbite to PBR
// Also good ref: https://www.radiance-online.org/community/workshops/2004-fribourg/presentations/Wandachowicz_paper.pdf

// convert intensity (lumen) to nits
public static float CalculateLineLightIntensity(float intensity, float lineWidth)
{
// Line lights in the shader expect intensity (W / sr).
// In the UI, we specify luminous flux(power) in lumens.
// First, it needs to be converted to radiometric units(radiant flux, W).
// Then we must recall how to compute power from intensity for a line light:
// power = Integral{length, Integral{sphere, intensity}}.
// For an isotropic line light, intensity is constant, so
// power = length * (4 * Pi) * intensity,
// intensity = power / (length * (4 * Pi)).
//Line lights expect radiance (W / (sr * m^2)) in the shader.
//In the UI, we specify luminous flux (power) in lumens.
//First, it needs to be converted to radiometric units (radiant flux, W).
//Then we must recall how to compute power from radiance:
//radiance = differential_power / (differrential_projected_area * differential_solid_angle),
//radiance = differential_power / (differrential_area * differential_solid_angle * <N, L>),
//power = Integral{area, Integral{hemisphere, radiance * <N, L>}}.
//Unlike tube lights, our line lights have no surface area, so the integral becomes:
//power = Integral{length, Integral{sphere, radiance}}.
//For an isotropic line light, radiance is constant, therefore:
//power = length * (4 * Pi) * radiance,
//radiance = power / (length * (4 * Pi)).
return intensity / (4.0f * Mathf.PI * lineWidth);
}
}

23
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbeCache.cs


m_ProbeSize = probeSize;
m_CacheSize = cacheSize;
m_TextureCache = new TextureCache2D();
m_TextureCache = new TextureCache2D("PlanarReflectionProbe");
m_TextureCache.AllocTextureArray(cacheSize, probeSize, probeSize, probeFormat, isMipmaped);
m_IBLFilterGGX = iblFilter;

m_TempRenderTexture.dimension = TextureDimension.Tex2D;
m_TempRenderTexture.useMipMap = true;
m_TempRenderTexture.autoGenerateMips = false;
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflection", mips : true);
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflectionTemp", mips : true);
m_TempRenderTexture.Create();
m_ConvolutionTargetTexture = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);

public void Release()
{
if (m_TextureCache != null)
{
m_TextureCache.Release();
m_TextureCache = null;
}
if (m_TempRenderTexture != null)
{
m_TempRenderTexture.Release();
m_TempRenderTexture = null;
}
if (m_ConvolutionTargetTexture != null)
{
m_ConvolutionTargetTexture.Release();
m_ConvolutionTargetTexture = null;
}
m_TextureCache.Release();
CoreUtils.Destroy(m_TempRenderTexture);
CoreUtils.Destroy(m_ConvolutionTargetTexture);
m_ProbeBakingState = null;
CoreUtils.Destroy(m_ConvertTextureMaterial);

25
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCache.cs


m_ProbeSize = probeSize;
m_CacheSize = cacheSize;
m_TextureCache = new TextureCacheCubemap();
m_TextureCache = new TextureCacheCubemap("ReflectionProbe");
m_TextureCache.AllocTextureArray(cacheSize, probeSize, probeFormat, isMipmaped, m_CubeToPano);
m_IBLFilterGGX = iblFilter;

m_TempRenderTexture.dimension = TextureDimension.Cube;
m_TempRenderTexture.useMipMap = true;
m_TempRenderTexture.autoGenerateMips = false;
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflection", mips : true);
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "ReflectionProbeTemp", mips : true);
m_TempRenderTexture.Create();
m_ConvolutionTargetTexture = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);

m_ConvolutionTargetTexture.autoGenerateMips = false;
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflection", mips : true);
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "ReflectionProbeConvolution", mips : true);
m_ConvolutionTargetTexture.Create();
InitializeProbeBakingStates();

public void Release()
{
if (m_TextureCache != null)
{
m_TextureCache.Release();
m_TextureCache = null;
}
if (m_TempRenderTexture != null)
{
m_TempRenderTexture.Release();
m_TempRenderTexture = null;
}
if (m_ConvolutionTargetTexture != null)
{
m_ConvolutionTargetTexture.Release();
m_ConvolutionTargetTexture = null;
}
m_TextureCache.Release();
CoreUtils.Destroy(m_TempRenderTexture);
CoreUtils.Destroy(m_ConvolutionTargetTexture);
m_ProbeBakingState = null;
CoreUtils.Destroy(m_ConvertTextureMaterial);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/MRTBufferManager.cs


public abstract void CreateBuffers();
public void BindBufferAsTextures(CommandBuffer cmd)
public virtual void BindBufferAsTextures(CommandBuffer cmd)
{
for (int i = 0; i < m_BufferCount; ++i)
{

21
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/GBufferManager.cs


using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

bool m_EnableShadowMask = false;
bool m_SupportShadowMask = false;
RenderPipelineMaterial m_DeferredMaterial;
protected RenderTargetIdentifier[] m_RTIDsNoShadowMask;

m_DeferredMaterial = deferredMaterial;
m_GBufferCount = deferredMaterial.GetMaterialGBufferCount();
m_EnableShadowMask = enableBakeShadowMask;
m_SupportShadowMask = enableBakeShadowMask;
m_RTIDsNoShadowMask = new RenderTargetIdentifier[m_GBufferCount];
}

m_RTIDsNoShadowMask[gbufferIndex] = HDShaderIDs._GBufferTexture[gbufferIndex];
}
if (m_EnableShadowMask)
if (m_SupportShadowMask)
}
}
public override void BindBufferAsTextures(CommandBuffer cmd)
{
for (int i = 0; i < m_BufferCount; ++i)
{
cmd.SetGlobalTexture(m_TextureShaderIDs[i], m_RTs[i]);
}
// When shadow mask are disabled (i.e we haven't created shadow mask texture, bind a white texture).
if (!m_SupportShadowMask)
{
cmd.SetGlobalTexture(HDShaderIDs._ShadowMaskTexture, RuntimeUtilities.whiteTexture);
}
}

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/GGXConvolution/RuntimeFilterIBL.cs


m_GgxIblSampleData.enableRandomWrite = true;
m_GgxIblSampleData.filterMode = FilterMode.Point;
m_GgxIblSampleData.name = CoreUtils.GetRenderTargetAutoName(m_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, RenderTextureFormat.ARGBHalf, "GGXIblSampleData");
m_GgxIblSampleData.hideFlags = HideFlags.HideAndDontSave;
m_GgxIblSampleData.Create();
m_ComputeGgxIblSampleDataCS.SetTexture(m_ComputeGgxIblSampleDataKernel, "output", m_GgxIblSampleData);

var lookAt = Matrix4x4.LookAt(Vector3.zero, CoreUtils.lookAtList[i], CoreUtils.upVectorList[i]);
m_faceWorldToViewMatrixMatrices[i] = lookAt * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API. ...
}
}
public void Cleanup()
{
CoreUtils.Destroy(m_GgxConvolveMaterial);
CoreUtils.Destroy(m_GgxIblSampleData);
}
void FilterCubemapCommon( CommandBuffer cmd,

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs


{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Bilinear
filterMode = FilterMode.Bilinear,
name = CoreUtils.GetTextureAutoName(k_LtcLUTResolution, k_LtcLUTResolution, TextureFormat.RGBAHalf, depth: 3, dim: TextureDimension.Tex2DArray, name: "LTC_LUT")
};
LoadLUT(m_LtcData, 0, TextureFormat.RGBAHalf, s_LtcGGXMatrixData);

public override void Cleanup()
{
CoreUtils.Destroy(m_InitPreFGD);
CoreUtils.Destroy(m_PreIntegratedFGD);
CoreUtils.Destroy(m_LtcData);
// TODO: how to delete RenderTexture ? or do we need to do it ?
m_isInit = false;

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/MaterialUtilities.hlsl


#if defined(UNITY_LIGHTMAP_RGBM_ENCODING)
float4 decodeInstructions = float4(34.493242, 2.2, 0.0, 0.0); // range^2.2 = 5^2.2, gamma = 2.2
#else
float4 decodeInstructions = float4(0.0, 0.0, 0.0, 0.0); // range = 2.0^2.2 = 4.59
float4 decodeInstructions = float4(2.0, 2.2, 0.0, 0.0); // range = 2.0^2.2 = 4.59
#endif
#endif

#endif
#ifdef DYNAMICLIGHTMAP_ON
float4 decodeInstructions = float4(0.0, 0.0, 0.0, 0.0); // Never used but needed for the interface since it supports gamma lightmaps
#ifdef DIRLIGHTMAP_COMBINED
bakeDiffuseLighting += SampleDirectionalLightmap(TEXTURE2D_PARAM(unity_DynamicLightmap, samplerunity_DynamicLightmap),
TEXTURE2D_PARAM(unity_DynamicDirectionality, samplerunity_DynamicLightmap),

103
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/FrameSettings.cs


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

public bool enableShadowMask = false;
public LightLoopSettings lightLoopSettings = new LightLoopSettings();
static DebugUI.Widget[] s_DebugEntries;
public void CopyTo(FrameSettings frameSettings)
{

public static void RegisterDebug(string menuName, FrameSettings frameSettings)
{
s_DebugEntries = new DebugUI.Widget[]
List<DebugUI.Widget> widgets = new List<DebugUI.Widget>();
widgets.AddRange(
new DebugUI.Widget[]
new DebugUI.BoolField { displayName = "Enable Shadows", getter = () => frameSettings.enableShadow, setter = value => frameSettings.enableShadow = value },
new DebugUI.BoolField { displayName = "Enable Contact Shadows", getter = () => frameSettings.enableContactShadows, setter = value => frameSettings.enableContactShadows = value },
new DebugUI.BoolField { displayName = "Enable SSR", getter = () => frameSettings.enableSSR, setter = value => frameSettings.enableSSR = value },
new DebugUI.BoolField { displayName = "Enable SSAO", getter = () => frameSettings.enableSSAO, setter = value => frameSettings.enableSSAO = value },
new DebugUI.BoolField { displayName = "Enable SubsurfaceScattering", getter = () => frameSettings.enableSubsurfaceScattering, setter = value => frameSettings.enableSubsurfaceScattering = value },
new DebugUI.BoolField { displayName = "Enable Transmission", getter = () => frameSettings.enableTransmission, setter = value => frameSettings.enableTransmission = value },
new DebugUI.BoolField { displayName = "Forward Only", getter = () => frameSettings.enableForwardRenderingOnly, setter = value => frameSettings.enableForwardRenderingOnly = value },
new DebugUI.BoolField { displayName = "Deferred Depth Prepass", getter = () => frameSettings.enableDepthPrepassWithDeferredRendering, setter = value => frameSettings.enableDepthPrepassWithDeferredRendering = value },
new DebugUI.BoolField { displayName = "Deferred Depth Prepass ATest Only", getter = () => frameSettings.enableAlphaTestOnlyInDeferredPrepass, setter = value => frameSettings.enableAlphaTestOnlyInDeferredPrepass = value },
new DebugUI.BoolField { displayName = "Enable Transparent Prepass", getter = () => frameSettings.enableTransparentPrepass, setter = value => frameSettings.enableTransparentPrepass = value },
new DebugUI.BoolField { displayName = "Enable Motion Vectors", getter = () => frameSettings.enableMotionVectors, setter = value => frameSettings.enableMotionVectors = value },
new DebugUI.BoolField { displayName = "Enable Object Motion Vectors", getter = () => frameSettings.enableObjectMotionVectors, setter = value => frameSettings.enableObjectMotionVectors = value },
new DebugUI.BoolField { displayName = "Enable DBuffer", getter = () => frameSettings.enableDBuffer, setter = value => frameSettings.enableDBuffer = value },
new DebugUI.BoolField { displayName = "Enable Atmospheric Scattering", getter = () => frameSettings.enableAtmosphericScattering, setter = value => frameSettings.enableAtmosphericScattering = value },
new DebugUI.BoolField { displayName = "Enable Rough Refraction", getter = () => frameSettings.enableRoughRefraction, setter = value => frameSettings.enableRoughRefraction = value },
new DebugUI.BoolField { displayName = "Enable Transparent Postpass", getter = () => frameSettings.enableTransparentPostpass, setter = value => frameSettings.enableTransparentPostpass = value },
new DebugUI.BoolField { displayName = "Enable Distortion", getter = () => frameSettings.enableDistortion, setter = value => frameSettings.enableDistortion = value },
new DebugUI.BoolField { displayName = "Enable Postprocess", getter = () => frameSettings.enablePostprocess, setter = value => frameSettings.enablePostprocess = value },
new DebugUI.BoolField { displayName = "Enable Stereo Rendering", getter = () => frameSettings.enableStereo, setter = value => frameSettings.enableStereo = value },
new DebugUI.BoolField { displayName = "Enable Async Compute", getter = () => frameSettings.enableAsyncCompute, setter = value => frameSettings.enableAsyncCompute = value },
new DebugUI.BoolField { displayName = "Enable Opaque Objects", getter = () => frameSettings.enableOpaqueObjects, setter = value => frameSettings.enableOpaqueObjects = value },
new DebugUI.BoolField { displayName = "Enable Transparent Objects", getter = () => frameSettings.enableTransparentObjects, setter = value => frameSettings.enableTransparentObjects = value },
new DebugUI.Container
{
displayName = "Rendering Passes",
children =
{
new DebugUI.BoolField { displayName = "Enable Transparent Prepass", getter = () => frameSettings.enableTransparentPrepass, setter = value => frameSettings.enableTransparentPrepass = value },
new DebugUI.BoolField { displayName = "Enable Transparent Postpass", getter = () => frameSettings.enableTransparentPostpass, setter = value => frameSettings.enableTransparentPostpass = value },
new DebugUI.BoolField { displayName = "Enable Motion Vectors", getter = () => frameSettings.enableMotionVectors, setter = value => frameSettings.enableMotionVectors = value },
new DebugUI.BoolField { displayName = "Enable Object Motion Vectors", getter = () => frameSettings.enableObjectMotionVectors, setter = value => frameSettings.enableObjectMotionVectors = value },
new DebugUI.BoolField { displayName = "Enable DBuffer", getter = () => frameSettings.enableDBuffer, setter = value => frameSettings.enableDBuffer = value },
new DebugUI.BoolField { displayName = "Enable Atmospheric Scattering", getter = () => frameSettings.enableAtmosphericScattering, setter = value => frameSettings.enableAtmosphericScattering = value },
new DebugUI.BoolField { displayName = "Enable Rough Refraction", getter = () => frameSettings.enableRoughRefraction, setter = value => frameSettings.enableRoughRefraction = value },
new DebugUI.BoolField { displayName = "Enable Distortion", getter = () => frameSettings.enableDistortion, setter = value => frameSettings.enableDistortion = value },
new DebugUI.BoolField { displayName = "Enable Postprocess", getter = () => frameSettings.enablePostprocess, setter = value => frameSettings.enablePostprocess = value },
}
},
new DebugUI.Container
{
displayName = "Rendering Settings",
children =
{
new DebugUI.BoolField { displayName = "Forward Only", getter = () => frameSettings.enableForwardRenderingOnly, setter = value => frameSettings.enableForwardRenderingOnly = value },
new DebugUI.BoolField { displayName = "Deferred Depth Prepass", getter = () => frameSettings.enableDepthPrepassWithDeferredRendering, setter = value => frameSettings.enableDepthPrepassWithDeferredRendering = value },
new DebugUI.BoolField { displayName = "Deferred Depth Prepass ATest Only", getter = () => frameSettings.enableAlphaTestOnlyInDeferredPrepass, setter = value => frameSettings.enableAlphaTestOnlyInDeferredPrepass = value },
new DebugUI.BoolField { displayName = "Enable Async Compute", getter = () => frameSettings.enableAsyncCompute, setter = value => frameSettings.enableAsyncCompute = value },
new DebugUI.BoolField { displayName = "Enable Opaque Objects", getter = () => frameSettings.enableOpaqueObjects, setter = value => frameSettings.enableOpaqueObjects = value },
new DebugUI.BoolField { displayName = "Enable Transparent Objects", getter = () => frameSettings.enableTransparentObjects, setter = value => frameSettings.enableTransparentObjects = value },
new DebugUI.BoolField { displayName = "Enable MSAA", getter = () => frameSettings.enableMSAA, setter = value => frameSettings.enableMSAA = value },
}
},
new DebugUI.Container
{
displayName = "XR Settings",
children =
{
new DebugUI.BoolField { displayName = "Enable Stereo Rendering", getter = () => frameSettings.enableStereo, setter = value => frameSettings.enableStereo = value }
}
},
new DebugUI.Container
{
displayName = "Lighting Settings",
children =
{
new DebugUI.BoolField { displayName = "Enable SSR", getter = () => frameSettings.enableSSR, setter = value => frameSettings.enableSSR = value },
new DebugUI.BoolField { displayName = "Enable SSAO", getter = () => frameSettings.enableSSAO, setter = value => frameSettings.enableSSAO = value },
new DebugUI.BoolField { displayName = "Enable SubsurfaceScattering", getter = () => frameSettings.enableSubsurfaceScattering, setter = value => frameSettings.enableSubsurfaceScattering = value },
new DebugUI.BoolField { displayName = "Enable Transmission", getter = () => frameSettings.enableTransmission, setter = value => frameSettings.enableTransmission = value },
new DebugUI.BoolField { displayName = "Enable Shadows", getter = () => frameSettings.enableShadow, setter = value => frameSettings.enableShadow = value },
new DebugUI.BoolField { displayName = "Enable Contact Shadows", getter = () => frameSettings.enableContactShadows, setter = value => frameSettings.enableContactShadows = value },
new DebugUI.BoolField { displayName = "Enable ShadowMask", getter = () => frameSettings.enableShadowMask, setter = value => frameSettings.enableShadowMask = value },
}
}
});
new DebugUI.BoolField { displayName = "Enable MSAA", getter = () => frameSettings.enableMSAA, setter = value => frameSettings.enableMSAA = value },
new DebugUI.BoolField { displayName = "Enable ShadowMask", getter = () => frameSettings.enableShadowMask, setter = value => frameSettings.enableShadowMask = value },
};
LightLoopSettings.RegisterDebug(frameSettings.lightLoopSettings, widgets);
panel.children.Add(s_DebugEntries);
LightLoopSettings.RegisterDebug(menuName, frameSettings.lightLoopSettings);
}
panel.children.Add(widgets.ToArray());
}
var panel = DebugManager.instance.GetPanel(menuName);
if (panel != null)
panel.children.Remove(s_DebugEntries);
LightLoopSettings.UnRegisterDebug(menuName);
DebugManager.instance.RemovePanel(menuName);
}
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassForward.hlsl


// We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.
#ifdef DEBUG_DISPLAY
// Init in debug display mode to quiet warning
#ifdef OUTPUT_SPLIT_LIGHTING
outDiffuseLighting = 0;
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
#endif
if (_DebugLightingMode != DEBUGLIGHTINGMODE_NONE || _DebugMipMapMode != DEBUGMIPMAPMODE_NONE)
#endif
{

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs


public void Cleanup()
{
CoreUtils.Destroy(m_StandardSkyboxMaterial);
CoreUtils.Destroy(m_BlitCubemapMaterial);
CoreUtils.Destroy(m_OpaqueAtmScatteringMaterial);
m_BakingSky.Cleanup();
m_VisualSky.Cleanup();

33
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightAssetEditor.cs


using System.Linq;
using UnityEditor.Experimental.Rendering;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
{

EditorGUILayout.PropertyField(prop, content);
}
protected void DoPopup(GUIContent label, SerializedProperty property, string[] options)
{
var mode = property.intValue;
EditorGUI.BeginChangeCheck();
if (mode >= options.Length)
Debug.LogError(string.Format("Invalid option while trying to set {0}", label.text));
mode = EditorGUILayout.Popup(label, mode, options);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(property.objectReferenceValue, property.name);
property.intValue = mode;
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();

EditorGUILayout.LabelField(Styles.shadowLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
DoPopup(Styles.shadowType, m_ShadowTypeProp, Styles.shadowTypeOptions);
CoreEditorUtils.DrawPopup(Styles.shadowType, m_ShadowTypeProp, Styles.shadowTypeOptions);
EditorGUILayout.PropertyField(m_ShadowDistanceProp, Styles.shadowDistante);
DoPopup(Styles.shadowCascades, m_ShadowCascadesProp, Styles.shadowCascadeOptions);
m_ShadowDistanceProp.floatValue = Mathf.Max(0.0f, EditorGUILayout.FloatField(Styles.shadowDistante, m_ShadowDistanceProp.floatValue));
CoreEditorUtils.DrawPopup(Styles.shadowCascades, m_ShadowCascadesProp, Styles.shadowCascadeOptions);
{
EditorGUILayout.PropertyField(m_ShadowCascade4SplitProp, Styles.shadowCascadeSplit);
}
CoreEditorUtils.DrawCascadeSplitGUI<Vector3>(ref m_ShadowCascade4SplitProp);
{
EditorGUILayout.PropertyField(m_ShadowCascade2SplitProp, Styles.shadowCascadeSplit);
}
CoreEditorUtils.DrawCascadeSplitGUI<float>(ref m_ShadowCascade2SplitProp);
EditorGUI.indentLevel--;

3
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


private MixedLightingSetup m_MixedLightingSetup;
private const int kDepthStencilBufferBits = 32;
private const int kShadowBufferBits = 16;
private Vector4[] m_DirectionalShadowSplitDistances = new Vector4[kMaxCascades];
private Vector4 m_DirectionalShadowSplitRadii;

var cmd = CommandBufferPool.Get("Prepare Shadowmap");
cmd.GetTemporaryRT(m_ShadowMapRTID, m_ShadowSettings.shadowAtlasWidth,
m_ShadowSettings.shadowAtlasHeight, kDepthStencilBufferBits, FilterMode.Bilinear, m_ShadowSettings.renderTextureFormat);
m_ShadowSettings.shadowAtlasHeight, kShadowBufferBits, FilterMode.Bilinear, m_ShadowSettings.renderTextureFormat);
// LightweightPipeline.SetRenderTarget is meant to be used with camera targets, not shadowmaps
CoreUtils.SetRenderTarget(cmd, m_ShadowMapRT, ClearFlag.Depth, CoreUtils.ConvertSRGBToActiveColorSpace(m_CurrCamera.backgroundColor));

8
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl


#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "Input.hlsl"
#if !defined(SHADER_HINT_NICE_QUALITY)
#ifdef SHADER_API_MOBILE
#define SHADER_HINT_NICE_QUALITY 0
#else
#define SHADER_HINT_NICE_QUALITY 1
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
#ifdef _NORMALMAP
#define OUTPUT_NORMAL(IN, OUT) OutputTangentToWorld(IN.tangent, IN.normal, OUT.tangent, OUT.binormal, OUT.normal)

13
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl


half4 GetMainLightDirectionAndAttenuation(LightInput lightInput, float3 positionWS)
{
half4 directionAndAttenuation = lerp(half4(lightInput.position.xyz, 1.0), GetLightDirectionAndAttenuation(lightInput, positionWS), lightInput.position.w);
half4 directionAndAttenuation = GetLightDirectionAndAttenuation(lightInput, positionWS);
// Cookies are only computed for main light
directionAndAttenuation.w *= CookieAttenuation(positionWS);

// 1) Gives good estimate of illumination as if light would've been shadowed during the bake.
// Preserves bounce and other baked lights
// No shadows on the geometry facing away from the light
// We only subtract the main direction light. This is accounted in the contribution term below.
half NdotL = saturate(dot(mainLight.direction, normalWS));
half3 lambert = mainLight.color * NdotL;
half contributionTerm = saturate(dot(mainLight.direction, normalWS)) * (1.0 - _MainLightPosition.w);
half3 lambert = mainLight.color * contributionTerm;
half3 estimatedLightContributionMaskedByInverseOfShadow = lambert * (1.0 - mainLight.attenuation);
half3 subtractedLightmap = bakedGI - estimatedLightContributionMaskedByInverseOfShadow;

void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout half3 bakedGI, half4 shadowMask)
{
#if defined(_MIXED_LIGHTING_SUBTRACTIVE) && defined(LIGHTMAP_ON) && defined(_SHADOWS_ENABLED)
bakedGI = lerp(SubtractDirectMainLightFromLightmap(light, normalWS, bakedGI), bakedGI, _MainLightPosition.w);
#if defined(_MIXED_LIGHTING_SUBTRACTIVE) && defined(LIGHTMAP_ON)
bakedGI = SubtractDirectMainLightFromLightmap(light, normalWS, bakedGI);
#endif
#if defined(LIGHTMAP_ON)

16
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl


inputData.normalWS = normalize(IN.normal);
#endif
#ifdef SHADER_API_MOBILE
// viewDirection should be normalized here, but we avoid doing it as it's close enough and we save some ALU.
inputData.viewDirectionWS = IN.viewDir;
#if SHADER_HINT_NICE_QUALITY
inputData.viewDirectionWS = SafeNormalize(IN.viewDir);
inputData.viewDirectionWS = normalize(IN.viewDir);
// View direction is already normalize in vertex. Small acceptable error to save ALU.
inputData.viewDirectionWS = IN.viewDir;
#endif
inputData.shadowCoord = IN.shadowCoord;

o.posWS = TransformObjectToWorld(v.vertex.xyz);
o.clipPos = TransformWorldToHClip(o.posWS);
o.viewDir = SafeNormalize(GetCameraPositionWS() - o.posWS);
o.viewDir = GetCameraPositionWS() - o.posWS;
#if !SHADER_HINT_NICE_QUALITY
// Normalize in vertex and avoid renormalizing it in frag to save ALU.
o.viewDir = SafeNormalize(o.viewDir);
#endif
// initializes o.normal and if _NORMALMAP also o.tangent and o.binormal
OUTPUT_NORMAL(v, o);

4
Tests/Scripts/Editor/GraphicTests/Framework/TestFrameworkCustomBuild.cs


private static readonly string s_TestSceneFolder = "/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes";
private static readonly string s_BuildFolder = "/TestScenesBuild";
[MenuItem("Internal/RenderPipeline/TestFramework/Build-iOS")]
//[MenuItem("Internal/RenderPipeline/TestFramework/Build-iOS")]
public static void BuildiOS()
{
TestFrameworkCustomBuild builder = new TestFrameworkCustomBuild();

[MenuItem("Internal/RenderPipeline/TestFramework/Build-iOS", true)]
//[MenuItem("Internal/RenderPipeline/TestFramework/Build-iOS", true)]
public static bool ValidateBuildiOS()
{
#if UNITY_STANDALONE_OSX

正在加载...
取消
保存