浏览代码

Merge branch 'master' into classicDeferredMobile

/main
Filip Iliescu 7 年前
当前提交
dda281fd
共有 499 个文件被更改,包括 4149 次插入3373 次删除
  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. 34
      Assets/ScriptableRenderPipeline/ShaderLibrary/BSDF.hlsl
  46. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  47. 6
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl
  48. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/EntityLighting.hlsl
  49. 2
      Assets/ScriptableRenderPipeline/ShaderLibrary/ImageBasedLighting.hlsl
  50. 3
      Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl
  51. 97
      Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl
  52. 10
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  53. 6
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  54. 13
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl
  55. 26
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl
  56. 61
      Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.cs
  57. 6
      Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.asset
  58. 21
      Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  59. 9
      Assets/ScriptableRenderPipeline/LightweightPipeline/TestScenes/Materials/LDRenderPipeMaterials/LDSpecularSphere0.mat
  60. 44
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineShadows.cginc
  61. 14
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc
  62. 70
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader
  63. 6
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightParticlesMultiply.shader
  64. 6
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightParticlesAdd.shader
  65. 14
      Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightPipelineUpgraders.cs
  66. 21
      Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightPipelineMaterialEditor.cs
  67. 12
      Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightAssetInspector.cs
  68. 10
      Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LegacyShadersToLightweightPipelineUpgrader.cs
  69. 2
      Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/UpgradeCommon.cs
  70. 2
      Assets/TestScenes/HDTest/GraphicTest/SSS/Materials/SSSHead.mat
  71. 451
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity
  72. 8
      ProjectSettings/EditorBuildSettings.asset
  73. 2
      ProjectSettings/ProjectVersion.txt
  74. 89
      ProjectSettings/TagManager.asset
  75. 1
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_Reflection_Non.mat
  76. 3
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_Reflection_Cube.mat
  77. 3
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_06_All.mat
  78. 5
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_05_Emission.mat
  79. 5
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/LDpipe_targetTex.mat
  80. 1
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/Cornell Box_red.mat
  81. 1
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/Cornell Box_green.mat
  82. 1
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/Cornell Box.mat
  83. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/DrawGaussianProfile.shader
  84. 34
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/DrawTransmittanceGraph.shader
  85. 2
      Assets/ScriptableRenderPipeline/Fptl/LightDefinitions.cs.hlsl
  86. 999
      ImageTemplates/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderMaps.unity.png
  87. 999
      ImageTemplates/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes.unity.png
  88. 113
      Assets/GraphicsTests/Framework/Editor/TestFrameworkCustomBuild.cs
  89. 8
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/SimpleCube.unity
  90. 7
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderReflection.unity
  91. 332
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderMaps.unity
  92. 5
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr.meta
  93. 1001
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr
  94. 4
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/LightingData.asset.meta
  95. 154
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/LightingData.asset
  96. 31
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes.unity
  97. 6
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Camera/LDPipe_Camera_TargetTexture.unity
  98. 7
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Camera/LDPipe_Camera_Ortho.unity
  99. 7
      Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Camera/LDPipe_Camera_Clip.unity
  100. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplayLatlong.shader

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 DebugItemDrawerIntEnum(m_CameraNames, m_CameraIndices));
DebugMenuManager.instance.AddDebugItem<int>("Camera", "Camera Switcher", () => m_CurrentCameraIndex, (value) => SetCameraIndex((int)value), false, new DebugItemHandlerIntEnum(m_CameraNames, m_CameraIndices));
}
int GetCameraCount()

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


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

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

DebugActionDesc persistent = new DebugActionDesc();
persistent.buttonTriggerList.Add(new[] { kPersistentBtn });
persistent.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.Persistent, persistent);
AddAction(DebugAction.MakePersistent, persistent);
AddAction(DebugAction.MoveVertical, new DebugActionDesc { axisTrigger = kDPadVertical, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.2f } );
AddAction(DebugAction.MoveHorizontal, new DebugActionDesc { axisTrigger = kDPadHorizontal, repeatMode = DebugActionRepeatMode.Delay, repeatDelay = 0.2f } );

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


{
public class DebugMenuManager
{
static private DebugMenuManager s_Instance = null;
private static 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; } }
LookUpDebugMenuClasses();
m_PersistentDebugMenu = new DebugMenu("Persistent");
m_PersistentDebugPanel = new DebugPanel<DebugPanelUI>("Persistent");
}
bool m_Enabled = false;
int m_ActiveMenuIndex = 0;
List<DebugMenu> m_DebugMenus = new List<DebugMenu>();
DebugMenu m_PersistentDebugMenu = null;
DebugMenuUI m_DebugMenuUI = null;
LookUpDebugPanelClasses();
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; } }
var updater = GameObject.Find("DebugMenuUpdater");
if (updater == null)
{
GameObject go = new GameObject("DebugMenuUpdater");
go.hideFlags = HideFlags.HideAndDontSave;
go.AddComponent<DebugMenuUpdater>();
}
}
public DebugMenu GetDebugMenu(int index)
public DebugPanel GetDebugPanel(int index)
if (index < m_DebugMenus.Count)
return m_DebugMenus[index];
if (index < m_DebugPanels.Count)
return m_DebugPanels[index];
public DebugMenu GetPersistentDebugMenu()
public DebugPanel GetPersistentDebugPanel()
return m_PersistentDebugMenu;
return m_PersistentDebugPanel;
void LookUpDebugMenuClasses()
void LookUpDebugPanelClasses()
var types = Assembly.GetAssembly(typeof(DebugMenu)).GetTypes()
.Where(t => t.IsSubclassOf(typeof(DebugMenu)));
var types = Assembly.GetAssembly(typeof(DebugPanel)).GetTypes()
.Where(t => t.IsSubclassOf(typeof(DebugPanel)));
m_DebugMenus.Clear();
m_DebugPanels.Clear();
m_DebugMenus.Add((DebugMenu)Activator.CreateInstance(type));
}
}
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()
{
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);
if(!type.IsGenericTypeDefinition)
AddDebugPanel((DebugPanel)Activator.CreateInstance(type));
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
T GetDebugPanel<T>() where T:DebugPanel
foreach(DebugMenu menu in m_DebugMenus)
foreach(DebugPanel menu in m_DebugPanels)
{
if (menu is T)
return menu as T;

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

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

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_MenuRoots = null;
GameObject m_MainPanelLayout = null;
GameObject m_PersistentPanelLayout = null;
List<DebugPanelUI> m_DebugPanelUIs = new List<DebugPanelUI>();
DebugPanelUI m_PersistentDebugPanelUI = null;
GameObject m_PersistentMenuRoot = null;
bool m_Enabled = false;
GameObject m_PersistentPanelRoot = null;
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 Toggle()
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()
m_MainMenuRoot.SetActive(m_Enabled);
if(m_Enabled)
{
BuildGUI();
m_MainMenuRoot.SetActive(true);
m_DebugPanelUIs[m_ActivePanelIndex].SetSelected(m_Enabled);
}
else
{
m_MainMenuRoot.SetActive(false);
}
}
public void OnValidate()
{
m_DebugPanelUIs[m_ActivePanelIndex].OnValidate();
public void EnablePersistentView(bool value)
public void OnMoveHorizontal(float value)
m_PersistentMenuRoot.SetActive(value);
m_DebugPanelUIs[m_ActivePanelIndex].OnMoveHorizontal(value);
}
public void OnMoveVertical(float value)
{
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();
void CleanUpGUI()
public void OnMakePersistent()
Object.Destroy(m_Root);
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);
}
}
public void BuildGUI()

image.rectTransform.sizeDelta = new Vector2(-(kBorderSize * 2.0f), -(kBorderSize * 2.0f));
image.color = kBackgroundColor;
GameObject goVL = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_MainMenuRoot);
RectTransform menuVLRectTransform = goVL.GetComponent<RectTransform>();
m_MainPanelLayout = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_MainMenuRoot);
RectTransform menuVLRectTransform = m_MainPanelLayout.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_PersistentMenuRoot = new GameObject("Background_Persistent");
m_PersistentMenuRoot.AddComponent<CanvasRenderer>();
image = m_PersistentMenuRoot.AddComponent<UI.Image>();
m_PersistentMenuRoot.transform.SetParent(m_Root.transform, false);
m_PersistentPanelRoot = new GameObject("Background_Persistent");
m_PersistentPanelRoot.AddComponent<CanvasRenderer>();
image = m_PersistentPanelRoot.AddComponent<UI.Image>();
m_PersistentPanelRoot.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;
GameObject goVL2 = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_PersistentMenuRoot);
menuVLRectTransform = goVL2.GetComponent<RectTransform>();
m_PersistentPanelLayout = DebugMenuUI.CreateVerticalLayoutGroup("DebugMenu VLayout", true, true, true, false, 5.0f, m_PersistentPanelRoot);
menuVLRectTransform = m_PersistentPanelLayout.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_PersistentMenuRoot.SetActive(false);
m_PersistentPanelRoot.SetActive(false);
DebugMenuUI.CreateTextElement("DebugMenuTitle", "Debug Menu", 14, TextAnchor.MiddleCenter, goVL);
DebugMenuUI.CreateTextElement("DebugMenuTitle", "Debug Menu", 14, TextAnchor.MiddleCenter, m_MainPanelLayout);
int menuCount = m_DebugMenuManager.menuCount;
m_MenuRoots = new GameObject[menuCount];
for (int i = 0; i < menuCount; ++i)
m_DebugMenuManager.GetPersistentDebugPanel().panelUI.BuildGUI(m_PersistentPanelLayout);
m_PersistentDebugPanelUI = m_DebugMenuManager.GetPersistentDebugPanel().panelUI;
for (int i = 0; i < m_DebugMenuManager.panelCount; ++i)
m_MenuRoots[i] = m_DebugMenuManager.GetDebugMenu(i).BuildGUI(goVL);
m_DebugMenuManager.GetDebugPanel(i).panelUI.BuildGUI(m_MainPanelLayout);
m_DebugPanelUIs[i].SetSelected(false);
}
m_DebugMenuManager.GetPersistentDebugMenu().BuildGUI(goVL2);
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();
}
}
#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.ToggleMenu();
DebugMenuManager.instance.menuUI.ToggleMenu();
if (DebugMenuManager.instance.isEnabled)
if (DebugMenuManager.instance.menuUI.isEnabled)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.PreviousDebugMenu) != 0.0f)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.PreviousDebugPanel) != 0.0f)
DebugMenuManager.instance.PreviousDebugMenu();
DebugMenuManager.instance.menuUI.PreviousDebugPanel();
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.NextDebugMenu) != 0.0f)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.NextDebugPanel) != 0.0f)
DebugMenuManager.instance.NextDebugMenu();
DebugMenuManager.instance.menuUI.NextDebugPanel();
DebugMenuManager.instance.OnValidate();
DebugMenuManager.instance.menuUI.OnValidate();
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.Persistent) != 0.0f)
if (DebugActionManager.instance.GetAction(DebugActionManager.DebugAction.MakePersistent) != 0.0f)
DebugMenuManager.instance.OnMakePersistent();
DebugMenuManager.instance.menuUI.OnMakePersistent();
DebugMenuManager.instance.OnMoveHorizontal(moveHorizontal);
DebugMenuManager.instance.menuUI.OnMoveHorizontal(moveHorizontal);
DebugMenuManager.instance.OnMoveVertical(moveVertical);
DebugMenuManager.instance.menuUI.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;
DebugMenuEditor()
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 OnEnable()
void OnDisable()
m_DebugMenu = DebugMenuManager.instance;
DebugItem.OnItemDirty -= DebugItem_OnDirty;
}
void OnDestroy()
{
Object.DestroyImmediate(m_DebugMenuState);
}
void DebugItem_OnDirty(DebugItem item)
{
DebugItemState debugItemState = m_DebugMenuState.FindDebugItemState(item);
UnityEditor.Undo.RecordObject(debugItemState, "DebugMenu State Update");
debugItemState.SetValue(item.GetValue());
EditorUtility.SetDirty(m_DebugMenuState);
}
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();
int debugMenuCount = m_DebugMenu.menuCount;
int activeMenuIndex = m_DebugMenu.activeMenuIndex;
DebugMenuUI debugMenuUI = m_DebugMenu.menuUI;
int debugMenuCount = m_DebugMenu.panelCount;
int activePanelIndex = debugMenuUI.activePanelIndex;
using (new EditorGUILayout.HorizontalScope())
{
for(int i = 0 ; i < debugMenuCount ; ++i)

style = EditorStyles.miniButtonLeft;
if (i == debugMenuCount - 1)
style = EditorStyles.miniButtonRight;
if (GUILayout.Toggle(i == activeMenuIndex, new GUIContent(m_DebugMenu.GetDebugMenu(i).name), style))
activeMenuIndex = i;
string name = m_DebugMenu.GetDebugPanel(i).name;
if (GUILayout.Toggle(i == activePanelIndex, new GUIContent(name), style))
activePanelIndex = i;
m_DebugMenu.activeMenuIndex = activeMenuIndex;
debugMenuUI.activePanelIndex = activePanelIndex;
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();
}
if (needRepaint)
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
debugMenuUI.OnEditorGUI();
}
}

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, 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 );
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 );
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.3f , 1.0f , 0.0001f);
readonly ValRange m_DefMSM_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.0f , 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/common/Shadow/ShadowBase.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderPipeline/Core/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, Vector3 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, float[] 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.
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, splitRatio, (int) width, nearPlaneOffset, out view, out proj, out splitData );
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 );
// 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 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", "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", "GBuffer",() => materialDebugSettings.debugViewGBuffer, (value) => SetDebugViewGBuffer((int)value), false, new DebugItemDrawerIntEnum(DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "GBuffer",() => materialDebugSettings.debugViewGBuffer, (value) => SetDebugViewGBuffer((int)value), false, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues));
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, 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, float>("Sky Reflection Mipmap", () => lightingDebugSettings.skyReflectionMipmap, (value) => lightingDebugSettings.skyReflectionMipmap = (float)value, false, new DebugItemDrawFloatMinMax(0.0f, 1.0f));
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<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(HDRenderPipeline))]
[CustomEditor(typeof(HDRenderPipelineAsset))]
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_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[] 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 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 enableTileAndCluster = new GUIContent("Enable tile/clustered", "Toggle");
public readonly GUIContent enableSplitLightEvaluation = new GUIContent("Split light and reflection evaluation", "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;
// 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;
// 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;
// Rendering Settings
SerializedProperty m_RenderingUseForwardOnly = null;

m_DefaultDiffuseMaterial = serializedObject.FindProperty("m_DefaultDiffuseMaterial");
m_DefaultShader = serializedObject.FindProperty("m_DefaultShader");
// 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);
// Following way of getting property allow to handle change of properties name with serializations
// 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
// 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);
//TODO!
// Rendering settings
m_RenderingUseForwardOnly = FindProperty(x => x.renderingSettings.useForwardRenderingOnly);

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

method.Invoke(asset, new object[0]);
}
private void DebuggingUI(HDRenderPipeline renderContext, HDRenderPipelineInstance renderpipelineInstance)
private void TileSettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.LabelField(styles.debugging);
// Debug Display settings
EditorGUI.indentLevel++;
m_DebugOverlayRatio.floatValue = EditorGUILayout.Slider(styles.debugOverlayRatio, m_DebugOverlayRatio.floatValue, 0.1f, 1.0f);
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;
EditorGUILayout.LabelField(styles.tileLightLoopSettings);
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;
}
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntPopup(styles.debugViewEngine, hdPipe.debugDisplaySettings.materialDebugSettings.debugViewEngine, DebugDisplaySettings.debugViewEngineStrings, DebugDisplaySettings.debugViewEngineValues);
if (EditorGUI.EndChangeCheck())
{
hdPipe.debugDisplaySettings.SetDebugViewEngine(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.debugViewMaterialVarying, (int)hdPipe.debugDisplaySettings.materialDebugSettings.debugViewVarying, DebugDisplaySettings.debugViewMaterialVaryingStrings, DebugDisplaySettings.debugViewMaterialVaryingValues);
hdPipe.debugDisplaySettings.SetDebugViewVarying((Attributes.DebugViewVarying)value);
dirty = true;
HackSetDirty(renderContext); // Repaint
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.IntPopup(styles.debugViewMaterialGBuffer, (int)hdPipe.debugDisplaySettings.materialDebugSettings.debugViewGBuffer, DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues);
if (EditorGUI.EndChangeCheck())
{
hdPipe.debugDisplaySettings.SetDebugViewGBuffer(value);
dirty = true;
}
if(dirty)
HackSetDirty(renderContext); // Repaint
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)
private void SssSettingsUI(HDRenderPipelineAsset renderContext)
{
EditorGUILayout.Space();

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

}
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)
private void SettingsUI(HDRenderPipelineAsset renderContext)
EditorGUI.BeginChangeCheck();
renderContext.lightLoopProducer = (LightLoopProducer)EditorGUILayout.ObjectField(new GUIContent("Light Loop"), renderContext.lightLoopProducer, typeof(LightLoopProducer), false);
if (EditorGUI.EndChangeCheck())
{
HackSetDirty(renderContext); // Repaint
}
//TilePassUI(renderContext);
TileSettingsUI(renderContext);
private void ShadowSettingsUI(HDRenderPipeline renderContext)
private void ShadowSettingsUI(HDRenderPipelineAsset renderContext)
{
EditorGUILayout.Space();
var shadowSettings = renderContext.shadowSettings;

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

EditorGUI.indentLevel--;
}
private void TextureSettingsUI(HDRenderPipeline renderContext)
private void TextureSettingsUI(HDRenderPipelineAsset 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 HDRenderPipeline;
HDRenderPipelineInstance renderpipelineInstance = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
var renderContext = target as HDRenderPipelineAsset;
HDRenderPipeline renderpipeline = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipeline;
if (!renderContext || renderpipelineInstance == null)
if (!renderContext || renderpipeline == 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 artits to re-synchronise all layered materials
// This script is a helper for the artists 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()
{
HDRenderPipelineInstance renderpipelineInstance = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if(renderpipelineInstance == null)
HDRenderPipeline renderpipeline = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipeline;
if(renderpipeline == null)
Texture2D result = renderpipelineInstance.ExportSkyToTexture();
Texture2D result = renderpipeline.ExportSkyToTexture();
if(result == null)
{
return;

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


CreateAsset<CommonSettings>("NewCommonSettings");
}
if (GUILayout.Button("Create new HDRI sky params"))
if (GUILayout.Button("Create new HDRI Sky Settings"))
if (GUILayout.Button("Create new Procedural sky params"))
if (GUILayout.Button("Create new Procedural Sky Settings"))
{
CreateAsset<ProceduralSkySettings>("NewProceduralSkySettings");
}
if (GUILayout.Button("Create new Ambient Occlusion Settings"))
CreateAsset<ProceduralSkySettings>("NewProceduralSkyParameters");
CreateAsset<ScreenSpaceAmbientOcclusionSettings>("NewAmbientOcclusionSettings");
}
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 HDRenderPipelineInstance : RenderPipeline
public class HDRenderPipeline : RenderPipeline
private readonly HDRenderPipeline m_Owner;
private readonly HDRenderPipelineAsset m_Asset;
// 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 (recycled on every frame to avoid GC alloc)
// Post-processing context and screen-space effects (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();
private readonly BaseLightLoop m_LightLoop;
readonly LightLoop m_LightLoop = new LightLoop();
get { return m_Owner.debugDisplaySettings; }
get { return m_Asset.debugDisplaySettings; }
get { return m_Owner.sssSettings; }
get { return m_Asset.sssSettings; }
public HDRenderPipelineInstance(HDRenderPipeline owner)
public HDRenderPipeline(HDRenderPipelineAsset asset)
m_Owner = owner;
m_Asset = asset;
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_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraSubsurfaceBufferRT = new RenderTargetIdentifier(m_CameraSubsurfaceBuffer);
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();
if (owner.lightLoopProducer)
m_LightLoop = owner.lightLoopProducer.CreateLightLoop();
m_LitRenderLoop.Build(asset.renderPipelineResources);
if (m_LightLoop != null)
m_LightLoop.Build(owner.textureSettings);
m_LightLoop.Build(asset.renderPipelineResources, asset.tileSettings, asset.textureSettings);
m_SkyManager.Build();
m_SkyManager.skySettings = owner.skySettingsToUse;
m_SkyManager.Build(asset.renderPipelineResources);
m_SkyManager.skySettings = asset.skySettingsToUse;
m_SsaoEffect = new ScreenSpaceAmbientOcclusionEffect();
m_SsaoEffect.Build(asset.renderPipelineResources);
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewMaterialGBuffer");
m_DebugDisplayLatlong = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayLatlong");
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugViewMaterialGBufferShader);
m_DebugDisplayLatlong = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugDisplayLatlongShader);
m_LitRenderLoop.Build();
m_LitRenderLoop.Build(m_Asset.renderPipelineResources);
}
public override void Dispose()

if (m_LightLoop != null)
m_LightLoop.Cleanup();
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_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;
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)
bool resolutionChanged = camera.pixelWidth != m_CurrentWidth || camera.pixelHeight != m_CurrentHeight;

}
// Broadcast SSS parameters to all shaders.
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);
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);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

m_LitRenderLoop.RenderInit(renderContext);
// Do anything we need to do upon a new frame.
if (m_LightLoop != null)
m_LightLoop.NewFrame();
m_LightLoop.NewFrame();
m_Owner.ApplyDebugDisplaySettings();
m_Owner.UpdateCommonSettings();
m_Asset.ApplyDebugDisplaySettings();
m_Asset.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_Owner.renderingSettings.useForwardRenderingOnly)
if (!m_Asset.renderingSettings.useForwardRenderingOnly)
{
CopyDepthBufferIfNeeded(renderContext);
}

}
else
{
if (m_LightLoop != null)
using (new Utilities.ProfilingSample("Build Light list and render shadows", renderContext))
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
}
// 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);
PushGlobalParams(hdCamera, renderContext, m_Owner.sssSettings);
PushGlobalParams(hdCamera, renderContext, m_Asset.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_Owner.sssSettings);
CombineSubsurfaceScattering(hdCamera, renderContext, m_Asset.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_Owner.renderingSettings.useForwardRenderingOnly)
if (m_Asset.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_Owner.renderingSettings.useDepthPrepass)
if (!m_Asset.renderingSettings.useDepthPrepass)
return;
using (new Utilities.ProfilingSample("Depth Prepass", renderContext))

void RenderGBuffer(CullResults cull, Camera camera, ScriptableRenderContext renderContext)
{
if (m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
if (m_Asset.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_Owner.renderingSettings.ShouldUseForwardRenderingOnly() && !m_Owner.renderingSettings.useDepthPrepass)
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && !m_Asset.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_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
{
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewMaterialGBuffer);
// Render GBuffer opaque
if (!m_Asset.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_Owner.renderingSettings.ShouldUseForwardRenderingOnly() || m_LightLoop == null)
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{
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_Owner.renderingSettings.ShouldUseForwardRenderingOnly()) return;
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly()) return;
// 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);
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);
// 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 == null ? null : m_LightLoop.GetCurrentSunLight(), renderContext);
m_SkyManager.UpdateEnvironment(hdCamera,m_LightLoop.GetCurrentSunLight(), renderContext);
m_SkyManager.RenderSky(hdCamera, m_LightLoop == null ? null : m_LightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, renderContext);
m_SkyManager.RenderSky(hdCamera, m_LightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, renderContext);
}
public Texture2D ExportSkyToTexture()

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

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

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

{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
if (m_LightLoop != null)
m_LightLoop.RenderForward(camera, renderContext, true);
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_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
if ((ShaderConfig.s_VelocityInGbuffer == 1) || m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
return;
int w = camera.pixelWidth;

renderContext.ExecuteCommandBuffer(debugCB);
if (m_LightLoop != null)
m_LightLoop.RenderDebugOverlay(camera, renderContext, debugDisplaySettings, ref x, ref y, overlaySize, camera.pixelWidth);
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_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{
m_gbufferManager.InitGBuffers(w, h, cmd);
}

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

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


public float unused2;
};
public class LightLoop : BaseLightLoop
[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 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_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 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 clearDispatchIndirectShader { get { return m_PassResources.clearDispatchIndirectShader; } }
private ComputeShader shadeOpaqueShader { get { return m_PassResources.shadeOpaqueShader; } }
private ComputeShader clearDispatchIndirectShader { get { return m_Resources.clearDispatchIndirectShader; } }
private ComputeShader shadeOpaqueShader { get { return m_Resources.shadeOpaqueShader; } }
static int s_GenAABBKernel;
static int s_GenListPerTileKernel;

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

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

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

bool enableFeatureVariants = GetFeatureVariantsEnabled();
if (enableFeatureVariants)
{
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_PassSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile_FeatureFlags" : "TileLightListGen_FeatureFlags");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_TileSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile_FeatureFlags" : "TileLightListGen_FeatureFlags");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_PassSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile" : "TileLightListGen");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_TileSettings.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_PassSettings.enableClustered)
if (m_TileSettings.enableClustered)
var kernelName = m_PassSettings.enableBigTilePrepass ? (k_UseDepthBuffer ? "TileLightListGen_DepthRT_SrcBigTile" : "TileLightListGen_NoDepthRT_SrcBigTile") : (k_UseDepthBuffer ? "TileLightListGen_DepthRT" : "TileLightListGen_NoDepthRT");
var kernelName = m_TileSettings.enableBigTilePrepass ? (k_UseDepthBuffer ? "TileLightListGen_DepthRT_SrcBigTile" : "TileLightListGen_NoDepthRT_SrcBigTile") : (k_UseDepthBuffer ? "TileLightListGen_DepthRT" : "TileLightListGen_NoDepthRT");
if (m_PassSettings.enableBigTilePrepass)
if (m_TileSettings.enableBigTilePrepass)
{
s_GenListPerBigTileKernel = buildPerBigTileLightListShader.FindKernel("BigTileLightListGen");
}

string[] tileKeywords = {"LIGHTLOOP_TILE_DIRECT", "LIGHTLOOP_TILE_INDIRECT", "LIGHTLOOP_TILE_ALL"};
m_DeferredDirectMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_DeferredDirectMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
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("Hidden/HDRenderPipeline/Deferred");
m_DeferredDirectMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
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("Hidden/HDRenderPipeline/Deferred");
m_DeferredIndirectMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
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("Hidden/HDRenderPipeline/Deferred");
m_DeferredIndirectMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
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("Hidden/HDRenderPipeline/Deferred");
m_DeferredAllMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
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("Hidden/HDRenderPipeline/Deferred");
m_DeferredAllMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
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_DebugViewTilesMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewTiles");
m_SingleDeferredMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_SingleDeferredMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_SingleDeferredMaterialSRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialSRT.SetInt("_StencilRef", (int)StencilBits.SSS);

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

m_DebugDisplayShadowMap = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayShadowMap");
m_DebugViewTilesMaterial = Utilities.CreateEngineMaterial(m_Resources.debugViewTilesShader);
m_DebugDisplayShadowMap = Utilities.CreateEngineMaterial(m_Resources.debugDisplayShadowMapShader);
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 override void Cleanup()
public void Cleanup()
{
DeinitShadowSystem();

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

public override bool NeedResize()
public bool NeedResize()
(s_BigTileLightList == null && m_PassSettings.enableBigTilePrepass) ||
(s_PerVoxelLightLists == null && m_PassSettings.enableClustered);
(s_BigTileLightList == null && m_TileSettings.enableBigTilePrepass) ||
(s_PerVoxelLightLists == null && m_TileSettings.enableClustered);
public override void ReleaseResolutionDependentBuffers()
public 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 override void AllocResolutionDependentBuffers(int width, int height)
public 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_PassSettings.enableClustered)
if (m_TileSettings.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_PassSettings.enableBigTilePrepass)
if (m_TileSettings.enableBigTilePrepass)
{
var nrBigTilesX = (width + 63) / 64;
var nrBigTilesY = (height + 63) / 64;

{
var directionalLightData = new DirectionalLightData();
float diffuseDimmer = m_PassSettings.diffuseGlobalDimmer * additionalData.lightDimmer;
float specularDimmer = m_PassSettings.specularGlobalDimmer * additionalData.lightDimmer;
float diffuseDimmer = m_TileSettings.diffuseGlobalDimmer * additionalData.lightDimmer;
float specularDimmer = m_TileSettings.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_PassSettings.diffuseGlobalDimmer : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? lightScale * m_PassSettings.specularGlobalDimmer : 0.0f;
lightData.diffuseScale = additionalData.affectDiffuse ? lightScale * m_TileSettings.diffuseGlobalDimmer : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? lightScale * m_TileSettings.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 override int GetCurrentShadowCount()
public int GetCurrentShadowCount()
public override void UpdateCullingParameters(ref CullingParameters cullingParams)
public void UpdateCullingParameters(ref CullingParameters cullingParams)
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)
public void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)
{
m_lightList.Clear();

}
}
float oldSpecularGlobalDimmer = m_PassSettings.specularGlobalDimmer;
float oldSpecularGlobalDimmer = m_TileSettings.specularGlobalDimmer;
m_PassSettings.specularGlobalDimmer = 0.0f;
m_TileSettings.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);
Array.Sort(sortKeys, 0, sortCount);
// 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);
Array.Sort(sortKeys, 0, sortCount);
for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex)
{

Debug.Assert(m_lightList.envLights.Count == envLightCount);
// Restore values after "special rendering"
m_PassSettings.specularGlobalDimmer = oldSpecularGlobalDimmer;
m_TileSettings.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_PassSettings.enableBigTilePrepass)
if (m_TileSettings.enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vBigTileLightList", s_BigTileLightList);
if (k_UseDepthBuffer)

cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
}
public override void BuildGPULightLists(Camera camera, ScriptableRenderContext loop, RenderTargetIdentifier cameraDepthBufferRT)
public 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_PassSettings.enableBigTilePrepass)
if (m_TileSettings.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_PassSettings.enableBigTilePrepass)
if (m_TileSettings.enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vBigTileLightList", s_BigTileLightList);

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

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

#endif
public override void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults)
public 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 override void RenderLightingDebug(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
public void RenderLightingDebug(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
if (m_PassSettings.tileDebugByCategory == TileLightLoopProducer.TileSettings.TileDebug.None)
if (m_TileSettings.tileDebugByCategory == TileSettings.TileDebug.None)
return;
var cmd = new CommandBuffer();

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

m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_TileSettings.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_PassSettings.tileDebugByCategory != TileLightLoopProducer.TileSettings.TileDebug.None)
else if (m_TileSettings.tileDebugByCategory != TileSettings.TileDebug.None)
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_TileSettings.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 override void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
DebugDisplaySettings debugDisplaySettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
bool outputSplitLightingForSSS)
public void RenderDeferredLighting( HDCamera hdCamera, ScriptableRenderContext renderContext,
DebugDisplaySettings debugDisplaySettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
bool outputSplitLightingForSSS)
using (new Utilities.ProfilingSample((m_PassSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass") + (outputSplitLightingForSSS ? " MRT" : ""), renderContext))
using (new Utilities.ProfilingSample((m_TileSettings.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_PassSettings.enableTileAndCluster)
if (!m_TileSettings.enableTileAndCluster)
{
PushGlobalParams(camera, renderContext, null, 0);

int numTilesY = (h + 15) / 16;
int numTiles = numTilesX * numTilesY;
if (m_PassSettings.enableComputeLightEvaluation)
if (m_TileSettings.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_PassSettings.enableSplitLightEvaluation)
if (m_TileSettings.enableSplitLightEvaluation)
{
if (outputSplitLightingForSSS)
{

} // TilePass - Deferred Lighting Pass
}
public override void RenderForward(Camera camera, ScriptableRenderContext renderContext, bool renderOpaque)
public 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_PassSettings.enableTileAndCluster)
if (!m_TileSettings.enableTileAndCluster)
{
cmd.name = "Forward pass";
cmd.EnableShaderKeyword("LIGHTLOOP_SINGLE_PASS");

cmd.Dispose();
}
public override void RenderDebugOverlay(Camera camera, ScriptableRenderContext renderContext, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width)
public 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;
diffuseLighting += bakeDiffuseLighting * context.ambientOcclusion;
#endif
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);

out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
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();

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

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


for (int i = 0; i < kMaxLayerCount; ++i)
{
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE" + i, ((NormalMapSpace)material.GetFloat(kNormalMapSpace + i)) == NormalMapSpace.TangentSpace);
NormalMapSpace normalMapSpace = ((NormalMapSpace)material.GetFloat(kNormalMapSpace + i));
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE" + i, normalMapSpace == NormalMapSpace.TangentSpace);
SetKeyword(material, "_NORMALMAP" + i, material.GetTexture(kNormalMap + i));
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, "_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
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[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
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[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 doubleSidedMirrorEnableText = new GUIContent("Mirror normal", "This will mirror the normal with vertex normal plane if enabled, else flip the normal");
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 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 doubleSidedMirrorEnable = null;
protected const string kDoubleSidedMirrorEnable = "_DoubleSidedMirrorEnable";
protected MaterialProperty doubleSidedNormalMode = null;
protected const string kDoubleSidedNormalMode = "_DoubleSidedNormalMode";
protected MaterialProperty depthOffsetEnable = null;
protected const string kDepthOffsetEnable = "_DepthOffsetEnable";

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

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

SetupBaseUnlitKeywords(material);
bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f;
bool doubleSidedMirrorEnable = material.GetFloat(kDoubleSidedMirrorEnable) > 0.0f;
if (doubleSidedMirrorEnable)
{
// Mirror mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f));
}
else
DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode);
switch (doubleSidedNormalMode)
// Flip mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f));
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;
bool depthOffsetEnable = material.GetFloat(kDepthOffsetEnable) > 0.0f;
// Depth offset is only enabled if per pixel displacement is
bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && (material.GetFloat(kEnablePerPixelDisplacement) > 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 (BC5) - DXT5 for test");
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 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)
{
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
if (subsurfaceProfile == null)
{

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

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

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

EditorGUILayout.HelpBox(Styles.normalMapSpaceWarning.text, MessageType.Error);
}
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
// 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.heightMapText, heightMap);
if (!heightMap.hasMixedValue && heightMap.textureValue != null)

SetupBaseLitKeywords(material);
SetupBaseLitMaterialPass(material);
NormalMapSpace normalMapSpace = (NormalMapSpace)material.GetFloat(kNormalMapSpace);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", ((NormalMapSpace)material.GetFloat(kNormalMapSpace)) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", (normalMapSpace == NormalMapSpace.TangentSpace));
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
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, "_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 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
public bool enableTransmission; // Read from the SSS profile
public bool useThinObjectMode; // Read from the SSS profile
public Vector3 transmittance;
// SpecColor
// fold into fresnel0

tex.SetPixels(pixels, arrayElement);
}
public void Build()
public void Build(RenderPipelineResources renderPipelineResources)
{
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_TRANSMISSION_TYPE (1045)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION (1045)
#define DEBUGVIEW_LIT_BSDFDATA_USE_THIN_OBJECT_MODE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1047)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.GBufferMaterial: static fields

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

case DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_PROFILE:
result = GetIndexColor(bsdfdata.subsurfaceProfile);
break;
case DEBUGVIEW_LIT_BSDFDATA_TRANSMISSION_TYPE:
result = GetIndexColor(bsdfdata.transmissionType);
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);
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
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
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
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material

#endif
}
// 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)
// 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)
thickness /= CENTIMETERS_TO_METERS;
float t2 = thickness * thickness;
float3 expOneThird = exp(((-1.0 / 3.0) * thickness) * S);
// 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;
return 0.5 * (expOneThird + expOneThird * expOneThird * expOneThird) * surfaceAlbedo;
}
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 = CENTIMETERS_TO_METERS * subsurfaceRadius + 0.0001;
bsdfData.thickness = CENTIMETERS_TO_METERS * (_ThicknessRemaps[subsurfaceProfile][0] +
_ThicknessRemaps[subsurfaceProfile][1] * thickness);
bsdfData.subsurfaceRadius = subsurfaceRadius;
bsdfData.thickness = _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.transmissionType != TRANSMISSIONTYPE_NONE)
if (bsdfData.enableTransmission)
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);
bsdfData.transmittance = ComputeTransmittance(_ShapeParameters[subsurfaceProfile].rgb,
_SurfaceAlbedos[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.
bsdfData.diffuseColor = performPostScatterTexturing ? float3(1.0, 1.0, 1.0) : sqrt(bsdfData.diffuseColor);
// 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);
}
else
{
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
}
}
//-----------------------------------------------------------------------------

}
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_PROFILES_MAX - 1));
// 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));
}
else if (surfaceData.materialId == MATERIALID_LIT_SPECULAR)
{

bsdfData.specularOcclusion = inGBuffer0.a;
#ifdef USE_NORMAL_TETRAHEDRON_ENCODING
uint faceIndex;
int faceIndex;
uint octNormalSign;
int 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)
{
int subsurfaceProfile = (SSS_PROFILES_MAX - 0.9) * inGBuffer2.a;
float subsurfaceRadius = inGBuffer2.r;
float thickness = inGBuffer2.g;
// 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);
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.transmissionType != TRANSMISSIONTYPE_NONE)
[branch] if (bsdfData.enableTransmission)
// 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)));
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);
// For thin material we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.transmissionType == TRANSMISSIONTYPE_THIN_OBJECT) ? shadow : 1;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? 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.transmissionType != TRANSMISSIONTYPE_NONE)
[branch] if (bsdfData.enableTransmission)
// 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;
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);
// For thin material we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.transmissionType == TRANSMISSIONTYPE_THIN_OBJECT) ? shadow : 1;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? 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.transmissionType != TRANSMISSIONTYPE_NONE)
[branch] if (bsdfData.enableTransmission)
// 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;
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);
// For thin material we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.transmissionType == TRANSMISSIONTYPE_THIN_OBJECT) ? shadow : 1;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? 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;
specularLighting *= bsdfData.specularOcclusion * GetSpecularOcclusion(preLightData.NdotV, lightLoopContext.ambientOcclusion, bsdfData.roughness);
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" {}
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map
_NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value
_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
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[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, input.worldToTangent[2].xyz, _HorizonFade);
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);
}
// 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)
#define SAMPLER_NORMALMAP_IDX sampler_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_NormalMap1
#if defined(_NORMALMAP_TANGENT_SPACE1)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap1
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS1
#endif
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap2
#if defined(_NORMALMAP_TANGENT_SPACE2)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap2
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS2
#endif
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap3
#if defined(_NORMALMAP_TANGENT_SPACE3)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap3
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS3
#endif
#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
// 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.
// 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.
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
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
normalTS *= ADD_IDX(_NormalScale);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D_BIAS(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias), 1.0);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D_BIAS(ADD_IDX(_NormalMapOS), 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(_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 = 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 = UnpackNormalRGB(SAMPLE_TEXTURE2D(ADD_IDX(_NormalMap), SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv), 1.0);
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(ADD_IDX(_NormalMapOS), 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(_TangentMap, sampler_TangentMap, layerTexCoord.base.uv), 1.0);
float3 tangentOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(_TangentMapOS, sampler_TangentMapOS, 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(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);
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))
// 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" {}
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map
_NormalMapOS("NormalMapOS", 2D) = "white" {} // Object space normal map - no good default value
_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
[ToggleOff] _DoubleSidedMirrorEnable("Double sided mirror enable", Float) = 1.0
[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[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 [_DstBlend]
Blend One One
// #pragma enable_d3d11_debug_symbols
#pragma enable_d3d11_debug_symbols
#pragma multi_compile _ SSS_FILTER_HORIZONTAL_AND_COMBINE
#pragma multi_compile _ DEBUG_DISPLAY
#define SSS_PASS
#define MILLIMETERS_PER_METER 1000
//-------------------------------------------------------------------------------------
// 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
//-------------------------------------------------------------------------------------
#define N_PROFILES 8
#define N_SAMPLES 11
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
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
TEXTURE2D(_IrradianceSource); // RGB = irradiance on the back side of the object
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters
TEXTURE2D(_IrradianceSource); // Includes transmitted light
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;
float invDistScale = rcp(distScale);
int profileID = bsdfData.subsurfaceProfile;
float distScale = bsdfData.subsurfaceRadius;
float3 shapeParam = _ShapeParameters[profileID].rgb;
float maxDistance = _ShapeParameters[profileID].a;
float2 cornerPosSS = posInput.positionSS + 0.5 * _ScreenSize.zw;
// 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);
float3 cornerPosVS = ComputeViewSpacePosition(cornerPosSS, rawDepth, _InvProjMatrix);
// Load (1 / (2 * WeightedVariance)) for bilateral weighting.
#ifdef RBG_BILATERAL_WEIGHTS
float3 halfRcpVariance = _HalfRcpWeightedVariances[profileID].rgb;
#else
float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;
#endif
// 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);
float3 sampleWeight = _FilterKernels[profileID][0].rgb;
// Accumulate filtered irradiance.
float3 totalIrradiance = sampleWeight * sampleIrradiance;
// 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);
}
// Make sure bilateral filtering does not cause energy loss.
// TODO: ask Morten if there is a better way to do this.
float3 totalWeight = sampleWeight;
bool useNearFieldKernel = true; // TODO
[unroll]
for (int i = 1; i < N_SAMPLES; i++)
if (useNearFieldKernel)
samplePosition = posInput.unPositionSS + rotatedDirection * _FilterKernels[profileID][i].a;
sampleWeight = _FilterKernels[profileID][i].rgb;
float sampleRcpPdf = _FilterKernelsNearField[profileID][0][1];
float3 sampleWeight = KernelValCircle(0, shapeParam) * sampleRcpPdf;
rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
// Accumulate filtered irradiance and bilateral weights (for renormalization).
float3 totalIrradiance = sampleWeight * sampleIrradiance;
float3 totalWeight = sampleWeight;
// 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);
// 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.
if (any(sampleIrradiance) == false)
[unroll]
for (uint i = 1; i < SSS_N_SAMPLES_NEAR_FIELD; i++)
// 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;
}
// 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));
totalIrradiance += sampleWeight * sampleIrradiance;
totalWeight += sampleWeight;
}
samplePosition = posInput.unPositionSS + pos * scaledPixPerMm;
sampleRcpPdf = _FilterKernelsNearField[profileID][i][1];
#ifdef SSS_FILTER_HORIZONTAL_AND_COMBINE
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, profileID);
rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
// 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
[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;
}
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
}
else
{
return float4(0, 0, 0, 1); // TODO
}
}
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_PROFILES_MAX = 8;
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 enum TexturingMode : int { PreAndPostScatter = 0, PostScatter = 1 };
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 const int numSamples = 11; // Must be an odd number
[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 Color surfaceAlbedo; // Color, 0 to 1
public float lenVolMeanFreePath; // Length of the volume mean free path (in millimeters)
public bool enableTransmission;
public bool enableThinObject;
public Color tintColor;
public Vector2 thicknessRemap;
public TransmissionMode transmissionMode;
public Vector2 thicknessRemap; // X = min, Y = max (in millimeters)
public float worldScale; // Size of the world unit in meters
public int settingsIndex;
public int settingsIndex; // SubsurfaceScatteringSettings.profiles[i]
Vector4[] m_FilterKernel;
Vector3 m_S; // RGB = shape parameter: S = 1 / D
[SerializeField]
float m_ScatteringDistance; // Filter radius (in millimeters)
Vector3[] m_HalfRcpVariances;
Vector2[] m_FilterKernelNearField; // X = radius, Y = reciprocal of the PDF
Vector4 m_HalfRcpWeightedVariances;
Vector2[] m_FilterKernelFarField; // X = radius, Y = reciprocal of the PDF
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
UpdateKernelAndVarianceData();
}
public Vector4[] filterKernel
{
// Set via UpdateKernelAndVarianceData().
get { return m_FilterKernel; }
}
public Vector3[] halfRcpVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpVariances; }
}
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
public Vector4 halfRcpWeightedVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpWeightedVariances; }
BuildKernel();
public void UpdateKernelAndVarianceData()
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar.
public void BuildKernel()
if (m_FilterKernel == null || m_FilterKernel.Length != numSamples)
if (m_FilterKernelNearField == null || m_FilterKernelNearField.Length != SssConstants.SSS_N_SAMPLES_NEAR_FIELD)
m_FilterKernel = new Vector4[numSamples];
m_FilterKernelNearField = new Vector2[SssConstants.SSS_N_SAMPLES_NEAR_FIELD];
if (m_HalfRcpVariances == null)
if (m_FilterKernelFarField == null || m_FilterKernelFarField.Length != SssConstants.SSS_N_SAMPLES_FAR_FIELD)
m_HalfRcpVariances = new Vector3[2];
m_FilterKernelFarField = new Vector2[SssConstants.SSS_N_SAMPLES_FAR_FIELD];
// Apply the three-sigma rule.
Color stdDev1 = scatterDistance1 * (1.0f / 3.0f);
Color stdDev2 = scatterDistance2 * (1.0f / 3.0f);
m_S = new Vector3();
// 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++)
{
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);
}
// Importance sample the linear combination of two Gaussians.
for (uint i = 0; i < numSamples; i++)
{
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 Gaussian(float x, float stdDev)
static float KernelCdf(float r, float s)
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
return 1.0f - 0.25f * Mathf.Exp(-r * s) - 0.75f * Mathf.Exp(-r * s * (1.0f / 3.0f));
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
static float KernelCdfDerivative1(float r, float s)
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
return 0.25f * s * Mathf.Exp(-r * s) * (1.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
static float RationalApproximation(float t)
static float KernelCdfDerivative2(float r, float s)
// 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);
return (-1.0f / 12.0f) * s * s * Mathf.Exp(-r * s) * (3.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
// 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)
float x;
// Supply the initial guess.
float r = (Mathf.Pow(10.0f, p) - 1.0f) / s;
float t = float.MaxValue;
if (p < 0.5)
while (true)
// 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)));
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)));
if (Mathf.Abs(dr) < t)
{
r = r - dr;
t = Mathf.Abs(dr);
}
else
{
// Converged to the best result.
break;
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
return r;
}
}

public const int neutralProfileID = SSSConstants.SSS_PROFILES_MAX - 1;
public int numProfiles;
public int numProfiles; // Excluding the neutral profile
// 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;
// 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
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
transmissionType = null;
texturingModeFlags = 0;
tintColors = null;
thicknessRemaps = null;
halfRcpVariancesAndLerpWeights = null;
halfRcpWeightedVariances = null;
filterKernels = null;
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
shapeParameters = null;
filterKernelsNearField = null;
filterKernelsFarField = null;
UpdateCache();
}

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

}
}
Color c = new Color();
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].thicknessRemap.y = Mathf.Max(profiles[i].thicknessRemap.y, 0);
profiles[i].thicknessRemap.y = Mathf.Max(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y);
profiles[i].worldScale = Mathf.Max(profiles[i].worldScale, 0.001f);
profiles[i].UpdateKernelAndVarianceData();
profiles[i].BuildKernel();
}
UpdateCache();

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

texturingModeFlags |= ((int)profiles[i].texturingMode) << i;
if (profiles[i].enableTransmission)
{
transmissionType[i] = (float)(profiles[i].enableThinObject ? Lit.TransmissionType.ThinObject :Lit.TransmissionType.Regular);
}
else
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++)
transmissionType[i] = (float)Lit.TransmissionType.None;
filterKernelsNearField[2 * (n * i + j) + 0] = profiles[i].filterKernelNearField[j].x;
filterKernelsNearField[2 * (n * i + j) + 1] = profiles[i].filterKernelNearField[j].y;
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++)
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
filterKernels[n * i + j] = profiles[i].filterKernel[j];
filterKernelsFarField[2 * (n * i + j) + 0] = profiles[i].filterKernelFarField[j].x;
filterKernelsFarField[2 * (n * i + j) + 1] = profiles[i].filterKernelFarField[j].y;
int i = neutralProfileID;
int i = SssConstants.SSS_NEUTRAL_PROFILE_ID;
halfRcpWeightedVariances[i] = Vector4.one;
shapeParameters[i] = Vector4.zero;
surfaceAlbedos[i] = Vector4.zero;
worldScales[i] = 1.0f;
for (int j = 0, n = SubsurfaceScatteringProfile.numSamples; j < n; j++)
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
filterKernels[n * i + j] = Vector4.one;
filterKernels[n * i + j].w = 0.0f;
filterKernelsNearField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsNearField[2 * (n * i + j) + 1] = 1.0f;
}
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
{
filterKernelsFarField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsFarField[2 * (n * i + j) + 1] = 1.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 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]
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]
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).")
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).")
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 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 GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);

private RenderTexture m_ProfileImage, m_TransmittanceImage;
private Material m_ProfileMaterial, m_TransmittanceMaterial;
private SerializedProperty m_ScatterDistance1, m_ScatterDistance2, m_LerpWeight, m_TintColor, m_ThinObject,
m_TexturingMode, m_Transmission, m_ThicknessRemap;
private SerializedProperty m_LenVolMeanFreePath, m_ScatteringDistance, m_SurfaceAlbedo, m_S,
m_TexturingMode, m_TransmissionMode, m_ThicknessRemap, m_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_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_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawSssProfile");
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_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);
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_ThinObject, styles.sssProfileThinObject);
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.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0.0f, 50.0f);
EditorGUILayout.PropertyField(m_WorldScale, styles.sssProfileWorldScale);
EditorGUILayout.LabelField(styles.sssProfilePreview3, EditorStyles.centeredGreyMiniLabel);
// Apply the three-sigma rule.
Color stdDev1 = m_ScatterDistance1.colorValue * (1.0f / 3.0f);
Color stdDev2 = m_ScatterDistance2.colorValue * (1.0f / 3.0f);
float d = m_ScatteringDistance.floatValue;
Vector4 A = m_SurfaceAlbedo.colorValue;
Vector3 S = m_S.vector3Value;
Vector2 R = m_ThicknessRemap.vector2Value;
m_ProfileMaterial.SetColor("_StdDev1", stdDev1);
m_ProfileMaterial.SetColor("_StdDev2", stdDev2);
m_ProfileMaterial.SetFloat("_LerpWeight", m_LerpWeight.floatValue);
m_ProfileMaterial.SetFloat("_ScatteringDistance", d);
m_ProfileMaterial.SetVector("_SurfaceAlbedo", A);
m_ProfileMaterial.SetVector("_ShapeParameter", S);
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.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);
m_TransmittanceMaterial.SetFloat("_ScatteringDistance", d);
m_TransmittanceMaterial.SetVector("_SurfaceAlbedo", transmissionEnabled ? A : Vector4.zero);
m_TransmittanceMaterial.SetVector("_ShapeParameter", S);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", R);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
serializedObject.ApplyModifiedProperties();

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

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_PROFILES_MAX (8)
#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)
#endif

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


fileFormatVersion: 2
guid: 0348d78eb59f5e143ab4aa357c26f2c4
timeCreated: 1494501874
guid: 5ecd8d3cc501ee64181689bfb64bba66
timeCreated: 1495110790
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));
tangentWS = normalize(tangentWS - dot(tangentWS, normalWS) * 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: 12566b1a9c5807b4f8d3d0409255095a
guid: 12189449092048747a09af3b5d8a8720
timeCreated: 1487178659
timeCreated: 1496331368
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()

HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
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, mul((float3x3)unity_ObjectToWorld, dirOS));
return mul(worldToTangent, TransformObjectToWorldDir(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 = Resources.Load<ComputeShader>("ComputeGgxIblSampleData");
m_ComputeGgxIblSampleDataCS = m_RenderPipelinesResources.computeGgxIblSampleData;
m_BuildProbabilityTablesCS = Resources.Load<ComputeShader>("BuildProbabilityTables");
m_BuildProbabilityTablesCS = m_RenderPipelinesResources.buildProbabilityTables;
m_ConditionalDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeConditionalDensities");
m_MarginalRowDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeMarginalRowDensities");
}

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

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


RebuildSkyMeshes(nearPlane, farPlane);
}
public void Build()
public void Build(RenderPipelineResources renderPipelinesResources)
m_iblFilterGgx = new IBLFilterGGX();
m_iblFilterGgx = new IBLFilterGGX(renderPipelinesResources);
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial(renderPipelinesResources.skyboxCubemap);
m_BlitCubemapMaterial = Utilities.CreateEngineMaterial("Hidden/BlitCubemap");
m_BlitCubemapMaterial = Utilities.CreateEngineMaterial(renderPipelinesResources.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.

34
Assets/ScriptableRenderPipeline/ShaderLibrary/BSDF.hlsl


float F_Schlick(float f0, float u)
{
return F_Schlick(f0, 1.0, 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
}
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 mad
return (float3(f90, f90, f90) - f0) * x5 + f0; // sub mul mul mul sub*3 mad*3
return F_Schlick(f0, 1.0, u);
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
}
//-----------------------------------------------------------------------------

{
float facing = 0.5 + 0.5 * LdotV;
float rough = facing * (0.9 - 0.4 * facing) * ((0.5 + NdotH) / NdotH);
float transmitL = 1 - F_Schlick(0, 1, NdotL);
float transmitV = 1 - F_Schlick(0, 1, NdotV);
float transmitL = F_Transm_Schlick(0, NdotL);
float transmitV = F_Transm_Schlick(0, 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 size, uint offset)
uint BitFieldExtract(uint data, uint numBits, uint offset)
return (data >> offset) & ((1u << size) - 1u);
uint mask = 0xFFFFFFFFu >> (32u - numBits);
return (data >> offset) & mask;
bool IsBitSet(uint number, uint bitPos)
bool IsBitSet(uint data, uint bitPos)
return ((number >> bitPos) & 1) != 0;
return BitFieldExtract(data, 1u, bitPos) != 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).
#define LIGHTMAP_RGBM_RANGE 5.0
// 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
// 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)
{
return rgbmInput.rgb * rgbmInput.a * LIGHTMAP_RGBM_RANGE;
// 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;
}
float3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), float2 uv, float4 transform, bool lightmapRGBM)

{
illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
}
return SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
return illuminance;
}
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 - 2.8 * perceptualRoughness) / 1.4);
return saturate(1.7 / 1.4 - sqrt(2.89 / 1.96 - (2.8 / 1.96) * perceptualRoughness));
}
// 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 space normal map
// 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
// 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 PackLogLuv(float3 vRGB)
float4 PackToLogLuv(float3 vRGB)
{
// M matrix, for encoding
const float3x3 M = float3x3(

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

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

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

}
//-----------------------------------------------------------------------------
// Byte packing
// Integer 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 to sint/uint
// Float packing
uint PackFloatToUInt(float src, uint size, uint offset)
uint PackFloatToUInt(float src, uint numBits, uint offset)
const float maxValue = float((1u << size) - 1u) + 0.5; // Shader compiler should be able to remove this
return uint(src * maxValue) << offset;
return UnpackInt(src, numBits) << offset;
float UnpackUIntToFloat(uint src, uint size, uint offset)
float UnpackUIntToFloat(uint src, uint numBits, uint offset)
const float invMaxValue = 1.0 / float((1 << size) - 1);
return float(BitFieldExtract(src, size, offset)) * invMaxValue;
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return float(BitFieldExtract(src, numBits, offset)) * rcp(maxInt);
uint PackR10G10B10A2(float4 rgba)
uint PackToR10G10B10A2(float4 rgba)
float4 UnpackR10G10B10A2(uint rgba)
float4 UnpackFromR10G10B10A2(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
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp, 4:= reversed z
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( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ).x;
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
avgMoments = DepthToMoments( depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x );
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x;
avgMoments = DepthToMoments( reverse_z ? (1.0-depth) : depth );
#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;
return int( 4.0 - dot( weights, float4(4.0, 3.0, 2.0, 1.0 ) ) );
int idx = int( 4.0 - dot( weights, float4( 4.0, 3.0, 2.0, 1.0 ) ) );
return idx <= 3 ? idx : -1;
}
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;
float depth = tcs.z + depthBias;
#if UNITY_REVERSED_Z
float depth = (1.0 - tcs.z) + depthBias;
#else
float depth = tcs.z + depthBias;
#endif
payloadOffset++;
float4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );

61
Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.cs


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

_2048 = 2048
}
public class LowEndMobilePipelineAsset : RenderPipelineAsset
public class LightweightPipelineAsset : RenderPipelineAsset
#region AssetAndPipelineCreation
private static readonly string m_PipelineFolder = "Assets/ScriptableRenderPipeline/LightweightPipeline";
private static readonly string m_AssetName = "LightweightPipelineAsset.asset";
[UnityEditor.MenuItem("RenderPipeline/LowEndMobilePipeline/Create Pipeline Asset")]
static void CreateLowEndPipeline()
[UnityEditor.MenuItem("RenderPipeline/LightweightPipeline/Create Pipeline Asset")]
static void CreateLightweightPipeline()
var instance = ScriptableObject.CreateInstance<LowEndMobilePipelineAsset>();
UnityEditor.AssetDatabase.CreateAsset(instance,
"Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset");
var instance = ScriptableObject.CreateInstance<LightweightPipelineAsset>();
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 LowEndMobilePipeline(this);
return new LightweightPipeline(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_DefaultDiffuseMaterial;
return m_DefaultSpriteMaterial;
}
public override Shader GetDefaultShader()
{

6
Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.asset


m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3}
m_Name: LowEndMobilePipelineAsset
m_Name: LightweightPipelineAsset
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: 654f7c5a4dd5d4d139a072ab9b5c5738,
m_DefaultDiffuseMaterial: {fileID: 2100000, guid: 6a1143ee683302f4aa628c052723efc1,
type: 2}
m_DefaultSpriteMaterial: {fileID: 2100000, guid: e3ef893926d86c448a80512fe05b8a37,
type: 2}
m_DefaultShader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}

21
Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


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

public int shadowResolution;
}
public class LowEndMobilePipeline : RenderPipeline, IComparer<VisibleLight>
public class LightweightPipeline : RenderPipeline, IComparer<VisibleLight>
private readonly LowEndMobilePipelineAsset m_Asset;
private readonly LightweightPipelineAsset 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("LowEndMobileForward");
private static readonly ShaderPassName m_ForwardBasePassName = new ShaderPassName("LightweightForward");
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 LowEndMobilePipeline(LowEndMobilePipelineAsset asset)
public LightweightPipeline(LightweightPipelineAsset 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 lowend mobile pipeline");
Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
return false;
}

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


m_PrefabInternal: {fileID: 0}
m_Name: LDSpecularSphere0
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_ShaderKeywords: _GLOSSINESS_FROM_BASE_ALPHA _SPECULAR_COLOR
m_ShaderKeywords: _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

44
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineShadows.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/LightweightPipeline/Shaders/LightweightPipelineCore.cginc


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

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

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

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

70
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader


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

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

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

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

NormalMap(i, normal);
half4 specularGloss;
SpecularGloss(i.uv01.xy, diffuse, alpha, specularGloss);
SpecularGloss(i.uv01.xy, 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);
}

half3 emissionColor;
Emission(i, emissionColor);
color += emissionColor;
Emission(i.uv01.xy, color);
#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
#pragma fragment frag_meta_ld
#pragma shader_feature _METALLICGLOSSMAP
#pragma shader_feature _SPECGLOSSMAP
#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 "LowendMobilePipelineMaterialEditor"
CustomEditor "LightweightPipelineMaterialEditor"
}

6
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightParticlesMultiply.shader


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

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

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

6
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightParticlesAdd.shader


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

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

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

14
Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightPipelineUpgraders.cs


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

{
public LegacyBlinnPhongUpgrader(string oldShaderName, UpgradeParams upgradeParams)
{
RenameShader(oldShaderName, "ScriptableRenderPipeline/LowEndMobile/NonPBR", UpdateMaterialKeywords);
RenameShader(oldShaderName, "ScriptableRenderPipeline/LightweightPipeline/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_MAP", material.GetTexture("_EmissionMap"));
SetKeyword(material, "_EMISSION", material.GetTexture("_EmissionMap"));
}
private static void UpdateMaterialBlendMode(Material material)

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

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

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

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

21
Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightPipelineMaterialEditor.cs


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

m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMapProp);
EditorGUILayout.Space();
m_MaterialEditor.TexturePropertySingleLine(Styles.emissionMapLabel, emissionMapProp, emissionColorProp);
DoEmission();
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);
}
}

12
Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightAssetInspector.cs


using UnityEditor;
namespace UnityEngine.Experimental.Rendering.LowendMobile
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
[CustomEditor(typeof(LowEndMobilePipelineAsset))]
public class LowendPipelineAssetInspector : Editor
[CustomEditor(typeof(LightweightPipelineAsset))]
public class LightweightAssetInspector : 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--;

10
Assets/ScriptableRenderPipeline/LightweightPipeline/Editor/LegacyShadersToLightweightPipelineUpgrader.cs


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

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

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


namespace UnityEditor.Experimental.Rendering.LowendMobile
namespace UnityEditor.Experimental.Rendering.LightweightPipeline
{
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
文件差异内容过多而无法显示
查看文件

8
ProjectSettings/EditorBuildSettings.asset


m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes:
- enabled: 0
- enabled: 1
- 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.0a1
m_EditorVersion: 2017.2.0a2

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: 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: bg
uniqueID: 3786281603
locked: 0
- name: Default
uniqueID: 0
locked: 0

1
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_Reflection_Non.mat


m_ShaderKeywords: _SPECULAR_COLOR
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

3
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_Reflection_Cube.mat


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

3
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_06_All.mat


m_PrefabInternal: {fileID: 0}
m_Name: LDPipe_LitMat_06_All
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_ShaderKeywords: _EMISSION_MAP _NORMALMAP _SPECGLOSSMAP_BASE_ALPHA
m_ShaderKeywords: _EMISSION _NORMALMAP _SPECGLOSSMAP_BASE_ALPHA
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

5
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_Shader/LDPipe_LitMat_05_Emission.mat


m_PrefabInternal: {fileID: 0}
m_Name: LDPipe_LitMat_05_Emission
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_ShaderKeywords: _EMISSION_MAP _SPECULAR_COLOR
m_LightmapFlags: 4
m_ShaderKeywords: _EMISSION _SPECULAR_COLOR
m_LightmapFlags: 2
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

5
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/LDpipe_targetTex.mat


m_PrefabInternal: {fileID: 0}
m_Name: LDpipe_targetTex
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_ShaderKeywords: _EMISSION_MAP _SPECULAR_COLOR
m_LightmapFlags: 4
m_ShaderKeywords: _EMISSION _SPECULAR_COLOR
m_LightmapFlags: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

1
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/Cornell Box_red.mat


m_ShaderKeywords: _SPECULAR_COLOR
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

1
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/Cornell Box_green.mat


m_ShaderKeywords: _SPECULAR_COLOR
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

1
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/LDPipe_CommonAssets/Materials/Cornell Box.mat


m_ShaderKeywords: _SPECULAR_COLOR
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/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

34
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/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"
#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"
float4 _StdDev1, _StdDev2, _ThicknessRemap, _TintColor;
float _LerpWeight; // See 'SubsurfaceScatteringParameters'
float4 _SurfaceAlbedo, _ShapeParameter, _ThicknessRemap;
float _ScatteringDistance; // See 'SubsurfaceScatteringProfile'
//-------------------------------------------------------------------------------------
// Implementation

float4 Frag(Varyings input) : SV_Target
{
float thickness = _ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x);
float t2 = thickness * thickness;
float d = (_ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x));
float3 T = ComputeTransmittance(_ShapeParameter.rgb, _SurfaceAlbedo.rgb, d, 1);
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(transmittance * _TintColor.rgb, 1);
return float4(T, 1);
}
ENDHLSL
}

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

999
ImageTemplates/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderMaps.unity.png
文件差异内容过多而无法显示
查看文件

999
ImageTemplates/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes.unity.png
文件差异内容过多而无法显示
查看文件

113
Assets/GraphicsTests/Framework/Editor/TestFrameworkCustomBuild.cs


using System.IO;
using UnityEditor;
public class TestFrameworkCustomBuild
{
private static readonly string s_TestSceneFolder = "/GraphicsTests/Scenes";
private static readonly string s_BuildFolder = "/TestScenesBuild";
public class TestFrameworkCustomBuild
{
private static readonly string s_TestSceneFolder = "/GraphicsTests/RenderPipeline/LightweightPipeline/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", true)]
public static bool ValidateBuildiOS()
{
#if UNITY_STANDALONE_OSX
return true;
#else
return false;
#endif
}
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);
[MenuItem("RenderPipeline/TestFramework/Build-iOS")]
public static void BuildiOS()
{
TestFrameworkCustomBuild builder = new TestFrameworkCustomBuild();
builder.Build(BuildTarget.iOS, BuildOptions.AcceptExternalModificationsToPlayer);
}
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);
}
foreach (GameObject go in objects)
{
GotoNextScene component = go.GetComponent<GotoNextScene>();
if (component != null)
{
component.m_NextSceneIndex = (i + 1) % levels.Length;
componentFound = true;
break;
}
}
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;
if (!componentFound)
{
GameObject gotoNextScene = new GameObject("GotoNextScene");
GotoNextScene component = gotoNextScene.AddComponent<GotoNextScene>();
component.m_NextSceneIndex = (i + 1) % levels.Length;
}
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);
}
}
}
}
EditorSceneManager.SaveScene(scene);
EditorSceneManager.UnloadSceneAsync(scene);
}
}
}
}

8
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/SimpleCube.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.18022086, g: 0.2256495, b: 0.30683416, a: 1}
m_IndirectSpecularColor: {r: 0.18028377, g: 0.22571409, b: 0.30692285, 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: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, 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/RenderPipeline/LightweightPipeline/Scenes/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: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, 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/RenderPipeline/LightweightPipeline/Scenes/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.2, y: -0.6, z: 0}
m_LocalPosition: {x: -1.686, 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, y: 0.6, z: 0}
m_LocalPosition: {x: -0.486, 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: 1.2, y: -0.6, z: 0}
m_LocalPosition: {x: 0.714, 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.2, y: 0.6, z: 0}
m_LocalPosition: {x: -1.686, 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: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, 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, y: -0.6, z: 0}
m_LocalPosition: {x: -0.486, 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: 1.2, y: 0.6, z: 0}
m_LocalPosition: {x: 0.714, 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/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/Lightmap-0_comp_light.exr.meta


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

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

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

4
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/LightingData.asset.meta


fileFormatVersion: 2
guid: 47357896581e84c039d57ae749fa9786
timeCreated: 1493310899
guid: de71753d509098b47b2d1fc3de525375
timeCreated: 1496330219
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 25800000

154
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes/LightingData.asset
文件差异内容过多而无法显示
查看文件

31
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Shaders/LDPipe_LitShaderLightProbes.unity


m_PVRFilteringAtrousColorSigma: 1
m_PVRFilteringAtrousNormalSigma: 1
m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 112000002, guid: 47357896581e84c039d57ae749fa9786,
m_LightingDataAsset: {fileID: 112000002, guid: de71753d509098b47b2d1fc3de525375,
type: 2}
m_UseShadowmask: 0
--- !u!196 &4

manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &98766303
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_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_Script: {fileID: 11500000, guid: c20dfc007a9a74ad8a2bfd0d59abe398, type: 3}
m_Name:
m_EditorClassIdentifier:
renderPipeline: {fileID: 11400000, guid: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, 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_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

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

6
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Camera/LDPipe_Camera_TargetTexture.unity


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

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: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, 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

7
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Camera/LDPipe_Camera_Ortho.unity


manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &418390279
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_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: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, type: 2}
cameraToUse: {fileID: 971756574}
hdr: 0
width: 1280

7
Assets/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/Camera/LDPipe_Camera_Clip.unity


manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &418390279
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_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: 877878ed40e8ad94095582ff91179016, type: 2}
renderPipeline: {fileID: 11400000, guid: e6987eea1dd29074597d54ed91a54a26, type: 2}
cameraToUse: {fileID: 971756574}
hdr: 0
width: 1280

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/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);

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

正在加载...
取消
保存