浏览代码

merge changes from remote to local branch

/classicDeferredMobile
Filip Iliescu 7 年前
当前提交
9c290707
共有 346 个文件被更改,包括 3065 次插入3937 次删除
  1. 31
      Assets/ScriptableRenderPipeline/Core/AdditionalLightData.cs
  2. 2
      Assets/ScriptableRenderPipeline/Core/Camera/CameraSwitcher.cs
  3. 24
      Assets/ScriptableRenderPipeline/Core/Debugging/DebugActionManager.cs
  4. 156
      Assets/ScriptableRenderPipeline/Core/Debugging/DebugMenuManager.cs
  5. 163
      Assets/ScriptableRenderPipeline/Core/Debugging/DebugMenuUI.cs
  6. 22
      Assets/ScriptableRenderPipeline/Core/Debugging/DebugMenuUpdater.cs
  7. 56
      Assets/ScriptableRenderPipeline/Core/Debugging/Editor/DebugMenuEditor.cs
  8. 18
      Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  9. 2
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs.hlsl
  10. 7
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowUtilities.cs
  11. 26
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  12. 337
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  13. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  14. 11
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/SceneSettingsManagementWindow.cs
  15. 393
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  16. 210
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  17. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  18. 32
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  19. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  20. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  21. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  22. 42
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  23. 58
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  24. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  25. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  26. 140
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  27. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  28. 46
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  29. 26
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  30. 24
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  31. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  32. 177
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  33. 549
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  34. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.hlsl
  35. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.hlsl.meta
  36. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl
  37. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  38. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources.meta
  39. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettings.cs
  40. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettingsManager.cs
  41. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  42. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs
  43. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  44. 21
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
  45. 1
      Assets/ScriptableRenderPipeline/MobileRenderPipeline/ClassicDeferred/ClassicDeferredPipeline.cs
  46. 34
      Assets/ScriptableRenderPipeline/ShaderLibrary/BSDF.hlsl
  47. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  48. 6
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl
  49. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/EntityLighting.hlsl
  50. 2
      Assets/ScriptableRenderPipeline/ShaderLibrary/ImageBasedLighting.hlsl
  51. 3
      Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl
  52. 97
      Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl
  53. 10
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  54. 6
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  55. 13
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl
  56. 26
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl
  57. 61
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/LowEndMobilePipelineAsset.cs
  58. 6
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset
  59. 21
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/LowEndMobilePipeline.cs
  60. 9
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/TestScenes/Materials/LDRenderPipeMaterials/LDSpecularSphere0.mat
  61. 6
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndParticlesMultiply.shader
  62. 6
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndParticlesAdd.shader
  63. 44
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndMobilePipelineShadows.cginc
  64. 14
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndMobilePipelineCore.cginc
  65. 70
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndMobilePipeline.shader
  66. 14
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LowendUpgraders.cs
  67. 12
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LowendPipelineAssetInspector.cs
  68. 21
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LowendMobilePipelineMaterialEditor.cs
  69. 10
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LegacyShadersToLowEndUpgrader.cs
  70. 2
      Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/UpgradeCommon.cs
  71. 2
      Assets/TestScenes/HDTest/GraphicTest/SSS/Materials/SSSHead.mat
  72. 451
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity
  73. 245
      Assets/TestScenes/MobileDeferredTest/ClassicDeferredTest/ClassicDeferredTest.unity
  74. 8
      ProjectSettings/EditorBuildSettings.asset
  75. 2
      ProjectSettings/ProjectVersion.txt
  76. 89
      ProjectSettings/TagManager.asset
  77. 2
      Assets/ScriptableRenderPipeline/fptl/LightDefinitions.cs.hlsl
  78. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
  79. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader
  80. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayShadowMap.shader
  81. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader
  82. 248
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute
  83. 48
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/scrbound.compute
  84. 1001
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild.compute
  85. 32
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  86. 22
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
  87. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader
  88. 34
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader
  89. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawGaussianProfile.shader
  90. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/GGXConvolve.shader
  91. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute
  92. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/BuildProbabilityTables.compute
  93. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/BlitCubemap.shader
  94. 113
      Assets/GraphicsTests/Editor/TestFrameworkCustomBuild.cs
  95. 51
      Assets/GraphicsTests/Editor/TestFramework.cs
  96. 8
      Assets/GraphicsTests/Scenes/LowEnd/SimpleCube.unity
  97. 7
      Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderReflection.unity
  98. 332
      Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderMaps.unity
  99. 5
      Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr.meta
  100. 1001
      Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr

31
Assets/ScriptableRenderPipeline/Core/AdditionalLightData.cs


public int[] data;
};
[HideInInspector, SerializeField] private int shadowCascadeCount = 4;
[HideInInspector, SerializeField] private float[] shadowCascadeRatios = new float[3]{ 0.05f, 0.2f, 0.3f };
[HideInInspector, SerializeField] private int shadowAlgorithm;
[HideInInspector, SerializeField] private int shadowVariant;
[HideInInspector, SerializeField] private int shadowPrecision;

public void GetShadowCascades( out int cascadeCount, out float[] cascadeRatios ) { cascadeCount = shadowCascadeCount; cascadeRatios = shadowCascadeRatios; }
public void GetShadowAlgorithm( out int algorithm, out int variant, out int precision ) { algorithm = shadowAlgorithm; variant = shadowVariant; precision = shadowPrecision; }
public void SetShadowAlgorithm( int algorithm, int variant, int precision, int format, int[] data )
{

UnityEditor.SerializedProperty m_ShadowData;
UnityEditor.SerializedProperty m_ShadowDatas;
#pragma warning restore 414
UnityEditor.SerializedProperty m_ShadowCascadeCount;
UnityEditor.SerializedProperty m_ShadowCascadeRatios;
public static void SetRegistry( ShadowRegistry registry ) { m_ShadowRegistry = registry; }

m_ShadowVariant = serializedObject.FindProperty( "shadowVariant" );
m_ShadowData = serializedObject.FindProperty( "shadowData" );
m_ShadowDatas = serializedObject.FindProperty( "shadowDatas" );
m_ShadowCascadeCount = serializedObject.FindProperty( "shadowCascadeCount" );
m_ShadowCascadeRatios = serializedObject.FindProperty( "shadowCascadeRatios" );
}
public override void OnInspectorGUI()
{

return;
UnityEditor.EditorGUI.BeginChangeCheck();
// cascade code
if( ald.gameObject.GetComponent<Light>().type == LightType.Directional )
{
UnityEditor.EditorGUI.BeginChangeCheck();
UnityEditor.EditorGUILayout.PropertyField( m_ShadowCascadeCount );
if( UnityEditor.EditorGUI.EndChangeCheck() )
{
const int kMaxCascades = (int) ShadowAtlas.k_MaxCascadesInShader; // depending on where you look this is either 32 or 4, so we're limiting it to 4 for now
int newcnt = m_ShadowCascadeCount.intValue <= 0 ? 1 : (m_ShadowCascadeCount.intValue > kMaxCascades ? kMaxCascades : m_ShadowCascadeCount.intValue);
m_ShadowCascadeCount.intValue = newcnt;
m_ShadowCascadeRatios.arraySize = newcnt-1;
}
UnityEditor.EditorGUI.indentLevel++;
for( int i = 0; i < m_ShadowCascadeRatios.arraySize; i++ )
{
UnityEditor.EditorGUILayout.Slider( m_ShadowCascadeRatios.GetArrayElementAtIndex( i ), 0.0f, 1.0f, new GUIContent( "Cascade " + i ) );
}
UnityEditor.EditorGUI.indentLevel--;
}
if( UnityEditor.EditorGUI.EndChangeCheck() )
{
UnityEditor.EditorUtility.SetDirty( ald );

}
}
#endif
}
}

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


m_CameraNames[GetCameraCount() - 1] = new GUIContent("Original Camera");
m_CameraIndices[GetCameraCount() - 1] = GetCameraCount() - 1;
DebugMenuManager.instance.AddDebugItem<int>("Camera", "Camera Switcher", () => m_CurrentCameraIndex, (value) => SetCameraIndex((int)value), false, new DebugItemHandlerIntEnum(m_CameraNames, m_CameraIndices));
DebugMenuManager.instance.AddDebugItem<int>("Camera", "Camera Switcher", () => m_CurrentCameraIndex, (value) => SetCameraIndex((int)value), false, new DebugItemDrawerIntEnum(m_CameraNames, m_CameraIndices));
}
int GetCameraCount()

24
Assets/ScriptableRenderPipeline/Core/Debugging/DebugActionManager.cs


public enum DebugAction
{
EnableDebugMenu,
PreviousDebugPanel,
NextDebugPanel,
PreviousDebugMenu,
NextDebugMenu,
MakePersistent,
Persistent,
MoveVertical,
MoveHorizontal,
DebugActionCount

enableDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.EnableDebugMenu, enableDebugMenu);
DebugActionDesc nextDebugPanel = new DebugActionDesc();
nextDebugPanel.buttonTriggerList.Add(new[] { kDebugNextBtn });
nextDebugPanel.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.NextDebugPanel, nextDebugPanel);
DebugActionDesc nextDebugMenu = new DebugActionDesc();
nextDebugMenu.buttonTriggerList.Add(new[] { kDebugNextBtn });
nextDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.NextDebugMenu, nextDebugMenu);
DebugActionDesc previousDebugPanel = new DebugActionDesc();
previousDebugPanel.buttonTriggerList.Add(new[] { kDebugPreviousBtn });
previousDebugPanel.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.PreviousDebugPanel, previousDebugPanel);
DebugActionDesc previousDebugMenu = new DebugActionDesc();
previousDebugMenu.buttonTriggerList.Add(new[] { kDebugPreviousBtn });
previousDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.PreviousDebugMenu, previousDebugMenu);
DebugActionDesc validate = new DebugActionDesc();
validate.buttonTriggerList.Add(new[] { kValidateBtn });

DebugActionDesc persistent = new DebugActionDesc();
persistent.buttonTriggerList.Add(new[] { kPersistentBtn });
persistent.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.MakePersistent, persistent);
AddAction(DebugAction.Persistent, 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 } );

156
Assets/ScriptableRenderPipeline/Core/Debugging/DebugMenuManager.cs


{
public class DebugMenuManager
{
private static DebugMenuManager s_Instance = null;
static private DebugMenuManager s_Instance = null;
static public DebugMenuManager instance
{

}
}
List<DebugPanel> m_DebugPanels = new List<DebugPanel>();
DebugPanel m_PersistentDebugPanel = null;
DebugMenuUI m_DebugMenuUI = null;
public int panelCount { get { return m_DebugPanels.Count; } }
public DebugMenuUI menuUI { get { return m_DebugMenuUI; } }
m_PersistentDebugPanel = new DebugPanel<DebugPanelUI>("Persistent");
LookUpDebugMenuClasses();
m_PersistentDebugMenu = new DebugMenu("Persistent");
}
LookUpDebugPanelClasses();
bool m_Enabled = false;
int m_ActiveMenuIndex = 0;
List<DebugMenu> m_DebugMenus = new List<DebugMenu>();
DebugMenu m_PersistentDebugMenu = null;
DebugMenuUI m_DebugMenuUI = null;
var updater = GameObject.Find("DebugMenuUpdater");
if (updater == null)
{
GameObject go = new GameObject("DebugMenuUpdater");
go.hideFlags = HideFlags.HideAndDontSave;
go.AddComponent<DebugMenuUpdater>();
}
}
public bool isEnabled { get { return m_Enabled; } }
public int activeMenuIndex { get { return m_ActiveMenuIndex; } set { m_ActiveMenuIndex = value; } }
public int menuCount { get { return m_DebugMenus.Count; } }
public DebugPanel GetDebugPanel(int index)
public DebugMenu GetDebugMenu(int index)
if (index < m_DebugPanels.Count)
return m_DebugPanels[index];
if (index < m_DebugMenus.Count)
return m_DebugMenus[index];
public DebugPanel GetPersistentDebugPanel()
public DebugMenu GetPersistentDebugMenu()
return m_PersistentDebugPanel;
return m_PersistentDebugMenu;
void LookUpDebugPanelClasses()
void LookUpDebugMenuClasses()
var types = Assembly.GetAssembly(typeof(DebugPanel)).GetTypes()
.Where(t => t.IsSubclassOf(typeof(DebugPanel)));
var types = Assembly.GetAssembly(typeof(DebugMenu)).GetTypes()
.Where(t => t.IsSubclassOf(typeof(DebugMenu)));
m_DebugPanels.Clear();
m_DebugMenus.Clear();
if(!type.IsGenericTypeDefinition)
AddDebugPanel((DebugPanel)Activator.CreateInstance(type));
m_DebugMenus.Add((DebugMenu)Activator.CreateInstance(type));
T GetDebugPanel<T>() where T:DebugPanel
public void PreviousDebugMenu()
{
m_DebugMenus[m_ActiveMenuIndex].SetSelected(false);
m_ActiveMenuIndex = m_ActiveMenuIndex - 1;
if (m_ActiveMenuIndex == -1)
m_ActiveMenuIndex = m_DebugMenus.Count - 1;
m_DebugMenus[m_ActiveMenuIndex].SetSelected(true);
}
public void NextDebugMenu()
{
m_DebugMenus[m_ActiveMenuIndex].SetSelected(false);
m_ActiveMenuIndex = (m_ActiveMenuIndex + 1) % m_DebugMenus.Count;
m_DebugMenus[m_ActiveMenuIndex].SetSelected(true);
}
public void ToggleMenu()
foreach(DebugPanel menu in m_DebugPanels)
m_Enabled = !m_Enabled;
m_DebugMenuUI.BuildGUI();
m_DebugMenuUI.Toggle();
m_DebugMenus[m_ActiveMenuIndex].SetSelected(m_Enabled);
}
public void OnValidate()
{
m_DebugMenus[m_ActiveMenuIndex].OnValidate();
}
public void OnMakePersistent()
{
DebugMenuItem selectedItem = m_DebugMenus[m_ActiveMenuIndex].GetSelectedDebugMenuItem();
if(selectedItem != null && selectedItem.readOnly)
{
if(m_PersistentDebugMenu.HasItem(selectedItem))
{
m_PersistentDebugMenu.RemoveDebugItem(selectedItem);
}
else
{
m_PersistentDebugMenu.AddDebugItem(selectedItem);
}
}
if(m_PersistentDebugMenu.itemCount == 0)
{
m_PersistentDebugMenu.SetSelected(false);
m_DebugMenuUI.EnablePersistentView(false); // Temp, should just need the above. Wait for background UI to be moved to menu itself
}
else
{
m_PersistentDebugMenu.SetSelected(true);
m_DebugMenuUI.EnablePersistentView(true);
}
}
public void OnMoveHorizontal(float value)
{
m_DebugMenus[m_ActiveMenuIndex].OnMoveHorizontal(value);
}
public void OnMoveVertical(float value)
{
m_DebugMenus[m_ActiveMenuIndex].OnMoveVertical(value);
}
T GetDebugMenu<T>() where T:DebugMenu
{
foreach(DebugMenu menu in m_DebugMenus)
{
if (menu is T)
return menu as T;

}
public DebugPanel GetDebugPanel(string name)
DebugMenu GetDebugMenu(string name)
foreach(DebugPanel menu in m_DebugPanels)
foreach(DebugMenu menu in m_DebugMenus)
{
if (menu.name == name)
return menu;

public void Update()
{
m_DebugMenuUI.Update();
}
if (m_ActiveMenuIndex != -1)
m_DebugMenus[m_ActiveMenuIndex].Update();
private void AddDebugPanel(DebugPanel panel)
{
m_DebugPanels.Add(panel);
m_DebugMenuUI.AddDebugPanel(panel);
m_PersistentDebugMenu.Update();
public void AddDebugItem<DebugPanelType, DebugItemType>(string name, Func<object> getter, Action<object> setter = null, bool dynamicDisplay = false, DebugItemHandler handler = null) where DebugPanelType : DebugPanel
public void AddDebugItem<DebugMenuType, ItemType>(string name, Func<object> getter, Action<object> setter = null, bool dynamicDisplay = false, DebugItemDrawer drawer = null) where DebugMenuType : DebugMenu
DebugPanelType debugMenu = GetDebugPanel<DebugPanelType>();
DebugMenuType debugMenu = GetDebugMenu<DebugMenuType>();
debugMenu.AddDebugItem<DebugItemType>(name, getter, setter, dynamicDisplay, handler);
debugMenu.AddDebugMenuItem<ItemType>(name, getter, setter, dynamicDisplay, drawer);
public void AddDebugItem<DebugItemType>(string debugPanelName, string name, Func<object> getter, Action<object> setter = null, bool dynamicDisplay = false, DebugItemHandler handler = null)
public void AddDebugItem<ItemType>(string debugMenuName, string name, Func<object> getter, Action<object> setter = null, bool dynamicDisplay = false, DebugItemDrawer drawer = null)
DebugPanel debugPanel = GetDebugPanel(debugPanelName);
DebugMenu debugMenu = GetDebugMenu(debugMenuName);
if(debugPanel == null)
if(debugMenu == null)
debugPanel = new DebugPanel<DebugPanelUI>(debugPanelName);
AddDebugPanel(debugPanel);
debugMenu = new DebugMenu(debugMenuName);
m_DebugMenus.Add(debugMenu);
if (debugPanel != null)
if (debugMenu != null)
debugPanel.AddDebugItem<DebugItemType>(name, getter, setter, dynamicDisplay, handler);
debugMenu.AddDebugMenuItem<ItemType>(name, getter, setter, dynamicDisplay, drawer);
}
}
}

163
Assets/ScriptableRenderPipeline/Core/Debugging/DebugMenuUI.cs


public static Color kBackgroundColor = new Color(0.5f, 0.5f, 0.5f, 0.4f);
public static float kDebugItemNameWidth = 150.0f;
bool m_Enabled = false;
int m_ActivePanelIndex = 0;
GameObject m_MainPanelLayout = null;
GameObject m_PersistentPanelLayout = null;
List<DebugPanelUI> m_DebugPanelUIs = new List<DebugPanelUI>();
DebugPanelUI m_PersistentDebugPanelUI = null;
GameObject[] m_MenuRoots = null;
GameObject m_PersistentPanelRoot = null;
GameObject m_PersistentMenuRoot = null;
bool m_Enabled = false;
public int panelCount { get { return m_DebugPanelUIs.Count; } }
public bool isEnabled { get { return m_Enabled; } }
public int activePanelIndex { get { return m_ActivePanelIndex; } set { m_ActivePanelIndex = value; } }
static bool s_UIChanged = false;
static public bool changed { get { return s_UIChanged; } set { s_UIChanged = value; } }
public void EnablePersistentView(bool value)
{
m_PersistentPanelRoot.SetActive(value);
}
public void PreviousDebugPanel()
{
m_DebugPanelUIs[m_ActivePanelIndex].SetSelected(false);
m_ActivePanelIndex = m_ActivePanelIndex - 1;
if (m_ActivePanelIndex == -1)
m_ActivePanelIndex = m_DebugPanelUIs.Count - 1;
m_DebugPanelUIs[m_ActivePanelIndex].SetSelected(true);
// HACK: for some reason, the layout of the selected menu may fail if the previous menu in the list is disabled
// Disabling and re-enabling everything seems to fix the issue...
m_MainMenuRoot.SetActive(false);
m_MainMenuRoot.SetActive(true);
}
public void NextDebugPanel()
{
m_DebugPanelUIs[m_ActivePanelIndex].SetSelected(false);
m_ActivePanelIndex = (m_ActivePanelIndex + 1) % m_DebugPanelUIs.Count;
m_DebugPanelUIs[m_ActivePanelIndex].SetSelected(true);
// HACK: for some reason, the layout of the selected menu may fail if the previous menu in the list is disabled
// Disabling and re-enabling everything seems to fix the issue...
m_MainMenuRoot.SetActive(false);
m_MainMenuRoot.SetActive(true);
}
public void ToggleMenu()
public void Toggle()
if(m_Enabled)
{
BuildGUI();
m_MainMenuRoot.SetActive(true);
m_DebugPanelUIs[m_ActivePanelIndex].SetSelected(m_Enabled);
}
else
{
m_MainMenuRoot.SetActive(false);
}
m_MainMenuRoot.SetActive(m_Enabled);
public void OnValidate()
{
m_DebugPanelUIs[m_ActivePanelIndex].OnValidate();
}
public void OnMoveHorizontal(float value)
public void EnablePersistentView(bool value)
m_DebugPanelUIs[m_ActivePanelIndex].OnMoveHorizontal(value);
m_PersistentMenuRoot.SetActive(value);
public void OnMoveVertical(float value)
void CleanUpGUI()
m_DebugPanelUIs[m_ActivePanelIndex].OnMoveVertical(value);
}
public void Update()
{
if(m_PersistentDebugPanelUI != null)
m_PersistentDebugPanelUI.Update();
if (!m_Enabled)
return;
if (m_ActivePanelIndex != -1)
m_DebugPanelUIs[m_ActivePanelIndex].Update();
}
public void OnMakePersistent()
{
DebugPanel persistentPanel = DebugMenuManager.instance.GetPersistentDebugPanel();
DebugItem selectedItem = m_DebugPanelUIs[m_ActivePanelIndex].GetSelectedDebugItem();
if (selectedItem != null && selectedItem.readOnly)
{
if (persistentPanel.HasDebugItem(selectedItem))
{
persistentPanel.RemoveDebugItem(selectedItem);
}
else
{
persistentPanel.AddDebugItem(selectedItem);
}
}
if (m_PersistentDebugPanelUI.itemCount == 0)
{
m_PersistentDebugPanelUI.SetSelected(false);
EnablePersistentView(false); // Temp, should just need the above. Wait for background UI to be moved to menu itself
}
else
{
m_PersistentDebugPanelUI.SetSelected(true);
EnablePersistentView(true);
}
Object.Destroy(m_Root);
}
public void BuildGUI()

image.rectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
image.color = kBackgroundColor;
m_MainPanelLayout = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_MainMenuRoot);
RectTransform menuVLRectTransform = m_MainPanelLayout.GetComponent<RectTransform>();
GameObject goVL = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_MainMenuRoot);
RectTransform menuVLRectTransform = goVL.GetComponent<RectTransform>();
menuVLRectTransform.pivot = new Vector2(0.0f, 0.0f);
menuVLRectTransform.localPosition = Vector3.zero;
menuVLRectTransform.localScale = Vector3.one;

menuVLRectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
// TODO: Move background an layout to the menu itself.
m_PersistentPanelRoot = new GameObject("Background_Persistent");
m_PersistentPanelRoot.AddComponent<CanvasRenderer>();
image = m_PersistentPanelRoot.AddComponent<UI.Image>();
m_PersistentPanelRoot.transform.SetParent(m_Root.transform, false);
m_PersistentMenuRoot = new GameObject("Background_Persistent");
m_PersistentMenuRoot.AddComponent<CanvasRenderer>();
image = m_PersistentMenuRoot.AddComponent<UI.Image>();
m_PersistentMenuRoot.transform.SetParent(m_Root.transform, false);
image.rectTransform.pivot = new Vector2(0.0f, 0.0f);
image.rectTransform.localPosition = Vector3.zero;
image.rectTransform.localScale = Vector3.one;

image.rectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
image.color = kBackgroundColor;
m_PersistentPanelLayout = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_PersistentPanelRoot);
menuVLRectTransform = m_PersistentPanelLayout.GetComponent<RectTransform>();
GameObject goVL2 = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_PersistentMenuRoot);
menuVLRectTransform = goVL2.GetComponent<RectTransform>();
menuVLRectTransform.pivot = new Vector2(0.0f, 0.0f);
menuVLRectTransform.localPosition = Vector3.zero;
menuVLRectTransform.localScale = Vector3.one;

menuVLRectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
m_PersistentPanelRoot.SetActive(false);
DebugMenuUI.CreateTextElement("DebugMenuTitle", "Debug Menu", 14, TextAnchor.MiddleCenter, m_MainPanelLayout);
m_PersistentMenuRoot.SetActive(false);
m_DebugMenuManager.GetPersistentDebugPanel().panelUI.BuildGUI(m_PersistentPanelLayout);
m_PersistentDebugPanelUI = m_DebugMenuManager.GetPersistentDebugPanel().panelUI;
DebugMenuUI.CreateTextElement("DebugMenuTitle", "Debug Menu", 14, TextAnchor.MiddleCenter, goVL);
for (int i = 0; i < m_DebugMenuManager.panelCount; ++i)
int menuCount = m_DebugMenuManager.menuCount;
m_MenuRoots = new GameObject[menuCount];
for (int i = 0; i < menuCount; ++i)
m_DebugMenuManager.GetDebugPanel(i).panelUI.BuildGUI(m_MainPanelLayout);
m_DebugPanelUIs[i].SetSelected(false);
m_MenuRoots[i] = m_DebugMenuManager.GetDebugMenu(i).BuildGUI(goVL);
}
public void AddDebugPanel(DebugPanel panel)
{
m_DebugPanelUIs.Add(panel.panelUI);
}
#if UNITY_EDITOR
public void OnEditorGUI()
{
s_UIChanged = false;
m_DebugPanelUIs[m_ActivePanelIndex].OnEditorGUI();
if(s_UIChanged)
{
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
m_DebugMenuManager.GetPersistentDebugMenu().BuildGUI(goVL2);
#endif
public static GameObject CreateVerticalLayoutGroup(string name, bool controlWidth, bool controlHeight, bool forceExpandWidth, bool forceExpandHeight, GameObject parent = null )
{

22
Assets/ScriptableRenderPipeline/Core/Debugging/DebugMenuUpdater.cs


if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.EnableDebugMenu) != 0.0f)
{
DebugMenuManager.instance.menuUI.ToggleMenu();
DebugMenuManager.instance.ToggleMenu();
if (DebugMenuManager.instance.menuUI.isEnabled)
if (DebugMenuManager.instance.isEnabled)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.PreviousDebugPanel) != 0.0f)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.PreviousDebugMenu) != 0.0f)
DebugMenuManager.instance.menuUI.PreviousDebugPanel();
DebugMenuManager.instance.PreviousDebugMenu();
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.NextDebugPanel) != 0.0f)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.NextDebugMenu) != 0.0f)
DebugMenuManager.instance.menuUI.NextDebugPanel();
DebugMenuManager.instance.NextDebugMenu();
DebugMenuManager.instance.menuUI.OnValidate();
DebugMenuManager.instance.OnValidate();
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.MakePersistent) != 0.0f)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.Persistent) != 0.0f)
DebugMenuManager.instance.menuUI.OnMakePersistent();
DebugMenuManager.instance.OnMakePersistent();
DebugMenuManager.instance.menuUI.OnMoveHorizontal(moveHorizontal);
DebugMenuManager.instance.OnMoveHorizontal(moveHorizontal);
DebugMenuManager.instance.menuUI.OnMoveVertical(moveVertical);
DebugMenuManager.instance.OnMoveVertical(moveVertical);
}
}
}

56
Assets/ScriptableRenderPipeline/Core/Debugging/Editor/DebugMenuEditor.cs


// This is the class that handles rendering the debug menu in the editor (as opposed to the runtime version in the player)
public class DebugMenuEditor : EditorWindow
{
[SerializeField]
private DebugMenuState m_DebugMenuState;
[MenuItem("HDRenderPipeline/Debug Menu")]
static void DisplayDebugMenu()

DebugMenuManager m_DebugMenu = null;
void OnEnable()
{
m_DebugMenu = DebugMenuManager.instance;
DebugItem.OnItemDirty += DebugItem_OnDirty;
if(m_DebugMenuState == null)
{
m_DebugMenuState = ScriptableObject.CreateInstance<DebugMenuState>();
m_DebugMenuState.hideFlags = HideFlags.DontSave;
}
}
void OnDisable()
DebugMenuEditor()
DebugItem.OnItemDirty -= DebugItem_OnDirty;
void OnDestroy()
{
Object.DestroyImmediate(m_DebugMenuState);
}
void DebugItem_OnDirty(DebugItem item)
void OnEnable()
DebugItemState debugItemState = m_DebugMenuState.FindDebugItemState(item);
UnityEditor.Undo.RecordObject(debugItemState, "DebugMenu State Update");
debugItemState.SetValue(item.GetValue());
EditorUtility.SetDirty(m_DebugMenuState);
m_DebugMenu = DebugMenuManager.instance;
}
void OnGUI()

// Contrary to the menu in the player, here we always render the menu wether it's enabled or not. This is a separate window so user can manage it however they want.
EditorGUI.BeginChangeCheck();
DebugMenuUI debugMenuUI = m_DebugMenu.menuUI;
int debugMenuCount = m_DebugMenu.panelCount;
int activePanelIndex = debugMenuUI.activePanelIndex;
int debugMenuCount = m_DebugMenu.menuCount;
int activeMenuIndex = m_DebugMenu.activeMenuIndex;
using (new EditorGUILayout.HorizontalScope())
{
for(int i = 0 ; i < debugMenuCount ; ++i)

style = EditorStyles.miniButtonLeft;
if (i == debugMenuCount - 1)
style = EditorStyles.miniButtonRight;
string name = m_DebugMenu.GetDebugPanel(i).name;
if (GUILayout.Toggle(i == activePanelIndex, new GUIContent(name), style))
activePanelIndex = i;
if (GUILayout.Toggle(i == activeMenuIndex, new GUIContent(m_DebugMenu.GetDebugMenu(i).name), style))
activeMenuIndex = i;
debugMenuUI.activePanelIndex = activePanelIndex;
m_DebugMenu.activeMenuIndex = activeMenuIndex;
using(new EditorGUILayout.VerticalScope())
{
DebugMenu activeMenu = m_DebugMenu.GetDebugMenu(m_DebugMenu.activeMenuIndex);
bool needRepaint = false;
for (int i = 0; i < activeMenu.itemCount; ++i)
{
needRepaint = needRepaint || activeMenu.GetDebugMenuItem(i).drawer.OnEditorGUI();
}
debugMenuUI.OnEditorGUI();
if (needRepaint)
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
}
}

18
Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs


GPUShadowAlgorithm sanitizedAlgo = ShadowUtils.ClearPrecision( sr.shadowAlgorithm );
int cascadeCnt = 0;
float[] cascadeRatios = null;
if( sr.shadowType == GPUShadowType.Directional )
{
AdditionalLightData ald = lights[sr.index].light.GetComponent<AdditionalLightData>();
if( !ald )
return false;
ald.GetShadowCascades( out cascadeCnt, out cascadeRatios );
}
if( multiFace )
{
// For lights with multiple faces, the first shadow data contains

vp = ShadowUtils.ExtractSpotLightMatrix( lights[sr.index], out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData );
else if( sr.shadowType == GPUShadowType.Directional )
{
vp = ShadowUtils.ExtractDirectionalLightMatrix( lights[sr.index], key.faceIdx, cascadeCnt, cascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int) sr.index );
vp = ShadowUtils.ExtractDirectionalLightMatrix( lights[sr.index], key.faceIdx, m_CascadeCount, m_CascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int) sr.index );
m_TmpSplits[key.faceIdx] = ce.current.splitData.cullingSphere;
if( ce.current.splitData.cullingSphere.w != float.NegativeInfinity )
m_TmpSplits[key.faceIdx].w *= ce.current.splitData.cullingSphere.w;

{
bpp_16 = 1 << 0,
channels_2 = 1 << 1,
reversed_z = 1 << 2
}
protected readonly Flags m_Flags;

readonly ValRange m_DefEVSM_PosExponent_16 = new ValRange( "Positive Exponent" , 1.0f, 1.0f , 5.54f , 1.0f );
readonly ValRange m_DefEVSM_NegExponent_16 = new ValRange( "Negative Exponent" , 1.0f, 1.0f , 5.54f , 1.0f );
readonly ValRange m_DefMSM_LightLeakBias = new ValRange( "Light leak bias" , 0.0f, 0.5f , 0.99f , 1.0f );
readonly ValRange m_DefMSM_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.0f , 1.0f , 0.0001f);
readonly ValRange m_DefMSM_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.3f , 1.0f , 0.0001f);
readonly ValRange m_DefMSM_DepthBias = new ValRange( "Depth Bias" , 0.0f, 0.1f , 1.0f , 0.1f );
public static RenderTextureFormat GetFormat( bool use_16_BitsPerChannel, bool use_2_Channels, bool use_MSM )

{
m_Flags |= (base.m_ShadowmapFormat == RenderTextureFormat.ARGBHalf || base.m_ShadowmapFormat == RenderTextureFormat.RGHalf || base.m_ShadowmapFormat == RenderTextureFormat.ARGB64) ? Flags.bpp_16 : 0;
m_Flags |= (base.m_ShadowmapFormat == RenderTextureFormat.RGFloat || base.m_ShadowmapFormat == RenderTextureFormat.RGHalf) ? Flags.channels_2 : 0;
m_Flags |= SystemInfo.usesReversedZBuffer ? Flags.reversed_z : 0;
m_Shadowmap.enableRandomWrite = true;
m_SampleCount = 1; // TODO: Unity can't bind msaa rts as textures, yet, so this has to remain 1 for now

2
Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs. Please don't edit by hand.
//
#ifndef SHADOWBASE_CS_HLSL

7
Assets/ScriptableRenderPipeline/Core/Shadow/ShadowUtilities.cs


return proj * view;
}
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, float[] splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, Vector3 splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
{
Debug.Assert( width == height, "Currently the cascaded shadow mapping code requires square cascades." );
splitData = new ShadowSplitData();

// TODO: At some point this logic should be moved to C#, then the parameters cullResults and lightIndex can be removed as well
// For directional lights shadow data is extracted from the cullResults, so that needs to be somehow provided here.
// Check ScriptableShadowsUtility.cpp ComputeDirectionalShadowMatricesAndCullingPrimitives(...) for details.
Vector3 ratios = new Vector3();
for( int i = 0, cnt = splitRatio.Length < 3 ? splitRatio.Length : 3; i < cnt; i++ )
ratios[i] = splitRatio[i];
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, ratios, (int) width, nearPlaneOffset, out view, out proj, out splitData );
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, splitRatio, (int) width, nearPlaneOffset, out view, out proj, out splitData );
// and the compound
return proj * view;
}

26
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


VisualizeCascade
}
[Serializable]
public bool displayMaterialDebug = false;
public bool displayRenderingDebug = false;
public bool displayLightingDebug = false;
public MaterialDebugSettings materialDebugSettings = new MaterialDebugSettings();
public LightingDebugSettings lightingDebugSettings = new LightingDebugSettings();

DebugMenuManager.instance.AddDebugItem<float>("Display Stats", "Frame Rate", () => 1.0f / Time.deltaTime, null, true);
DebugMenuManager.instance.AddDebugItem<float>("Display Stats", "Frame Time", () => Time.deltaTime * 1000.0f, null, true);
DebugMenuManager.instance.AddDebugItem<int>("Material", "Material",() => materialDebugSettings.debugViewMaterial, (value) => SetDebugViewMaterial((int)value), false, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewMaterialStrings, DebugDisplaySettings.debugViewMaterialValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "Engine",() => materialDebugSettings.debugViewEngine, (value) => SetDebugViewEngine((int)value), false, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewEngineStrings, DebugDisplaySettings.debugViewEngineValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "Material",() => materialDebugSettings.debugViewMaterial, (value) => SetDebugViewMaterial((int)value), false, new DebugItemDrawerIntEnum(DebugDisplaySettings.debugViewMaterialStrings, DebugDisplaySettings.debugViewMaterialValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "Engine",() => materialDebugSettings.debugViewEngine, (value) => SetDebugViewEngine((int)value), false, new DebugItemDrawerIntEnum(DebugDisplaySettings.debugViewEngineStrings, DebugDisplaySettings.debugViewEngineValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "GBuffer",() => materialDebugSettings.debugViewGBuffer, (value) => SetDebugViewGBuffer((int)value), false, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "GBuffer",() => materialDebugSettings.debugViewGBuffer, (value) => SetDebugViewGBuffer((int)value), false, new DebugItemDrawerIntEnum(DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, bool>("Enable Shadows", () => lightingDebugSettings.enableShadows, (value) => lightingDebugSettings.enableShadows = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, ShadowMapDebugMode>("Shadow Debug Mode", () => lightingDebugSettings.shadowDebugMode, (value) => lightingDebugSettings.shadowDebugMode = (ShadowMapDebugMode)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, uint>("Shadow Map Index", () => lightingDebugSettings.shadowMapIndex, (value) => lightingDebugSettings.shadowMapIndex = (uint)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, DebugLightingMode>("Lighting Debug Mode", () => lightingDebugSettings.debugLightingMode, (value) => SetDebugLightingMode((DebugLightingMode)value));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, bool>("Override Smoothness", () => lightingDebugSettings.overrideSmoothness, (value) => lightingDebugSettings.overrideSmoothness = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>("Override Smoothness Value", () => lightingDebugSettings.overrideSmoothnessValue, (value) => lightingDebugSettings.overrideSmoothnessValue = (float)value, false, new DebugItemHandlerFloatMinMax(0.0f, 1.0f));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, Color>("Debug Lighting Albedo", () => lightingDebugSettings.debugLightingAlbedo, (value) => lightingDebugSettings.debugLightingAlbedo = (Color)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, bool>("Enable Shadows", () => lightingDebugSettings.enableShadows, (value) => lightingDebugSettings.enableShadows = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, ShadowMapDebugMode>("Shadow Debug Mode", () => lightingDebugSettings.shadowDebugMode, (value) => lightingDebugSettings.shadowDebugMode = (ShadowMapDebugMode)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, uint>("Shadow Map Index", () => lightingDebugSettings.shadowMapIndex, (value) => lightingDebugSettings.shadowMapIndex = (uint)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, DebugLightingMode>("Lighting Debug Mode", () => lightingDebugSettings.debugLightingMode, (value) => SetDebugLightingMode((DebugLightingMode)value));
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, bool>("Override Smoothness", () => lightingDebugSettings.overrideSmoothness, (value) => lightingDebugSettings.overrideSmoothness = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, float>("Override Smoothness Value", () => lightingDebugSettings.overrideSmoothnessValue, (value) => lightingDebugSettings.overrideSmoothnessValue = (float)value, false, new DebugItemDrawFloatMinMax(0.0f, 1.0f));
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, Color>("Debug Lighting Albedo", () => lightingDebugSettings.debugLightingAlbedo, (value) => lightingDebugSettings.debugLightingAlbedo = (Color)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>("Sky Reflection Mipmap", () => lightingDebugSettings.skyReflectionMipmap, (value) => lightingDebugSettings.skyReflectionMipmap = (float)value, false, new DebugItemHandlerFloatMinMax(0.0f, 1.0f));
DebugMenuManager.instance.AddDebugItem<LightingDebugMenu, float>("Sky Reflection Mipmap", () => lightingDebugSettings.skyReflectionMipmap, (value) => lightingDebugSettings.skyReflectionMipmap = (float)value, false, new DebugItemDrawFloatMinMax(0.0f, 1.0f));
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Display Opaque",() => renderingDebugSettings.displayOpaqueObjects, (value) => renderingDebugSettings.displayOpaqueObjects = (bool)value);
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Display Transparency",() => renderingDebugSettings.displayTransparentObjects, (value) => renderingDebugSettings.displayTransparentObjects = (bool)value);

337
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(HDRenderPipelineAsset))]
[CustomEditor(typeof(HDRenderPipeline))]
public class HDRenderPipelineInspector : Editor
{
private class Styles

public readonly GUIContent shadowsAtlasHeight = new GUIContent("Atlas height");
// Subsurface Scattering Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SssConstants.SSS_N_PROFILES - 1] { new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"),
new GUIContent("Profile #6"), new GUIContent("Profile #7")/*, new GUIContent("Profile #8"), new GUIContent("Profile #9"), new GUIContent("Profile #10"),
new GUIContent("Profile #11"), new GUIContent("Profile #12"), new GUIContent("Profile #13"), new GUIContent("Profile #14"), new GUIContent("Profile #15")*/ };
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
public readonly GUIContent[] sssProfiles = new GUIContent[SSSConstants.SSS_PROFILES_MAX] { new GUIContent("Profile #0"), new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"), new GUIContent("Profile #6"), new GUIContent("Profile #7") };
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
public readonly GUIContent enableTileAndCluster = new GUIContent("Enable tile/clustered", "Toggle");
public readonly GUIContent enableSplitLightEvaluation = new GUIContent("Split light and reflection evaluation", "Toggle");
public readonly string[] tileLightLoopDebugTileFlagStrings = new string[] { "Punctual Light", "Area Light", "Env Light"};
public readonly GUIContent splitLightEvaluation = new GUIContent("Split light and reflection evaluation", "Toggle");
public readonly GUIContent bigTilePrepass = new GUIContent("Enable big tile prepass", "Toggle");
public readonly GUIContent clustered = new GUIContent("Enable clustered", "Toggle");
public readonly GUIContent enableTileAndCluster = new GUIContent("Enable Tile/clustered", "Toggle");
public readonly GUIContent enableComputeFeatureVariants = new GUIContent("Enable Compute Features Variants", "Toggle");
public readonly GUIContent enableClustered = new GUIContent("Enable clustered", "Toggle");
public readonly GUIContent enableFptlForOpaqueWhenClustered = new GUIContent("Enable Fptl For Opaque When Clustered", "Toggle");
public readonly GUIContent enableBigTilePrepass = new GUIContent("Enable big tile prepass", "Toggle");
public readonly GUIContent tileDebugByCategory = new GUIContent("Enable Debug By Category", "Toggle");
// Debug Display Settings
public readonly GUIContent debugging = new GUIContent("Debugging");
public readonly GUIContent debugOverlayRatio = new GUIContent("Overlay Ratio");
// Material debug
public readonly GUIContent materialDebugLabel = new GUIContent("Material Debug");
public readonly GUIContent debugViewMaterial = new GUIContent("DebugView Material", "Display various properties of Materials.");
public readonly GUIContent debugViewEngine = new GUIContent("DebugView Engine", "Display various properties of Materials.");
public readonly GUIContent debugViewMaterialVarying = new GUIContent("DebugView Attributes", "Display varying input of Materials.");
public readonly GUIContent debugViewMaterialGBuffer = new GUIContent("DebugView GBuffer", "Display GBuffer properties.");
// Rendering Debug
public readonly GUIContent renderingDebugSettings = new GUIContent("Rendering Debug");
public readonly GUIContent displayOpaqueObjects = new GUIContent("Display Opaque Objects", "Toggle opaque objects rendering on and off.");
public readonly GUIContent displayTransparentObjects = new GUIContent("Display Transparent Objects", "Toggle transparent objects rendering on and off.");
public readonly GUIContent enableDistortion = new GUIContent("Enable Distortion");
public readonly GUIContent enableSSS = new GUIContent("Enable Subsurface Scattering");
// Lighting Debug
public readonly GUIContent lightingDebugSettings = new GUIContent("Lighting Debug");
public readonly GUIContent shadowDebugEnable = new GUIContent("Enable Shadows");
public readonly GUIContent lightingVisualizationMode = new GUIContent("Lighting Debug Mode");
public readonly GUIContent[] debugViewLightingStrings = { new GUIContent("None"), new GUIContent("Diffuse Lighting"), new GUIContent("Specular Lighting"), new GUIContent("Visualize Cascades") };
public readonly int[] debugViewLightingValues = { (int)DebugLightingMode.None, (int)DebugLightingMode.DiffuseLighting, (int)DebugLightingMode.SpecularLighting, (int)DebugLightingMode.VisualizeCascade };
public readonly GUIContent shadowDebugVisualizationMode = new GUIContent("Shadow Maps Debug Mode");
public readonly GUIContent shadowDebugVisualizeShadowIndex = new GUIContent("Visualize Shadow Index");
public readonly GUIContent lightingDebugOverrideSmoothness = new GUIContent("Override Smoothness");
public readonly GUIContent lightingDebugOverrideSmoothnessValue = new GUIContent("Smoothness Value");
public readonly GUIContent lightingDebugAlbedo = new GUIContent("Lighting Debug Albedo");
public readonly GUIContent lightingDisplaySkyReflection = new GUIContent("Display Sky Reflection");
public readonly GUIContent lightingDisplaySkyReflectionMipmap = new GUIContent("Reflection Mipmap");
}
private static Styles s_Styles = null;

private SerializedProperty m_DefaultDiffuseMaterial;
private SerializedProperty m_DefaultShader;
// TilePass settings
SerializedProperty m_enableTileAndCluster;
SerializedProperty m_enableSplitLightEvaluation;
SerializedProperty m_enableComputeLightEvaluation;
SerializedProperty m_enableComputeFeatureVariants;
SerializedProperty m_enableClustered;
SerializedProperty m_enableFptlForOpaqueWhenClustered;
SerializedProperty m_enableBigTilePrepass;
SerializedProperty m_tileDebugByCategory;
// Display Debug
SerializedProperty m_ShowMaterialDebug = null;
SerializedProperty m_ShowLightingDebug = null;
SerializedProperty m_ShowRenderingDebug = null;
SerializedProperty m_DebugOverlayRatio = null;
// Rendering Debug
SerializedProperty m_DisplayOpaqueObjects = null;
SerializedProperty m_DisplayTransparentObjects = null;
SerializedProperty m_EnableDistortion = null;
SerializedProperty m_EnableSSS = null;
// Lighting debug
SerializedProperty m_DebugShadowEnabled = null;
SerializedProperty m_ShadowDebugMode = null;
SerializedProperty m_ShadowDebugShadowMapIndex = null;
SerializedProperty m_LightingDebugOverrideSmoothness = null;
SerializedProperty m_LightingDebugOverrideSmoothnessValue = null;
SerializedProperty m_LightingDebugAlbedo = null;
SerializedProperty m_LightingDebugDisplaySkyReflection = null;
SerializedProperty m_LightingDebugDisplaySkyReflectionMipmap = null;
// Rendering Settings
SerializedProperty m_RenderingUseForwardOnly = null;

m_DefaultDiffuseMaterial = serializedObject.FindProperty("m_DefaultDiffuseMaterial");
m_DefaultShader = serializedObject.FindProperty("m_DefaultShader");
// Following way of getting property allow to handle change of properties name with serializations
// DebugDisplay debug
m_DebugOverlayRatio = FindProperty(x => x.debugDisplaySettings.debugOverlayRatio);
m_ShowLightingDebug = FindProperty(x => x.debugDisplaySettings.displayLightingDebug);
m_ShowRenderingDebug = FindProperty(x => x.debugDisplaySettings.displayRenderingDebug);
m_ShowMaterialDebug = FindProperty(x => x.debugDisplaySettings.displayMaterialDebug);
// Tile settings
m_enableTileAndCluster = FindProperty(x => x.tileSettings.enableTileAndCluster);
m_enableSplitLightEvaluation = FindProperty(x => x.tileSettings.enableSplitLightEvaluation);
m_enableComputeLightEvaluation = FindProperty(x => x.tileSettings.enableComputeLightEvaluation);
m_enableComputeFeatureVariants = FindProperty(x => x.tileSettings.enableComputeFeatureVariants);
m_enableClustered = FindProperty(x => x.tileSettings.enableClustered);
m_enableFptlForOpaqueWhenClustered = FindProperty(x => x.tileSettings.enableFptlForOpaqueWhenClustered);
m_enableBigTilePrepass = FindProperty(x => x.tileSettings.enableBigTilePrepass);
m_tileDebugByCategory = FindProperty(x => x.tileSettings.tileDebugByCategory);
// Rendering debug
m_DisplayOpaqueObjects = FindProperty(x => x.debugDisplaySettings.renderingDebugSettings.displayOpaqueObjects);
m_DisplayTransparentObjects = FindProperty(x => x.debugDisplaySettings.renderingDebugSettings.displayTransparentObjects);
m_EnableDistortion = FindProperty(x => x.debugDisplaySettings.renderingDebugSettings.enableDistortion);
m_EnableSSS = FindProperty(x => x.debugDisplaySettings.renderingDebugSettings.enableSSS);
// Shadow settings
//TODO!
// Lighting debug
m_DebugShadowEnabled = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.enableShadows);
m_ShadowDebugMode = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.shadowDebugMode);
m_ShadowDebugShadowMapIndex = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.shadowMapIndex);
m_LightingDebugOverrideSmoothness = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.overrideSmoothness);
m_LightingDebugOverrideSmoothnessValue = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.overrideSmoothnessValue);
m_LightingDebugAlbedo = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.debugLightingAlbedo);
m_LightingDebugDisplaySkyReflection = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.displaySkyReflection);
m_LightingDebugDisplaySkyReflectionMipmap = FindProperty(x => x.debugDisplaySettings.lightingDebugSettings.skyReflectionMipmap);
// Rendering settings
m_RenderingUseForwardOnly = FindProperty(x => x.renderingSettings.useForwardRenderingOnly);

m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
SerializedProperty FindProperty<TValue>(Expression<Func<HDRenderPipelineAsset, TValue>> expr)
SerializedProperty FindProperty<TValue>(Expression<Func<HDRenderPipeline, TValue>> expr)
{
var path = Utilities.GetFieldPath(expr);
return serializedObject.FindProperty(path);

method.Invoke(asset, new object[0]);
}
private void TileSettingsUI(HDRenderPipelineAsset renderContext)
private void DebuggingUI(HDRenderPipeline renderContext, HDRenderPipelineInstance renderpipelineInstance)
EditorGUILayout.LabelField(styles.debugging);
// Debug Display settings
EditorGUI.indentLevel++;
m_DebugOverlayRatio.floatValue = EditorGUILayout.Slider(styles.debugOverlayRatio, m_DebugOverlayRatio.floatValue, 0.1f, 1.0f);
EditorGUILayout.LabelField(styles.tileLightLoopSettings);
RenderingDebugSettingsUI(renderContext);
MaterialDebugSettingsUI(renderContext);
LightingDebugSettingsUI(renderContext, renderpipelineInstance);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
private void MaterialDebugSettingsUI(HDRenderPipeline renderContext)
{
HDRenderPipeline hdPipe = target as HDRenderPipeline;
m_ShowMaterialDebug.boolValue = EditorGUILayout.Foldout(m_ShowMaterialDebug.boolValue, styles.materialDebugLabel);
if (!m_ShowMaterialDebug.boolValue)
return;
bool dirty = false;
int value = EditorGUILayout.IntPopup(styles.debugViewMaterial, hdPipe.debugDisplaySettings.materialDebugSettings.debugViewMaterial, DebugDisplaySettings.debugViewMaterialStrings, DebugDisplaySettings.debugViewMaterialValues);
if (EditorGUI.EndChangeCheck())
{
hdPipe.debugDisplaySettings.SetDebugViewMaterial(value);
dirty = true;
}
EditorGUILayout.PropertyField(m_enableTileAndCluster, styles.enableTileAndCluster);
EditorGUILayout.PropertyField(m_enableSplitLightEvaluation, styles.enableSplitLightEvaluation);
EditorGUILayout.PropertyField(m_enableComputeLightEvaluation, styles.enableComputeLightEvaluation);
EditorGUILayout.PropertyField(m_enableComputeFeatureVariants, styles.enableComputeFeatureVariants);
EditorGUILayout.PropertyField(m_enableClustered, styles.enableClustered);
EditorGUILayout.PropertyField(m_enableFptlForOpaqueWhenClustered, styles.enableFptlForOpaqueWhenClustered);
EditorGUILayout.PropertyField(m_enableBigTilePrepass, styles.enableBigTilePrepass);
EditorGUILayout.PropertyField(m_tileDebugByCategory, styles.tileDebugByCategory);
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntPopup(styles.debugViewEngine, hdPipe.debugDisplaySettings.materialDebugSettings.debugViewEngine, DebugDisplaySettings.debugViewEngineStrings, DebugDisplaySettings.debugViewEngineValues);
if (EditorGUI.EndChangeCheck())
{
hdPipe.debugDisplaySettings.SetDebugViewEngine(value);
dirty = true;
}
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntPopup(styles.debugViewMaterialVarying, (int)hdPipe.debugDisplaySettings.materialDebugSettings.debugViewVarying, DebugDisplaySettings.debugViewMaterialVaryingStrings, DebugDisplaySettings.debugViewMaterialVaryingValues);
if (EditorGUI.EndChangeCheck())
{
hdPipe.debugDisplaySettings.SetDebugViewVarying((Attributes.DebugViewVarying)value);
dirty = true;
}
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntPopup(styles.debugViewMaterialGBuffer, (int)hdPipe.debugDisplaySettings.materialDebugSettings.debugViewGBuffer, DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues);
hdPipe.debugDisplaySettings.SetDebugViewGBuffer(value);
dirty = true;
}
if(dirty)
}
private void SssSettingsUI(HDRenderPipelineAsset renderContext)
private void RenderingDebugSettingsUI(HDRenderPipeline renderContext)
{
m_ShowRenderingDebug.boolValue = EditorGUILayout.Foldout(m_ShowRenderingDebug.boolValue, styles.renderingDebugSettings);
if (!m_ShowRenderingDebug.boolValue)
return;
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_DisplayOpaqueObjects, styles.displayOpaqueObjects);
EditorGUILayout.PropertyField(m_DisplayTransparentObjects, styles.displayTransparentObjects);
EditorGUILayout.PropertyField(m_EnableDistortion, styles.enableDistortion);
EditorGUILayout.PropertyField(m_EnableSSS, styles.enableSSS);
EditorGUI.indentLevel--;
}
private void SssSettingsUI(HDRenderPipeline pipe)
{
EditorGUILayout.Space();

EditorGUILayout.PropertyField(m_NumProfiles, styles.sssNumProfiles);
for (int i = 0, n = m_Profiles.arraySize; i < n; i++)
for (int i = 0, n = Math.Min(m_Profiles.arraySize, SSSConstants.SSS_PROFILES_MAX); i < n; i++)
{
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.sssProfiles[i]);

}
private void SettingsUI(HDRenderPipelineAsset renderContext)
private void LightingDebugSettingsUI(HDRenderPipeline renderContext, HDRenderPipelineInstance renderpipelineInstance)
{
m_ShowLightingDebug.boolValue = EditorGUILayout.Foldout(m_ShowLightingDebug.boolValue, styles.lightingDebugSettings);
if (!m_ShowLightingDebug.boolValue)
return;
HDRenderPipeline hdPipe = target as HDRenderPipeline;
bool dirty = false;
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_DebugShadowEnabled, styles.shadowDebugEnable);
EditorGUILayout.PropertyField(m_ShadowDebugMode, styles.shadowDebugVisualizationMode);
if (!m_ShadowDebugMode.hasMultipleDifferentValues)
{
if ((ShadowMapDebugMode)m_ShadowDebugMode.intValue == ShadowMapDebugMode.VisualizeShadowMap)
{
EditorGUILayout.IntSlider(m_ShadowDebugShadowMapIndex, 0, renderpipelineInstance.GetCurrentShadowCount() - 1, styles.shadowDebugVisualizeShadowIndex);
}
}
if (EditorGUI.EndChangeCheck())
{
dirty = true;
}
EditorGUI.BeginChangeCheck();
int value = EditorGUILayout.IntPopup(styles.lightingVisualizationMode, (int)hdPipe.debugDisplaySettings.lightingDebugSettings.debugLightingMode, styles.debugViewLightingStrings, styles.debugViewLightingValues);
if (EditorGUI.EndChangeCheck())
{
hdPipe.debugDisplaySettings.SetDebugLightingMode((DebugLightingMode)value);
dirty = true;
}
EditorGUI.BeginChangeCheck();
if (hdPipe.debugDisplaySettings.GetDebugLightingMode() == DebugLightingMode.DiffuseLighting)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_LightingDebugAlbedo, styles.lightingDebugAlbedo);
EditorGUI.indentLevel--;
}
if (hdPipe.debugDisplaySettings.GetDebugLightingMode() == DebugLightingMode.SpecularLighting)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_LightingDebugOverrideSmoothness, styles.lightingDebugOverrideSmoothness);
if (!m_LightingDebugOverrideSmoothness.hasMultipleDifferentValues && m_LightingDebugOverrideSmoothness.boolValue == true)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_LightingDebugOverrideSmoothnessValue, styles.lightingDebugOverrideSmoothnessValue);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(m_LightingDebugDisplaySkyReflection, styles.lightingDisplaySkyReflection);
if (!m_LightingDebugDisplaySkyReflection.hasMultipleDifferentValues && m_LightingDebugDisplaySkyReflection.boolValue == true)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_LightingDebugDisplaySkyReflectionMipmap, styles.lightingDisplaySkyReflectionMipmap);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
dirty = true;
}
if(dirty)
HackSetDirty(renderContext);
}
private void SettingsUI(HDRenderPipeline renderContext)
EditorGUI.BeginChangeCheck();
renderContext.lightLoopProducer = (LightLoopProducer)EditorGUILayout.ObjectField(new GUIContent("Light Loop"), renderContext.lightLoopProducer, typeof(LightLoopProducer), false);
if (EditorGUI.EndChangeCheck())
{
HackSetDirty(renderContext); // Repaint
}
TileSettingsUI(renderContext);
//TilePassUI(renderContext);
private void ShadowSettingsUI(HDRenderPipelineAsset renderContext)
private void ShadowSettingsUI(HDRenderPipeline renderContext)
{
EditorGUILayout.Space();
var shadowSettings = renderContext.shadowSettings;

EditorGUI.indentLevel--;
}
private void RendereringSettingsUI(HDRenderPipelineAsset renderContext)
private void RendereringSettingsUI(HDRenderPipeline renderContext)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.renderingSettingsLabel);

EditorGUI.indentLevel--;
}
private void TextureSettingsUI(HDRenderPipelineAsset renderContext)
private void TextureSettingsUI(HDRenderPipeline renderContext)
{
EditorGUILayout.Space();
var textureSettings = renderContext.textureSettings;

EditorGUI.indentLevel--;
}
/* private void TilePassUI(HDRenderPipeline renderContext)
{
EditorGUILayout.Space();
// TODO: we should call a virtual method or something similar to setup the UI, inspector should not know about it
var tilePass = renderContext.tileSettings;
if (tilePass != null)
{
EditorGUILayout.LabelField(styles.tileLightLoopSettings);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
tilePass.enableBigTilePrepass = EditorGUILayout.Toggle(styles.bigTilePrepass, tilePass.enableBigTilePrepass);
tilePass.enableClustered = EditorGUILayout.Toggle(styles.clustered, tilePass.enableClustered);
if (EditorGUI.EndChangeCheck())
{
HackSetDirty(renderContext); // Repaint
// SetAssetDirty will tell renderloop to rebuild
renderContext.DestroyCreatedInstances();
}
EditorGUI.BeginChangeCheck();
tilePass.debugViewTilesFlags = EditorGUILayout.MaskField("DebugView Tiles", tilePass.debugViewTilesFlags, styles.tileLightLoopDebugTileFlagStrings);
tilePass.enableSplitLightEvaluation = EditorGUILayout.Toggle(styles.splitLightEvaluation, tilePass.enableSplitLightEvaluation);
tilePass.enableTileAndCluster = EditorGUILayout.Toggle(styles.enableTileAndCluster, tilePass.enableTileAndCluster);
tilePass.enableComputeLightEvaluation = EditorGUILayout.Toggle(styles.enableComputeLightEvaluation, tilePass.enableComputeLightEvaluation);
if (EditorGUI.EndChangeCheck())
{
HackSetDirty(renderContext); // Repaint
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
EditorGUI.indentLevel--;
}
}*/
public void OnEnable()
{
InitializeProperties();

{
var renderContext = target as HDRenderPipelineAsset;
HDRenderPipeline renderpipeline = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipeline;
var renderContext = target as HDRenderPipeline;
HDRenderPipelineInstance renderpipelineInstance = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if (!renderContext || renderpipeline == null)
if (!renderContext || renderpipelineInstance == null)
return;
serializedObject.Update();

EditorGUILayout.PropertyField(m_DefaultShader, Styles.defaultShader);
EditorGUI.indentLevel--;
DebuggingUI(renderContext, renderpipelineInstance);
SettingsUI(renderContext);
serializedObject.ApplyModifiedProperties();

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs


{
public class HDRenderPipelineMenuItems
{
// This script is a helper for the artists to re-synchronise all layered materials
// This script is a helper for the artits to re-synchronise all layered materials
[MenuItem("HDRenderPipeline/Synchronize all Layered materials")]
static void SynchronizeAllLayeredMaterial()
{

}
}
// TEMP: will be remove after data upgrade
[MenuItem("HDRenderPipeline/Swap standard and SSS material IDs")]
static void SwapStandardAndSssMaterialIds()
{

}
}
// Funtion used only to check performance of data with and without tessellation
[MenuItem("HDRenderPipeline/Debug/Remove tessellation materials (not reversible)")]
static void RemoveTessellationMaterials()
{

[MenuItem("HDRenderPipeline/Export Sky to Image")]
static void ExportSkyToImage()
{
HDRenderPipeline renderpipeline = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipeline;
if(renderpipeline == null)
HDRenderPipelineInstance renderpipelineInstance = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if(renderpipelineInstance == null)
Texture2D result = renderpipeline.ExportSkyToTexture();
Texture2D result = renderpipelineInstance.ExportSkyToTexture();
if(result == null)
{
return;

11
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/SceneSettingsManagementWindow.cs


CreateAsset<CommonSettings>("NewCommonSettings");
}
if (GUILayout.Button("Create new HDRI Sky Settings"))
if (GUILayout.Button("Create new HDRI sky params"))
if (GUILayout.Button("Create new Procedural Sky Settings"))
if (GUILayout.Button("Create new Procedural sky params"))
CreateAsset<ProceduralSkySettings>("NewProceduralSkySettings");
}
if (GUILayout.Button("Create new Ambient Occlusion Settings"))
{
CreateAsset<ScreenSpaceAmbientOcclusionSettings>("NewAmbientOcclusionSettings");
CreateAsset<ProceduralSkySettings>("NewProceduralSkyParameters");
}
EditorGUILayout.Space();

393
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[ExecuteInEditMode]
// This HDRenderPipeline assume linear lighting. Don't work with gamma.
public class HDRenderPipeline : RenderPipelineAsset
{
const string k_HDRenderPipelinePath = "Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset";
#if UNITY_EDITOR
[MenuItem("RenderPipeline/Create HDRenderPipeline")]
static void CreateHDRenderPipeline()
{
var instance = CreateInstance<HDRenderPipeline>();
AssetDatabase.CreateAsset(instance, k_HDRenderPipelinePath);
}
[UnityEditor.MenuItem("HDRenderPipeline/UpdateHDRenderPipeline")]
static void UpdateHDRenderPipeline()
{
var guids = AssetDatabase.FindAssets("t:HDRenderPipeline");
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
var pipeline = AssetDatabase.LoadAssetAtPath<HDRenderPipeline>(path);
EditorUtility.SetDirty(pipeline);
}
}
[UnityEditor.MenuItem("HDRenderPipeline/Add \"Additional Light Data\" (if not present)")]
static void AddAdditionalLightData()
{
Light[] lights = FindObjectsOfType(typeof(Light)) as Light[];
foreach (Light light in lights)
{
// Do not add a component if there already is one.
if (light.GetComponent<AdditionalLightData>() == null)
{
light.gameObject.AddComponent<AdditionalLightData>();
}
}
}
#endif
private HDRenderPipeline()
{}
[SerializeField]
private LightLoopProducer m_LightLoopProducer;
public LightLoopProducer lightLoopProducer
{
get { return m_LightLoopProducer; }
set { m_LightLoopProducer = value; }
}
protected override IRenderPipeline InternalCreatePipeline()
{
return new HDRenderPipelineInstance(this);
}
// NOTE:
// All those properties are public because of how HDRenderPipelineInspector retrieve those properties via serialization/reflection
// Those that are not will be refatored later.
// Debugging
public DebugDisplaySettings debugDisplaySettings = new DebugDisplaySettings();
// Renderer Settings (per project)
public RenderingSettings renderingSettings = new RenderingSettings();
public SubsurfaceScatteringSettings sssSettings = new SubsurfaceScatteringSettings();
[SerializeField]
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
[SerializeField]
TextureSettings m_TextureSettings = TextureSettings.Default;
public ShadowSettings shadowSettings { get { return m_ShadowSettings; } }
public TextureSettings textureSettings { get { return m_TextureSettings; } set { m_TextureSettings = value; } }
// Renderer Settings (per "scene")
[SerializeField] private CommonSettings.Settings m_CommonSettings = CommonSettings.Settings.s_Defaultsettings;
[SerializeField] private SkySettings m_SkySettings;
public CommonSettings.Settings commonSettingsToUse
{
get
{
if (CommonSettingsSingleton.overrideSettings)
return CommonSettingsSingleton.overrideSettings.settings;
return m_CommonSettings;
}
}
public SkySettings skySettings
{
get { return m_SkySettings; }
set { m_SkySettings = value; }
}
public SkySettings skySettingsToUse
{
get
{
if (SkySettingsSingleton.overrideSettings)
return SkySettingsSingleton.overrideSettings;
return m_SkySettings;
}
}
[SerializeField] private Material m_DefaultDiffuseMaterial;
[SerializeField] private Shader m_DefaultShader;
public Material DefaultDiffuseMaterial
{
get { return m_DefaultDiffuseMaterial; }
private set { m_DefaultDiffuseMaterial = value; }
}
public Shader DefaultShader
{
get { return m_DefaultShader; }
private set { m_DefaultShader = value; }
}
public override Shader GetDefaultShader()
{
return m_DefaultShader;
}
public override Material GetDefaultMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefaultParticleMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefaultLineMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefaultTerrainMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefaultUIMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefaultUIOverdrawMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefaultUIETC1SupportedMaterial()
{
return m_DefaultDiffuseMaterial;
}
public override Material GetDefault2DMaterial()
{
return m_DefaultDiffuseMaterial;
}
public void ApplyDebugDisplaySettings()
{
m_ShadowSettings.enabled = debugDisplaySettings.lightingDebugSettings.enableShadows;
LightingDebugSettings lightingDebugSettings = debugDisplaySettings.lightingDebugSettings;
Vector4 debugAlbedo = new Vector4(lightingDebugSettings.debugLightingAlbedo.r, lightingDebugSettings.debugLightingAlbedo.g, lightingDebugSettings.debugLightingAlbedo.b, 0.0f);
Vector4 debugSmoothness = new Vector4(lightingDebugSettings.overrideSmoothness ? 1.0f : 0.0f, lightingDebugSettings.overrideSmoothnessValue, 0.0f, 0.0f);
Shader.SetGlobalInt("_DebugViewMaterial", (int)debugDisplaySettings.GetDebugMaterialIndex());
Shader.SetGlobalInt("_DebugLightingMode", (int)debugDisplaySettings.GetDebugLightingMode());
Shader.SetGlobalVector("_DebugLightingAlbedo", debugAlbedo);
Shader.SetGlobalVector("_DebugLightingSmoothness", debugSmoothness);
}
public void UpdateCommonSettings()
{
var commonSettings = commonSettingsToUse;
m_ShadowSettings.directionalLightCascadeCount = commonSettings.shadowCascadeCount;
m_ShadowSettings.directionalLightCascades = new Vector3(commonSettings.shadowCascadeSplit0, commonSettings.shadowCascadeSplit1, commonSettings.shadowCascadeSplit2);
m_ShadowSettings.maxShadowDistance = commonSettings.shadowMaxDistance;
m_ShadowSettings.directionalLightNearPlaneOffset = commonSettings.shadowNearPlaneOffset;
}
public void OnValidate()
{
debugDisplaySettings.OnValidate();
sssSettings.OnValidate();
}
void OnEnable()
{
debugDisplaySettings.RegisterDebug();
}
}
[Serializable]
public class RenderingSettings
{

RenderTextureReadWrite[] sRGBWrites = new RenderTextureReadWrite[MaxGbuffer];
}
public class HDRenderPipeline : RenderPipeline
public class HDRenderPipelineInstance : RenderPipeline
private readonly HDRenderPipelineAsset m_Asset;
private readonly HDRenderPipeline m_Owner;
// TODO: Find a way to automatically create/iterate through deferred material
// TODO TO CHECK: SebL I move allocation from Build() to here, but there was a comment "// Our object can be garbage collected, so need to be allocate here", it is still true ?

// Various set of material use in render loop
readonly Material m_FilterSubsurfaceScattering;
readonly Material m_FilterAndCombineSubsurfaceScattering;
private Material m_DebugViewMaterialGBuffer;

// It is stored within 'm_CameraSubsurfaceBufferRT'.
readonly RenderTargetIdentifier m_CameraColorBufferRT;
readonly RenderTargetIdentifier m_CameraSubsurfaceBufferRT;
readonly RenderTargetIdentifier m_CameraFilteringBufferRT;
readonly RenderTargetIdentifier m_VelocityBufferRT;
readonly RenderTargetIdentifier m_DistortionBufferRT;

private RenderTargetIdentifier m_CameraDepthStencilBufferCopyRT;
// Post-processing context and screen-space effects (recycled on every frame to avoid GC alloc)
// Post-processing context (recycled on every frame to avoid GC alloc)
readonly ScreenSpaceAmbientOcclusionEffect m_SsaoEffect;
// Detect when windows size is changing
int m_CurrentWidth;

readonly SkyManager m_SkyManager = new SkyManager();
readonly LightLoop m_LightLoop = new LightLoop();
private readonly BaseLightLoop m_LightLoop;
get { return m_Asset.debugDisplaySettings; }
get { return m_Owner.debugDisplaySettings; }
get { return m_Asset.sssSettings; }
get { return m_Owner.sssSettings; }
public HDRenderPipeline(HDRenderPipelineAsset asset)
public HDRenderPipelineInstance(HDRenderPipeline owner)
m_Asset = asset;
m_Owner = owner;
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraSubsurfaceBufferRT = new RenderTargetIdentifier(m_CameraSubsurfaceBuffer);
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraSubsurfaceBufferRT = new RenderTargetIdentifier(m_CameraSubsurfaceBuffer);
m_CameraFilteringBufferRT = new RenderTargetIdentifier(m_CameraFilteringBuffer);
m_FilterSubsurfaceScattering = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineSubsurfaceScattering");
m_FilterSubsurfaceScattering.DisableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_FilterSubsurfaceScattering.SetFloat("_DstBlend", (float)BlendMode.Zero);
m_FilterAndCombineSubsurfaceScattering.EnableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_FilterAndCombineSubsurfaceScattering.SetFloat("_DstBlend", (float)BlendMode.One);
InitializeDebugMaterials();

m_DistortionBuffer = Shader.PropertyToID("_DistortionTexture");
m_DistortionBufferRT = new RenderTargetIdentifier(m_DistortionBuffer);
m_LitRenderLoop.Build(asset.renderPipelineResources);
m_LitRenderLoop.Build();
m_LightLoop.Build(asset.renderPipelineResources, asset.tileSettings, asset.textureSettings);
if (owner.lightLoopProducer)
m_LightLoop = owner.lightLoopProducer.CreateLightLoop();
m_SkyManager.Build(asset.renderPipelineResources);
m_SkyManager.skySettings = asset.skySettingsToUse;
if (m_LightLoop != null)
m_LightLoop.Build(owner.textureSettings);
m_SkyManager.Build();
m_SkyManager.skySettings = owner.skySettingsToUse;
m_SsaoEffect = new ScreenSpaceAmbientOcclusionEffect();
m_SsaoEffect.Build(asset.renderPipelineResources);
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugViewMaterialGBufferShader);
m_DebugDisplayLatlong = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugDisplayLatlongShader);
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewMaterialGBuffer");
m_DebugDisplayLatlong = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayLatlong");
m_LitRenderLoop.Build(m_Asset.renderPipelineResources);
m_LitRenderLoop.Build();
}
public override void Dispose()

m_LightLoop.Cleanup();
if (m_LightLoop != null)
m_LightLoop.Cleanup();
m_LitRenderLoop.Cleanup();

m_SkyManager.Cleanup();
m_SsaoEffect.Cleanup();
#if UNITY_EDITOR
SupportedRenderingFeatures.active = SupportedRenderingFeatures.Default;
#endif

// TODO: This is the wrong way to handle resize/allocation. We can have several different camera here, mean that the loop on camera will allocate and deallocate
// the below buffer which is bad. Best is to have a set of buffer for each camera that is persistent and reallocate resource if need
// For now consider we have only one camera that go to this code, the main one.
m_SkyManager.skySettings = m_Asset.skySettingsToUse;
m_SkyManager.Resize(camera.nearClipPlane, camera.farClipPlane); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (useful for lookdev)
m_SkyManager.skySettings = m_Owner.skySettingsToUse;
m_SkyManager.Resize(camera.nearClipPlane, camera.farClipPlane); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
if (m_LightLoop == null)
return;
bool resolutionChanged = camera.pixelWidth != m_CurrentWidth || camera.pixelHeight != m_CurrentHeight;

}
// Broadcast SSS parameters to all shaders.
Shader.SetGlobalInt( "_EnableSSS", debugDisplaySettings.renderingDebugSettings.enableSSS ? 1 : 0);
Shader.SetGlobalInt( "_TexturingModeFlags", (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt( "_TransmissionFlags", (int)sssParameters.transmissionFlags);
cmd.SetGlobalFloatArray( "_ThicknessRemaps", sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray("_ShapeParameters", sssParameters.shapeParameters);
cmd.SetGlobalVectorArray("_SurfaceAlbedos", sssParameters.surfaceAlbedos);
Shader.SetGlobalInt("_EnableSSS", debugDisplaySettings.renderingDebugSettings.enableSSS ? 1 : 0);
cmd.SetGlobalFloatArray("_TransmissionType", sssParameters.transmissionType);
Shader.SetGlobalInt("_TexturingModeFlags", sssParameters.texturingModeFlags);
cmd.SetGlobalFloatArray("_ThicknessRemaps", sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray("_TintColors", sssParameters.tintColors);
cmd.SetGlobalVectorArray("_HalfRcpVariancesAndLerpWeights", sssParameters.halfRcpVariancesAndLerpWeights);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

m_LitRenderLoop.RenderInit(renderContext);
// Do anything we need to do upon a new frame.
m_LightLoop.NewFrame();
m_Asset.ApplyDebugDisplaySettings();
m_Asset.UpdateCommonSettings();
if (m_LightLoop != null)
m_LightLoop.NewFrame();
m_Owner.ApplyDebugDisplaySettings();
m_Owner.UpdateCommonSettings();
// Set Frame constant buffer
// TODO...

// If full forward rendering, we did not do any rendering yet, so don't need to copy the buffer.
// If Deferred then the depth buffer is full (regular GBuffer + ForwardOnly depth prepass are done so we can copy it safely.
if (!m_Asset.renderingSettings.useForwardRenderingOnly)
if (!m_Owner.renderingSettings.useForwardRenderingOnly)
{
CopyDepthBufferIfNeeded(renderContext);
}

}
else
{
using (new Utilities.ProfilingSample("Build Light list and render shadows", renderContext))
if (m_LightLoop != null)
// TODO: Everything here (SSAO, Shadow, Build light list, material and light classification can be parallelize with Async compute)
m_SsaoEffect.Render(m_Asset.ssaoSettingsToUse, hdCamera, renderContext, GetDepthTexture(), m_Asset.renderingSettings.useForwardRenderingOnly);
m_LightLoop.PrepareLightsForGPU(m_Asset.shadowSettings, cullResults, camera);
m_LightLoop.RenderShadows(renderContext, cullResults);
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthStencilBufferRT);
using (new Utilities.ProfilingSample("Build Light list and render shadows", renderContext))
{
m_LightLoop.PrepareLightsForGPU(m_Owner.shadowSettings, cullResults, camera);
m_LightLoop.RenderShadows(renderContext, cullResults);
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthStencilBufferRT); // TODO: Use async compute here to run light culling during shadow
}
PushGlobalParams(hdCamera, renderContext, m_Asset.sssSettings);
PushGlobalParams(hdCamera, renderContext, m_Owner.sssSettings);
// Caution: We require sun light here as some sky use the sun light to render, mean UpdateSkyEnvironment
// must be call after BuildGPULightLists.

// We compute subsurface scattering here. Therefore, no objects rendered afterwards will exhibit SSS.
// Currently, there is no efficient way to switch between SRT and MRT for the forward pass;
// therefore, forward-rendered objects do not output split lighting required for the SSS pass.
CombineSubsurfaceScattering(hdCamera, renderContext, m_Asset.sssSettings);
CombineSubsurfaceScattering(hdCamera, renderContext, m_Owner.sssSettings);
// For opaque forward we have split rendering in two categories
// Material that are always forward and material that can be deferred or forward depends on render pipeline options (like switch to rendering forward only mode)

// If full forward rendering, we did just rendered everything, so we can copy the depth buffer
// If Deferred nothing needs copying anymore.
if (m_Asset.renderingSettings.useForwardRenderingOnly)
if (m_Owner.renderingSettings.useForwardRenderingOnly)
{
CopyDepthBufferIfNeeded(renderContext);
}

{
// If we are forward only we will do a depth prepass
// TODO: Depth prepass should be enabled based on light loop settings. LightLoop define if they need a depth prepass + forward only...
if (!m_Asset.renderingSettings.useDepthPrepass)
if (!m_Owner.renderingSettings.useDepthPrepass)
return;
using (new Utilities.ProfilingSample("Depth Prepass", renderContext))

void RenderGBuffer(CullResults cull, Camera camera, ScriptableRenderContext renderContext)
{
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
if (m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
{
return;
}

{
// If we are forward only we don't need to render ForwardOnlyOpaqueDepthOnly object
// But in case we request a prepass we render it
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && !m_Asset.renderingSettings.useDepthPrepass)
if (m_Owner.renderingSettings.ShouldUseForwardRenderingOnly() && !m_Owner.renderingSettings.useDepthPrepass)
return;
using (new Utilities.ProfilingSample("Forward opaque depth", renderContext))

void RenderDebugViewMaterial(CullResults cull, HDCamera hdCamera, ScriptableRenderContext renderContext)
{
using (new Utilities.ProfilingSample("DisplayDebug ViewMaterial", renderContext))
// Render Opaque forward
// Render Opaque forward
}
// Render GBuffer opaque
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewMaterialGBuffer);
// Render GBuffer opaque
if (!m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
{
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewMaterialGBuffer);
// m_gbufferManager.BindBuffers(m_DebugViewMaterialGBuffer);
// TODO: Bind depth textures
var cmd = new CommandBuffer { name = "DebugViewMaterialGBuffer" };
cmd.Blit(null, m_CameraColorBufferRT, m_DebugViewMaterialGBuffer, 0);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// m_gbufferManager.BindBuffers(m_DebugViewMaterialGBuffer);
// TODO: Bind depth textures
var cmd = new CommandBuffer { name = "DebugViewMaterialGBuffer" };
cmd.Blit(null, m_CameraColorBufferRT, m_DebugViewMaterialGBuffer, 0);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// Render forward transparent
{
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, "ForwardDisplayDebug", Utilities.kRendererConfigurationBakedLighting);
}
// Render forward transparent
{
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, "ForwardDisplayDebug", Utilities.kRendererConfigurationBakedLighting);
}
// Last blit

void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext)
{
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
if (m_Owner.renderingSettings.ShouldUseForwardRenderingOnly() || m_LightLoop == null)
{
return;
}

void CombineSubsurfaceScattering(HDCamera hdCamera, ScriptableRenderContext context, SubsurfaceScatteringSettings sssParameters)
{
// Currently, forward-rendered objects do not output split lighting required for the SSS pass.
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly()) return;
if (m_Owner.renderingSettings.ShouldUseForwardRenderingOnly()) return;
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT); // Cannot set a RT on a material
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_WorldScales", sssParameters.worldScales);
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_FilterKernelsNearField", sssParameters.filterKernelsNearField);
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_FilterKernelsFarField", sssParameters.filterKernelsFarField);
// Perform the vertical SSS filtering pass.
m_FilterSubsurfaceScattering.SetVectorArray("_FilterKernels", sssParameters.filterKernels);
m_FilterSubsurfaceScattering.SetVectorArray("_HalfRcpWeightedVariances", sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT);
Utilities.DrawFullScreen(cmd, m_FilterSubsurfaceScattering, hdCamera, m_CameraFilteringBufferRT, m_CameraDepthStencilBufferRT);
// when recombining the lighting, we apply albedo. This need to be modified in case of debug display with diffuse lighting only.
Utilities.SetKeyword(m_FilterAndCombineSubsurfaceScattering, "DEBUG_DISPLAY", debugDisplaySettings.IsDebugDisplayEnabled());
// Perform the horizontal SSS filtering pass, and combine diffuse and specular lighting.
m_FilterAndCombineSubsurfaceScattering.SetVectorArray("_FilterKernels", sssParameters.filterKernels);
m_FilterAndCombineSubsurfaceScattering.SetVectorArray("_HalfRcpWeightedVariances", sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalTexture("_IrradianceSource", m_CameraFilteringBufferRT);
Utilities.DrawFullScreen(cmd, m_FilterAndCombineSubsurfaceScattering, hdCamera, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
context.ExecuteCommandBuffer(cmd);

void UpdateSkyEnvironment(HDCamera hdCamera, ScriptableRenderContext renderContext)
{
m_SkyManager.UpdateEnvironment(hdCamera,m_LightLoop.GetCurrentSunLight(), renderContext);
m_SkyManager.UpdateEnvironment(hdCamera, m_LightLoop == null ? null : m_LightLoop.GetCurrentSunLight(), renderContext);
m_SkyManager.RenderSky(hdCamera, m_LightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, renderContext);
m_SkyManager.RenderSky(hdCamera, m_LightLoop == null ? null : m_LightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, renderContext);
}
public Texture2D ExportSkyToTexture()

void RenderLightingDebug(HDCamera camera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
{
m_LightLoop.RenderLightingDebug(camera, renderContext, colorBuffer);
if (m_LightLoop != null)
m_LightLoop.RenderLightingDebug(camera, renderContext, colorBuffer);
}
void RenderForward(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, bool renderOpaque)

if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && renderOpaque)
if (!m_Owner.renderingSettings.ShouldUseForwardRenderingOnly() && renderOpaque)
return;
string passName = debugDisplaySettings.IsDebugDisplayEnabled() ? "ForwardDisplayDebug" : "Forward";

Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
m_LightLoop.RenderForward(camera, renderContext, renderOpaque);
if (m_LightLoop != null)
m_LightLoop.RenderForward(camera, renderContext, renderOpaque);
if (renderOpaque)
{

{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
m_LightLoop.RenderForward(camera, renderContext, true);
if (m_LightLoop != null)
m_LightLoop.RenderForward(camera, renderContext, true);
RenderOpaqueRenderList(cullResults, camera, renderContext, passName, Utilities.kRendererConfigurationBakedLighting);
}

using (new Utilities.ProfilingSample("Velocity", renderContext))
{
// If opaque velocity have been render during GBuffer no need to render it here
if ((ShaderConfig.s_VelocityInGbuffer == 1) || m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
if ((ShaderConfig.s_VelocityInGbuffer == 1) || m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
return;
int w = camera.pixelWidth;

renderContext.ExecuteCommandBuffer(debugCB);
m_LightLoop.RenderDebugOverlay(camera, renderContext, debugDisplaySettings, ref x, ref y, overlaySize, camera.pixelWidth);
if (m_LightLoop != null)
m_LightLoop.RenderDebugOverlay(camera, renderContext, debugDisplaySettings, ref x, ref y, overlaySize, camera.pixelWidth);
}
void InitAndClearBuffer(Camera camera, ScriptableRenderContext renderContext)

cmd.GetTemporaryRT(m_CameraSubsurfaceBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraFilteringBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
if (!m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
{
m_gbufferManager.InitGBuffers(w, h, cmd);
}

}
// Clear GBuffers
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
if (!m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
{
using (new Utilities.ProfilingSample("Clear GBuffer", renderContext))
{

210
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


public float unused2;
};
[Serializable]
public class TileSettings
{
public bool enableTileAndCluster; // For debug / test
public bool enableSplitLightEvaluation;
public bool enableComputeLightEvaluation;
public bool enableComputeFeatureVariants;
// clustered light list specific buffers and data begin
public bool enableClustered;
public bool enableFptlForOpaqueWhenClustered; // still useful on opaques. Should be true by default to force tile on opaque.
public bool enableBigTilePrepass;
[Range(0.0f, 1.0f)]
public float diffuseGlobalDimmer = 1.0f;
[Range(0.0f, 1.0f)]
public float specularGlobalDimmer = 1.0f;
public enum TileDebug : int
{
None = 0, Punctual = 1, Area = 2, AreaAndPunctual = 3, Projector = 4, ProjectorAndPunctual = 5, ProjectorAndArea = 6, ProjectorAndAreaAndPunctual = 7,
Environment = 8, EnvironmentAndPunctual = 9, EnvironmentAndArea = 10, EnvironemntAndAreaAndPunctual = 11,
EnvironmentAndProjector = 12, EnvironmentAndProjectorAndPunctual = 13, EnvironmentAndProjectorAndArea = 14, EnvironmentAndProjectorAndAreaAndPunctual = 15,
FeatureVariants = 16
}; //TODO: we should probably make this checkboxes
public TileDebug tileDebugByCategory;
public TileSettings()
{
enableTileAndCluster = true;
enableSplitLightEvaluation = true;
enableComputeLightEvaluation = false;
enableComputeFeatureVariants = false;
enableClustered = true;
enableFptlForOpaqueWhenClustered = true;
enableBigTilePrepass = true;
diffuseGlobalDimmer = 1.0f;
specularGlobalDimmer = 1.0f;
tileDebugByCategory = TileDebug.None;
}
}
public class LightLoop
public class LightLoop : BaseLightLoop
{
public const int k_MaxDirectionalLightsOnScreen = 4;
public const int k_MaxPunctualLightsOnScreen = 512;

int m_projectorLightCount = 0;
int m_lightCount = 0;
private ComputeShader buildScreenAABBShader { get { return m_Resources.buildScreenAABBShader; } }
private ComputeShader buildPerTileLightListShader { get { return m_Resources.buildPerTileLightListShader; } }
private ComputeShader buildPerBigTileLightListShader { get { return m_Resources.buildPerBigTileLightListShader; } }
private ComputeShader buildPerVoxelLightListShader { get { return m_Resources.buildPerVoxelLightListShader; } }
private ComputeShader buildScreenAABBShader { get { return m_PassResources.buildScreenAABBShader; } }
private ComputeShader buildPerTileLightListShader { get { return m_PassResources.buildPerTileLightListShader; } }
private ComputeShader buildPerBigTileLightListShader { get { return m_PassResources.buildPerBigTileLightListShader; } }
private ComputeShader buildPerVoxelLightListShader { get { return m_PassResources.buildPerVoxelLightListShader; } }
private ComputeShader clearDispatchIndirectShader { get { return m_Resources.clearDispatchIndirectShader; } }
private ComputeShader shadeOpaqueShader { get { return m_Resources.shadeOpaqueShader; } }
private ComputeShader clearDispatchIndirectShader { get { return m_PassResources.clearDispatchIndirectShader; } }
private ComputeShader shadeOpaqueShader { get { return m_PassResources.shadeOpaqueShader; } }
static int s_GenAABBKernel;
static int s_GenListPerTileKernel;

get
{
bool isEnabledMSAA = false;
Debug.Assert(!isEnabledMSAA || m_TileSettings.enableClustered);
bool disableFptl = (!m_TileSettings.enableFptlForOpaqueWhenClustered && m_TileSettings.enableClustered) || isEnabledMSAA;
Debug.Assert(!isEnabledMSAA || m_PassSettings.enableClustered);
bool disableFptl = (!m_PassSettings.enableFptlForOpaqueWhenClustered && m_PassSettings.enableClustered) || isEnabledMSAA;
return !disableFptl;
}
}

Material m_SingleDeferredMaterialSRT = null;
Material m_SingleDeferredMaterialMRT = null;
Light m_CurrentSunLight = null;
public Light GetCurrentSunLight() { return m_CurrentSunLight; }
Material m_DebugDisplayShadowMap;
private Material m_DebugDisplayShadowMap;
// shadow related stuff
FrameId m_FrameId = new FrameId();

bool GetFeatureVariantsEnabled()
{
return m_TileSettings.enableComputeLightEvaluation && m_TileSettings.enableComputeFeatureVariants && !(m_TileSettings.enableClustered && !m_TileSettings.enableFptlForOpaqueWhenClustered);
return m_PassSettings.enableComputeLightEvaluation && m_PassSettings.enableComputeFeatureVariants && !(m_PassSettings.enableClustered && !m_PassSettings.enableFptlForOpaqueWhenClustered);
TileSettings m_TileSettings = null;
RenderPipelineResources m_Resources = null;
TileLightLoopProducer.TileSettings m_PassSettings;
private TilePassResources m_PassResources;
public LightLoop()
{}
public void Build(RenderPipelineResources renderPipelineResources, TileSettings tileSettings, TextureSettings textureSettings)
public LightLoop(TileLightLoopProducer producer)
m_Resources = renderPipelineResources;
m_TileSettings = tileSettings;
m_PassSettings = producer.tileSettings;
m_PassResources = producer.passResources;
}
public override void Build(TextureSettings textureSettings)
{
m_lightList = new LightList();
m_lightList.Allocate();

bool enableFeatureVariants = GetFeatureVariantsEnabled();
if (enableFeatureVariants)
{
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_TileSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile_FeatureFlags" : "TileLightListGen_FeatureFlags");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_PassSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile_FeatureFlags" : "TileLightListGen_FeatureFlags");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_TileSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile" : "TileLightListGen");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_PassSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile" : "TileLightListGen");
}
s_AABBBoundsBuffer = new ComputeBuffer(2 * k_MaxLightsOnScreen, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));

if (m_TileSettings.enableClustered)
if (m_PassSettings.enableClustered)
var kernelName = m_TileSettings.enableBigTilePrepass ? (k_UseDepthBuffer ? "TileLightListGen_DepthRT_SrcBigTile" : "TileLightListGen_NoDepthRT_SrcBigTile") : (k_UseDepthBuffer ? "TileLightListGen_DepthRT" : "TileLightListGen_NoDepthRT");
var kernelName = m_PassSettings.enableBigTilePrepass ? (k_UseDepthBuffer ? "TileLightListGen_DepthRT_SrcBigTile" : "TileLightListGen_NoDepthRT_SrcBigTile") : (k_UseDepthBuffer ? "TileLightListGen_DepthRT" : "TileLightListGen_NoDepthRT");
if (m_TileSettings.enableBigTilePrepass)
if (m_PassSettings.enableBigTilePrepass)
{
s_GenListPerBigTileKernel = buildPerBigTileLightListShader.FindKernel("BigTileLightListGen");
}

string[] tileKeywords = {"LIGHTLOOP_TILE_DIRECT", "LIGHTLOOP_TILE_INDIRECT", "LIGHTLOOP_TILE_ALL"};
m_DeferredDirectMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredDirectMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredDirectMaterialSRT, tileKeywords, 0);
m_DeferredDirectMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredDirectMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");

m_DeferredDirectMaterialSRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DeferredDirectMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredDirectMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredDirectMaterialMRT, tileKeywords, 0);
m_DeferredDirectMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredDirectMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");

m_DeferredDirectMaterialMRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DeferredIndirectMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredIndirectMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredIndirectMaterialSRT, tileKeywords, 1);
m_DeferredIndirectMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredIndirectMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");

m_DeferredIndirectMaterialSRT.SetInt("_DstBlend", (int)BlendMode.One); // Additive color & alpha source
m_DeferredIndirectMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredIndirectMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredIndirectMaterialMRT, tileKeywords, 1);
m_DeferredIndirectMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredIndirectMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");

m_DeferredIndirectMaterialMRT.SetInt("_DstBlend", (int)BlendMode.One); // Additive color & alpha source
m_DeferredAllMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredAllMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredAllMaterialSRT, tileKeywords, 2);
m_DeferredAllMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");

m_DeferredAllMaterialSRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DeferredAllMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredAllMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredAllMaterialMRT, tileKeywords, 2);
m_DeferredAllMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");

m_DeferredAllMaterialMRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_SingleDeferredMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DebugViewTilesMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewTiles");
m_SingleDeferredMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_SingleDeferredMaterialSRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialSRT.SetInt("_StencilRef", (int)StencilBits.SSS);

m_SingleDeferredMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_SingleDeferredMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_SingleDeferredMaterialMRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialMRT.SetInt("_StencilRef", (int)StencilBits.SSS);

m_DebugViewTilesMaterial = Utilities.CreateEngineMaterial(m_Resources.debugViewTilesShader);
m_DebugDisplayShadowMap = Utilities.CreateEngineMaterial(m_Resources.debugDisplayShadowMapShader);
m_DebugDisplayShadowMap = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayShadowMap");
m_DefaultTexture2DArray = new Texture2DArray(1, 1, 1, TextureFormat.ARGB32, false);
m_DefaultTexture2DArray.SetPixels32(new Color32[1] { new Color32(128, 128, 128, 128) }, 0);

InitShadowSystem(ShadowSettings.Default);
}
public void Cleanup()
public override void Cleanup()
{
DeinitShadowSystem();

s_DefaultAdditionalLightData = null;
}
public void NewFrame()
public override void NewFrame()
{
m_CookieTexArray.NewFrame();
m_CubeCookieTexArray.NewFrame();

public bool NeedResize()
public override bool NeedResize()
(s_BigTileLightList == null && m_TileSettings.enableBigTilePrepass) ||
(s_PerVoxelLightLists == null && m_TileSettings.enableClustered);
(s_BigTileLightList == null && m_PassSettings.enableBigTilePrepass) ||
(s_PerVoxelLightLists == null && m_PassSettings.enableClustered);
public void ReleaseResolutionDependentBuffers()
public override void ReleaseResolutionDependentBuffers()
{
Utilities.SafeRelease(s_LightList);
Utilities.SafeRelease(s_TileList);

return 8 * (1 << k_Log2NumClusters); // total footprint for all layers of the tile (measured in light index entries)
}
public void AllocResolutionDependentBuffers(int width, int height)
public override void AllocResolutionDependentBuffers(int width, int height)
{
var nrTilesX = (width + LightDefinitions.TILE_SIZE_FPTL - 1) / LightDefinitions.TILE_SIZE_FPTL;
var nrTilesY = (height + LightDefinitions.TILE_SIZE_FPTL - 1) / LightDefinitions.TILE_SIZE_FPTL;

s_LightList = new ComputeBuffer((int)LightCategory.Count * dwordsPerTile * nrTiles, sizeof(uint)); // enough list memory for a 4k x 4k display
s_TileList = new ComputeBuffer((int)LightDefinitions.NUM_FEATURE_VARIANTS * nrTiles, sizeof(uint));
if (m_TileSettings.enableClustered)
if (m_PassSettings.enableClustered)
{
var nrClustersX = (width + LightDefinitions.TILE_SIZE_CLUSTERED - 1) / LightDefinitions.TILE_SIZE_CLUSTERED;
var nrClustersY = (height + LightDefinitions.TILE_SIZE_CLUSTERED - 1) / LightDefinitions.TILE_SIZE_CLUSTERED;

}
}
if (m_TileSettings.enableBigTilePrepass)
if (m_PassSettings.enableBigTilePrepass)
{
var nrBigTilesX = (width + 63) / 64;
var nrBigTilesY = (height + 63) / 64;

{
var directionalLightData = new DirectionalLightData();
float diffuseDimmer = m_TileSettings.diffuseGlobalDimmer * additionalData.lightDimmer;
float specularDimmer = m_TileSettings.specularGlobalDimmer * additionalData.lightDimmer;
float diffuseDimmer = m_PassSettings.diffuseGlobalDimmer * additionalData.lightDimmer;
float specularDimmer = m_PassSettings.specularGlobalDimmer * additionalData.lightDimmer;
if (diffuseDimmer <= 0.0f && specularDimmer <= 0.0f)
return false;

float distanceFade = ComputeLinearDistanceFade(distanceToCamera, additionalData.fadeDistance);
float lightScale = additionalData.lightDimmer * distanceFade;
lightData.diffuseScale = additionalData.affectDiffuse ? lightScale * m_TileSettings.diffuseGlobalDimmer : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? lightScale * m_TileSettings.specularGlobalDimmer : 0.0f;
lightData.diffuseScale = additionalData.affectDiffuse ? lightScale * m_PassSettings.diffuseGlobalDimmer : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? lightScale * m_PassSettings.specularGlobalDimmer : 0.0f;
if (lightData.diffuseScale <= 0.0f && lightData.specularScale <= 0.0f)
return false;

m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
}
public int GetCurrentShadowCount()
public override int GetCurrentShadowCount()
public void UpdateCullingParameters(ref CullingParameters cullingParams)
public override void UpdateCullingParameters(ref CullingParameters cullingParams)
public void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)
{
m_lightList.Clear();

}
}
float oldSpecularGlobalDimmer = m_TileSettings.specularGlobalDimmer;
float oldSpecularGlobalDimmer = m_PassSettings.specularGlobalDimmer;
m_TileSettings.specularGlobalDimmer = 0.0f;
m_PassSettings.specularGlobalDimmer = 0.0f;
}
// 1. Count the number of lights and sort all lights by category, type and volume - This is required for the fptl/cluster shader code

sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
}
Array.Sort(sortKeys, 0, sortCount);
Array.Sort(sortKeys);
// TODO: Refactor shadow management
// The good way of managing shadow:

}
// Not necessary yet but call it for future modification with sphere influence volume
Array.Sort(sortKeys, 0, sortCount);
Array.Sort(sortKeys);
for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex)
{

Debug.Assert(m_lightList.envLights.Count == envLightCount);
// Restore values after "special rendering"
m_TileSettings.specularGlobalDimmer = oldSpecularGlobalDimmer;
m_PassSettings.specularGlobalDimmer = oldSpecularGlobalDimmer;
}
m_lightCount = m_lightList.lights.Count + m_lightList.envLights.Count;

cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vLayeredLightList", s_PerVoxelLightLists);
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_LayeredOffset", s_PerVoxelOffset);
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);
if (m_TileSettings.enableBigTilePrepass)
if (m_PassSettings.enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vBigTileLightList", s_BigTileLightList);
if (k_UseDepthBuffer)

cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
}
public void BuildGPULightLists(Camera camera, ScriptableRenderContext loop, RenderTargetIdentifier cameraDepthBufferRT)
public override void BuildGPULightLists(Camera camera, ScriptableRenderContext loop, RenderTargetIdentifier cameraDepthBufferRT)
{
var w = camera.pixelWidth;
var h = camera.pixelHeight;

}
// enable coarse 2D pass on 64x64 tiles (used for both fptl and clustered).
if (m_TileSettings.enableBigTilePrepass)
if (m_PassSettings.enableBigTilePrepass)
{
cmd.SetComputeIntParams(buildPerBigTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "_EnvLightIndexShift", m_lightList.lights.Count);

Utilities.SetMatrixCS(cmd, buildPerTileLightListShader, "g_mInvScrProjection", invProjscr);
cmd.SetComputeTextureParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_depth_tex", cameraDepthBufferRT);
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vLightList", s_LightList);
if (m_TileSettings.enableBigTilePrepass)
if (m_PassSettings.enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vBigTileLightList", s_BigTileLightList);

cmd.DispatchCompute(buildPerTileLightListShader, s_GenListPerTileKernel, numTilesX, numTilesY, 1);
}
if (m_TileSettings.enableClustered) // works for transparencies too.
if (m_PassSettings.enableClustered) // works for transparencies too.
{
VoxelLightListGeneration(cmd, camera, projscr, invProjscr, cameraDepthBufferRT);
}

SetGlobalInt("_NumTileClusteredX", GetNumTileClusteredX(camera));
SetGlobalInt("_NumTileClusteredY", GetNumTileClusteredY(camera));
if (m_TileSettings.enableBigTilePrepass)
if (m_PassSettings.enableBigTilePrepass)
if (m_TileSettings.enableClustered)
if (m_PassSettings.enableClustered)
{
SetGlobalFloat("g_fClustScale", m_ClustScale);
SetGlobalFloat("g_fClustBase", k_ClustLogBase);

#endif
public void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults)
public override void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults)
{
// kick off the shadow jobs here
m_ShadowMgr.RenderShadows(m_FrameId, renderContext, cullResults, cullResults.visibleLights);

Utilities.SetKeyword(m_SingleDeferredMaterialMRT, "DEBUG_DISPLAY", debugDisplayEnable);
}
public void RenderLightingDebug(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
public override void RenderLightingDebug(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
if (m_TileSettings.tileDebugByCategory == TileSettings.TileDebug.None)
if (m_PassSettings.tileDebugByCategory == TileLightLoopProducer.TileSettings.TileDebug.None)
return;
var cmd = new CommandBuffer();

// Debug tiles
PushGlobalParams(hdCamera.camera, renderContext, null, 0);
if (m_TileSettings.tileDebugByCategory == TileSettings.TileDebug.FeatureVariants)
if (m_PassSettings.tileDebugByCategory == TileLightLoopProducer.TileSettings.TileDebug.FeatureVariants)
{
if (GetFeatureVariantsEnabled())
{

m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_TileSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_DebugViewTilesMaterial.SetBuffer("g_TileList", s_TileList);
m_DebugViewTilesMaterial.SetBuffer("g_DispatchIndirectBuffer", s_DispatchIndirectBuffer);

cmd.DrawProcedural(Matrix4x4.identity, m_DebugViewTilesMaterial, 0, MeshTopology.Triangles, numTiles * 6);
}
}
else if (m_TileSettings.tileDebugByCategory != TileSettings.TileDebug.None)
else if (m_PassSettings.tileDebugByCategory != TileLightLoopProducer.TileSettings.TileDebug.None)
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_TileSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");

cmd.Dispose();
}
public void RenderDeferredLighting( HDCamera hdCamera, ScriptableRenderContext renderContext,
DebugDisplaySettings debugDisplaySettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
bool outputSplitLightingForSSS)
public override void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
DebugDisplaySettings debugDisplaySettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
bool outputSplitLightingForSSS)
using (new Utilities.ProfilingSample((m_TileSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass") + (outputSplitLightingForSSS ? " MRT" : ""), renderContext))
using (new Utilities.ProfilingSample((m_PassSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass") + (outputSplitLightingForSSS ? " MRT" : ""), renderContext))
{
var cmd = new CommandBuffer();
cmd.name = bUseClusteredForDeferred ? "Clustered pass" : "Tiled pass";

SetupDebugDisplayMode(debugDisplaySettings.IsDebugDisplayEnabled());
if (!m_TileSettings.enableTileAndCluster)
if (!m_PassSettings.enableTileAndCluster)
{
PushGlobalParams(camera, renderContext, null, 0);

int numTilesY = (h + 15) / 16;
int numTiles = numTilesX * numTilesY;
if (m_TileSettings.enableComputeLightEvaluation)
if (m_PassSettings.enableComputeLightEvaluation)
{
bool enableFeatureVariants = GetFeatureVariantsEnabled() && !debugDisplaySettings.IsDebugDisplayEnabled();

cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture1", Shader.PropertyToID("_GBufferTexture1"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture2", Shader.PropertyToID("_GBufferTexture2"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture3", Shader.PropertyToID("_GBufferTexture3"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_AmbientOcclusionTexture", Shader.PropertyToID("_AmbientOcclusionTexture"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_LtcData", Shader.GetGlobalTexture(Shader.PropertyToID("_LtcData")));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_PreIntegratedFGD", Shader.GetGlobalTexture("_PreIntegratedFGD"));

// Pixel shader evaluation
PushGlobalParams(camera, renderContext, null, 0);
if (m_TileSettings.enableSplitLightEvaluation)
if (m_PassSettings.enableSplitLightEvaluation)
{
if (outputSplitLightingForSSS)
{

} // TilePass - Deferred Lighting Pass
}
public void RenderForward(Camera camera, ScriptableRenderContext renderContext, bool renderOpaque)
public override void RenderForward(Camera camera, ScriptableRenderContext renderContext, bool renderOpaque)
{
// Note: if we use render opaque with deferred tiling we need to render a opaque depth pass for these opaque objects
bool useFptl = renderOpaque && usingFptl;

if (!m_TileSettings.enableTileAndCluster)
if (!m_PassSettings.enableTileAndCluster)
{
cmd.name = "Forward pass";
cmd.EnableShaderKeyword("LIGHTLOOP_SINGLE_PASS");

cmd.Dispose();
}
public void RenderDebugOverlay(Camera camera, ScriptableRenderContext renderContext, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width)
public override void RenderDebugOverlay(Camera camera, ScriptableRenderContext renderContext, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width)
{
LightingDebugSettings lightingDebug = debugDisplaySettings.lightingDebugSettings;

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


struct LightLoopContext
{
// Visible from Material
float ambientOcclusion;
// Not visible from Material (user should not use these properties in Material)
int sampleShadow;
int sampleReflection;
ShadowContext shadowContext;

return SAMPLE_TEXTURECUBE_LOD(_SkyTexture, sampler_SkyTexture, texCoord, lod);
}
}
//-----------------------------------------------------------------------------
// AmbientOcclusion
// ----------------------------------------------------------------------------
TEXTURE2D(_AmbientOcclusionTexture);

32
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------

out float3 specularLighting)
{
LightLoopContext context;
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
context.ambientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.unPositionSS).x;
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Directional(context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Punctual(context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;

if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Line(context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Area(context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}

// TODO: currently apply GI at the same time as reflection
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting * context.ambientOcclusion;
diffuseLighting += bakeDiffuseLighting;
#endif
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);

out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
context.ambientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.unPositionSS).x;
LightLoopContext context;
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();

specularLighting += iblSpecularLighting;
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting * context.ambientOcclusion;
diffuseLighting += bakeDiffuseLighting;
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs


for (int i = 0; i < kMaxLayerCount; ++i)
{
NormalMapSpace normalMapSpace = ((NormalMapSpace)material.GetFloat(kNormalMapSpace + i));
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE" + i, ((NormalMapSpace)material.GetFloat(kNormalMapSpace + i)) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE" + i, normalMapSpace == NormalMapSpace.TangentSpace);
if (normalMapSpace == NormalMapSpace.TangentSpace)
{
SetKeyword(material, "_NORMALMAP" + i, material.GetTexture(kNormalMap + i) || material.GetTexture(kDetailMap + i));
}
else
{
SetKeyword(material, "_NORMALMAP" + i, material.GetTexture(kNormalMapOS + i) || material.GetTexture(kDetailMap + i));
}
SetKeyword(material, "_NORMALMAP" + i, material.GetTexture(kNormalMap + i));
SetKeyword(material, "_MASKMAP" + i, material.GetTexture(kMaskMap + i));

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_NormalMap2("NormalMap2", 2D) = "bump" {}
_NormalMap3("NormalMap3", 2D) = "bump" {}
_NormalMapOS0("NormalMapOS0", 2D) = "white" {}
_NormalMapOS1("NormalMapOS1", 2D) = "white" {}
_NormalMapOS2("NormalMapOS2", 2D) = "white" {}
_NormalMapOS3("NormalMapOS3", 2D) = "white" {}
_NormalScale0("_NormalScale0", Range(0.0, 2.0)) = 1
_NormalScale1("_NormalScale1", Range(0.0, 2.0)) = 1
_NormalScale2("_NormalScale2", Range(0.0, 2.0)) = 1

[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[ToggleOff] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0

#define DEBUG_DISPLAY
#define SHADERPASS SHADERPASS_FORWARD
#include "../../Debug/DebugDisplay.hlsl"
#include "../../Lighting/Forward.hlsl"
#include "../../Lighting/Forward.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader


_NormalMap2("NormalMap2", 2D) = "bump" {}
_NormalMap3("NormalMap3", 2D) = "bump" {}
_NormalMapOS0("NormalMapOS0", 2D) = "white" {}
_NormalMapOS1("NormalMapOS1", 2D) = "white" {}
_NormalMapOS2("NormalMapOS2", 2D) = "white" {}
_NormalMapOS3("NormalMapOS3", 2D) = "white" {}
_NormalScale0("_NormalScale0", Range(0.0, 2.0)) = 1
_NormalScale1("_NormalScale1", Range(0.0, 2.0)) = 1
_NormalScale2("_NormalScale2", Range(0.0, 2.0)) = 1

[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[ToggleOff] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0

42
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs


{
protected static class StylesBaseLit
{
public static GUIContent doubleSidedNormalModeText = new GUIContent("Normal mode", "This will modify the normal base on the selected mode. None: untouch, Mirror: Mirror the normal with vertex normal plane, Flip: Flip the normal");
public static GUIContent doubleSidedMirrorEnableText = new GUIContent("Mirror normal", "This will mirror the normal with vertex normal plane if enabled, else flip the normal");
public static GUIContent depthOffsetEnableText = new GUIContent("Enable Depth Offset", "EnableDepthOffset on this shader (Use with heightmap)");
// Material ID

public static string vertexAnimation = "Vertex Animation";
}
public enum DoubleSidedNormalMode
{
None,
Mirror,
Flip
}
public enum TessellationMode
{
Phong,

protected MaterialProperty doubleSidedNormalMode = null;
protected const string kDoubleSidedNormalMode = "_DoubleSidedNormalMode";
protected MaterialProperty doubleSidedMirrorEnable = null;
protected const string kDoubleSidedMirrorEnable = "_DoubleSidedMirrorEnable";
protected MaterialProperty depthOffsetEnable = null;
protected const string kDepthOffsetEnable = "_DepthOffsetEnable";

{
base.FindBaseMaterialProperties(props);
doubleSidedNormalMode = FindProperty(kDoubleSidedNormalMode, props);
doubleSidedMirrorEnable = FindProperty(kDoubleSidedMirrorEnable, props);
depthOffsetEnable = FindProperty(kDepthOffsetEnable, props);
// MaterialID

if (doubleSidedEnable.floatValue > 0.0f)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(doubleSidedNormalMode, StylesBaseLit.doubleSidedNormalModeText);
m_MaterialEditor.ShaderProperty(doubleSidedMirrorEnable, StylesBaseLit.doubleSidedMirrorEnableText);
EditorGUI.indentLevel--;
}

SetupBaseUnlitKeywords(material);
bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f;
bool doubleSidedMirrorEnable = material.GetFloat(kDoubleSidedMirrorEnable) > 0.0f;
DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode);
switch (doubleSidedNormalMode)
if (doubleSidedMirrorEnable)
case DoubleSidedNormalMode.None:
material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f));
break;
case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f));
break;
case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f));
break;
// Mirror mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f));
}
else
{
// Flip mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f));
// Depth offset is only enabled if per pixel displacement is
bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && (material.GetFloat(kEnablePerPixelDisplacement) > 0.0f);
bool depthOffsetEnable = material.GetFloat(kDepthOffsetEnable) > 0.0f;
SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable);
// Set the reference value for the stencil test.

58
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (BC7/BC5/DXT5(nm))");
public static GUIContent normalMapOSText = new GUIContent("Normal Map OS", "Normal Map (BC7/DXT1/RGB)");
public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent horizonFadeText = new GUIContent("Horizon Fade (Spec occlusion)", "horizon fade is use to control specular occlusion");

public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC7/BC5/DXT5(nm))");
public static GUIContent tangentMapOSText = new GUIContent("Tangent Map OS", "Tangent Map (BC7/DXT1/RGB)");
public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC5) - DXT5 for test");
public static GUIContent anisotropyText = new GUIContent("Anisotropy", "Anisotropy scale factor");
public static GUIContent anisotropyMapText = new GUIContent("Anisotropy Map (B)", "Anisotropy");

protected const string kHorizonFade = "_HorizonFade";
protected MaterialProperty normalMap = null;
protected const string kNormalMap = "_NormalMap";
protected MaterialProperty normalMapOS = null;
protected const string kNormalMapOS = "_NormalMapOS";
protected MaterialProperty normalScale = null;
protected const string kNormalScale = "_NormalScale";
protected MaterialProperty normalMapSpace = null;

protected const string kHeightCenter = "_HeightCenter";
protected MaterialProperty tangentMap = null;
protected const string kTangentMap = "_TangentMap";
protected MaterialProperty tangentMapOS = null;
protected const string kTangentMapOS = "_TangentMapOS";
protected MaterialProperty anisotropy = null;
protected const string kAnisotropy = "_Anisotropy";
protected MaterialProperty anisotropyMap = null;

specularOcclusionMap = FindProperty(kSpecularOcclusionMap, props);
horizonFade = FindProperty(kHorizonFade, props);
normalMap = FindProperty(kNormalMap, props);
normalMapOS = FindProperty(kNormalMapOS, props);
normalScale = FindProperty(kNormalScale, props);
normalMapSpace = FindProperty(kNormalMapSpace, props);
heightMap = FindProperty(kHeightMap, props);

tangentMapOS = FindProperty(kTangentMapOS, props);
anisotropy = FindProperty(kAnisotropy, props);
anisotropyMap = FindProperty(kAnisotropyMap, props);
specularColor = FindProperty(kSpecularColor, props);

protected void ShaderSSSInputGUI(Material material)
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if (subsurfaceProfile == null)
{

// Load the profile from the GUI field.
int profileID = subsurfaceProfile.settingsIndex;
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length &&
hdPipeline.sssSettings.profiles[profileID] != null &&
hdPipeline.sssSettings.profiles[profileID] == subsurfaceProfile)
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length)
{
validProfile = true;
material.SetInt("_SubsurfaceProfile", profileID);

if (!validProfile)
{
// Disable SSS for this object.
material.SetInt("_SubsurfaceProfile", SssConstants.SSS_NEUTRAL_PROFILE_ID);
material.SetInt("_SubsurfaceProfile", SubsurfaceScatteringSettings.neutralProfileID);
}
m_MaterialEditor.ShaderProperty(subsurfaceRadius, Styles.subsurfaceRadiusText);

protected void ShaderStandardInputGUI()
{
if ((NormalMapSpace)normalMapSpace.floatValue == NormalMapSpace.TangentSpace)
{
m_MaterialEditor.TexturePropertySingleLine(Styles.tangentMapText, tangentMap);
}
else
{
m_MaterialEditor.TexturePropertySingleLine(Styles.tangentMapOSText, tangentMapOS);
}
m_MaterialEditor.TexturePropertySingleLine(Styles.tangentMapText, tangentMap);
m_MaterialEditor.ShaderProperty(anisotropy, Styles.anisotropyText);
m_MaterialEditor.TexturePropertySingleLine(Styles.anisotropyMapText, anisotropyMap);
}

EditorGUILayout.HelpBox(Styles.normalMapSpaceWarning.text, MessageType.Error);
}
// We have two different property for object space and tangent space normal map to allow
// 1. to go back and forth
// 2. to avoid the warning that ask to fix the object normal map texture (normalOS are just linear RGB texture
if ((NormalMapSpace)normalMapSpace.floatValue == NormalMapSpace.TangentSpace)
{
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
}
else
{
// No scaling in object space
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapOSText, normalMapOS);
}
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap);
if (!heightMap.hasMixedValue && heightMap.textureValue != null)

SetupBaseLitKeywords(material);
SetupBaseLitMaterialPass(material);
NormalMapSpace normalMapSpace = (NormalMapSpace)material.GetFloat(kNormalMapSpace);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", (normalMapSpace == NormalMapSpace.TangentSpace));
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", ((NormalMapSpace)material.GetFloat(kNormalMapSpace)) == NormalMapSpace.TangentSpace);
if (normalMapSpace == NormalMapSpace.TangentSpace)
{
// With details map, we always use a normal map and Unity provide a default (0, 0, 1) normal map for it
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap) || material.GetTexture(kDetailMap));
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMap));
}
else // Object space
{
// With details map, we always use a normal map but in case of objects space there is no good default, so the result will be weird until users fix it
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMapOS) || material.GetTexture(kDetailMap));
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMapOS));
}
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap) || material.GetTexture(kDetailMap)); // With details map, we always use a normal map and Unity provide a default (0, 0, 1) normal map for ir
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMap));
SetKeyword(material, "_ANISOTROPYMAP", material.GetTexture(kAnisotropyMap));
SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));
SetKeyword(material, "_SUBSURFACE_RADIUS_MAP", material.GetTexture(kSubsurfaceRadiusMap));

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


public float subsurfaceRadius;
public float thickness;
public int subsurfaceProfile;
public bool enableTransmission; // Read from the SSS profile
public bool useThinObjectMode; // Read from the SSS profile
public Vector3 transmittance;
public TransmissionType transmissionType; // Compute from the SSS profile. 0 is none, 1 is regular transmission, 2 is thin transmission
public Vector3 transmittance; // Compute from SSS profile
// SpecColor
// fold into fresnel0

tex.SetPixels(pixels, arrayElement);
}
public void Build(RenderPipelineResources renderPipelineResources)
public void Build()
{
m_InitPreFGD = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/PreIntegratedFGD");

15
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl


#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_RADIUS (1042)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1043)
#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_PROFILE (1044)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION (1045)
#define DEBUGVIEW_LIT_BSDFDATA_USE_THIN_OBJECT_MODE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1047)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMISSION_TYPE (1045)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1046)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.GBufferMaterial: static fields

float subsurfaceRadius;
float thickness;
int subsurfaceProfile;
bool enableTransmission;
bool useThinObjectMode;
int transmissionType;
float3 transmittance;
};

case DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_PROFILE:
result = GetIndexColor(bsdfdata.subsurfaceProfile);
break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION:
result = (bsdfdata.enableTransmission) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_USE_THIN_OBJECT_MODE:
result = (bsdfdata.useThinObjectMode) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
case DEBUGVIEW_LIT_BSDFDATA_TRANSMISSION_TYPE:
result = GetIndexColor(bsdfdata.transmissionType);
break;
case DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE:
result = bsdfdata.transmittance;

140
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


#define LTC_LUT_SCALE ((LTC_LUT_SIZE - 1) * rcp(LTC_LUT_SIZE))
#define LTC_LUT_OFFSET (0.5 * rcp(LTC_LUT_SIZE))
#define MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV'
#define MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV'
// SSS parameters
#define CENTIMETERS_TO_METERS 0.01
uint _EnableSSS; // Globally toggles subsurface scattering on/off
uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
uint _TransmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
float _ThicknessRemaps[SSS_N_PROFILES][2]; // Remap: 0 = start, 1 = end - start
float4 _ShapeParameters[SSS_N_PROFILES]; // RGB = S = 1 / D; A = filter radius
float4 _SurfaceAlbedos[SSS_N_PROFILES]; // RGB = color, A = unused
uint _EnableSSS; // Globally toggles subsurface scattering on/off
uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
float _TransmissionType[SSS_PROFILES_MAX]; // transmissionType enum - TODO: no int array in Unity :(
float4 _TintColors[SSS_PROFILES_MAX]; // For transmission; alpha is unused
float _ThicknessRemaps[SSS_PROFILES_MAX][2]; // Remap: 0 = start, 1 = end - start
float4 _HalfRcpVariancesAndLerpWeights[SSS_PROFILES_MAX][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material

#endif
}
// Computes the fraction of light passing through the object.
// N.b.: it is not just zero scattering (light traveling in a straight path)!
// We derive the transmittance function from the SSS profile, by normalizing it s.t. R(0) = 1.
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar (BSSRDF only).
float3 ComputeTransmittance(float3 S, float3 surfaceAlbedo, float thickness, float radiusScale)
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians.
// Computes results for each color channel separately.
// Ref: Real-Time Realistic Skin Translucency (2010), equation 9 (modified).
float3 ComputeTransmittance(float3 halfRcpVariance1, float lerpWeight1,
float3 halfRcpVariance2, float lerpWeight2,
float3 tintColor, float thickness, float radiusScale)
thickness /= CENTIMETERS_TO_METERS;
float3 expOneThird = exp(((-1.0 / 3.0) * thickness) * S);
float t2 = thickness * thickness;
return 0.5 * (expOneThird + expOneThird * expOneThird * expOneThird) * surfaceAlbedo;
// TODO: 6 exponentials is kind of expensive... Should we use a LUT instead?
// T = lerp(exp(-t2 * halfRcpVariance1), exp(-t2 * halfRcpVariance2), lerpWeight2)
float3 transmittance = exp(-t2 * halfRcpVariance1) * lerpWeight1
+ exp(-t2 * halfRcpVariance2) * lerpWeight2;
return transmittance * tintColor;
}
void FillMaterialIdStandardData(float3 baseColor, float specular, float metallic, float roughness, float3 normalWS, float3 tangentWS, float anisotropy, inout BSDFData bsdfData)

// TODO take from subsurfaceProfile
bsdfData.fresnel0 = 0.04; // Should be 0.028 for the skin
bsdfData.subsurfaceProfile = subsurfaceProfile;
bsdfData.subsurfaceRadius = subsurfaceRadius;
bsdfData.thickness = _ThicknessRemaps[subsurfaceProfile][0] +
_ThicknessRemaps[subsurfaceProfile][1] * thickness;
bsdfData.subsurfaceRadius = CENTIMETERS_TO_METERS * subsurfaceRadius + 0.0001;
bsdfData.thickness = CENTIMETERS_TO_METERS * (_ThicknessRemaps[subsurfaceProfile][0] +
_ThicknessRemaps[subsurfaceProfile][1] * thickness);
uint transmissionMode = BitFieldExtract(_TransmissionFlags, 2u, 2u * subsurfaceProfile);
bsdfData.transmissionType = (int)_TransmissionType[subsurfaceProfile];
bsdfData.enableTransmission = transmissionMode != SSS_TRSM_MODE_NONE;
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
if (bsdfData.enableTransmission)
if (bsdfData.transmissionType != TRANSMISSIONTYPE_NONE)
bsdfData.transmittance = ComputeTransmittance(_ShapeParameters[subsurfaceProfile].rgb,
_SurfaceAlbedos[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
bsdfData.transmittance = ComputeTransmittance( _HalfRcpVariancesAndLerpWeights[subsurfaceProfile][0].xyz,
_HalfRcpVariancesAndLerpWeights[subsurfaceProfile][0].w,
_HalfRcpVariancesAndLerpWeights[subsurfaceProfile][1].xyz,
_HalfRcpVariancesAndLerpWeights[subsurfaceProfile][1].w,
_TintColors[subsurfaceProfile].rgb, bsdfData.thickness, bsdfData.subsurfaceRadius);
#ifndef SSS_FILTER_HORIZONTAL_AND_COMBINE // When doing the SSS comine pass, we must not apply the modification of diffuse color
// Handle post-scatter, or pre- and post-scatter texturing.
// We modify diffuseColor here so it affect all the lighting + GI (lightprobe / lightmap) (Need to be done also in GBuffer pass) + transmittance
// diffuseColor will be solely use during lighting pass. The other contribution will be apply in subsurfacescattering convolution.
// We modify the albedo here as this code is used by all lighting (including light maps and GI).
if (performPostScatterTexturing)
{
#ifndef SSS_PASS
bsdfData.diffuseColor = float3(1.0, 1.0, 1.0);
bsdfData.diffuseColor = performPostScatterTexturing ? float3(1.0, 1.0, 1.0) : sqrt(bsdfData.diffuseColor);
}
else
{
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
}
}
//-----------------------------------------------------------------------------

}
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
// Use 16 bits to encode the thickness, and up to 8 bits to encode the profile ID.
// We need a lot of precision to minimize banding of NdotV-weighted thickness.
outGBuffer2 = float4(surfaceData.subsurfaceRadius,
PackFloatToR8G8(surfaceData.thickness),
PackByte(surfaceData.subsurfaceProfile));
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_PROFILES_MAX - 1));
}
else if (surfaceData.materialId == MATERIALID_LIT_SPECULAR)
{

bsdfData.specularOcclusion = inGBuffer0.a;
#ifdef USE_NORMAL_TETRAHEDRON_ENCODING
int faceIndex;
uint faceIndex;
int octNormalSign;
uint octNormalSign;
UnpackFloatInt10bit(inGBuffer1.b, 4.0, bsdfData.perceptualRoughness, octNormalSign);
inGBuffer1.r *= (octNormalSign & 1) ? 1.0 : -1.0;
inGBuffer1.g *= (octNormalSign & 2) ? 1.0 : -1.0;

}
else if (supportsSSS && bsdfData.materialId == MATERIALID_LIT_SSS)
{
// Use 16 bits to encode the thickness, and up to 8 bits to encode the profile ID.
// We need a lot of precision to minimize banding of NdotV-weighted thickness.
float subsurfaceRadius = inGBuffer2.x;
float thickness = UnpackFloatFromR8G8(inGBuffer2.yz);
int subsurfaceProfile = UnpackByte(inGBuffer2.w);
int subsurfaceProfile = (SSS_PROFILES_MAX - 0.9) * inGBuffer2.a;
float subsurfaceRadius = inGBuffer2.r;
float thickness = inGBuffer2.g;
FillMaterialIdSSSData(baseColor, subsurfaceProfile, subsurfaceRadius, thickness, bsdfData);
}
else if (supportsSpecular && bsdfData.materialId == MATERIALID_LIT_SPECULAR)

specularLighting *= (cookie.rgb * lightData.color) * (illuminance * lightData.specularScale);
}
[branch] if (bsdfData.enableTransmission)
[branch] if (bsdfData.transmissionType != TRANSMISSIONTYPE_NONE)
float LdotV = dot(L, V); // Also computed in BSDF()
// Compute the normal at the back of the object as R = reflect(N, -V)
// float RdotL = NdotL - 2 * preLightData.NdotV * LdotV;
float illuminance = saturate(-LdotV);
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
// For thin material we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.transmissionType == TRANSMISSIONTYPE_THIN_OBJECT) ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.

specularLighting *= (cookie.rgb * lightData.color) * (illuminance * lightData.specularScale);
}
[branch] if (bsdfData.enableTransmission)
[branch] if (bsdfData.transmissionType != TRANSMISSIONTYPE_NONE)
float LdotV = dot(L, V); // Also computed in BSDF()
// Compute the normal at the back of the object as R = reflect(N, -V)
// float RdotL = NdotL - 2 * preLightData.NdotV * LdotV;
float illuminance = saturate(-LdotV * attenuation);
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
illuminance *= attenuation;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
// For thin material we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.transmissionType == TRANSMISSIONTYPE_THIN_OBJECT) ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.

specularLighting *= (cookie.rgb * lightData.color) * (illuminance * lightData.specularScale);
}
[branch] if (bsdfData.enableTransmission)
[branch] if (bsdfData.transmissionType != TRANSMISSIONTYPE_NONE)
float LdotV = dot(L, V); // Also computed in BSDF()
// Compute the normal at the back of the object as R = reflect(N, -V)
// float RdotL = NdotL - 2 * preLightData.NdotV * LdotV;
float illuminance = saturate(-LdotV * clipFactor);
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
illuminance *= clipFactor;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
// For thin material we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.transmissionType == TRANSMISSIONTYPE_THIN_OBJECT) ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.

specularLighting = preLD.rgb * preLightData.specularFGD;
// Apply specular occlusion on it
specularLighting *= bsdfData.specularOcclusion * GetSpecularOcclusion(preLightData.NdotV, lightLoopContext.ambientOcclusion, bsdfData.roughness);
specularLighting *= bsdfData.specularOcclusion;
diffuseLighting = float3(0.0, 0.0, 0.0);
#endif

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


_SpecularOcclusionMap("SpecularOcclusion", 2D) = "white" {}
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map
_NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value
_NormalMap("NormalMap", 2D) = "bump" {}
_NormalScale("_NormalScale", Range(0.0, 2.0)) = 1
_HeightMap("HeightMap", 2D) = "black" {}

_DetailSmoothnessScale("_DetailSmoothnessScale", Range(-2.0, 2.0)) = 1
_TangentMap("TangentMap", 2D) = "bump" {}
_TangentMapOS("TangentMapOS", 2D) = "white" {}
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}

[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[ToggleOff] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _UVBase("UV Set for base", Float) = 0

46
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


#ifndef LAYERED_LIT_SHADER
// Want to use only one sampler for normalmap either we use OS or TS.
#ifdef _NORMALMAP_TANGENT_SPACE
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS
#endif
#define SAMPLER_DETAILMASK_IDX sampler_DetailMask
#define SAMPLER_DETAILMAP_IDX sampler_DetailMap
#define SAMPLER_MASKMAP_IDX sampler_MaskMap

ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
float3 interpolatedVertexNormal = input.worldToTangent[2].xyz;
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;

surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, interpolatedVertexNormal, _HorizonFade);
uint transmissionMode = BitFieldExtract(_TransmissionFlags, 2u, 2u * surfaceData.subsurfaceProfile);
if (transmissionMode != SSS_TRSM_MODE_THIN)
{
// Convert thickness along the normal to thickness along the viewing direction.
// We assume that the thickness along the normal corresponds to the diameter of a sphere.
// We then find a position on the sphere which corresponds to the normal, and
// compute the length of the chord of the sphere along the viewing direction.
// We add a small bias to (hopefully) have non-zero thickness.
surfaceData.thickness *= saturate(dot(interpolatedVertexNormal, V) + 0.01);
}
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.worldToTangent[2].xyz, _HorizonFade);
// Caution: surfaceData must be fully initialize before calling GetBuiltinData
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);

// for this we put the constraint that the sampler are the same in a layered material for all textures of the same type
// then we take the sampler matching the first textures use of this type
#if defined(_NORMALMAP0)
#if defined(_NORMALMAP_TANGENT_SPACE0)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap0
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS0
#endif
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap0
#if defined(_NORMALMAP_TANGENT_SPACE1)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap1
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS1
#endif
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap1
#if defined(_NORMALMAP_TANGENT_SPACE2)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap2
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS2
#endif
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap2
#if defined(_NORMALMAP_TANGENT_SPACE3)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap3
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS3
#endif
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap3
#endif
#if defined(_DETAIL_MAP0)

26
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


normalTS = SAMPLE_UVMAPPING_NORMALMAP(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base), ADD_IDX(_NormalScale));
}
#else // Object space
// We forbid scale in case of object space as it make no sense
// To be able to combine object space normal with detail map then later we will re-transform it to world space.
// to be able to combine object space normal with detail map or to apply a "scale" we transform it to tangent space (object space normal composition is complex operation).
// then later we will re-transform it to world space.
float3 normalOS = SAMPLE_TEXTURE2D_BIAS(ADD_IDX(_NormalMapOS), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias).xyz * 2.0 - 1.0;
// no need to renormalize normalOS for SurfaceGradientFromPerturbedNormal
float3 normalOS = SAMPLE_TEXTURE2D_BIAS(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias).xyz * 2.0 - 1.0;
// normalize(normalOS) // TO CHECK: SurfaceGradientFromPerturbedNormal doesn't require normalOS to be normalize, to check
normalTS *= ADD_IDX(_NormalScale);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D_BIAS(ADD_IDX(_NormalMapOS), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias), 1.0);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D_BIAS(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias), 1.0);
normalTS.xy *= ADD_IDX(_NormalScale); // Scale in tangent space
normalTS = (normalTS);
#endif
}
else

float3 normalOS = SAMPLE_TEXTURE2D(ADD_IDX(_NormalMapOS), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv).xyz * 2.0 - 1.0;
// no need to renormalize normalOS for SurfaceGradientFromPerturbedNormal
normalTS = SurfaceGradientFromPerturbedNormal(input.worldToTangent[2], TransformObjectToWorldDir(normalOS));
float3 normalOS = SAMPLE_TEXTURE2D(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv).xyz * 2.0 - 1.0;
// normalize(normalOS) // TO CHECK: SurfaceGradientFromPerturbedNormal doesn't require normalOS to be normalize, to check
normalTS = SurfaceGradientFromPerturbedNormal(input.worldToTangent[2], normalOS);
normalTS *= ADD_IDX(_NormalScale);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(ADD_IDX(_NormalMapOS), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv), 1.0);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv), 1.0);
normalTS.xy *= ADD_IDX(_NormalScale); // Scale in tangent space
normalTS = (normalTS);
#endif
}
#endif

surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.worldToTangent);
#else // Object space
// Note: There is no such a thing like triplanar with object space normal, so we call directly 2D function
float3 tangentOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(_TangentMapOS, sampler_TangentMapOS, layerTexCoord.base.uv), 1.0);
float3 tangentOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(_TangentMap, sampler_TangentMap, layerTexCoord.base.uv), 1.0);
surfaceData.tangentWS = TransformObjectToWorldDir(tangentOS);
#endif
#else

24
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl


TEXTURE2D(_NormalMap);
SAMPLER2D(sampler_NormalMap);
TEXTURE2D(_NormalMapOS);
SAMPLER2D(sampler_NormalMapOS);
float _NormalScale;
TEXTURE2D(_DetailMask);

TEXTURE2D(_TangentMap);
SAMPLER2D(sampler_TangentMap);
TEXTURE2D(_TangentMapOS);
SAMPLER2D(sampler_TangentMapOS);
float _Anisotropy;
TEXTURE2D(_AnisotropyMap);

#else // LAYERED_LIT_SHADER
// Set of users variables
#define PROP_DECL(type, name) type name, name##0, name##1, name##2, name##3
#define PROP_DECL(type, name) type name, name##0, name##1, name##2, name##3;
TEXTURE2D(MERGE_NAME(name, 0)); \
SAMPLER2D(MERGE_NAME(MERGE_NAME(sampler, name), 0)); \
TEXTURE2D(MERGE_NAME(name, 1)); \
SAMPLER2D(MERGE_NAME(MERGE_NAME(sampler, name), 1)); \
TEXTURE2D(MERGE_NAME(name, 2)); \
SAMPLER2D(MERGE_NAME(MERGE_NAME(sampler, name), 2)); \
TEXTURE2D(MERGE_NAME(name, 3)); \
SAMPLER2D(MERGE_NAME(MERGE_NAME(sampler, name), 3))
TEXTURE2D(name##0); \
SAMPLER2D(sampler##name##0); \
TEXTURE2D(name##1); \
SAMPLER2D(sampler##name##1); \
TEXTURE2D(name##2); \
SAMPLER2D(sampler##name##2); \
TEXTURE2D(name##3); \
SAMPLER2D(sampler##name##3);
// Set of users variables
PROP_DECL(float4, _BaseColor);

PROP_DECL_TEX2D(_SpecularOcclusionMap);
PROP_DECL_TEX2D(_NormalMap);
PROP_DECL_TEX2D(_NormalMapOS);
PROP_DECL(float, _NormalScale);
float4 _NormalMap0_TexelSize; // Unity facility. This will provide the size of the base normal to the shader

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader


_SpecularOcclusionMap("SpecularOcclusion", 2D) = "white" {}
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map
_NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value
_NormalMap("NormalMap", 2D) = "bump" {}
_NormalScale("_NormalScale", Range(0.0, 2.0)) = 1
_HeightMap("HeightMap", 2D) = "black" {}

_DetailSmoothnessScale("_DetailSmoothnessScale", Range(-2.0, 2.0)) = 1
_TangentMap("TangentMap", 2D) = "bump" {}
_TangentMapOS("TangentMapOS", 2D) = "white" {}
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}

[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[ToggleOff] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _UVBase("UV Set for base", Float) = 0

177
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


Cull Off
ZTest Always
ZWrite Off
Blend One One
Blend One [_DstBlend]
#pragma enable_d3d11_debug_symbols
// #pragma enable_d3d11_debug_symbols
#define SSS_PASS
#define MILLIMETERS_PER_METER 1000
#pragma multi_compile _ SSS_FILTER_HORIZONTAL_AND_COMBINE
#pragma multi_compile _ DEBUG_DISPLAY
//-------------------------------------------------------------------------------------
// Include

#include "../../../Debug/DebugDisplay.hlsl"
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#define UNITY_MATERIAL_LIT // Needs to be defined before including Material.hlsl

// Inputs & outputs
//-------------------------------------------------------------------------------------
float _WorldScales[SSS_N_PROFILES]; // Size of the world unit in meters
float _FilterKernelsNearField[SSS_N_PROFILES][SSS_N_SAMPLES_NEAR_FIELD][2]; // 0 = radius, 1 = reciprocal of the PDF
float _FilterKernelsFarField[SSS_N_PROFILES][SSS_N_SAMPLES_FAR_FIELD][2]; // 0 = radius, 1 = reciprocal of the PDF
#define N_PROFILES 8
#define N_SAMPLES 11
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
TEXTURE2D(_IrradianceSource); // Includes transmitted light
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters
TEXTURE2D(_IrradianceSource); // RGB = irradiance on the back side of the object
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal().
// N.b.: the returned value is multiplied by 4. It is irrelevant due to weight renormalization.
float3 KernelValCircle(float r, float3 S)
{
float3 expOneThird = exp(((-1.0 / 3.0) * r) * S);
return /* 0.25 * */ S * (expOneThird + expOneThird * expOneThird * expOneThird);
}
// Computes F(x)/P(x), s.t. x = sqrt(r^2 + z^2).
float3 ComputeBilateralWeight(float3 S, float r, float z, float rcpDistScale, float rcpPdf)
{
// Reducing the integration distance is equivalent to stretching the integration axis.
float3 valX = KernelValCircle(sqrt(r * r + z * z) * rcpDistScale, S);
// The reciprocal of the PDF could be reinterpreted as a 'dx' term in Int{F(x)dx}.
// As we shift the location of the value on the curve during integration,
// the length of the segment 'dx' under the curve changes approximately linearly.
float rcpPdfX = rcpPdf * (1 + abs(z) / r);
return valX * rcpPdfX;
}
struct Attributes
{
uint vertexID : SV_VertexID;

FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
DECODE_FROM_GBUFFER(gbuffer, 0xFFFFFFFF, bsdfData, unused);
int profileID = bsdfData.subsurfaceProfile;
float distScale = bsdfData.subsurfaceRadius;
float3 shapeParam = _ShapeParameters[profileID].rgb;
float maxDistance = _ShapeParameters[profileID].a;
int profileID = bsdfData.subsurfaceProfile;
float distScale = bsdfData.subsurfaceRadius;
float invDistScale = rcp(distScale);
float2 cornerPosSS = posInput.positionSS + 0.5 * _ScreenSize.zw;
float3 cornerPosVS = ComputeViewSpacePosition(cornerPosSS, rawDepth, _InvProjMatrix);
// Compute the view-space dimensions of the pixel as a quad projected onto geometry.
float2 unitsPerPixel = 2 * (cornerPosVS.xy - centerPosVS.xy);
float metersPerUnit = _WorldScales[profileID];
float millimPerUnit = MILLIMETERS_PER_METER * metersPerUnit;
float2 scaledPixPerMm = distScale * rcp(millimPerUnit * unitsPerPixel);
// Compute the dimensions of the surface fragment viewed as a quad facing the camera.
float fragWidth = ddx_fine(centerPosVS.x);
float fragheight = ddy_fine(centerPosVS.y);
float stepSizeX = rcp(fragWidth);
float stepSizeY = rcp(fragheight);
// Compute the filtering direction.
#ifdef SSS_FILTER_HORIZONTAL_AND_COMBINE
float stepSize = stepSizeX;
float2 unitDirection = float2(1, 0);
#else
float stepSize = stepSizeY;
float2 unitDirection = float2(0, 1);
#endif
float2 scaledDirection = distScale * stepSize * unitDirection;
float phi = 0; // Random rotation; unused for now
float2x2 rotationMatrix = float2x2(cos(phi), -sin(phi), sin(phi), cos(phi));
float2 rotatedDirection = mul(rotationMatrix, scaledDirection);
// Load (1 / (2 * WeightedVariance)) for bilateral weighting.
#ifdef RBG_BILATERAL_WEIGHTS
float3 halfRcpVariance = _HalfRcpWeightedVariances[profileID].rgb;
#else
float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;
#endif
float3 sampleWeight = _FilterKernels[profileID][0].rgb;
// We perform point sampling. Therefore, we can avoid the cost
// of filtering if we stay within the bounds of the current pixel.
[branch]
if (maxDistance * max(scaledPixPerMm.x, scaledPixPerMm.y) < 0.5)
{
return float4(bsdfData.diffuseColor * sampleIrradiance, 1);
}
// Accumulate filtered irradiance.
float3 totalIrradiance = sampleWeight * sampleIrradiance;
bool useNearFieldKernel = true; // TODO
// Make sure bilateral filtering does not cause energy loss.
// TODO: ask Morten if there is a better way to do this.
float3 totalWeight = sampleWeight;
if (useNearFieldKernel)
[unroll]
for (int i = 1; i < N_SAMPLES; i++)
float sampleRcpPdf = _FilterKernelsNearField[profileID][0][1];
float3 sampleWeight = KernelValCircle(0, shapeParam) * sampleRcpPdf;
samplePosition = posInput.unPositionSS + rotatedDirection * _FilterKernels[profileID][i].a;
sampleWeight = _FilterKernels[profileID][i].rgb;
// Accumulate filtered irradiance and bilateral weights (for renormalization).
float3 totalIrradiance = sampleWeight * sampleIrradiance;
float3 totalWeight = sampleWeight;
rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
// Perform integration over the screen-aligned plane in the view space.
// TODO: it would be more accurate to use the tangent plane in the world space.
// Apply bilateral weighting.
// Ref #1: Skin Rendering by Pseudo–Separable Cross Bilateral Filtering.
// Ref #2: Separable SSS, Supplementary Materials, Section E.
float sampleDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float zDistance = invDistScale * sampleDepth - (invDistScale * centerPosVS.z);
sampleWeight *= exp(-zDistance * zDistance * halfRcpVariance);
[unroll]
for (uint i = 1; i < SSS_N_SAMPLES_NEAR_FIELD; i++)
if (any(sampleIrradiance) == false)
// Everything except for the radius is a compile-time constant.
float r = _FilterKernelsNearField[profileID][i][0];
float phi = TWO_PI * Fibonacci2d(i, SSS_N_SAMPLES_NEAR_FIELD).y;
float2 pos = r * float2(cos(phi), sin(phi));
samplePosition = posInput.unPositionSS + pos * scaledPixPerMm;
sampleRcpPdf = _FilterKernelsNearField[profileID][i][1];
rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
[flatten]
if (any(sampleIrradiance) == false)
{
// The irradiance is 0. This could happen for 3 reasons.
// Most likely, the surface fragment does not have an SSS material.
// Alternatively, our sample comes from a region without any geometry.
// Finally, the surface fragment could be completely shadowed.
// Our blur is energy-preserving, so 'sampleWeight' should be set to 0.
// We do not terminate the loop since we want to gather the contribution
// of the remaining samples (e.g. in case of hair covering skin).
continue;
}
// Apply bilateral weighting.
float sampleZ = LinearEyeDepth(rawDepth, _ZBufferParams);
float z = millimPerUnit * sampleZ - (millimPerUnit * centerPosVS.z);
sampleWeight = ComputeBilateralWeight(shapeParam, r, z, rcp(distScale), sampleRcpPdf);
totalIrradiance += sampleWeight * sampleIrradiance;
totalWeight += sampleWeight;
// The irradiance is 0. This could happen for 2 reasons.
// Most likely, the surface fragment does not have an SSS material.
// Alternatively, the surface fragment could be completely shadowed.
// Our blur is energy-preserving, so 'sampleWeight' should be set to 0.
// We do not terminate the loop since we want to gather the contribution
// of the remaining samples (e.g. in case of hair covering skin).
continue;
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
}
else
{
return float4(0, 0, 0, 1); // TODO
totalIrradiance += sampleWeight * sampleIrradiance;
totalWeight += sampleWeight;
#ifdef SSS_FILTER_HORIZONTAL_AND_COMBINE
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, profileID);
// It's either post-scatter, or pre- and post-scatter texturing.
float3 diffuseContrib = performPostScatterTexturing ? bsdfData.diffuseColor
: sqrt(bsdfData.diffuseColor);
return float4(diffuseContrib * totalIrradiance / totalWeight, 1.0);
#else
return float4(totalIrradiance / totalWeight, 1.0);
#endif
}
ENDHLSL
}

549
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


using System;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor;
public class SssConstants
public class SSSConstants
public const int SSS_N_PROFILES = 8; // Max. number of profiles, including the slot taken by the neutral profile
public const int SSS_NEUTRAL_PROFILE_ID = SSS_N_PROFILES - 1; // Does not result in blurring
public const int SSS_N_SAMPLES_NEAR_FIELD = 55; // Used for extreme close ups; must be a Fibonacci number
public const int SSS_N_SAMPLES_FAR_FIELD = 34; // Used at a regular distance; must be a Fibonacci number
public const int SSS_TRSM_MODE_NONE = 0;
public const int SSS_TRSM_MODE_THIN = 1;
public const int SSS_PROFILES_MAX = 8;
public enum TexturingMode : uint { PreAndPostScatter = 0, PostScatter = 1 };
public enum TransmissionMode : uint { None = SssConstants.SSS_TRSM_MODE_NONE, ThinObject = SssConstants.SSS_TRSM_MODE_THIN, Regular };
public enum TexturingMode : int { PreAndPostScatter = 0, PostScatter = 1 };
public const int numSamples = 11; // Must be an odd number
public Color surfaceAlbedo; // Color, 0 to 1
public float lenVolMeanFreePath; // Length of the volume mean free path (in millimeters)
[ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color scatterDistance1;
[ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color scatterDistance2;
public float lerpWeight;
public TransmissionMode transmissionMode;
public Vector2 thicknessRemap; // X = min, Y = max (in millimeters)
public float worldScale; // Size of the world unit in meters
public bool enableTransmission;
public bool enableThinObject;
public Color tintColor;
public Vector2 thicknessRemap;
public int settingsIndex; // SubsurfaceScatteringSettings.profiles[i]
public int settingsIndex;
Vector3 m_S; // RGB = shape parameter: S = 1 / D
Vector4[] m_FilterKernel;
float m_ScatteringDistance; // Filter radius (in millimeters)
Vector3[] m_HalfRcpVariances;
Vector2[] m_FilterKernelNearField; // X = radius, Y = reciprocal of the PDF
[SerializeField]
Vector2[] m_FilterKernelFarField; // X = radius, Y = reciprocal of the PDF
Vector4 m_HalfRcpWeightedVariances;
surfaceAlbedo = Color.white;
lenVolMeanFreePath = 0.5f;
texturingMode = TexturingMode.PreAndPostScatter;
transmissionMode = TransmissionMode.None;
thicknessRemap = new Vector2(0.0f, 5.0f);
worldScale = 1.0f;
settingsIndex = SssConstants.SSS_NEUTRAL_PROFILE_ID; // Updated by SubsurfaceScatteringSettings.OnValidate() once assigned
scatterDistance1 = new Color(0.3f, 0.3f, 0.3f, 0.0f);
scatterDistance2 = new Color(0.6f, 0.6f, 0.6f, 0.0f);
lerpWeight = 0.5f;
texturingMode = TexturingMode.PreAndPostScatter;
enableTransmission = false;
enableThinObject = false;
tintColor = Color.white;
thicknessRemap = new Vector2(0, 1);
settingsIndex = SubsurfaceScatteringSettings.neutralProfileID; // Updated by SubsurfaceScatteringSettings.OnValidate() once assigned
BuildKernel();
UpdateKernelAndVarianceData();
}
public Vector4[] filterKernel
{
// Set via UpdateKernelAndVarianceData().
get { return m_FilterKernel; }
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar.
public void BuildKernel()
public Vector3[] halfRcpVariances
if (m_FilterKernelNearField == null || m_FilterKernelNearField.Length != SssConstants.SSS_N_SAMPLES_NEAR_FIELD)
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpVariances; }
}
public Vector4 halfRcpWeightedVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpWeightedVariances; }
}
public void UpdateKernelAndVarianceData()
{
if (m_FilterKernel == null || m_FilterKernel.Length != numSamples)
m_FilterKernelNearField = new Vector2[SssConstants.SSS_N_SAMPLES_NEAR_FIELD];
m_FilterKernel = new Vector4[numSamples];
if (m_FilterKernelFarField == null || m_FilterKernelFarField.Length != SssConstants.SSS_N_SAMPLES_FAR_FIELD)
if (m_HalfRcpVariances == null)
m_FilterKernelFarField = new Vector2[SssConstants.SSS_N_SAMPLES_FAR_FIELD];
m_HalfRcpVariances = new Vector3[2];
m_S = new Vector3();
// Apply the three-sigma rule.
Color stdDev1 = scatterDistance1 * (1.0f / 3.0f);
Color stdDev2 = scatterDistance2 * (1.0f / 3.0f);
// Our goal is to blur the image using a filter which is represented
// as a product of a linear combination of two normalized 1D Gaussians
// as suggested by Jimenez et al. in "Separable Subsurface Scattering".
// A normalized (i.e. energy-preserving) 1D Gaussian with the mean of 0
// is defined as follows: G1(x, v) = exp(-x * x / (2 * v)) / sqrt(2 * Pi * v),
// where 'v' is variance and 'x' is the radial distance from the origin.
// Using the weight 'w', our 1D and the resulting 2D filters are given as:
// A1(v1, v2, w, x) = G1(x, v1) * (1 - w) + G1(r, v2) * w,
// A2(v1, v2, w, x, y) = A1(v1, v2, w, x) * A1(v1, v2, w, y).
// The resulting filter function is a non-Gaussian PDF.
// It is separable by design, but generally not radially symmetric.
// Evaluate the fit for diffuse surface transmission.
m_S.x = FindFitForS(surfaceAlbedo.r);
m_S.y = FindFitForS(surfaceAlbedo.g);
m_S.z = FindFitForS(surfaceAlbedo.b);
// Find the widest Gaussian across 3 color channels.
float maxStdDev1 = Mathf.Max(stdDev1.r, stdDev1.g, stdDev1.b);
float maxStdDev2 = Mathf.Max(stdDev2.r, stdDev2.g, stdDev2.b);
// Compute { 1 / D = S / L } as you can substitute s = 1 / d in all formulas.
m_S.x *= 1.0f / lenVolMeanFreePath;
m_S.y *= 1.0f / lenVolMeanFreePath;
m_S.z *= 1.0f / lenVolMeanFreePath;
Vector3 weightSum = new Vector3(0, 0, 0);
// We importance sample the color channel with the highest albedo value,
// since higher albedo values result in scattering over a larger distance.
// S(A) is a monotonically decreasing function.
float s = Mathf.Min(m_S.x, m_S.y, m_S.z);
float rcpNumSamples = 1.0f / numSamples;
// Importance sample the normalized diffusion profile for the computed value of 's'.
// ------------------------------------------------------------------------------------
// R(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / (8 * Pi * r)
// PDF(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / 4
// CDF(r, s) = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]
// ------------------------------------------------------------------------------------
// Importance sample the near field kernel.
for (int i = 0; i < SssConstants.SSS_N_SAMPLES_NEAR_FIELD; i++)
// Importance sample the linear combination of two Gaussians.
for (uint i = 0; i < numSamples; i++)
float p = i * (1.0f / SssConstants.SSS_N_SAMPLES_NEAR_FIELD);
float r = KernelCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo
// of the actual geometry is performed at runtime (in the shader).
m_FilterKernelNearField[i].x = r;
m_FilterKernelNearField[i].y = 1.0f / KernelPdf(r, s);
}
float u = (i <= numSamples / 2) ? 0.5f - i * rcpNumSamples // The center and to the left
: (i + 0.5f) * rcpNumSamples; // From the center to the right
m_ScatteringDistance = m_FilterKernelNearField[SssConstants.SSS_N_SAMPLES_NEAR_FIELD - 1].x;
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, lerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, lerpWeight);
// TODO: far field.
}
Vector3 val;
val.x = GaussianCombination(pos, stdDev1.r, stdDev2.r, lerpWeight);
val.y = GaussianCombination(pos, stdDev1.g, stdDev2.g, lerpWeight);
val.z = GaussianCombination(pos, stdDev1.b, stdDev2.b, lerpWeight);
public Vector3 shapeParameter
{
// Set in BuildKernel().
get { return m_S; }
}
// We do not divide by 'numSamples' since we will renormalize, anyway.
m_FilterKernel[i].x = val.x * (1 / pdf);
m_FilterKernel[i].y = val.y * (1 / pdf);
m_FilterKernel[i].z = val.z * (1 / pdf);
m_FilterKernel[i].w = pos;
public float scatteringDistance
{
// Set in BuildKernel().
get { return m_ScatteringDistance; }
}
weightSum.x += m_FilterKernel[i].x;
weightSum.y += m_FilterKernel[i].y;
weightSum.z += m_FilterKernel[i].z;
}
public Vector2[] filterKernelNearField
{
// Set in BuildKernel().
get { return m_FilterKernelNearField; }
}
public Vector2[] filterKernelFarField
{
// Set in BuildKernel().
get { return m_FilterKernelFarField; }
}
// Renormalize the weights to conserve energy.
for (uint i = 0; i < numSamples; i++)
{
m_FilterKernel[i].x *= 1 / weightSum.x;
m_FilterKernel[i].y *= 1 / weightSum.y;
m_FilterKernel[i].z *= 1 / weightSum.z;
}
// --- Private Methods ---
// Store (1 / (2 * Variance)) per color channel per Gaussian.
m_HalfRcpVariances[0].x = 0.5f / (stdDev1.r * stdDev1.r);
m_HalfRcpVariances[0].y = 0.5f / (stdDev1.g * stdDev1.g);
m_HalfRcpVariances[0].z = 0.5f / (stdDev1.b * stdDev1.b);
m_HalfRcpVariances[1].x = 0.5f / (stdDev2.r * stdDev2.r);
m_HalfRcpVariances[1].y = 0.5f / (stdDev2.g * stdDev2.g);
m_HalfRcpVariances[1].z = 0.5f / (stdDev2.b * stdDev2.b);
static float FindFitForS(float A)
{
return 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
}
Vector4 weightedStdDev;
weightedStdDev.x = Mathf.Lerp(stdDev1.r, stdDev2.r, lerpWeight);
weightedStdDev.y = Mathf.Lerp(stdDev1.g, stdDev2.g, lerpWeight);
weightedStdDev.z = Mathf.Lerp(stdDev1.b, stdDev2.b, lerpWeight);
weightedStdDev.w = Mathf.Lerp(maxStdDev1, maxStdDev2, lerpWeight);
static float KernelVal(float r, float s)
{
return s * (Mathf.Exp(-r * s) + Mathf.Exp(-r * s * (1.0f / 3.0f))) / (8.0f * Mathf.PI * r);
// Store (1 / (2 * WeightedVariance)) per color channel.
m_HalfRcpWeightedVariances.x = 0.5f / (weightedStdDev.x * weightedStdDev.x);
m_HalfRcpWeightedVariances.y = 0.5f / (weightedStdDev.y * weightedStdDev.y);
m_HalfRcpWeightedVariances.z = 0.5f / (weightedStdDev.z * weightedStdDev.z);
m_HalfRcpWeightedVariances.w = 0.5f / (weightedStdDev.w * weightedStdDev.w);
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal().
static float KernelValCircle(float r, float s)
{
return 0.25f * s * (Mathf.Exp(-r * s) + Mathf.Exp(-r * s * (1.0f / 3.0f)));
}
// --- Private Methods ---
static float KernelPdf(float r, float s)
{
return KernelValCircle(r, s);
}
static float KernelCdf(float r, float s)
static float Gaussian(float x, float stdDev)
return 1.0f - 0.25f * Mathf.Exp(-r * s) - 0.75f * Mathf.Exp(-r * s * (1.0f / 3.0f));
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
static float KernelCdfDerivative1(float r, float s)
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
return 0.25f * s * Mathf.Exp(-r * s) * (1.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
static float KernelCdfDerivative2(float r, float s)
static float RationalApproximation(float t)
return (-1.0f / 12.0f) * s * s * Mathf.Exp(-r * s) * (3.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
// Abramowitz and Stegun formula 26.2.23.
// The absolute value of the error should be less than 4.5 e-4.
float[] c = {2.515517f, 0.802853f, 0.010328f};
float[] d = {1.432788f, 0.189269f, 0.001308f};
return t - ((c[2] * t + c[1]) * t + c[0]) / (((d[2] * t + d[1]) * t + d[0]) * t + 1.0f);
// The CDF is not analytically invertible, so we use Halley's Method of root finding.
// { f(r, s, p) = CDF(r, s) - p = 0 } with the initial guess { r = (10^p - 1) / s }.
static float KernelCdfInverse(float p, float s)
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
// Supply the initial guess.
float r = (Mathf.Pow(10.0f, p) - 1.0f) / s;
float t = float.MaxValue;
float x;
while (true)
if (p < 0.5)
float f0 = KernelCdf(r, s) - p;
float f1 = KernelCdfDerivative1(r, s);
float f2 = KernelCdfDerivative2(r, s);
float dr = f0 / (f1 * (1.0f - f0 * f2 / (2.0f * f1 * f1)));
// F^-1(p) = - G^-1(p)
x = -RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(p)));
}
else
{
// F^-1(p) = G^-1(1-p)
x = RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(1.0f - p)));
}
if (Mathf.Abs(dr) < t)
{
r = r - dr;
t = Mathf.Abs(dr);
}
else
{
// Converged to the best result.
break;
}
}
return x * stdDev;
}
return r;
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
}

public int numProfiles; // Excluding the neutral profile
public const int neutralProfileID = SSSConstants.SSS_PROFILES_MAX - 1;
public int numProfiles;
// Below are the cached values.
[NonSerialized] public uint texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
[NonSerialized] public uint transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
[NonSerialized] public float[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
[NonSerialized] public Vector4[] shapeParameters; // RGB = S = 1 / D, A = filter radius
[NonSerialized] public Vector4[] surfaceAlbedos; // RGB = color, A = unused
[NonSerialized] public float[] worldScales; // Size of the world unit in meters
[NonSerialized] public float[] filterKernelsNearField; // 0 = radius, 1 = reciprocal of the PDF
[NonSerialized] public float[] filterKernelsFarField; // 0 = radius, 1 = reciprocal of the PDF
// Below is the cache filled during OnValidate().
[NonSerialized] public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
[NonSerialized] public float[] transmissionType; // TODO: no int array suppport in shader in Unity :(
[NonSerialized] public Vector4[] tintColors; // For transmission; alpha is unused
[NonSerialized] public float[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
[NonSerialized] public Vector4[] halfRcpVariancesAndLerpWeights;
[NonSerialized] public Vector4[] halfRcpWeightedVariances;
[NonSerialized] public Vector4[] filterKernels;
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
shapeParameters = null;
filterKernelsNearField = null;
filterKernelsFarField = null;
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
transmissionType = null;
texturingModeFlags = 0;
tintColors = null;
thicknessRemaps = null;
halfRcpVariancesAndLerpWeights = null;
halfRcpWeightedVariances = null;
filterKernels = null;
UpdateCache();
}

// Reserve one slot for the neutral profile.
numProfiles = Math.Min(profiles.Length, SssConstants.SSS_N_PROFILES - 1);
numProfiles = Math.Min(profiles.Length, SSSConstants.SSS_PROFILES_MAX - 1);
if (profiles.Length != numProfiles)
{

}
}
Color c = new Color();
profiles[i].thicknessRemap.y = Mathf.Max(profiles[i].thicknessRemap.y, 0);
c.r = Mathf.Clamp(profiles[i].scatterDistance1.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].scatterDistance1.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(profiles[i].scatterDistance1.b, 0.05f, 2.0f);
c.a = 0.0f;
profiles[i].scatterDistance1 = c;
c.r = Mathf.Clamp(profiles[i].scatterDistance2.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].scatterDistance2.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(profiles[i].scatterDistance2.b, 0.05f, 2.0f);
c.a = 0.0f;
profiles[i].scatterDistance2 = c;
profiles[i].lerpWeight = Mathf.Clamp01(profiles[i].lerpWeight);
profiles[i].tintColor.r = Mathf.Clamp01(profiles[i].tintColor.r);
profiles[i].tintColor.g = Mathf.Clamp01(profiles[i].tintColor.g);
profiles[i].tintColor.b = Mathf.Clamp01(profiles[i].tintColor.b);
profiles[i].tintColor.a = 1.0f;
profiles[i].worldScale = Mathf.Max(profiles[i].worldScale, 0.001f);
profiles[i].thicknessRemap.y = Mathf.Max(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y);
profiles[i].BuildKernel();
profiles[i].UpdateKernelAndVarianceData();
}
UpdateCache();

{
texturingModeFlags = transmissionFlags = 0;
texturingModeFlags = 0;
const int thicknessRemapsLen = SssConstants.SSS_N_PROFILES * 2;
if (thicknessRemaps == null || thicknessRemaps.Length != thicknessRemapsLen)
if (transmissionType == null || transmissionType.Length != (SSSConstants.SSS_PROFILES_MAX))
thicknessRemaps = new float[thicknessRemapsLen];
transmissionType = new float[SSSConstants.SSS_PROFILES_MAX];
const int worldScalesLen = SssConstants.SSS_N_PROFILES;
if (worldScales == null || worldScales.Length != worldScalesLen)
if (tintColors == null || tintColors.Length != SSSConstants.SSS_PROFILES_MAX)
worldScales = new float[worldScalesLen];
tintColors = new Vector4[SSSConstants.SSS_PROFILES_MAX];
const int shapeParametersLen = SssConstants.SSS_N_PROFILES;
if (shapeParameters == null || shapeParameters.Length != shapeParametersLen)
if (thicknessRemaps == null || thicknessRemaps.Length != (SSSConstants.SSS_PROFILES_MAX * 2))
shapeParameters = new Vector4[shapeParametersLen];
thicknessRemaps = new float[SSSConstants.SSS_PROFILES_MAX * 2];
const int surfaceAlbedosLen = SssConstants.SSS_N_PROFILES;
if (surfaceAlbedos == null || surfaceAlbedos.Length != surfaceAlbedosLen)
if (halfRcpVariancesAndLerpWeights == null || halfRcpVariancesAndLerpWeights.Length != (SSSConstants.SSS_PROFILES_MAX * 2))
surfaceAlbedos = new Vector4[surfaceAlbedosLen];
halfRcpVariancesAndLerpWeights = new Vector4[SSSConstants.SSS_PROFILES_MAX * 2];
const int filterKernelsNearFieldLen = 2 * SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_NEAR_FIELD;
if (filterKernelsNearField == null || filterKernelsNearField.Length != filterKernelsNearFieldLen)
if (halfRcpWeightedVariances == null || halfRcpWeightedVariances.Length != SSSConstants.SSS_PROFILES_MAX)
filterKernelsNearField = new float[filterKernelsNearFieldLen];
halfRcpWeightedVariances = new Vector4[SSSConstants.SSS_PROFILES_MAX];
const int filterKernelsFarFieldLen = 2 * SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_FAR_FIELD;
if (filterKernelsFarField == null || filterKernelsFarField.Length != filterKernelsFarFieldLen)
if (filterKernels == null || filterKernels.Length != (SSSConstants.SSS_PROFILES_MAX * SubsurfaceScatteringProfile.numSamples))
filterKernelsFarField = new float[filterKernelsFarFieldLen];
filterKernels = new Vector4[SSSConstants.SSS_PROFILES_MAX * SubsurfaceScatteringProfile.numSamples];
}
for (int i = 0; i < numProfiles; i++)

Debug.Assert(numProfiles < 16, "Transmission flags (32-bit integer) cannot support more than 16 profiles.");
texturingModeFlags |= (uint)profiles[i].texturingMode << i;
transmissionFlags |= (uint)profiles[i].transmissionMode << i * 2;
thicknessRemaps[2 * i] = profiles[i].thicknessRemap.x;
thicknessRemaps[2 * i + 1] = profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x;
worldScales[i] = profiles[i].worldScale;
shapeParameters[i] = profiles[i].shapeParameter;
shapeParameters[i].w = profiles[i].scatteringDistance;
surfaceAlbedos[i] = profiles[i].surfaceAlbedo;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
texturingModeFlags |= ((int)profiles[i].texturingMode) << i;
if (profiles[i].enableTransmission)
filterKernelsNearField[2 * (n * i + j) + 0] = profiles[i].filterKernelNearField[j].x;
filterKernelsNearField[2 * (n * i + j) + 1] = profiles[i].filterKernelNearField[j].y;
transmissionType[i] = (float)(profiles[i].enableThinObject ? Lit.TransmissionType.ThinObject :Lit.TransmissionType.Regular);
}
else
{
transmissionType[i] = (float)Lit.TransmissionType.None;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
tintColors[i] = profiles[i].tintColor;
thicknessRemaps[2 * i] = profiles[i].thicknessRemap.x;
thicknessRemaps[2 * i + 1] = profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x;
halfRcpVariancesAndLerpWeights[2 * i] = profiles[i].halfRcpVariances[0];
halfRcpVariancesAndLerpWeights[2 * i].w = 1.0f - profiles[i].lerpWeight;
halfRcpVariancesAndLerpWeights[2 * i + 1] = profiles[i].halfRcpVariances[1];
halfRcpVariancesAndLerpWeights[2 * i + 1].w = profiles[i].lerpWeight;
halfRcpWeightedVariances[i] = profiles[i].halfRcpWeightedVariances;
for (int j = 0, n = SubsurfaceScatteringProfile.numSamples; j < n; j++)
filterKernelsFarField[2 * (n * i + j) + 0] = profiles[i].filterKernelFarField[j].x;
filterKernelsFarField[2 * (n * i + j) + 1] = profiles[i].filterKernelFarField[j].y;
filterKernels[n * i + j] = profiles[i].filterKernel[j];
int i = SssConstants.SSS_NEUTRAL_PROFILE_ID;
shapeParameters[i] = Vector4.zero;
surfaceAlbedos[i] = Vector4.zero;
worldScales[i] = 1.0f;
int i = neutralProfileID;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{
filterKernelsNearField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsNearField[2 * (n * i + j) + 1] = 1.0f;
}
halfRcpWeightedVariances[i] = Vector4.one;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
for (int j = 0, n = SubsurfaceScatteringProfile.numSamples; j < n; j++)
filterKernelsFarField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsFarField[2 * (n * i + j) + 1] = 1.0f;
filterKernels[n * i + j] = Vector4.one;
filterKernels[n * i + j].w = 0.0f;
}
}
}

{
private class Styles
{
public readonly GUIContent sssProfilePreview0 = new GUIContent("Profile Preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source (center).");
public readonly GUIContent sssProfilePreview2 = new GUIContent("The distance to the boundary of the image corresponds to the Scattering Distance.");
public readonly GUIContent sssProfilePreview3 = new GUIContent("Note that the intensity of pixels around the center may be clipped.");
public readonly GUIContent sssTransmittancePreview0 = new GUIContent("Transmittance Preview");
public readonly GUIContent sssTransmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object for thickness values from the remap.");
public readonly GUIContent sssTransmittancePreview2 = new GUIContent("Can be viewed as a cross section of a slab of material illuminated by white light from the left.");
public readonly GUIContent sssProfileSurfaceAlbedo = new GUIContent("Surface Albedo", "Color which determines the shape of the profile. Alpha is ignored.");
public readonly GUIContent sssProfileLenVolMeanFreePath = new GUIContent("Volume Mean Free Path", "The length of the volume mean free path (in millimeters) describes the average distance a photon travels within the volume before an extinction event occurs. Determines the effective radius of the filter.");
public readonly GUIContent sssProfileScatteringDistance = new GUIContent("Scattering Distance", "Effective radius of the filter (in millimeters). The blur is energy-preserving, so a wide filter results in a large area with small contributions of individual samples. Reducing the distance increases the sharpness of the result.");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing Mode", "Specifies when the diffuse texture should be applied.");
public readonly GUIContent[] sssTexturingModeOptions = new GUIContent[2]
public readonly GUIContent sssProfilePreview0 = new GUIContent("Profile Preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as the radius increases to 1.");
public readonly GUIContent sssProfilePreview2 = new GUIContent("Note that the intensity of the region in the center may be clamped.");
public readonly GUIContent sssTransmittancePreview0 = new GUIContent("Transmittance Preview");
public readonly GUIContent sssTransmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object for thickness values from the remap.");
public readonly GUIContent sssTransmittancePreview2 = new GUIContent("Can be thought of as a cross section of a slab of material illuminated by a white light from the left.");
public readonly GUIContent sssProfileScatterDistance1 = new GUIContent("Scatter Distance #1", "The radius (in centimeters) of the 1st Gaussian filter, one per color channel. Alpha is ignored. The blur is energy-preserving, so a wide filter results in a large area with small contributions of individual samples. Smaller values increase the sharpness.");
public readonly GUIContent sssProfileScatterDistance2 = new GUIContent("Scatter Distance #2", "The radius (in centimeters) of the 2nd Gaussian filter, one per color channel. Alpha is ignored. The blur is energy-preserving, so a wide filter results in a large area with small contributions of individual samples. Smaller values increase the sharpness.");
public readonly GUIContent sssProfileLerpWeight = new GUIContent("Filter Interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing Mode", "Specifies when the diffuse texture should be applied.");
public readonly GUIContent[] sssTexturingModeOptions = new GUIContent[2]
new GUIContent("Post-scatter", "Texturing is performed only during the SSS pass. Effectively preserves the sharpness of the diffuse texture. Choose this mode if your diffuse texture already contains SSS lighting (e.g. a photo of skin).")
};
public readonly GUIContent sssProfileTransmissionMode = new GUIContent("Transmission Mode", "Configures the simulation of light passing through thin objects. Depends on the thickness value (which is applied in the normal direction).");
public readonly GUIContent[] sssTransmissionModeOptions = new GUIContent[3]
{
new GUIContent("None", "Disables transmission. Choose this mode for completely opaque, or very thick translucent objects."),
new GUIContent("Thin Object", "Choose this mode for thin objects, such as paper or leaves. Transmitted light reuses the shadowing state of the surface."),
new GUIContent("Regular", "Choose this mode for moderately thick objects. For performance reasons, transmitted light ignores occlusion (shadows).")
new GUIContent("Post-scatter", "Texturing is performed only during the SSS pass. Effectively preserves the sharpness of the diffuse texture. Choose this mode if your diffuse texture already contains SSS lighting (e.g. a photo of skin).")
public readonly GUIContent sssProfileMinMaxThickness = new GUIContent("Min-Max Thickness", "Shows the values of the thickness remap below (in millimeters).");
public readonly GUIContent sssProfileThicknessRemap = new GUIContent("Thickness Remap", "Remaps the thickness parameter from [0, 1] to the desired range (in millimeters).");
public readonly GUIContent sssProfileWorldScale = new GUIContent("World Scale", "Size of the world unit in meters.");
public readonly GUIContent sssProfileTransmission = new GUIContent("Enable Transmission", "Toggles simulation of light passing through thin objects. Depends on the thickness of the material.");
public readonly GUIContent sssProfileTintColor = new GUIContent("Transmission Tint Color", "Tints transmitted light.");
public readonly GUIContent sssProfileThinObject = new GUIContent("Enable Thin Object", "Define is the object is thin (paper, leaf) or not. Allow to get cheap transmission and shadow.");
public readonly GUIContent sssProfileMinMaxThickness = new GUIContent("Min-Max Thickness", "Shows the values of the thickness remap below (in centimeters).");
public readonly GUIContent sssProfileThicknessRemap = new GUIContent("Thickness Remap", "Remaps the thickness parameter from [0, 1] to the desired range (in centimeters).");
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);

private RenderTexture m_ProfileImage, m_TransmittanceImage;
private Material m_ProfileMaterial, m_TransmittanceMaterial;
private SerializedProperty m_LenVolMeanFreePath, m_ScatteringDistance, m_SurfaceAlbedo, m_S,
m_TexturingMode, m_TransmissionMode, m_ThicknessRemap, m_WorldScale;
private SerializedProperty m_ScatterDistance1, m_ScatterDistance2, m_LerpWeight, m_TintColor, m_ThinObject,
m_TexturingMode, m_Transmission, m_ThicknessRemap;
m_SurfaceAlbedo = serializedObject.FindProperty("surfaceAlbedo");
m_LenVolMeanFreePath = serializedObject.FindProperty("lenVolMeanFreePath");
m_ScatteringDistance = serializedObject.FindProperty("m_ScatteringDistance");
m_S = serializedObject.FindProperty("m_S");
m_TexturingMode = serializedObject.FindProperty("texturingMode");
m_TransmissionMode = serializedObject.FindProperty("transmissionMode");
m_ThicknessRemap = serializedObject.FindProperty("thicknessRemap");
m_WorldScale = serializedObject.FindProperty("worldScale");
m_ScatterDistance1 = serializedObject.FindProperty("scatterDistance1");
m_ScatterDistance2 = serializedObject.FindProperty("scatterDistance2");
m_LerpWeight = serializedObject.FindProperty("lerpWeight");
m_TexturingMode = serializedObject.FindProperty("texturingMode");
m_Transmission = serializedObject.FindProperty("enableTransmission");
m_ThinObject = serializedObject.FindProperty("enableThinObject");
m_TintColor = serializedObject.FindProperty("tintColor");
m_ThicknessRemap = serializedObject.FindProperty("thicknessRemap");
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawSssProfile");
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_TransmittanceImage = new RenderTexture( 16, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImage = new RenderTexture(16, 256, 0, RenderTextureFormat.DefaultHDR);
}
public override void OnInspectorGUI()

EditorGUI.BeginChangeCheck();
{
EditorGUILayout.PropertyField(m_SurfaceAlbedo, styles.sssProfileSurfaceAlbedo);
m_LenVolMeanFreePath.floatValue = EditorGUILayout.Slider(styles.sssProfileLenVolMeanFreePath, m_LenVolMeanFreePath.floatValue, 0.01f, 1.0f);
GUI.enabled = false;
EditorGUILayout.PropertyField(m_ScatteringDistance, styles.sssProfileScatteringDistance);
GUI.enabled = true;
EditorGUILayout.PropertyField(m_ScatterDistance1, styles.sssProfileScatterDistance1);
EditorGUILayout.PropertyField(m_ScatterDistance2, styles.sssProfileScatterDistance2);
EditorGUILayout.PropertyField(m_LerpWeight, styles.sssProfileLerpWeight);
m_TexturingMode.intValue = EditorGUILayout.Popup(styles.sssTexturingMode, m_TexturingMode.intValue, styles.sssTexturingModeOptions);
EditorGUILayout.PropertyField(m_Transmission, styles.sssProfileTransmission);
EditorGUILayout.PropertyField(m_TintColor, styles.sssProfileTintColor);
m_TexturingMode.intValue = EditorGUILayout.Popup(styles.sssTexturingMode, m_TexturingMode.intValue, styles.sssTexturingModeOptions);
m_TransmissionMode.intValue = EditorGUILayout.Popup(styles.sssProfileTransmissionMode, m_TransmissionMode.intValue, styles.sssTransmissionModeOptions);
EditorGUILayout.PropertyField(m_ThinObject, styles.sssProfileThinObject);
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0.0f, 50.0f);
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
EditorGUILayout.PropertyField(m_WorldScale, styles.sssProfileWorldScale);
EditorGUILayout.LabelField(styles.sssProfilePreview3, EditorStyles.centeredGreyMiniLabel);
float d = m_ScatteringDistance.floatValue;
Vector4 A = m_SurfaceAlbedo.colorValue;
Vector3 S = m_S.vector3Value;
Vector2 R = m_ThicknessRemap.vector2Value;
// Apply the three-sigma rule.
Color stdDev1 = m_ScatterDistance1.colorValue * (1.0f / 3.0f);
Color stdDev2 = m_ScatterDistance2.colorValue * (1.0f / 3.0f);
m_ProfileMaterial.SetFloat("_ScatteringDistance", d);
m_ProfileMaterial.SetVector("_SurfaceAlbedo", A);
m_ProfileMaterial.SetVector("_ShapeParameter", S);
m_ProfileMaterial.SetColor("_StdDev1", stdDev1);
m_ProfileMaterial.SetColor("_StdDev2", stdDev2);
m_ProfileMaterial.SetFloat("_LerpWeight", m_LerpWeight.floatValue);
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);

bool transmissionEnabled = m_TransmissionMode.intValue != (int)SubsurfaceScatteringProfile.TransmissionMode.None;
m_TransmittanceMaterial.SetFloat("_ScatteringDistance", d);
m_TransmittanceMaterial.SetVector("_SurfaceAlbedo", transmissionEnabled ? A : Vector4.zero);
m_TransmittanceMaterial.SetVector("_ShapeParameter", S);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", R);
m_TransmittanceMaterial.SetColor("_StdDev1", stdDev1);
m_TransmittanceMaterial.SetColor("_StdDev2", stdDev2);
m_TransmittanceMaterial.SetFloat("_LerpWeight", m_LerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", m_ThicknessRemap.vector2Value);
m_TransmittanceMaterial.SetVector("_TintColor", m_TintColor.colorValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
serializedObject.ApplyModifiedProperties();

// Validate each individual asset and update caches.
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
}
}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.hlsl


#ifndef SUBSURFACESCATTERINGPROFILE_CS_HLSL
#define SUBSURFACESCATTERINGPROFILE_CS_HLSL
//
// UnityEngine.Experimental.Rendering.HDPipeline.SssConstants: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.SSSConstants: static fields
#define SSS_N_PROFILES (8)
#define SSS_NEUTRAL_PROFILE_ID (7)
#define SSS_N_SAMPLES_NEAR_FIELD (55)
#define SSS_N_SAMPLES_FAR_FIELD (34)
#define SSS_TRSM_MODE_NONE (0)
#define SSS_TRSM_MODE_THIN (1)
#define SSS_PROFILES_MAX (8)
#endif

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.hlsl.meta


fileFormatVersion: 2
guid: 5ecd8d3cc501ee64181689bfb64bba66
timeCreated: 1495110790
guid: 0348d78eb59f5e143ab4aa357c26f2c4
timeCreated: 1494501874
licenseType: Pro
ShaderImporter:
defaultTextures: []

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl


// Orthonormalize the basis vectors using the Gram-Schmidt process.
// We assume that the length of the surface normal is sufficiently close to 1.
// This is use with anisotropic material
tangentWS = normalize(tangentWS - dot(tangentWS, normalWS) * normalWS);
tangentWS = normalize(tangentWS - dot(tangentWS, normalWS));
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs


public static GUIContent distortionEnableText = new GUIContent("Distortion", "Enable distortion on this shader");
public static GUIContent distortionOnlyText = new GUIContent("Distortion Only", "This shader will only be use to render distortion");
public static GUIContent distortionDepthTestText = new GUIContent("Distortion Depth Test", "Enable the depth test for distortion");
public static string advancedText = "Advanced Options";
}
public enum SurfaceType

MaterialPropertiesGUI(material);
DoEmissionArea(material);
GUILayout.Label(StylesBaseUnlit.advancedText, EditorStyles.boldLabel);
// NB renderqueue editor is not shown on purpose: we want to override it based on blend mode
m_MaterialEditor.DoubleSidedGIField();
}
if (EditorGUI.EndChangeCheck())

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources.meta


fileFormatVersion: 2
guid: 12189449092048747a09af3b5d8a8720
guid: 12566b1a9c5807b4f8d3d0409255095a
timeCreated: 1496331368
timeCreated: 1487178659
licenseType: Pro
DefaultImporter:
userData:

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettings.cs


get { return m_SkySettings; }
}
public ScreenSpaceAmbientOcclusionSettings ssaoSettings
{
get { return m_SsaoSettings; }
}
[SerializeField] private ScreenSpaceAmbientOcclusionSettings m_SsaoSettings = null;
// Use this for initialization
void OnEnable()

HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if (hdPipeline != null)
{

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettingsManager.cs


{
CommonSettingsSingleton.overrideSettings = settings.commonSettings;
SkySettingsSingleton.overrideSettings = settings.skySettings;
ScreenSpaceAmbientOcclusionSettingsSingleton.overrideSettings = settings.ssaoSettings;
ScreenSpaceAmbientOcclusionSettingsSingleton.overrideSettings = null;
}
}
}

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


return normalize(mul((float3x3)GetObjectToWorldMatrix(), dirOS));
}
float3 TransformWorldToObjectDir(float3 dirWS)
{
// Normalize to support uniform scaling
return normalize(mul((float3x3)GetWorldToObjectMatrix(), dirWS));
}
// Transforms normal from object to world space
float3 TransformObjectToWorldNormal(float3 normalOS)
{

float3 TransformObjectToTangent(float3 dirOS, float3x3 worldToTangent)
{
return mul(worldToTangent, TransformObjectToWorldDir(dirOS));
return mul(worldToTangent, mul((float3x3)unity_ObjectToWorld, dirOS));
}
#endif // UNITY_SHADER_VARIABLES_INCLUDED

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs


bool m_SupportMIS = !TextureCache.isMobileBuildTarget;
RenderPipelineResources m_RenderPipelinesResources;
public IBLFilterGGX(RenderPipelineResources renderPipelinesResources)
{
m_RenderPipelinesResources = renderPipelinesResources;
}
public bool IsInitialized()
{
return m_GgxIblSampleData != null;

{
if (!m_ComputeGgxIblSampleDataCS)
{
m_ComputeGgxIblSampleDataCS = m_RenderPipelinesResources.computeGgxIblSampleData;
m_ComputeGgxIblSampleDataCS = Resources.Load<ComputeShader>("ComputeGgxIblSampleData");
m_BuildProbabilityTablesCS = m_RenderPipelinesResources.buildProbabilityTables;
m_BuildProbabilityTablesCS = Resources.Load<ComputeShader>("BuildProbabilityTables");
m_ConditionalDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeConditionalDensities");
m_MarginalRowDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeMarginalRowDensities");
}

m_GgxConvolveMaterial = Utilities.CreateEngineMaterial(m_RenderPipelinesResources.GGXConvolve);
m_GgxConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/GGXConvolve");
}
if (!m_GgxIblSampleData)

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs


RebuildSkyMeshes(nearPlane, farPlane);
}
public void Build(RenderPipelineResources renderPipelinesResources)
public void Build()
m_iblFilterGgx = new IBLFilterGGX(renderPipelinesResources);
m_iblFilterGgx = new IBLFilterGGX();
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial(renderPipelinesResources.skyboxCubemap);
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_BlitCubemapMaterial = Utilities.CreateEngineMaterial(renderPipelinesResources.blitCubemap);
m_BlitCubemapMaterial = Utilities.CreateEngineMaterial("Hidden/BlitCubemap");
m_CurrentUpdateTime = 0.0f;
}

21
Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs


return mat;
}
public static Material CreateEngineMaterial(Shader shader)
{
var mat = new Material(shader)
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static void Destroy(UnityObject obj)
{
if (obj != null)

material.DisableKeyword(keywords[i]);
}
}
}
public static HDRenderPipeline GetHDRenderPipeline()
{
HDRenderPipeline renderContext = GraphicsSettings.renderPipelineAsset as HDRenderPipeline;
if (renderContext == null)
{
Debug.LogWarning("HDRenderPipeline is not instantiated.");
return null;
}
return renderContext;
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.

1
Assets/ScriptableRenderPipeline/MobileRenderPipeline/ClassicDeferred/ClassicDeferredPipeline.cs


cmd.SetGlobalVector ("unity_SpecCube1_ProbePosition", new Vector4 (0.0f, 0.0f, 0.0f, 1.0f));
cmd.DrawMesh (m_QuadMesh, Matrix4x4.identity, m_ReflectionNearAndFarClipMaterial, 0, 0, props);
}
}

34
Assets/ScriptableRenderPipeline/ShaderLibrary/BSDF.hlsl


float F_Schlick(float f0, float u)
{
return F_Schlick(f0, 1.0, u); // sub mul mul mul sub mad
}
float F_Transm_Schlick(float f0, float f90, float u)
{
float x = 1.0 - u;
float x5 = x * x;
x5 = x5 * x5 * x;
return (1.0 - f0) - x5 * (f90 - f0); // sub mul mul mul sub sub mad
}
float F_Transm_Schlick(float f0, float u)
{
return F_Schlick(f0, 1.0, u); // sub mul mul mul sub mad
return F_Schlick(f0, 1.0, u);
}
float3 F_Schlick(float3 f0, float f90, float u)

x5 = x5 * x5 * x;
return (float3(f90, f90, f90) - f0) * x5 + f0; // sub mul mul mul sub*3 mad*3
return (float3(f90, f90, f90) - f0) * x5 + f0; // sub mul mul mul sub mad
float x = 1.0 - u;
float x5 = x * x;
x5 = x5 * x5 * x;
return f0 * (1.0 - x5) + float3(x5, x5, x5); // sub mul mul mul sub mad*3
}
float3 F_Transm_Schlick(float3 f0, float u)
{
float x = 1.0 - u;
float x2 = x * x;
float y = 1.0 - x2 * x2 * x;
return y - y * f0; // sub mul mul mad mad*3
return F_Schlick(f0, 1.0, u);
}
//-----------------------------------------------------------------------------

{
float facing = 0.5 + 0.5 * LdotV;
float rough = facing * (0.9 - 0.4 * facing) * ((0.5 + NdotH) / NdotH);
float transmitL = F_Transm_Schlick(0, NdotL);
float transmitV = F_Transm_Schlick(0, NdotV);
float transmitL = 1 - F_Schlick(0, 1, NdotL);
float transmitV = 1 - F_Schlick(0, 1, NdotV);
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

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


#ifndef INTRINSIC_BITFIELD_EXTRACT
// unsigned integer bit field extract implementation
uint BitFieldExtract(uint data, uint numBits, uint offset)
uint BitFieldExtract(uint data, uint size, uint offset)
uint mask = 0xFFFFFFFFu >> (32u - numBits);
return (data >> offset) & mask;
return (data >> offset) & ((1u << size) - 1u);
bool IsBitSet(uint data, uint bitPos)
bool IsBitSet(uint number, uint bitPos)
return BitFieldExtract(data, 1u, bitPos) != 0;
return ((number >> bitPos) & 1) != 0;
}
#ifndef INTRINSIC_CLAMP

6
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl


return specularOcclusion * specularOcclusion;
}
// Ref: Moving Frostbite to PBR - Gotanda siggraph 2011
float GetSpecularOcclusion(float NdotV, float ambientOcclusion, float roughness)
{
return saturate(PositivePow(NdotV + ambientOcclusion, exp2(-16.0 * roughness - 1.0)) - 1.0 + ambientOcclusion);
}
//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------

9
Assets/ScriptableRenderPipeline/ShaderLibrary/EntityLighting.hlsl


// It is required for other platform that aren't supporting this format to implement variant of these functions
// (But these kind of platform should use regular render loop and not news shaders).
// RGBM lightmaps are currently always gamma encoded, so we use a constant of range^2.2 = 5^2.2
#define LIGHTMAP_RGBM_RANGE 34.493242f
#define LIGHTMAP_RGBM_RANGE 5.0
// TODO: This is the max value allowed for emissive (bad name - but keep for now to retrieve it) (It is 8^2.2 (gamma) and 8 is the limit of punctual light slider...), comme from UnityCg.cginc. Fix it!
// Ask Jesper if this can be change for HDRenderPipeline
#define EMISSIVE_RGBM_SCALE 97.0

float3 UnpackLightmapRGBM(float4 rgbmInput)
{
// RGBM lightmaps are always gamma encoded for now, so decode with that in mind:
return rgbmInput.rgb * pow(rgbmInput.a, 2.2f) * LIGHTMAP_RGBM_RANGE;
return rgbmInput.rgb * rgbmInput.a * LIGHTMAP_RGBM_RANGE;
}
float3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), float2 uv, float4 transform, bool lightmapRGBM)

{
illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
}
return illuminance;
return SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
}
float3 SampleDirectionalLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_ARGS(lightmapDirTex, lightmapDirSampler), float2 uv, float4 transform, float3 normalWS, bool lightmapRGBM)

2
Assets/ScriptableRenderPipeline/ShaderLibrary/ImageBasedLighting.hlsl


{
float perceptualRoughness = saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);
return saturate(1.7 / 1.4 - sqrt(2.89 / 1.96 - (2.8 / 1.96) * perceptualRoughness));
return saturate(1.7 / 1.4 - sqrt(2.89 - 2.8 * perceptualRoughness) / 1.4);
}
// Ref: "Moving Frostbite to PBR", p. 69.

3
Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl


return deriv.x * vT + deriv.y * vB;
}
// surface gradient from an already generated "normal" such as from an object or world space normal map
// CAUTION: nrmVertexNormal and v must be in the same space. i.e world or object
// surface gradient from an already generated "normal" such as from an object space normal map
// this allows us to mix the contribution together with a series of other contributions including tangent space normals
// v does not need to be unit length as long as it establishes the direction.
float3 SurfaceGradientFromPerturbedNormal(float3 nrmVertexNormal, float3 v)

97
Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl


#ifndef UNITY_PACKING_INCLUDED
#define UNITY_PACKING_INCLUDED
#include "Common.hlsl"
//-----------------------------------------------------------------------------
// Normal packing
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Ref: http://realtimecollisiondetection.net/blog/?p=15
float4 PackToLogLuv(float3 vRGB)
float4 PackLogLuv(float3 vRGB)
{
// M matrix, for encoding
const float3x3 M = float3x3(

return vResult;
}
float3 UnpackFromLogLuv(float4 vLogLuv)
float3 UnpackLogLuv(float4 vLogLuv)
{
// Inverse M matrix, for decoding
const float3x3 InverseM = float3x3(

}
// The standard 32-bit HDR color format
uint PackToR11G11B10f(float3 rgb)
uint PackR11G11B10f(float3 rgb)
{
uint r = (f32tof16(rgb.x) << 17) & 0xFFE00000;
uint g = (f32tof16(rgb.y) << 6) & 0x001FFC00;

float3 UnpackFromR11G11B10f(uint rgb)
float3 UnpackR11G11B10f(uint rgb)
{
float r = f16tof32((rgb >> 17) & 0x7FF0);
float g = f16tof32((rgb >> 6) & 0x7FF0);

}
//-----------------------------------------------------------------------------
// Integer packing
// Byte packing
// Packs an integer stored using at most 'numBits' into a [0..1] float.
float PackInt(uint i, uint numBits)
{
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return saturate(i * rcp(maxInt));
}
// Unpacks a [0..1] float into an integer of size 'numBits'.
uint UnpackInt(float f, uint numBits)
{
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return (uint)(f * maxInt + 0.5); // Round instead of truncating
}
// Packs a [0..255] integer into a [0..1] float.
float PackByte(uint i)
{
return PackInt(i, 8);
}
// Unpacks a [0..1] float into a [0..255] integer.
uint UnpackByte(float f)
{
return UnpackInt(f, 8);
}
// Packs a [0..65535] integer into a [0..1] float.
float PackShort(uint i)
{
return PackInt(i, 16);
}
// Unpacks a [0..1] float into a [0..65535] integer.
uint UnpackShort(float f)
{
return UnpackInt(f, 16);
}
// Packs 8 lowermost bits of a [0..65535] integer into a [0..1] float.
float PackShortLo(uint i)
{
uint lo = BitFieldExtract(i, 8u, 0u);
return PackInt(lo, 8);
}
// Packs 8 uppermost bits of a [0..65535] integer into a [0..1] float.
float PackShortHi(uint i)
{
uint hi = BitFieldExtract(i, 8u, 8u);
return PackInt(hi, 8);
}
float Pack2Byte(float2 inputs)
{
float2 temp = inputs * float2(255.0, 255.0);

}
//-----------------------------------------------------------------------------
// Float packing
// float packing to sint/uint
uint PackFloatToUInt(float src, uint numBits, uint offset)
uint PackFloatToUInt(float src, uint size, uint offset)
return UnpackInt(src, numBits) << offset;
const float maxValue = float((1u << size) - 1u) + 0.5; // Shader compiler should be able to remove this
return uint(src * maxValue) << offset;
float UnpackUIntToFloat(uint src, uint numBits, uint offset)
float UnpackUIntToFloat(uint src, uint size, uint offset)
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return float(BitFieldExtract(src, numBits, offset)) * rcp(maxInt);
const float invMaxValue = 1.0 / float((1 << size) - 1);
return float(BitFieldExtract(src, size, offset)) * invMaxValue;
uint PackToR10G10B10A2(float4 rgba)
uint PackR10G10B10A2(float4 rgba)
float4 UnpackFromR10G10B10A2(uint rgba)
float4 UnpackR10G10B10A2(uint rgba)
{
float4 ouput;
ouput.x = UnpackUIntToFloat(rgba, 10, 0);

return ouput;
}
// Both the input and the output are in the [0, 1] range.
float2 PackFloatToR8G8(float f)
{
uint i = UnpackShort(f);
return float2(PackShortLo(i), PackShortHi(i));
}
// Both the input and the output are in the [0, 1] range.
float UnpackFloatFromR8G8(float2 f)
{
uint lo = UnpackByte(f.x);
uint hi = UnpackByte(f.y);
uint cb = (hi << 8) + lo;
return PackShort(cb);
}
#endif // UNITY_PACKING_INCLUDED

10
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute


#endif
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp, 4:= reversed z
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp
uniform float4 blurWeightsStorage[3]; // Unity expects float arrays to be tightly packed
static float blurWeights[12] = (float[12])blurWeightsStorage;

static const int kReversed_z = 4; // depth buffer contains reversed z
#if (SHADOW_MOMENT_ALGORITHM == VSM)
# define SHADOW_MOMENTS 2

const int4 validSrc = int4( srcRect.xy, srcRect.xy + srcRect.zw - 1 );
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + srcRect.xy;
int2 ldsIdx = groupThreadId.xy;
const bool reverse_z = (dstRect.w & kReversed_z) != 0;
// calculate an average moment over all samples for a given pixel and load the result into LDS
uint iw, ih, is;

#if MAX_MSAA > 1
for( is = 0; is < sampleCnt; is++ )
{
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
float depth = depthTex.Load( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ).x;
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x;
avgMoments = DepthToMoments( reverse_z ? (1.0-depth) : depth );
avgMoments = DepthToMoments( depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x );
#endif
moments[ldsIdx.y][ldsIdx.x] = avgMoments;

6
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
if( distances2.w > dirShadowSplitSphereSqRadii.w )
return -1;
int idx = int( 4.0 - dot( weights, float4( 4.0, 3.0, 2.0, 1.0 ) ) );
return idx <= 3 ? idx : -1;
return int( 4.0 - dot( weights, float4(4.0, 3.0, 2.0, 1.0 ) ) );
}
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out float4 splitSpheres[4] )

13
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl


float mD = depth - moments.x;
float p = variance / (variance + mD * mD);
#if UNITY_REVERSED_Z
p = saturate( (p - lightLeakBias) / (1.0f - lightLeakBias) );
return max( p, depth >= moments.x );
#else
#endif
}
// helper for EVSM

float quotient = (switchVal[0] * z[2] - b[0] * (switchVal[0] + z[2]) + b[1]) / ((z[2] - switchVal[1]) * (z[0] - z[1]));
float attenuation = saturate( switchVal[2] + switchVal[3] * quotient );
#if UNITY_REVERSED_Z // probably
return saturate( (attenuation - lightLeakBias) / (1.0f - lightLeakBias) );
#else
#endif
}
float ShadowMoments_SolveDelta4MSM( float3 z, float4 b, float lightLeakBias)

float w1Factor = (z[0] > zFree) ? 1.0 : 0.0;
float attenuation = saturate( (b[1] - b[0] + (b[2] - b[0] - (zFree + 1.0) * (b[1] - b[0])) * (zFree - w1Factor - z[0]) / (z[0] * (z[0] - zFree))) / (zFree - w1Factor) + 1.0 - b[0] );
#if UNITY_REVERSED_Z // probably
return saturate( (attenuation - lightLeakBias) / (1.0f - lightLeakBias) );
#else
#endif
}

26
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl


//
float SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float lightLeakBias = params.x;
float varianceBias = params.y;

float SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float lightLeakBias = params.x;
float varianceBias = params.y;

//
float SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx, bool fourMoments )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float varianceBias = params.y;

float SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float varianceBias = params.y;

float momentBias = params.y;
float depthBias = params.z;
float bpp16 = params.w;
#if UNITY_REVERSED_Z
float depth = (1.0 - tcs.z) + depthBias;
#else
#endif
payloadOffset++;
float4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );

float momentBias = params.y;
float depthBias = params.z;
float bpp16 = params.w;
#if UNITY_REVERSED_Z
float depth = (1.0 - tcs.z) + depthBias;
#else
float depth = tcs.z + depthBias;
#endif
float depth = tcs.z + depthBias;
payloadOffset++;
float4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );

61
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/LowEndMobilePipelineAsset.cs


namespace UnityEngine.Experimental.Rendering.LightweightPipeline
namespace UnityEngine.Experimental.Rendering.LowendMobile
{
public enum ShadowCascades
{

_2048 = 2048
}
public class LightweightPipelineAsset : RenderPipelineAsset
public class LowEndMobilePipelineAsset : RenderPipelineAsset
private static readonly string m_PipelineFolder = "Assets/ScriptableRenderPipeline/LightweightPipeline";
private static readonly string m_AssetName = "LightweightPipelineAsset.asset";
#region AssetAndPipelineCreation
[UnityEditor.MenuItem("RenderPipeline/LightweightPipeline/Create Pipeline Asset")]
static void CreateLightweightPipeline()
[UnityEditor.MenuItem("RenderPipeline/LowEndMobilePipeline/Create Pipeline Asset")]
static void CreateLowEndPipeline()
var instance = ScriptableObject.CreateInstance<LightweightPipelineAsset>();
var instance = ScriptableObject.CreateInstance<LowEndMobilePipelineAsset>();
UnityEditor.AssetDatabase.CreateAsset(instance,
"Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset");
}
string[] paths = m_PipelineFolder.Split('/');
string currentPath = paths[0];
for (int i = 1; i < paths.Length; ++i)
{
string folder = currentPath + "/" + paths[i];
if (!UnityEditor.AssetDatabase.IsValidFolder(folder))
UnityEditor.AssetDatabase.CreateFolder(currentPath, paths[i]);
currentPath = folder;
}
UnityEditor.AssetDatabase.CreateAsset(instance, m_PipelineFolder + "/" + m_AssetName);
}
return new LightweightPipeline(this);
return new LowEndMobilePipeline(this);
#endregion
[SerializeField] private Material m_DefaultSpriteMaterial;
[SerializeField] private Shader m_DefaultShader;
public int MaxSupportedPixelLights

private set { m_Cascade4Split = value; }
}
public Material DefaultDiffuseMaterial
{
get { return m_DefaultDiffuseMaterial; }
private set { m_DefaultDiffuseMaterial = value; }
}
public Shader DefaultShader
{
get { return m_DefaultShader; }
private set { m_DefaultShader = value; }
}
#endregion
public override Material GetDefaultMaterial()
{

public override Material GetDefault2DMaterial()
{
return m_DefaultSpriteMaterial;
return m_DefaultDiffuseMaterial;
}
public override Shader GetDefaultShader()
{

6
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset


m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3}
m_Name: LightweightPipelineAsset
m_Name: LowEndMobilePipelineAsset
m_EditorClassIdentifier:
m_MaxPixelLights: 1
m_SupportsVertexLight: 1

m_ShadowCascades: 1
m_Cascade2Split: 0.25
m_Cascade4Split: {x: 0.067, y: 0.2, z: 0.467}
m_DefaultDiffuseMaterial: {fileID: 2100000, guid: 6a1143ee683302f4aa628c052723efc1,
type: 2}
m_DefaultSpriteMaterial: {fileID: 2100000, guid: e3ef893926d86c448a80512fe05b8a37,
m_DefaultDiffuseMaterial: {fileID: 2100000, guid: 654f7c5a4dd5d4d139a072ab9b5c5738,
type: 2}
m_DefaultShader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}

21
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/LowEndMobilePipeline.cs


using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
namespace UnityEngine.Experimental.Rendering.LowendMobile
{
[Serializable]
public class ShadowSettings

public int shadowResolution;
}
public class LightweightPipeline : RenderPipeline, IComparer<VisibleLight>
public class LowEndMobilePipeline : RenderPipeline, IComparer<VisibleLight>
private readonly LightweightPipelineAsset m_Asset;
private readonly LowEndMobilePipelineAsset m_Asset;
private static readonly int kMaxCascades = 4;
private static readonly int kMaxLights = 8;

private int m_DepthBufferBits = 24;
private Vector4[] m_DirectionalShadowSplitDistances = new Vector4[kMaxCascades];
private static readonly ShaderPassName m_ForwardBasePassName = new ShaderPassName("LightweightForward");
private static readonly ShaderPassName m_ForwardBasePassName = new ShaderPassName("LowEndMobileForward");
private Vector4[] m_LightPositions = new Vector4[kMaxLights];
private Vector4[] m_LightColors = new Vector4[kMaxLights];

private ShadowSettings m_ShadowSettings = ShadowSettings.Default;
private ShadowSliceData[] m_ShadowSlices = new ShadowSliceData[kMaxCascades];
public LightweightPipeline(LightweightPipelineAsset asset)
public LowEndMobilePipeline(LowEndMobilePipelineAsset asset)
{
m_Asset = asset;

Shader.globalRenderPipeline = "LightweightPipeline";
}
public override void Dispose()
{
Shader.globalRenderPipeline = "";
var prevPipe = Shader.globalRenderPipeline;
Shader.globalRenderPipeline = "LowEndMobilePipeline";
base.Render(context, cameras);
foreach (Camera camera in cameras)

}
context.Submit();
Shader.globalRenderPipeline = prevPipe;
}
private void BuildShadowSettings()

}
else
{
Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
Debug.LogWarning("Only spot and directional shadow casters are supported in lowend mobile pipeline");
return false;
}

9
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/TestScenes/Materials/LDRenderPipeMaterials/LDSpecularSphere0.mat


m_PrefabInternal: {fileID: 0}
m_Name: LDSpecularSphere0
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_ShaderKeywords: _SPECULAR_COLOR
m_ShaderKeywords: _GLOSSINESS_FROM_BASE_ALPHA _SPECULAR_COLOR
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Cube:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _ReflectionSource: 0
- _Shininess: 1
- _SmoothnessTextureChannel: 0
- _SpecSource: 0
- _SpecularHighlights: 1

6
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndParticlesMultiply.shader


Shader "ScriptableRenderPipeline/LightweightPipeline/Particles/Multiply"
Shader "ScriptableRenderPipeline/LowEndMobile/Particles/Multiply"
{
Properties
{

Category
{
Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "RenderPipeline" = "LightweightPipeline" "PreviewType" = "Plane"}
Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "RenderPipeline" = "LowendMobile" "PreviewType" = "Plane"}
Blend Zero SrcColor
Cull Off Lighting Off ZWrite Off

{
Tags { "LightMode" = "LightweightForward" }
Tags { "LightMode" = "LowEndMobileForward" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

6
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndParticlesAdd.shader


Shader "ScriptableRenderPipeline/LightweightPipeline/Particles/Additive"
Shader "ScriptableRenderPipeline/LowEndMobile/Particles/Additive"
{
Properties
{

Category
{
Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "RenderPipeline" = "LightweightPipeline" "PreviewType" = "Plane"}
Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "RenderPipeline" = "LowEndPipeline" "PreviewType" = "Plane"}
Blend SrcAlpha One
Cull Off Lighting Off ZWrite Off

{
Tags{"LightMode" = "LightweightForward"}
Tags{"LightMode" = "LowEndMobileForward"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

44
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndMobilePipelineShadows.cginc


#endif
}
inline half ComputeShadowAttenuation(v2f i, float3 offset)
{
float3 posWorldOffsetNormal = i.posWS + offset;
int cascadeIndex = 0;
#ifdef _SHADOW_CASCADES
cascadeIndex = ComputeCascadeIndex(i.posWS);
if (cascadeIndex >= MAX_SHADOW_CASCADES)
return 1.0;
#endif
float4 shadowCoord = mul(_WorldToShadow[cascadeIndex], float4(posWorldOffsetNormal, 1.0));
shadowCoord.xyz /= shadowCoord.w;
shadowCoord.z = saturate(shadowCoord.z);
#if defined(_SOFT_SHADOWS) || defined(_SOFT_SHADOWS_CASCADES)
return ShadowPCF(shadowCoord.xyz);
#else
return ShadowAttenuation(shadowCoord.xyz);
#endif
}
inline half ComputeCascadeIndex(float3 wpos)
{
float3 fromCenter0 = wpos.xyz - _DirShadowSplitSpheres[0].xyz;

ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[4], _PCFKernel[5]) + offset, shadowCoord.z)) +
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[6], _PCFKernel[7]) + offset, shadowCoord.z));
return attenuation * 0.25;
}
inline half ComputeShadowAttenuation(v2f i, float3 offset)
{
float3 posWorldOffsetNormal = i.posWS + offset;
int cascadeIndex = 0;
#ifdef _SHADOW_CASCADES
cascadeIndex = ComputeCascadeIndex(i.posWS);
if (cascadeIndex >= MAX_SHADOW_CASCADES)
return 1.0;
#endif
float4 shadowCoord = mul(_WorldToShadow[cascadeIndex], float4(posWorldOffsetNormal, 1.0));
shadowCoord.xyz /= shadowCoord.w;
shadowCoord.z = saturate(shadowCoord.z);
#if defined(_SOFT_SHADOWS) || defined(_SOFT_SHADOWS_CASCADES)
return ShadowPCF(shadowCoord.xyz);
#else
return ShadowAttenuation(shadowCoord.xyz);
#endif
}
}

14
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndMobilePipelineCore.cginc


half4 spotDir;
};
struct LightweightVertexInput
struct LowendVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;

half4 _ReflectColor;
#ifdef _SHADOWS
#include "LightweightPipelineShadows.cginc"
#include "LowEndMobilePipelineShadows.cginc"
#endif
inline void NormalMap(v2f i, out half3 normal)

#endif
}
inline void SpecularGloss(half2 uv, half alpha, out half4 specularGloss)
inline void SpecularGloss(half2 uv, half3 diffuse, half alpha, out half4 specularGloss)
{
#ifdef _SPECGLOSSMAP
specularGloss = tex2D(_SpecGlossMap, uv) * _SpecColor;

#endif
}
inline void Emission(half2 uv, inout half3 color)
inline void Emission(v2f i, out half3 emission)
#ifdef _EMISSION
color += tex2D(_EmissionMap, uv) * _EmissionColor;
#ifdef _EMISSION_MAP
emission = tex2D(_EmissionMap, i.uv01.xy) * _EmissionColor;
color += _EmissionColor;
emission = _EmissionColor;
#endif
}

70
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Shaders/LowEndMobilePipeline.shader


// Shader targeted for low end devices. Single Pass Forward Rendering. Shader Model 2
Shader "ScriptableRenderPipeline/LightweightPipeline/NonPBR"
// Shader targeted for LowEnd mobile devices. Single Pass Forward Rendering. Shader Model 2
Shader "ScriptableRenderPipeline/LowEndMobile/NonPBR"
{
// Keep properties of StandardSpecular shader for upgrade reasons.
Properties

[HideInInspector] _ZWrite("__zw", Float) = 1.0
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" }
LOD 300
Pass
SubShader
Name "LD_SINGLE_PASS_FORWARD"
Tags { "LightMode" = "LightweightForward" }
Tags { "RenderType" = "Opaque" "RenderPipeline" = "LowEndMobilePipeline" }
LOD 300
Pass
{
Name "LD_SINGLE_PASS_FORWARD"
Tags { "LightMode" = "LowEndMobileForward" }
// Use same blending / depth states as Standard shader
Blend[_SrcBlend][_DstBlend]

#pragma target 3.0
#pragma target 2.0
#pragma shader_feature _EMISSION
#pragma shader_feature _EMISSION_MAP
#pragma shader_feature _ _REFLECTION_CUBEMAP _REFLECTION_PROBE
#pragma multi_compile _ LIGHTMAP_ON

#include "UnityStandardBRDF.cginc"
#include "UnityStandardInput.cginc"
#include "UnityStandardUtils.cginc"
#include "LightweightPipelineCore.cginc"
#include "LowEndMobilePipelineCore.cginc"
v2f vert(LightweightVertexInput v)
v2f vert(LowendVertexInput v)
{
v2f o = (v2f)0;

NormalMap(i, normal);
half4 specularGloss;
SpecularGloss(i.uv01.xy, alpha, specularGloss);
SpecularGloss(i.uv01.xy, diffuse, alpha, specularGloss);
half3 viewDir = i.viewDir.xyz;

LightInput lightData;
half NdotL;
INITIALIZE_LIGHT(lightData, lightIndex);
color += EvaluateOneLight(lightData, diffuse, specularGloss, normal, i.posWS, viewDir, NdotL);
color += EvaluateOneLight(lightData, diffuse, specularGloss, normal, i.posWS, viewDir, NdotL);
#if _NORMALMAP
float3 vertexNormal = float3(i.tangentToWorld0.z, i.tangentToWorld1.z, i.tangentToWorld2.z);
#else
float3 vertexNormal = i.normal;
#endif
#if _NORMALMAP
float3 vertexNormal = float3(i.tangentToWorld0.z, i.tangentToWorld1.z, i.tangentToWorld2.z);
#else
float3 vertexNormal = i.normal;
#endif
float bias = max(globalLightData.z, (1.0 - NdotL) * globalLightData.w);
color *= ComputeShadowAttenuation(i, vertexNormal * bias);
}

Emission(i.uv01.xy, color);
half3 emissionColor;
Emission(i, emissionColor);
color += emissionColor;
#if defined(LIGHTMAP_ON)
color += (DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv01.zw)) + i.fogCoord.yzw) * diffuse;

Cull Off
CGPROGRAM
#define UNITY_SETUP_BRDF_INPUT SpecularSetup
#pragma fragment frag_meta_ld
#pragma fragment frag_meta
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _METALLICGLOSSMAP
#include "LightweightPipelineCore.cginc"
fixed4 frag_meta_ld(v2f_meta i) : SV_Target
{
UnityMetaInput o;
UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
o.Albedo = Albedo(i.uv);
half4 specularColor;
SpecularGloss(i.uv.xy, 1.0, specularColor);
o.SpecularColor = specularColor;
Emission(i.uv.xy, o.Emission);
return UnityMetaFragment(o);
}
CustomEditor "LightweightPipelineMaterialEditor"
CustomEditor "LowendMobilePipelineMaterialEditor"
}

14
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LowendUpgraders.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.Rendering.LightweightPipeline
namespace UnityEditor.Experimental.Rendering.LowendMobile
{
public static class SupportedUpgradeParams
{

{
public LegacyBlinnPhongUpgrader(string oldShaderName, UpgradeParams upgradeParams)
{
RenameShader(oldShaderName, "ScriptableRenderPipeline/LightweightPipeline/NonPBR", UpdateMaterialKeywords);
RenameShader(oldShaderName, "ScriptableRenderPipeline/LowEndMobile/NonPBR", UpdateMaterialKeywords);
SetFloat("_Mode", (float)upgradeParams.blendMode);
SetFloat("_SpecSource", (float)upgradeParams.specularSource);
SetFloat("_GlossinessSource", (float)upgradeParams.glosinessSource);

UpdateMaterialReflectionSource(material);
SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap"));
SetKeyword(material, "_CUBEMAP_REFLECTION", material.GetTexture("_Cube"));
SetKeyword(material, "_EMISSION", material.GetTexture("_EmissionMap"));
SetKeyword(material, "_EMISSION_MAP", material.GetTexture("_EmissionMap"));
}
private static void UpdateMaterialBlendMode(Material material)

{
public ParticlesMultiplyUpgrader(string oldShaderName)
{
RenameShader(oldShaderName, "ScriptableRenderPipeline/LightweightPipeline/Particles/Multiply");
RenameShader(oldShaderName, "ScriptableRenderPipeline/LowEndMobile/Particles/Multiply");
}
}

{
RenameShader(oldShaderName, "ScriptableRenderPipeline/LightweightPipeline/Particles/Additive");
RenameShader(oldShaderName, "ScriptableRenderPipeline/LowEndMobile/Particles/Additive");
}
}

{
RenameShader(oldShaderName, "ScriptableRenderPipeline/LightweightPipeline/NonPBR");
RenameShader(oldShaderName, "ScriptableRenderPipeline/LowEndMobile/NonPBR");
}
}

{
RenameShader(oldShaderName, "ScriptableRenderPipeline/LightweightPipeline/NonPBR");
RenameShader(oldShaderName, "ScriptableRenderPipeline/LowEndMobile/NonPBR");
SetFloat("_Shininess", 1.0f);
}
}

12
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LowendPipelineAssetInspector.cs


using UnityEditor;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
namespace UnityEngine.Experimental.Rendering.LowendMobile
[CustomEditor(typeof(LightweightPipelineAsset))]
public class LightweightAssetInspector : Editor
[CustomEditor(typeof(LowEndMobilePipelineAsset))]
public class LowendPipelineAssetInspector : Editor
{
internal class Styles
{

public static GUIContent defaultDiffuseMaterial = new GUIContent("Default Diffuse Material",
"Material to use when creating objects");
public static GUIContent defaultSpriteMaterial = new GUIContent("Default Sprite Material",
"Material to use when creating Sprites");
public static GUIContent defaultShader = new GUIContent("Default Shader",
"Shader to use when creating materials");
}

private SerializedProperty m_ShadowCascade2SplitProp;
private SerializedProperty m_ShadowCascade4SplitProp;
private SerializedProperty m_DefaultDiffuseMaterial;
private SerializedProperty m_DefaultSpriteMaterial;
private SerializedProperty m_DefaultShader;
void OnEnable()

m_ShadowCascade2SplitProp = serializedObject.FindProperty("m_Cascade2Split");
m_ShadowCascade4SplitProp = serializedObject.FindProperty("m_Cascade4Split");
m_DefaultDiffuseMaterial = serializedObject.FindProperty("m_DefaultDiffuseMaterial");
m_DefaultSpriteMaterial = serializedObject.FindProperty("m_DefaultSpriteMaterial");
m_DefaultShader = serializedObject.FindProperty("m_DefaultShader");
}

EditorGUILayout.LabelField(Styles.defaults, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_DefaultDiffuseMaterial, Styles.defaultDiffuseMaterial);
EditorGUILayout.PropertyField(m_DefaultSpriteMaterial, Styles.defaultSpriteMaterial);
EditorGUILayout.PropertyField(m_DefaultShader, Styles.defaultShader);
EditorGUI.indentLevel--;

21
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LowendMobilePipelineMaterialEditor.cs


using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor.Experimental.Rendering.LightweightPipeline;
using UnityEditor.Experimental.Rendering.LowendMobile;
public class LightweightPipelineMaterialEditor : ShaderGUI
public class LowendMobilePipelineMaterialEditor : ShaderGUI
{
private const float kMinShininessValue = 0.01f;
private MaterialProperty blendModeProp = null;

m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMapProp);
EditorGUILayout.Space();
DoEmission();
m_MaterialEditor.TexturePropertySingleLine(Styles.emissionMapLabel, emissionMapProp, emissionColorProp);
EditorGUILayout.Space();
DoReflection();

kMinShininessValue, 1.0f);
if (EditorGUI.EndChangeCheck())
shininessProp.floatValue = shininess;
}
}
private void DoEmission()
{
if (m_MaterialEditor.EmissionEnabledProperty())
{
bool hadEmissionMap = emissionMapProp.textureValue != null;
m_MaterialEditor.TexturePropertySingleLine(Styles.emissionMapLabel, emissionMapProp, emissionColorProp);
float maxValue = emissionColorProp.colorValue.maxColorComponent;
if (emissionMapProp.textureValue != null && !hadEmissionMap && maxValue <= 0.0f)
emissionColorProp.colorValue = Color.white;
m_MaterialEditor.LightmapEmissionFlagsProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel, true);
}
}

10
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/LegacyShadersToLowEndUpgrader.cs


using System.Collections.Generic;
namespace UnityEditor.Experimental.Rendering.LightweightPipeline
namespace UnityEditor.Experimental.Rendering.LowendMobile
public class LegacyShadersToLightweightPipelineUpgrader
public class LegacyShadersToLowEndUpgrader
[MenuItem("RenderPipeline/LightweightPipeline/Material Upgraders/Upgrade Legacy Materials to LightweightPipeline - Project", false, 3)]
[MenuItem("RenderPipeline/LowEndMobilePipeline/Material Upgraders/Upgrade Legacy Materials to LowEndMobile - Project", false, 3)]
public static void UpgradeMaterialsToLDProject()
{
List<MaterialUpgrader> materialUpgraders = new List<MaterialUpgrader>();

}
[MenuItem("RenderPipeline/LightweightPipeline/Material Upgraders/Upgrade Legacy Materials to LightweightPipeline - Selection", false, 4)]
[MenuItem("RenderPipeline/LowEndMobilePipeline/Material Upgraders/Upgrade Legacy Materials to LowEndMobile - Selection", false, 4)]
MaterialUpgrader.UpgradeSelection(materialUpgraders, "Upgrade to Lightweight Materials");
MaterialUpgrader.UpgradeSelection(materialUpgraders, "Upgrade to LD Materials");
}
private static void GetUpgraders(ref List<MaterialUpgrader> materialUpgraders)

2
Assets/ScriptableRenderPipeline/LowEndMobilePipeline/Editor/UpgradeCommon.cs


namespace UnityEditor.Experimental.Rendering.LightweightPipeline
namespace UnityEditor.Experimental.Rendering.LowendMobile
{
public enum UpgradeBlendMode
{

2
Assets/TestScenes/HDTest/GraphicTest/SSS/Materials/SSSHead.mat


_ENABLEWIND_OFF _NORMALMAP _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:

- _DistortionOnly: 0
- _DoubleSidedEnable: 0
- _DoubleSidedMirrorEnable: 1
- _DoubleSidedNormalMode: 1
- _Drag: 1
- _DstBlend: 0
- _EmissiveColorMode: 1

451
Assets/TestScenes/HDTest/HDRenderLoopTest.unity
文件差异内容过多而无法显示
查看文件

245
Assets/TestScenes/MobileDeferredTest/ClassicDeferredTest/ClassicDeferredTest.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.37124014, g: 0.28119457, b: 0.32684708, a: 1}
m_IndirectSpecularColor: {r: 0.18328291, g: 0.2289299, b: 0.30645376, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1406517708}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1409540745
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1409540749}
- component: {fileID: 1409540748}
- component: {fileID: 1409540747}
- component: {fileID: 1409540746}
m_Layer: 0
m_Name: Plane (2)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &1409540746
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1409540745}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 02826327e99624cf7a3e639f66207fca, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &1409540747
MeshCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1409540745}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Convex: 0
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &1409540748
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1409540745}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1409540749
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1409540745}
m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 141.4, y: 45.6, z: -22.599419}
m_LocalScale: {x: 5, y: 1, z: 5}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 14
m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0}
--- !u!1 &1415543310
GameObject:
m_ObjectHideFlags: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1667490520}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1683524834
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1683524838}
- component: {fileID: 1683524837}
- component: {fileID: 1683524836}
- component: {fileID: 1683524835}
m_Layer: 0
m_Name: Plane (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &1683524835
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1683524834}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 02826327e99624cf7a3e639f66207fca, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &1683524836
MeshCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1683524834}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Convex: 0
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &1683524837
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1683524834}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1683524838
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1683524834}
m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 71, y: 45.6, z: -95.6}
m_LocalScale: {x: 5, y: 1, z: 5}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 13
m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0}
--- !u!1 &1719222740
GameObject:
m_ObjectHideFlags: 0

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

archetype: 0
lightLength: 0
lightWidth: 0
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05
- 0.2
- 0.3
shadowAlgorithm: 0
shadowVariant: 1
shadowPrecision: 0

8
ProjectSettings/EditorBuildSettings.asset


m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes:
- enabled: 1
- enabled: 0
- enabled: 1
path: Assets/TestScenes/HDTest/NewBatcherBench1.unity
guid: efeef759b5144ef4fa1cfc182ddbaea5
- enabled: 0
path: Assets/TestScenes/HDTest/NewBatcherBench2.unity
guid: 1816611d7c1a9bc41bbe1ae56076f699

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.2.0a2
m_EditorVersion: 2017.2.0a1

89
ProjectSettings/TagManager.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!78 &1
TagManager:
serializedVersion: 2
tags: []
layers:
- Default
- TransparentFX
- Ignore Raycast
-
- Water
- UI
-
-
- Don't Shadow Cast
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
m_SortingLayers:
- name: bg
uniqueID: 3786281603
locked: 0
- name: Default
uniqueID: 0
locked: 0
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!78 &1
TagManager:
serializedVersion: 2
tags: []
layers:
- Default
- TransparentFX
- Ignore Raycast
-
- Water
- UI
-
-
- Don't Shadow Cast
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
m_SortingLayers:
- name: Default
uniqueID: 0
locked: 0

2
Assets/ScriptableRenderPipeline/fptl/LightDefinitions.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/Fptl/LightDefinitions.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderPipeline/fptl/LightDefinitions.cs. Please don't edit by hand.
//
#ifndef LIGHTDEFINITIONS_CS_HLSL

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader


// Include
//-------------------------------------------------------------------------------------
#include "../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../ShaderConfig.cs.hlsl"
#include "../ShaderVariables.hlsl"
#include "../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration

19
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader


#pragma vertex Vert
#pragma fragment Frag
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/Color.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../ShaderConfig.cs.hlsl"
#include "../ShaderVariables.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../Debug/DebugDisplay.hlsl"
#include "../Material/Material.hlsl"
#include "../../Debug/DebugDisplay.hlsl"
#include "../../Material/Material.hlsl"
uint vertexID : SV_VertexID;
float3 positionOS : POSITION;
};
struct Varyings

Varyings Vert(Attributes input)
{
// TODO: implement SV_vertexID full screen quad
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
float3 positionWS = TransformObjectToWorld(input.positionOS);
output.positionCS = TransformWorldToHClip(positionWS);
return output;
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayShadowMap.shader


#pragma vertex Vert
#pragma fragment Frag
#include "../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/Shadow/Shadow.hlsl"
#include "../../../ShaderLibrary/Shadow/Shadow.hlsl"
#undef SHADOW_TILEPASS
SamplerState ltc_linear_clamp_sampler;

{
ShadowContext shadowContext = InitShadowContext();
// Caution: ShadowContext is define in Shadowcontext.hlsl for current render pipeline. This shader must be in sync with its content else it doesn't work.
// Caution: ShadowContext is define in Shadowcontext.hlsl for current render pipeline. This shader must be in sync with its content else it doesn't work.
return SAMPLE_TEXTURE2D_ARRAY(_ShadowmapExp_PCF, ltc_linear_clamp_sampler, input.texcoord, 0).xxxx;
}

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader


#pragma vertex Vert
#pragma fragment Frag
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
TEXTURECUBE(_InputCubemap);
SAMPLERCUBE(sampler_InputCubemap);

248
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute


#pragma kernel ShadeOpaque_Direct_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl USE_FPTL_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Fptl_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl_DebugDisplay USE_FPTL_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Direct_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered USE_CLUSTERED_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Clustered_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered_DebugDisplay USE_CLUSTERED_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant0 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant1 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant2 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant3 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant4 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant5 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant6 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant7 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant8 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant9 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant10 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant11 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant12 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant13 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant14 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant15 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant0 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant1 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant2 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant3 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant4 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant5 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant6 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant7 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant8 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant9 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant10 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant11 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant12 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant13 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant14 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant15 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma #pragma enable_d3d11_debug_symbols
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../Debug/DebugDisplay.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../Lighting/TilePass/FeatureFlags.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
#if USE_INDIRECT
uint g_TileListOffset;
StructuredBuffer<uint> g_TileList;
// Indirect
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 groupThreadId : SV_GroupThreadID, uint groupId : SV_GroupID)
{
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, tileCoord);
uint featureFlags = TileVariantToFeatureFlags(VARIANT);
#else
// Direct
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
{
uint2 pixelCoord = dispatchThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, groupId);
uint featureFlags = 0xFFFFFFFF;
#endif
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, featureFlags, bsdfData, bakeDiffuseLighting);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;
float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}
#pragma kernel ShadeOpaque_Direct_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl USE_FPTL_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Fptl_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl_DebugDisplay USE_FPTL_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Direct_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered USE_CLUSTERED_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Clustered_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered_DebugDisplay USE_CLUSTERED_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant0 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant1 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant2 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant3 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant4 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant5 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant6 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant7 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant8 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant9 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant10 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant11 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant12 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant13 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant14 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant15 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant0 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant1 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant2 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant3 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant4 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant5 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant6 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant7 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant8 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant9 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant10 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant11 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant12 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant13 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant14 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant15 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma #pragma enable_d3d11_debug_symbols
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../Debug/DebugDisplay.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../../Lighting/TilePass/FeatureFlags.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
#if USE_INDIRECT
uint g_TileListOffset;
StructuredBuffer<uint> g_TileList;
// Indirect
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 groupThreadId : SV_GroupThreadID, uint groupId : SV_GroupID)
{
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, tileCoord);
uint featureFlags = TileVariantToFeatureFlags(VARIANT);
#else
// Direct
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
{
uint2 pixelCoord = dispatchThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, groupId);
uint featureFlags = 0xFFFFFFFF;
#endif
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, featureFlags, bsdfData, bakeDiffuseLighting);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;
float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}

48
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/scrbound.compute


#pragma kernel ScreenBoundsAABB
#include "../../../ShaderLibrary/common.hlsl"
#include "TilePass.cs.hlsl"
#include "../../../../ShaderLibrary/common.hlsl"
#include "../TilePass.cs.hlsl"
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvProjection;

int ClipAgainstPlane(const int iSrcIndex, const int iNrSrcVerts, const int subLigt, const int p);
void CalcBound(out bool2 bIsMinValid, out bool2 bIsMaxValid, out float2 vMin, out float2 vMax, float4x4 InvProjection, float3 pos_view_space, float r);
#include "LightingConvexHullUtils.hlsl"
#include "../LightingConvexHullUtils.hlsl"
[numthreads(NR_THREADS, 1, 1)]

//uint vindex = groupID * NR_THREADS + threadID;
unsigned int g = groupID;
unsigned int t = threadID;

const int sideIndex = (int) (t%8);
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)

const unsigned int uFlag3 = GetClip(vP3);
const float4 vPnts[] = {vP0, vP1, vP2, vP3};
// screen-space AABB of one quad (assuming no intersection)
float3 vMin, vMax;
for(int k=0; k<4; k++)

fW = fS * (fWabs<FLT_EPSILON ? FLT_EPSILON : fWabs);
float3 vP = float3(vPnts[k].x/fW, vPnts[k].y/fW, vPnts[k].z/fW);
if(k==0) { vMin=vP; vMax=vP; }
vMax = max(vMax, vP); vMin = min(vMin, vP);
}

float3 vFaceMi = float3(posX[subLigt*MAX_PNTS*2 + sideIndex + 0], posY[subLigt*MAX_PNTS*2 + sideIndex + 0], posZ[subLigt*MAX_PNTS*2 + sideIndex + 0]);
float3 vFaceMa = float3(posX[subLigt*MAX_PNTS*2 + sideIndex + 6], posY[subLigt*MAX_PNTS*2 + sideIndex + 6], posZ[subLigt*MAX_PNTS*2 + sideIndex + 6]);
vMax = max(vMax, vP); vMin = min(vMin, vP);
}
}

else // :( need true clipping
{
// 4 vertices to a quad of the convex hull in post projection space
const float4 vP0 = mul(g_mProjection, float4(q0, 1));
const float4 vP1 = mul(g_mProjection, float4(q1, 1));

int iSrcIndex = 0;
int offs = iSrcIndex*MAX_PNTS+subLigt*MAX_PNTS*2;

for(int k=0; k<iNrSrcVerts; k++)
{
float4 vCur = float4(posX[offs_src+k], posY[offs_src+k], posZ[offs_src+k], posW[offs_src+k]);
}
////////////////////// look for camera frustum verts that need to be included. That is frustum vertices inside the convex hull for the light

float3 vVertPSpace = float3((i&1)!=0 ? 1 : (-1), (i&2)!=0 ? 1 : (-1), (i&4)!=0 ? 1 : 0);
float4 v4ViewSpace = mul(g_mInvProjection, float4(vVertPSpace,1));
float3 vViewSpace = float3(v4ViewSpace.x/v4ViewSpace.w, v4ViewSpace.y/v4ViewSpace.w, v4ViewSpace.z/v4ViewSpace.w);

float3 vP = float3((i&1)!=0 ? 1 : (-1), (i&2)!=0 ? 1 : (-1), (i&4)!=0 ? 1 : 0);
if(!bSetBoundYet) { vMin=vP; vMax=vP; bSetBoundYet=true; }
vMax = max(vMax, vP); vMin = min(vMin, vP);
}
}

// determine AABB bound in [-1;1]x[-1;1] screen space using bounding sphere.

float2 vMi, vMa;
bool2 bMi, bMa;
CalcBound(bMi, bMa, vMi, vMa, g_mInvProjection, center, radius);
vMin.xy = bMi ? max(vMin.xy, vMi) : vMin.xy;
vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy;
}

// to see if the light is occluded: vMin.z*VIEWPORT_SCALE_Z > MipTexelMaxDepth
//g_vBoundsBuffer[lgtIndex+0] = float3(0.5*vMin.x+0.5, -0.5*vMax.y+0.5, vMin.z*VIEWPORT_SCALE_Z);
//g_vBoundsBuffer[lgtIndex+g_iNrVisibLights] = float3(0.5*vMax.x+0.5, -0.5*vMin.y+0.5, vMax.z*VIEWPORT_SCALE_Z);
// changed for unity
g_vBoundsBuffer[lgtIndex+0] = float3(0.5*vMin.x+0.5, 0.5*vMin.y+0.5, vMin.z*VIEWPORT_SCALE_Z);
g_vBoundsBuffer[lgtIndex+(int) g_iNrVisibLights] = float3(0.5*vMax.x+0.5, 0.5*vMax.y+0.5, vMax.z*VIEWPORT_SCALE_Z);

++nrVertsDst;
}
}
if(bIsCurVisib)
{
//assert(nrVertsDst<MAX_PNTS);

const int index = ((uint) p)/2;
float x1 = index==0 ? vVisib.x : (index==1 ? vVisib.y : vVisib.z);
float x0 = index==0 ? vInvisib.x : (index==1 ? vInvisib.y : vInvisib.z);
//fS*((vVisib.w-vInvisib.w)*t + vInvisib.w) = (x1-x0)*t + x0;
const float fT = (fS*vInvisib.w-x0)/((x1-x0) - fS*(vVisib.w-vInvisib.w));

float4 planeY0 = TransformPlaneToPostSpace(InvProjection, float4(0, planeY.x, planeY.y, 0));
float4 planeY1 = TransformPlaneToPostSpace(InvProjection, float4(0, planeY.z, planeY.w, 0));
// convert planes to the forms (1,0,0,D) and (0,1,0,D)
// 2D bound is given by -D components
float2 A = -float2(planeX0.w / planeX0.x, planeY0.w / planeY0.y);

1001
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild.compute
文件差异内容过多而无法显示
查看文件

32
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-clustered.compute


#pragma kernel TileLightListGen_DepthRT_MSAA_SrcBigTile LIGHTLISTGEN=TileLightListGen_DepthRT_MSAA_SrcBigTile ENABLE_DEPTH_TEXTURE_BACKPLANE MSAA_ENABLED USE_TWO_PASS_TILED_LIGHTING
#pragma kernel ClearAtomic
#include "../../../ShaderLibrary/common.hlsl"
#include "ShaderBase.hlsl"
#include "TilePass.cs.hlsl"
#include "LightingConvexHullUtils.hlsl"
#include "../../../../ShaderLibrary/common.hlsl"
#include "../ShaderBase.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#include "SortingComputeUtils.hlsl"
#include "../SortingComputeUtils.hlsl"
#endif
//#define EXACT_EDGE_TESTS

uniform float g_fFarPlane;
uniform int g_iLog2NumClusters; // numClusters = (1<<g_iLog2NumClusters)
#include "ClusteredUtils.hlsl"
#include "../ClusteredUtils.hlsl"
#ifdef MSAA_ENABLED

for(int p=0; p<6; p++)
{
float4 plane = lightPlanes[6*(l&3)+p];
bool bAllInvisib = true;
for(int i=0; i<8; i++)

#endif
int iNrCoarseLights = min(lightOffs,MAX_NR_COARSE_ENTRIES);
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
iNrCoarseLights = SphericalIntersectionTests( t, iNrCoarseLights, float2(min(viTilLL.xy+uint2(TILE_SIZE_CLUSTERED/2,TILE_SIZE_CLUSTERED/2), uint2(iWidth-1, iHeight-1))) );
#endif

//////////////////////////////////////////////////////////
uint start = 0;
int i=(int) t;
int iSpaceAvail = 0;

float4 FetchPlane(int l, int p)
{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)

float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = (TILE_SIZE_CLUSTERED/2)*onePixDiagDist; // scale by half a tile
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lgtDat = g_data[coarseList[l]];

[branch]if (_LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)

int idx_cur=0, idx_twin=0;
float3 vP0, vE0;
GetHullEdge(idx_cur, idx_twin, vP0, vE0, e0, boxX, boxY, boxZ, center, scaleXY);
int positive=0, negative=0;
for(int k=1; k<8; k++) // only need to test 7 verts (technically just 6).
{

22
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute


#pragma kernel BigTileLightListGen
#include "../../../ShaderLibrary/common.hlsl"
#include "TilePass.cs.hlsl"
#include "LightingConvexHullUtils.hlsl"
#include "SortingComputeUtils.hlsl"
#include "../../../../ShaderLibrary/common.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#include "../SortingComputeUtils.hlsl"
#define EXACT_EDGE_TESTS
#define PERFORM_SPHERICAL_INTERSECTION_TESTS

float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 32*onePixDiagDist; // scale by half a tile
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
lightsListLDS[l]=0xffffffff;
}

[branch]if(canEnter)
{
SFiniteLightBound lgtDat = g_data[idxCoarse];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)

int idx_cur=0, idx_twin=0;
float3 vP0, vE0;
GetHullEdge(idx_cur, idx_twin, vP0, vE0, e0, boxX, boxY, boxZ, center, scaleXY);
int positive=0, negative=0;
for(int k=1; k<8; k++) // only need to test 7 verts (technically just 6).
{

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader


// Include
//-------------------------------------------------------------------------------------
#include "../../ShaderLibrary/Common.hlsl"
#include "../Debug/DebugDisplay.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../Debug/DebugDisplay.hlsl"
#include "../ShaderConfig.cs.hlsl"
#include "../ShaderVariables.hlsl"
#include "../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration

34
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader


Shader "Hidden/HDRenderPipeline/DrawTransmittanceGraph"
{
Properties
{
[HideInInspector] _StdDev1("", Color) = (0, 0, 0)
[HideInInspector] _StdDev2("", Color) = (0, 0, 0)
[HideInInspector] _LerpWeight("", Float) = 0
[HideInInspector] _ThicknessScale("", Float) = 0
[HideInInspector] _TintColor("", Color) = (0, 0, 0)
}
SubShader
{
Pass

// Include
//-------------------------------------------------------------------------------------
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/Color.hlsl"
#include "../ShaderVariables.hlsl"
#define UNITY_MATERIAL_LIT // Needs to be defined before including Material.hlsl
#include "../Material/Material.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../../ShaderVariables.hlsl"
float4 _SurfaceAlbedo, _ShapeParameter, _ThicknessRemap;
float _ScatteringDistance; // See 'SubsurfaceScatteringProfile'
float4 _StdDev1, _StdDev2, _ThicknessRemap, _TintColor;
float _LerpWeight; // See 'SubsurfaceScatteringParameters'
//-------------------------------------------------------------------------------------
// Implementation

float4 Frag(Varyings input) : SV_Target
{
float d = (_ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x));
float3 T = ComputeTransmittance(_ShapeParameter.rgb, _SurfaceAlbedo.rgb, d, 1);
float thickness = _ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x);
float t2 = thickness * thickness;
float3 var1 = _StdDev1.rgb * _StdDev1.rgb;
float3 var2 = _StdDev2.rgb * _StdDev2.rgb;
// See ComputeTransmittance() in Lit.hlsl for more details.
float3 transmittance = lerp(exp(-t2 * 0.5 * rcp(var1)),
exp(-t2 * 0.5 * rcp(var2)), _LerpWeight);
return float4(T, 1);
return float4(transmittance * _TintColor.rgb, 1);
}
ENDHLSL
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawGaussianProfile.shader


// Include
//-------------------------------------------------------------------------------------
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/Color.hlsl"
#include "../ShaderVariables.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../../ShaderVariables.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/GGXConvolve.shader


#pragma vertex Vert
#pragma fragment Frag
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "SkyManager.cs.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "../SkyManager.cs.hlsl"
struct Attributes
{

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute


// Precomputes data for IntegrateLD(). See that function for a detailed description.
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
#ifdef SHADER_API_MOBILE
#define MAX_IBL_SAMPLE_CNT 34

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/BuildProbabilityTables.compute


// Ref: PBRT v3, 13.6.7 "Piecewise-Constant 2D Distributions".
// Note that we use the equiareal sphere-to-square mapping instead of the latitude-longitude one.
#include "../../ShaderLibrary/Common.hlsl"
#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
/* --- Input --- */

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/BlitCubemap.shader


#pragma fragment frag
#pragma target 4.5
#include "../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
TEXTURECUBE(_MainTex);
SAMPLERCUBE(sampler_MainTex);

113
Assets/GraphicsTests/Editor/TestFrameworkCustomBuild.cs


using System.IO;
using UnityEditor;
public class TestFrameworkCustomBuild
{
private static readonly string s_TestSceneFolder = "/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes";
private static readonly string s_BuildFolder = "/TestScenesBuild";
public class TestFrameworkCustomBuild
{
private static readonly string s_TestSceneFolder = "/GraphicsTests/Scenes";
private static readonly string s_BuildFolder = "/TestScenesBuild";
[MenuItem("RenderPipeline/TestFramework/Build-iOS")]
public static void BuildiOS()
{
TestFrameworkCustomBuild builder = new TestFrameworkCustomBuild();
builder.Build(BuildTarget.iOS, BuildOptions.AcceptExternalModificationsToPlayer);
}
[MenuItem("RenderPipeline/TestFramework/Build-iOS")]
public static void BuildiOS()
{
TestFrameworkCustomBuild builder = new TestFrameworkCustomBuild();
builder.Build(BuildTarget.iOS, BuildOptions.AcceptExternalModificationsToPlayer);
}
[MenuItem("RenderPipeline/TestFramework/Build-iOS", true)]
public void Build(BuildTarget target, BuildOptions options)
{
var absoluteScenesPath = Application.dataPath + s_TestSceneFolder;
string[] levels = System.IO.Directory.GetFiles(absoluteScenesPath, "*.unity", System.IO.SearchOption.AllDirectories);
CheckAndAddGotoNextSceneBehavior(levels);
public static bool ValidateBuildiOS()
{
#if UNITY_STANDALONE_OSX
return true;
#else
return false;
#endif
}
string savePath = EditorUtility.SaveFolderPanel("Select folder to save project", "", "");
BuildPipeline.BuildPlayer(levels, savePath + s_BuildFolder, target, options);
}
public void Build(BuildTarget target, BuildOptions options)
{
var absoluteScenesPath = Application.dataPath + s_TestSceneFolder;
string[] levels = System.IO.Directory.GetFiles(absoluteScenesPath, "*.unity", System.IO.SearchOption.AllDirectories);
CheckAndAddGotoNextSceneBehavior(levels);
private void CheckAndAddGotoNextSceneBehavior(string[] levels)
{
for (int i = 0; i < levels.Length; ++i)
{
string levelPath = levels[i];
var scene = EditorSceneManager.OpenScene(levelPath);
GameObject[] objects = scene.GetRootGameObjects();
bool componentFound = false;
string savePath = EditorUtility.SaveFolderPanel("Select folder to save project", "", "");
BuildPipeline.BuildPlayer(levels, savePath + s_BuildFolder, target, options);
}
private void CheckAndAddGotoNextSceneBehavior(string[] levels)
{
for (int i = 0; i < levels.Length; ++i)
{
string levelPath = levels[i];
var scene = EditorSceneManager.OpenScene(levelPath);
GameObject[] objects = scene.GetRootGameObjects();
bool componentFound = false;
foreach (GameObject go in objects)
{
GotoNextScene component = go.GetComponent<GotoNextScene>();
if (component != null)
{
component.m_NextSceneIndex = (i + 1) % levels.Length;
componentFound = true;
break;
}
}
if (!componentFound)
{
GameObject gotoNextScene = new GameObject("GotoNextScene");
GotoNextScene component = gotoNextScene.AddComponent<GotoNextScene>();
component.m_NextSceneIndex = (i + 1) % levels.Length;
}
EditorSceneManager.SaveScene(scene);
EditorSceneManager.UnloadSceneAsync(scene);
}
}
}
}
foreach (GameObject go in objects)
{
GotoNextScene component = go.GetComponent<GotoNextScene>();
if (component != null)
{
component.m_NextSceneIndex = (i + 1) % levels.Length;
componentFound = true;
break;
}
}
if (!componentFound)
{
GameObject gotoNextScene = new GameObject("GotoNextScene");
GotoNextScene component = gotoNextScene.AddComponent<GotoNextScene>();
component.m_NextSceneIndex = (i + 1) % levels.Length;
}
EditorSceneManager.SaveScene(scene);
EditorSceneManager.UnloadSceneAsync(scene);
}
}
}
}

51
Assets/GraphicsTests/Editor/TestFramework.cs


private static readonly string[] s_Path =
{
"GraphicsTests",
"RenderPipeline"
};
private static readonly string[] s_PipelinePath =
{
"LightweightPipeline",
"HDRenderPipeline",
"Scenes"
// info that gets generated for use
// in a dod way
// info that gets generated for use
// in a dod way
public struct TestInfo
{
public string name;

{
get
{
// find all the scenes
var allPaths = System.IO.Directory.GetFiles(absoluteScenesPath, "*.unity", System.IO.SearchOption.AllDirectories);
foreach (var pipelinePath in s_PipelinePath)
// construct all the needed test infos
foreach (var path in allPaths)
var p = new FileInfo (path);
var split = s_Path.Aggregate ("", Path.Combine);
split = string.Format("{0}{1}", split, Path.DirectorySeparatorChar);
var splitPaths = p.FullName.Split(new[] {split}, StringSplitOptions.RemoveEmptyEntries);
var filesPath = Path.Combine(absoluteScenesPath, pipelinePath);
// find all the scenes
var allPaths = System.IO.Directory.GetFiles(filesPath, "*.unity", System.IO.SearchOption.AllDirectories);
// construct all the needed test infos
foreach (var path in allPaths)
{
var p = new FileInfo(path);
var split = s_Path.Aggregate("", Path.Combine);
split = string.Format("{0}{1}", split, Path.DirectorySeparatorChar);
var splitPaths = p.FullName.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries);
yield return new TestInfo
{
name = p.Name,
relativePath = splitPaths.Last(),
threshold = 0.02f,
frameWait = 100
};
}
yield return new TestInfo
{
name = p.Name,
relativePath = splitPaths.Last(),
threshold = 0.02f,
frameWait = 100
};
}
}
}

{
var prjRelativeGraphsPath = s_Path.Aggregate("Assets", Path.Combine);
var filePath = Path.Combine(prjRelativeGraphsPath, testInfo.relativePath);
// open the scene
EditorSceneManager.OpenScene(filePath);

8
Assets/GraphicsTests/Scenes/LowEnd/SimpleCube.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.18028377, g: 0.22571409, b: 0.30692285, a: 1}
m_IndirectSpecularColor: {r: 0.18022086, g: 0.2256495, b: 0.30683416, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &380492249
GameObject:

m_Script: {fileID: 11500000, guid: c20dfc007a9a74ad8a2bfd0d59abe398, type: 3}
m_Name:
m_EditorClassIdentifier:
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, type: 2}
renderPipeline: {fileID: 11400000, guid: 877878ed40e8ad94095582ff91179016, type: 2}
hdr: 0
width: 1280
height: 720
--- !u!1 &707831285

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

7
Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderReflection.unity


manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &167879083
GameObject:

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_Script: {fileID: 11500000, guid: c20dfc007a9a74ad8a2bfd0d59abe398, type: 3}
m_Name:
m_EditorClassIdentifier:
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, type: 2}
renderPipeline: {fileID: 11400000, guid: 877878ed40e8ad94095582ff91179016, type: 2}
cameraToUse: {fileID: 971756574}
hdr: 0
width: 1280

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

332
Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderMaps.unity


manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &35430816
GameObject:

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 35430816}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -1.686, y: -0.6, z: 0}
m_LocalPosition: {x: -1.2, y: -0.6, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 167879083}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.486, y: 0.6, z: 0}
m_LocalPosition: {x: 0, y: 0.6, z: 0}
--- !u!1 &222008785
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 222008789}
- component: {fileID: 222008788}
- component: {fileID: 222008787}
- component: {fileID: 222008786}
m_Layer: 0
m_Name: Quad (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &222008786
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 222008785}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 96f2a4d5f3b72eb468a638a4bed6ca76, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &222008787
MeshCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 222008785}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Convex: 0
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &222008788
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 222008785}
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &222008789
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 222008785}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.68, y: 0.041, z: -2.541}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &316403771
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 316403774}
- component: {fileID: 316403773}
- component: {fileID: 316403772}
m_Layer: 0
m_Name: UnlitSphere (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &316403772
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 316403771}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 46f4548be2fd99a49930be9c22b22312, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &316403773
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 316403771}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &316403774
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 316403771}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 2.079, y: 0.638, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 9
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &442397141
GameObject:
m_ObjectHideFlags: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 442397141}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.714, y: -0.6, z: 0}
m_LocalPosition: {x: 1.2, y: -0.6, z: 0}
--- !u!1 &576034924
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 576034928}
- component: {fileID: 576034927}
- component: {fileID: 576034926}
- component: {fileID: 576034925}
m_Layer: 0
m_Name: Quad
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &576034925
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 576034924}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: f51bbc8f90c3bf54588afe5d142636b3, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &576034926
MeshCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 576034924}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Convex: 0
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &576034927
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 576034924}
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &576034928
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 576034924}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.504, y: 0.041, z: -2.541}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &952102529
GameObject:
m_ObjectHideFlags: 0

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 952102529}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -1.686, y: 0.6, z: 0}
m_LocalPosition: {x: -1.2, y: 0.6, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

m_Script: {fileID: 11500000, guid: c20dfc007a9a74ad8a2bfd0d59abe398, type: 3}
m_Name:
m_EditorClassIdentifier:
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, type: 2}
renderPipeline: {fileID: 11400000, guid: 877878ed40e8ad94095582ff91179016, type: 2}
cameraToUse: {fileID: 971756574}
hdr: 0
width: 1280

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1511850536}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.486, y: -0.6, z: 0}
m_LocalPosition: {x: 0, y: -0.6, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1664660672}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.714, y: 0.6, z: 0}
m_LocalPosition: {x: 1.2, y: 0.6, z: 0}
--- !u!1 &1823431991
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1823431994}
- component: {fileID: 1823431993}
- component: {fileID: 1823431992}
m_Layer: 0
m_Name: UnlitSphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &1823431992
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1823431991}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 466de0b30ac50484c9d07caa7c51b179, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &1823431993
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1823431991}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1823431994
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1823431991}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 2.079, y: -0.626, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 8
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

5
Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr.meta


fileFormatVersion: 2
guid: 63403075b192e934286da6ba690accf9
timeCreated: 1496330219
guid: e4dc9d638c4ff407599842bfe66fed2b
timeCreated: 1493310899
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}

platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50

1001
Assets/GraphicsTests/Scenes/LowEnd/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr
文件差异内容过多而无法显示
查看文件

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

正在加载...
取消
保存