runes 8 年前
当前提交
84860a17
共有 77 个文件被更改,包括 2323 次插入1368 次删除
  1. 6
      Assets/ScriptableRenderPipeline/AdditionalLightData.cs
  2. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/HDRenderPipelineDebug.cs
  3. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl
  4. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader
  5. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
  6. 154
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  7. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/SceneSettingsManagementWindow.cs
  8. 125
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset
  9. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset.meta
  10. 262
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  11. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs
  12. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader
  13. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TileLightLoopProducer.cs
  14. 23
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  15. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute
  16. 166
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  17. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  18. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  19. 42
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  20. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  21. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  22. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  23. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  24. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  25. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  26. 46
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  27. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  28. 120
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  29. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  30. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  31. 3
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  32. 55
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  33. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassDebugViewMaterial.hlsl
  34. 62
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  35. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl
  36. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  37. 18
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl
  38. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader
  39. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  40. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
  41. 80
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  42. 17
      Assets/ScriptableRenderPipeline/ShaderLibrary/PerPixelDisplacement.hlsl
  43. 1
      Assets/ScriptableRenderPipeline/common/TextureCache.cs
  44. 19
      Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs
  45. 3
      Assets/ScriptableRenderPipeline/fptl/LightDefinitions.cs
  46. 1
      Assets/ScriptableRenderPipeline/fptl/LightDefinitions.cs.hlsl
  47. 5
      Assets/ScriptableRenderPipeline/fptl/TiledLightingTemplate.hlsl
  48. 17
      Assets/ScriptableRenderPipeline/fptl/TiledLightingUtils.hlsl
  49. 5
      Assets/ScriptableRenderPipeline/fptl/TiledReflectionTemplate.hlsl
  50. 23
      Assets/ScriptableRenderPipeline/fptl/lightlistbuild-clustered.compute
  51. 2
      Assets/TestScenes/FPTL/Materials/Custom_NewSurfaceShader.mat
  52. 4
      Assets/TestScenes/FPTL/Materials/gray.mat
  53. 112
      Assets/TestScenes/HDTest/CascadedShadowsTest.unity
  54. 9
      Assets/TestScenes/HDTest/CascadedShadowsTest/CommonSettings_Cascaded.asset
  55. 2
      Assets/TestScenes/HDTest/CascadedShadowsTest/CommonSettings_Cascaded.asset.meta
  56. 2
      Assets/TestScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Rock.mat
  57. 2
      Assets/TestScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat
  58. 122
      Assets/TestScenes/fptl/Materials/FwdMat.mat
  59. 9
      ProjectSettings/GraphicsSettings.asset
  60. 718
      ProjectSettings/InputManager.asset
  61. 2
      ProjectSettings/ProjectVersion.txt
  62. 60
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader
  63. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader.meta
  64. 300
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs
  65. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs.meta
  66. 9
      Assets/ScriptableRenderPipeline/common/Camera.meta
  67. 136
      Assets/ScriptableRenderPipeline/common/Debugging.cs
  68. 12
      Assets/ScriptableRenderPipeline/common/Debugging.cs.meta
  69. 20
      Assets/TestScenes/HDTest/CascadedShadowsTest/HDRISkySettings_Cascaded.asset
  70. 9
      Assets/TestScenes/HDTest/CascadedShadowsTest/HDRISkySettings_Cascaded.asset.meta
  71. 108
      Assets/ScriptableRenderPipeline/common/Camera/CameraSwitcher.cs
  72. 12
      Assets/ScriptableRenderPipeline/common/Camera/CameraSwitcher.cs.meta
  73. 67
      Assets/ScriptableRenderPipeline/common/Camera/FreeCamera.cs
  74. 12
      Assets/ScriptableRenderPipeline/common/Camera/FreeCamera.cs.meta
  75. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs.meta
  76. 509
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs

6
Assets/ScriptableRenderPipeline/AdditionalLightData.cs


[Range(0.0F, 1.0F)]
public float shadowDimmer = 1.0f;
[Range(0.0F, 1.0F)]
public float lightDimmer = 1.0f;
// Not used for directional lights.
public float fadeDistance = 10000.0f;
public float shadowFadeDistance = 10000.0f;
public bool affectDiffuse = true;
public bool affectSpecular = true;

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/HDRenderPipelineDebug.cs


public bool displayOpaqueObjects = true;
public bool displayTransparentObjects = true;
public bool enableDistortion = true;
public bool enableSSS = true;
public enum ShadowDebugMode
public enum ShadowMapDebugMode
{
None,
VisualizeAtlas,

{
None,
DiffuseLighting,
SpecularLighting
SpecularLighting,
VisualizeCascade
}
[Serializable]

public ShadowDebugMode shadowDebugMode = ShadowDebugMode.None;
public ShadowMapDebugMode shadowDebugMode = ShadowMapDebugMode.None;
public uint shadowMapIndex = 0;
public LightingDebugMode lightingDebugMode = LightingDebugMode.None;

public bool displaySkyReflection = false;
public float skyReflectionMipmap = 0.0f;
skyReflectionMipmap = Mathf.Clamp(skyReflectionMipmap, 0.0f, 1.0f);
}
}
}

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl


#define LIGHTINGDEBUGMODE_NONE (0)
#define LIGHTINGDEBUGMODE_DIFFUSE_LIGHTING (1)
#define LIGHTINGDEBUGMODE_SPECULAR_LIGHTING (2)
#define LIGHTINGDEBUGMODE_VISUALIZE_CASCADE (3)
#endif

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


DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
TEXTURE2D_FLOAT(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
int _DebugViewMaterial;
struct Attributes

{
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);

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


// variable declaration
//-------------------------------------------------------------------------------------
TEXTURE2D_FLOAT(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
uint _ViewTilesFlags;
float2 _MousePixelCoord;

{
// positionCS is SV_Position
PositionInputs posInput = GetPositionInput(positionCS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
int2 pixelCoord = posInput.unPositionSS.xy;

if (tileCoord.y < LIGHTCATEGORY_COUNT && tileCoord.x < maxLights + 3)
{
PositionInputs mousePosInput = GetPositionInput(_MousePixelCoord, _ScreenSize.zw);
float depthMouse = LOAD_TEXTURE2D(_CameraDepthTexture, mousePosInput.unPositionSS).x;
float depthMouse = LOAD_TEXTURE2D(_MainDepthTexture, mousePosInput.unPositionSS).x;
UpdatePositionInput(depthMouse, _InvViewProjMatrix, _ViewProjMatrix, mousePosInput);
uint category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;

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


public readonly GUIContent shadowsAtlasWidth = new GUIContent("Atlas width");
public readonly GUIContent shadowsAtlasHeight = new GUIContent("Atlas height");
// Subsurface Scaterring Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SubsurfaceScatteringSettings.maxNumProfiles] { 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 sssProfilePreview0 = new GUIContent("Profile preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as 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 as thickness increases to 1.");
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
public readonly GUIContent sssProfileStdDev1 = new GUIContent("Standard deviation #1", "Determines the shape of the 1st Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileStdDev2 = new GUIContent("Standard deviation #2", "Determines the shape of the 2nd Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileLerpWeight = new GUIContent("Filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
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 sssProfileThicknessRemap = new GUIContent("Thickness remap", "Remaps the thickness parameter from [0, 1] to the desired range.");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing mode", "Specifies when the diffuse texture should be applied.");
public readonly GUIContent[] sssTexturingModeOptions = new GUIContent[3] { new GUIContent("Pre-scatter", "Before the blurring pass. Effectively results in the diffuse texture getting blurred together with the lighting."), new GUIContent("Post-scatter", "After the blurring pass. Effectively preserves the sharpness of the diffuse texture."), new GUIContent("Pre- and post-scatter", "Both before and after the blurring pass.") };
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);
// Tile pass Settings
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop Settings");
public readonly string[] tileLightLoopDebugTileFlagStrings = new string[] { "Punctual Light", "Area Light", "Env Light"};

public readonly GUIContent disableTileAndCluster = new GUIContent("Disable Tile/clustered", "Toggle");
public readonly GUIContent disableDeferredShadingInCompute = new GUIContent("Disable deferred shading in compute", "Toggle");
public readonly GUIContent enableTileAndCluster = new GUIContent("Enable Tile/clustered", "Toggle");
public readonly GUIContent enableComputeLightEvaluation = new GUIContent("Enable Compute Light Evaluation", "Toggle");
// Sky Settings
public readonly GUIContent skyParams = new GUIContent("Sky Settings");

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");
public readonly GUIContent shadowDebugVisualizationMode = new GUIContent("Shadow Debug Mode");
public readonly GUIContent shadowDebugVisualizationMode = new GUIContent("Shadow Maps Debug Mode");
public readonly GUIContent lightingDisplaySkyReflection = new GUIContent("Display Sky Reflection");
public readonly GUIContent lightingDisplaySkyReflectionMipmap = new GUIContent("Reflection Mipmap");
public Styles()
{
centeredMiniBoldLabel.alignment = TextAnchor.MiddleCenter;
centeredMiniBoldLabel.fontSize = 10;
centeredMiniBoldLabel.fontStyle = FontStyle.Bold;
}
}
private static Styles s_Styles = null;

SerializedProperty m_ShowRenderingDebug = null;
SerializedProperty m_DebugOverlayRatio = null;
// Rendering Debug
// Material Debug
SerializedProperty m_MaterialDebugMode = null;
// Rendering Debug

SerializedProperty m_EnableSSS = null;
// Lighting debug
SerializedProperty m_DebugShadowEnabled = null;

SerializedProperty m_LightingDebugOverrideSmoothness = null;
SerializedProperty m_LightingDebugOverrideSmoothnessValue = null;
SerializedProperty m_LightingDebugAlbedo = null;
SerializedProperty m_LightingDebugDisplaySkyReflection = null;
SerializedProperty m_LightingDebugDisplaySkyReflectionMipmap = null;
// Subsurface Scattering Settings
SerializedProperty m_TexturingMode = null;
SerializedProperty m_Profiles = null;
SerializedProperty m_NumProfiles = null;
// Subsurface Scattering internal data
private Material m_ProfileMaterial, m_TransmittanceMaterial;
private RenderTexture[] m_ProfileImages, m_TransmittanceImages;
private void InitializeProperties()
{
// Global debug

m_DisplayOpaqueObjects = FindProperty(x => x.globalDebugSettings.renderingDebugSettings.displayOpaqueObjects);
m_DisplayTransparentObjects = FindProperty(x => x.globalDebugSettings.renderingDebugSettings.displayTransparentObjects);
m_EnableDistortion = FindProperty(x => x.globalDebugSettings.renderingDebugSettings.enableDistortion);
m_EnableSSS = FindProperty(x => x.globalDebugSettings.renderingDebugSettings.enableSSS);
// Lighting debug
m_DebugShadowEnabled = FindProperty(x => x.globalDebugSettings.lightingDebugSettings.enableShadows);

m_LightingDebugOverrideSmoothness = FindProperty(x => x.globalDebugSettings.lightingDebugSettings.overrideSmoothness);
m_LightingDebugOverrideSmoothnessValue = FindProperty(x => x.globalDebugSettings.lightingDebugSettings.overrideSmoothnessValue);
m_LightingDebugAlbedo = FindProperty(x => x.globalDebugSettings.lightingDebugSettings.debugLightingAlbedo);
m_LightingDebugDisplaySkyReflection = FindProperty(x => x.globalDebugSettings.lightingDebugSettings.displaySkyReflection);
m_LightingDebugDisplaySkyReflectionMipmap = FindProperty(x => x.globalDebugSettings.lightingDebugSettings.skyReflectionMipmap);
// Subsurface Scattering Settings
m_TexturingMode = FindProperty(x => x.sssSettings.texturingMode);
m_Profiles = FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
void InitializeSSS()
{
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_TransmittanceMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileImages = new RenderTexture[SubsurfaceScatteringSettings.maxNumProfiles];
m_TransmittanceImages = new RenderTexture[SubsurfaceScatteringSettings.maxNumProfiles];
for (int i = 0; i < SubsurfaceScatteringSettings.maxNumProfiles; i++)
{
m_ProfileImages[i] = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImages[i] = new RenderTexture(16, 256, 0, RenderTextureFormat.DefaultHDR);
}
}
SerializedProperty FindProperty<TValue>(Expression<Func<HDRenderPipeline, TValue>> expr)

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--;
}

EditorGUILayout.LabelField(styles.sssSettings);
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
pipe.localSssParameters = (SubsurfaceScatteringParameters) EditorGUILayout.ObjectField(new GUIContent("Subsurface Scattering Parameters"), pipe.localSssParameters, typeof(SubsurfaceScatteringParameters), false);
EditorGUI.indentLevel--;
EditorGUI.BeginChangeCheck();
if (EditorGUI.EndChangeCheck())
EditorGUILayout.PropertyField(m_NumProfiles, styles.sssNumProfiles);
m_TexturingMode.intValue = EditorGUILayout.Popup(styles.sssTexturingMode, m_TexturingMode.intValue, styles.sssTexturingModeOptions, (GUILayoutOption[])null);
for (int i = 0, n = Math.Min(m_Profiles.arraySize, SubsurfaceScatteringSettings.maxNumProfiles); i < n; i++)
HackSetDirty(pipe); // Repaint
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.sssProfiles[i]);
if (profile.isExpanded)
{
EditorGUI.indentLevel++;
SerializedProperty profileStdDev1 = profile.FindPropertyRelative("stdDev1");
SerializedProperty profileStdDev2 = profile.FindPropertyRelative("stdDev2");
SerializedProperty profileLerpWeight = profile.FindPropertyRelative("lerpWeight");
SerializedProperty profileTransmission = profile.FindPropertyRelative("enableTransmission");
SerializedProperty profileThicknessRemap = profile.FindPropertyRelative("thicknessRemap");
EditorGUILayout.PropertyField(profileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(profileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(profileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(profileTransmission, styles.sssProfileTransmission);
Vector2 thicknessRemap = profileThicknessRemap.vector2Value;
EditorGUILayout.LabelField("Min thickness: ", thicknessRemap.x.ToString());
EditorGUILayout.LabelField("Max thickness: ", thicknessRemap.y.ToString());
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
profileThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssProfilePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImages[i], m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", profileThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImages[i], m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}
private void LightingDebugSettingsUI(HDRenderPipeline renderContext, HDRenderPipelineInstance renderpipelineInstance)

EditorGUILayout.PropertyField(m_ShadowDebugMode, styles.shadowDebugVisualizationMode);
if (!m_ShadowDebugMode.hasMultipleDifferentValues)
{
if ((ShadowDebugMode)m_ShadowDebugMode.intValue == ShadowDebugMode.VisualizeShadowMap)
if ((ShadowMapDebugMode)m_ShadowDebugMode.intValue == ShadowMapDebugMode.VisualizeShadowMap)
{
EditorGUILayout.IntSlider(m_ShadowDebugShadowMapIndex, 0, renderpipelineInstance.GetCurrentShadowCount() - 1, styles.shadowDebugVisualizeShadowIndex);
}

{
if ((LightingDebugMode)m_LightingDebugMode.intValue != LightingDebugMode.None)
{
{
{
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_LightingDebugOverrideSmoothnessValue, styles.lightingDebugOverrideSmoothnessValue);
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())

tilePass.debugViewTilesFlags = EditorGUILayout.MaskField("DebugView Tiles", tilePass.debugViewTilesFlags, styles.tileLightLoopDebugTileFlagStrings);
tilePass.enableSplitLightEvaluation = EditorGUILayout.Toggle(styles.splitLightEvaluation, tilePass.enableSplitLightEvaluation);
tilePass.disableTileAndCluster = EditorGUILayout.Toggle(styles.disableTileAndCluster, tilePass.disableTileAndCluster);
tilePass.disableDeferredShadingInCompute = EditorGUILayout.Toggle(styles.disableDeferredShadingInCompute, tilePass.disableDeferredShadingInCompute);
tilePass.enableTileAndCluster = EditorGUILayout.Toggle(styles.enableTileAndCluster, tilePass.enableTileAndCluster);
tilePass.enableComputeLightEvaluation = EditorGUILayout.Toggle(styles.enableComputeLightEvaluation, tilePass.enableComputeLightEvaluation);
if (EditorGUI.EndChangeCheck())
{

public void OnEnable()
{
InitializeProperties();
InitializeSSS();
}
public override void OnInspectorGUI()

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


void OnGUI()
{
// Keep it there temporarily until it's back to an "engine" setting in the HDRenderPipeline asset.
SubsurfaceScatteringSettings.overrideSettings = (SubsurfaceScatteringParameters)EditorGUILayout.ObjectField(new GUIContent("SSS Settings"), SubsurfaceScatteringSettings.overrideSettings, typeof(SubsurfaceScatteringParameters), false);
EditorGUILayout.Space();
if (GUILayout.Button("Create new Common Settings"))

if (GUILayout.Button("Create new Procedural sky params"))
{
CreateAsset<ProceduralSkySettings>("NewProceduralSkyParameters");
}
if (GUILayout.Button("Create new SSS params"))
{
CreateAsset<SubsurfaceScatteringParameters>("NewSssParameters");
}
EditorGUILayout.Space();

125
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset


displayOpaqueObjects: 1
displayTransparentObjects: 1
enableDistortion: 1
enableSSS: 1
sssSettings:
numProfiles: 1
transmissionFlags: 0
profiles:
- stdDev1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
stdDev2: {r: 0.6, g: 0.6, b: 0.6, a: 0}
lerpWeight: 0.5
enableTransmission: 0
thicknessRemap: {x: 0, y: 3}
m_FilterKernel:
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.6594821}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.3561445}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.000000048879357}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.35614443}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.659482}
m_HalfRcpVariances:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888}
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
thicknessRemaps:
- 0
- 3
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
halfRcpVariancesAndLerpWeights:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553, w: 0.5}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888, w: 0.5}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
halfRcpWeightedVariances:
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
filterKernels:
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.6594821}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.3561445}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.000000048879357}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.35614443}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.659482}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
maxShadowDistance: 400
maxShadowDistance: 1000
localSssParameters: {fileID: 0}
m_TextureSettings:
spotCookieSize: 128
pointCookieSize: 512

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset.meta


fileFormatVersion: 2
guid: e185fecca3c73cd47a09f1092663ef32
timeCreated: 1486997164
timeCreated: 1487689448
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000

262
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


// Those that are not will be refatored later.
// Debugging
public GlobalDebugSettings globalDebugSettings = new GlobalDebugSettings();
public GlobalDebugSettings globalDebugSettings = new GlobalDebugSettings();
public RenderingSettings renderingSettings = new RenderingSettings();
[SerializeField] ShadowSettings m_ShadowSettings = ShadowSettings.Default;
public SubsurfaceScatteringParameters localSssParameters;
[SerializeField] TextureSettings m_TextureSettings = TextureSettings.Default;
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; } }

}
}
public SubsurfaceScatteringParameters sssParameters
{
get
{
if (SubsurfaceScatteringSettings.overrideSettings != null)
{
return SubsurfaceScatteringSettings.overrideSettings;
}
if (localSssParameters == null)
{
localSssParameters = CreateInstance<SubsurfaceScatteringParameters>();
}
return localSssParameters;
}
}
public void ApplyDebugSettings()
{
m_ShadowSettings.enabled = globalDebugSettings.lightingDebugSettings.enableShadows;

public void OnValidate()
{
globalDebugSettings.OnValidate();
sssSettings.OnValidate();
}
}

public struct HDCamera
{
public Camera camera;
public Vector4 screenSize;
public Camera camera;
public Vector4 screenSize;
public Vector4 invProjectionParam;
}
public class GBufferManager

readonly GBufferManager m_gbufferManager = new GBufferManager();
// Various set of material use in render loop
readonly Material m_DebugViewMaterialGBuffer;
readonly Material m_DebugDisplayShadowMap;
private Material m_DebugDisplayShadowMap;
private Material m_DebugViewMaterialGBuffer;
private Material m_DebugDisplayLatlong;
readonly int m_CameraDepthStencilBuffer;
readonly int m_CameraDepthStencilBufferCopy; // This is temporary, we will need to provide the correct opaque depth buffer to transparent without needing a copy
readonly int m_CameraStencilBuffer;
readonly int m_VelocityBuffer;
readonly int m_DistortionBuffer;

readonly RenderTargetIdentifier m_CameraSubsurfaceBufferRT;
readonly RenderTargetIdentifier m_CameraFilteringBufferRT;
readonly RenderTargetIdentifier m_CameraDepthStencilBufferRT;
readonly RenderTargetIdentifier m_CameraDepthStencilBufferCopyRT;
// 'm_CameraStencilBufferRT' is a temporary copy of the stencil buffer and should be removed
// once we are able to read from the depth buffer and perform the stencil test simultaneously.
readonly RenderTargetIdentifier m_CameraStencilBufferRT;
private RenderTexture m_CameraDepthStencilBuffer = null;
private RenderTexture m_CameraDepthStencilBufferCopy = null;
private RenderTargetIdentifier m_CameraDepthStencilBufferRT;
private RenderTargetIdentifier m_CameraDepthStencilBufferCopyRT;
// Detect when windows size is changing
int m_CurrentWidth;

m_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
m_CameraSubsurfaceBuffer = Shader.PropertyToID("_CameraSubsurfaceTexture");
m_CameraFilteringBuffer = Shader.PropertyToID("_CameraFilteringBuffer");
m_CameraDepthStencilBuffer = Shader.PropertyToID("_CameraDepthTexture");
m_CameraDepthStencilBufferCopy = Shader.PropertyToID("_CameraDepthTextureCopy");
m_CameraStencilBuffer = Shader.PropertyToID("_CameraStencilTexture");
m_CameraDepthStencilBufferRT = new RenderTargetIdentifier(m_CameraDepthStencilBuffer);
m_CameraDepthStencilBufferCopyRT = new RenderTargetIdentifier(m_CameraDepthStencilBufferCopy);
m_CameraStencilBufferRT = new RenderTargetIdentifier(m_CameraStencilBuffer);
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewMaterialGBuffer");
m_FilterSubsurfaceScattering.DisableKeyword("FILTER_HORIZONTAL");
m_FilterSubsurfaceScattering.DisableKeyword("FILTER_HORIZONTAL_AND_COMBINE");
m_FilterSubsurfaceScattering.EnableKeyword("FILTER_HORIZONTAL");
m_FilterSubsurfaceScattering.EnableKeyword("FILTER_HORIZONTAL_AND_COMBINE");
m_DebugDisplayShadowMap = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayShadowMap");
InitializeDebugMaterials();
m_ShadowPass = new ShadowRenderPass(owner.shadowSettings);

m_SkyManager.skySettings = owner.skySettingsToUse;
}
void InitializeDebugMaterials()
{
m_DebugDisplayShadowMap = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayShadowMap");
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewMaterialGBuffer");
m_DebugDisplayLatlong = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugDisplayLatlong");
}
public override void Dispose()
{
base.Dispose();

};
#endif
void CreateDepthBuffer(Camera camera)
{
if (m_CameraDepthStencilBuffer != null)
{
m_CameraDepthStencilBuffer.Release();
}
m_CameraDepthStencilBuffer = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthStencilBuffer.filterMode = FilterMode.Point;
m_CameraDepthStencilBuffer.Create();
m_CameraDepthStencilBufferRT = new RenderTargetIdentifier(m_CameraDepthStencilBuffer);
if (NeedDepthBufferCopy())
{
if (m_CameraDepthStencilBufferCopy != null)
{
m_CameraDepthStencilBufferCopy.Release();
}
m_CameraDepthStencilBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthStencilBufferCopy.filterMode = FilterMode.Point;
m_CameraDepthStencilBufferCopy.Create();
m_CameraDepthStencilBufferCopyRT = new RenderTargetIdentifier(m_CameraDepthStencilBufferCopy);
}
}
void Resize(Camera camera)
{
// TODO: Detect if renderdoc just load and force a resize in this case, as often renderdoc require to realloc resource.

if (m_LightLoop == null)
return;
if (camera.pixelWidth != m_CurrentWidth || camera.pixelHeight != m_CurrentHeight || m_LightLoop.NeedResize())
bool resolutionChanged = camera.pixelWidth != m_CurrentWidth || camera.pixelHeight != m_CurrentHeight;
if (resolutionChanged || m_CameraDepthStencilBuffer == null)
{
CreateDepthBuffer(camera);
}
if (resolutionChanged || m_LightLoop.NeedResize())
{
if (m_CurrentWidth > 0 && m_CurrentHeight > 0)
{

m_LightLoop.AllocResolutionDependentBuffers(camera.pixelWidth, camera.pixelHeight);
// update recorded window resolution
m_CurrentWidth = camera.pixelWidth;
m_CurrentHeight = camera.pixelHeight;
// update recorded window resolution
m_CurrentWidth = camera.pixelWidth;
m_CurrentHeight = camera.pixelHeight;
public void PushGlobalParams(HDCamera hdCamera, ScriptableRenderContext renderContext, SubsurfaceScatteringParameters sssParameters)
public void PushGlobalParams(HDCamera hdCamera, ScriptableRenderContext renderContext, SubsurfaceScatteringSettings sssParameters)
var cmd = new CommandBuffer {name = "Push Global Parameters"};
cmd.SetGlobalVector("_ScreenSize", hdCamera.screenSize);
cmd.SetGlobalMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
cmd.SetGlobalMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
cmd.SetGlobalMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
cmd.SetGlobalVector("_InvProjParam", hdCamera.invProjectionParam);
// TODO: cmd.SetGlobalInt() does not exist, so we are forced to use Shader.SetGlobalInt() instead.
if (m_SkyManager.IsSkyValid())
{
m_SkyManager.SetGlobalSkyTexture();

// Broadcast SSS parameters to all shaders.
Shader.SetGlobalInt("_TransmissionFlags", sssParameters.transmissionFlags);
Shader.SetGlobalFloatArray("_ThicknessRemaps", sssParameters.thicknessRemaps);
Shader.SetGlobalVectorArray("_HalfRcpVariancesAndLerpWeights", sssParameters.halfRcpVariancesAndLerpWeights);
cmd.SetGlobalFloatArray("_ThicknessRemaps", sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray("_HalfRcpVariancesAndLerpWeights", sssParameters.halfRcpVariancesAndLerpWeights);
switch (sssParameters.texturingMode)
{
case SubsurfaceScatteringSettings.TexturingMode.PreScatter:
cmd.EnableShaderKeyword("SSS_PRE_SCATTER_TEXTURING");
cmd.DisableShaderKeyword("SSS_POST_SCATTER_TEXTURING");
break;
case SubsurfaceScatteringSettings.TexturingMode.PostScatter:
cmd.DisableShaderKeyword("SSS_PRE_SCATTER_TEXTURING");
cmd.EnableShaderKeyword("SSS_POST_SCATTER_TEXTURING");
break;
case SubsurfaceScatteringSettings.TexturingMode.PreAndPostScatter:
cmd.DisableShaderKeyword("SSS_PRE_SCATTER_TEXTURING");
cmd.DisableShaderKeyword("SSS_POST_SCATTER_TEXTURING");
break;
}
if (sssParameters.enableSSS)
if (globalDebugSettings.renderingDebugSettings.enableSSS)
Shader.EnableKeyword("_SUBSURFACE_SCATTERING");
cmd.EnableShaderKeyword("_SUBSURFACE_SCATTERING");
Shader.DisableKeyword("_SUBSURFACE_SCATTERING");
cmd.DisableShaderKeyword("_SUBSURFACE_SCATTERING");
var cmd = new CommandBuffer {name = "Push Global Parameters"};
cmd.SetGlobalVector("_ScreenSize", hdCamera.screenSize);
cmd.SetGlobalMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
cmd.SetGlobalMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

}
bool NeedDepthBufferCopy()
{
// For now we consider only PS4 to be able to read from a bound depth buffer. Need to test/implement for other platforms.
return SystemInfo.graphicsDeviceType != GraphicsDeviceType.PlayStation4;
}
Texture GetDepthTexture()
{
if (NeedDepthBufferCopy())
return m_CameraDepthStencilBufferCopy;
else
return m_CameraDepthStencilBuffer;
}
private void CopyDepthBufferIfNeeded(ScriptableRenderContext renderContext)
{
var cmd = new CommandBuffer();
if (NeedDepthBufferCopy())
{
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", renderContext))
{
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthStencilBufferCopyRT);
}
}
cmd.SetGlobalTexture("_MainDepthTexture", GetDepthTexture());
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
{
base.Render(renderContext, cameras);

RenderForwardOnlyOpaqueDepthPrepass(cullResults, camera, renderContext);
RenderGBuffer(cullResults, camera, renderContext);
// 'm_CameraStencilBufferRT' is a temporary copy of the stencil buffer and should be removed
// once we are able to read from the depth buffer and perform the stencil test simultaneously.
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", renderContext))
// 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)
var cmd = new CommandBuffer();
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraStencilBufferRT);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
CopyDepthBufferIfNeeded(renderContext);
}
if (globalDebugSettings.materialDebugSettings.debugViewMaterial != 0)

}
}
PushGlobalParams(hdCamera, renderContext, m_Owner.sssParameters);
PushGlobalParams(hdCamera, renderContext, m_Owner.sssSettings);
// Caution: We require sun light here as some sky use the sun light to render, mean UpdateSkyEnvironment
// must be call after BuildGPULightLists.

RenderDeferredLighting(hdCamera, renderContext, m_Owner.sssParameters.enableSSS);
RenderDeferredLighting(hdCamera, renderContext, m_Owner.globalDebugSettings.renderingDebugSettings.enableSSS);
CombineSubsurfaceScattering(hdCamera, renderContext, m_Owner.sssParameters);
CombineSubsurfaceScattering(hdCamera, renderContext, m_Owner.sssSettings);
// For opaque forward we have split rendering in two categories
// Material that are always forward and material that can be deferred or forward depends on render pipeline options (like switch to rendering forward only mode)

// 'm_CameraDepthStencilBufferCopyRT' is a temporary copy of the depth texture and should be removed
// once we are able to read from the depth buffer during transparent pass.
using (new Utilities.ProfilingSample("Copy depth-stencil buffer after all opaque", renderContext))
// 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)
var cmd = new CommandBuffer();
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthStencilBufferCopyRT);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
CopyDepthBufferIfNeeded(renderContext);
}
RenderSky(hdCamera, renderContext);

if (enableSSS)
{
// Output split lighting for materials tagged with the SSS stencil bit.
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, globalDebugSettings.lightingDebugSettings, colorRTs, m_CameraStencilBufferRT, true, enableSSS);
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, globalDebugSettings.lightingDebugSettings, colorRTs, m_CameraDepthStencilBufferRT, new RenderTargetIdentifier(GetDepthTexture()), true, enableSSS);
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, globalDebugSettings.lightingDebugSettings, colorRTs, m_CameraStencilBufferRT, false, enableSSS);
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, globalDebugSettings.lightingDebugSettings, colorRTs, m_CameraDepthStencilBufferRT, new RenderTargetIdentifier(GetDepthTexture()), false, enableSSS);
void CombineSubsurfaceScattering(HDCamera hdCamera, ScriptableRenderContext context, SubsurfaceScatteringParameters sssParameters)
void CombineSubsurfaceScattering(HDCamera hdCamera, ScriptableRenderContext context, SubsurfaceScatteringSettings sssParameters)
if (!sssParameters.enableSSS) return;
if (!globalDebugSettings.renderingDebugSettings.enableSSS) return;
m_FilterSubsurfaceScattering.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
m_CameraFilteringBufferRT, m_CameraStencilBufferRT);
m_CameraFilteringBufferRT, m_CameraDepthStencilBufferRT);
m_FilterAndCombineSubsurfaceScattering.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
m_CameraColorBufferRT, m_CameraStencilBufferRT);
m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();

void RenderDebugOverlay(Camera camera, ScriptableRenderContext renderContext)
{
// We don't want any overlay for these kind of rendering
if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview)
return;
CommandBuffer debugCB = new CommandBuffer();
debugCB.name = "Debug Overlay";

MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
LightingDebugSettings shadowDebug = globalDebugSettings.lightingDebugSettings;
LightingDebugSettings lightingDebug = globalDebugSettings.lightingDebugSettings;
if (shadowDebug.shadowDebugMode != ShadowDebugMode.None)
if (lightingDebug.shadowDebugMode != ShadowMapDebugMode.None)
if (shadowDebug.shadowDebugMode == ShadowDebugMode.VisualizeShadowMap)
if (lightingDebug.shadowDebugMode == ShadowMapDebugMode.VisualizeShadowMap)
uint visualizeShadowIndex = Math.Min(shadowDebug.shadowMapIndex, (uint)(GetCurrentShadowCount() - 1));
uint visualizeShadowIndex = Math.Min(lightingDebug.shadowMapIndex, (uint)(GetCurrentShadowCount() - 1));
ShadowLight shadowLight = m_ShadowsResult.shadowLights[visualizeShadowIndex];
for (int slice = 0; slice < shadowLight.shadowSliceCount; ++slice)
{

NextOverlayCoord(ref x, ref y, overlaySize, camera.pixelWidth);
}
}
else if (shadowDebug.shadowDebugMode == ShadowDebugMode.VisualizeAtlas)
else if (lightingDebug.shadowDebugMode == ShadowMapDebugMode.VisualizeAtlas)
{
propertyBlock.SetVector("_TextureScaleBias", new Vector4(1.0f, 1.0f, 0.0f, 0.0f));

}
}
if(lightingDebug.displaySkyReflection)
{
Texture skyReflection = m_SkyManager.skyReflection;
propertyBlock.SetTexture("_InputCubemap", skyReflection);
propertyBlock.SetFloat("_Mipmap", lightingDebug.skyReflectionMipmap);
debugCB.SetViewport(new Rect(x, y, overlaySize, overlaySize));
debugCB.DrawProcedural(Matrix4x4.identity, m_DebugDisplayLatlong, 0, MeshTopology.Triangles, 3, 1, propertyBlock);
NextOverlayCoord(ref x, ref y, overlaySize, camera.pixelWidth);
}
renderContext.ExecuteCommandBuffer(debugCB);
}

cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
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
cmd.GetTemporaryRT(m_CameraDepthStencilBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(m_CameraDepthStencilBufferCopy, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(m_CameraStencilBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
if (!m_Owner.renderingSettings.ShouldUseForwardRenderingOnly())
{

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs


public virtual void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
LightingDebugSettings lightDebugParameters,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier stencilBuffer,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
bool outputSplitLightingForSSS, bool enableSSS) {}
public virtual void RenderForward(Camera camera, ScriptableRenderContext renderContext, bool renderOpaque) {}

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


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
// #pragma enable_d3d11_debug_symbols
#pragma vertex Vert
#pragma fragment Frag

// Split lighting is utilized during the SSS pass.
#pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
// #ifdef OUTPUT_SPLIT_LIGHTING
#pragma shader_feature _ SSS_PRE_SCATTER_TEXTURING SSS_POST_SCATTER_TEXTURING
// #endif
#pragma multi_compile _ LIGHTING_DEBUG

DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
TEXTURE2D_FLOAT(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
struct Attributes
{
uint vertexID : SV_VertexID;

{
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TileLightLoopProducer.cs


[Serializable]
public class TileSettings
{
public bool enableDrawLightBoundsDebug;
public bool disableTileAndCluster; // For debug / test
public bool disableDeferredShadingInCompute;
public bool enableTileAndCluster; // For debug / test
public bool enableSplitLightEvaluation;
public bool enableComputeLightEvaluation;

public bool disableFptlWhenClustered; // still useful on opaques. Should be false 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;
enableDrawLightBoundsDebug = false,
disableTileAndCluster = false,
disableDeferredShadingInCompute = true,
enableTileAndCluster = true,
enableSplitLightEvaluation = true,
enableComputeLightEvaluation = false,

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


#else
g_depth_tex.GetDimensions(iWidth, iHeight);
#endif
uint nrTilesX = (iWidth+15)/16;
uint nrTilesY = (iHeight+15)/16;
const uint log2TileSize = firstbithigh(TILE_SIZE_CLUSTERED);
uint nrTilesX = (iWidth+(TILE_SIZE_CLUSTERED-1))>>log2TileSize;
uint nrTilesY = (iHeight+(TILE_SIZE_CLUSTERED-1))>>log2TileSize;
uint2 viTilLL = 16*tileIDX;
uint2 viTilUR = min( viTilLL+uint2(16,16), uint2(iWidth, iHeight) ); // not width and height minus 1 since viTilUR represents the end of the tile corner.
uint2 viTilLL = TILE_SIZE_CLUSTERED*tileIDX;
uint2 viTilUR = min( viTilLL+uint2(TILE_SIZE_CLUSTERED,TILE_SIZE_CLUSTERED), uint2(iWidth, iHeight) ); // not width and height minus 1 since viTilUR represents the end of the tile corner.
if(t==0)
{

// establish min and max depth first
dpt_ma=0.0;
for(int idx=t; idx<256; idx+=NR_THREADS)
for(int idx=t; idx<(TILE_SIZE_CLUSTERED*TILE_SIZE_CLUSTERED); idx+=NR_THREADS)
uint2 uPixCrd = min( uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1) );
uint2 uPixCrd = min( uint2(viTilLL.x+(idx&(TILE_SIZE_CLUSTERED-1)), viTilLL.y+(idx>>log2TileSize)), uint2(iWidth-1, iHeight-1) );
#ifdef MSAA_ENABLED
for(uint i=0; i<iNumSamplesMSAA; i++)
{

// build coarse list using AABB
#ifdef USE_TWO_PASS_TILED_LIGHTING
int NrBigTilesX = (nrTilesX+3)>>2;
const int bigTileIdx = (tileIDX.y>>2)*NrBigTilesX + (tileIDX.x>>2); // map the idx to 64x64 tiles
const uint log2BigTileToClustTileRatio = firstbithigh(64) - log2TileSize;
int NrBigTilesX = (nrTilesX+((1<<log2BigTileToClustTileRatio)-1))>>log2BigTileToClustTileRatio;
const int bigTileIdx = (tileIDX.y>>log2BigTileToClustTileRatio)*NrBigTilesX + (tileIDX.x>>log2BigTileToClustTileRatio); // map the idx to 64x64 tiles
int nrBigTileLights = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+0];
for(int l0=(int) t; l0<(int) nrBigTileLights; l0 += NR_THREADS)
{

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

#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
float halfTileSizeAtZDistOne = (TILE_SIZE_CLUSTERED/2)*onePixDiagDist; // scale by half a tile
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{

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


#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
#define USE_FPTL_LIGHTLIST 1
//-------------------------------------------------------------------------------------
// Include

DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
TEXTURE2D_FLOAT(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;

[numthreads(TILE_SIZE, TILE_SIZE, 1)]
[numthreads(16, 16, 1)]
// input.positionCS is SV_Position
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);

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


// enable unity's original left-hand shader camera space (right-hand internally in unity).
public static int USE_LEFTHAND_CAMERASPACE = 1;
public static int TILE_SIZE_FPTL = 16;
public static int TILE_SIZE_CLUSTERED = 32;
// flags
public static int IS_CIRCULAR_SPOT_SHAPE = 1;
public static int HAS_COOKIE_TEXTURE = 2;

Material m_SingleDeferredMaterialSRT = null;
Material m_SingleDeferredMaterialMRT = null;
const int k_TileSize = 16;
#if (SHADOWS_ENABLED)
// shadow related stuff
FrameId m_FrameId;

#endif
int GetNumTileX(Camera camera)
int GetNumTileFtplX(Camera camera)
return (camera.pixelWidth + (k_TileSize - 1)) / k_TileSize;
return (camera.pixelWidth + (LightDefinitions.TILE_SIZE_FPTL - 1)) / LightDefinitions.TILE_SIZE_FPTL;
}
int GetNumTileFtplY(Camera camera)
{
return (camera.pixelHeight + (LightDefinitions.TILE_SIZE_FPTL - 1)) / LightDefinitions.TILE_SIZE_FPTL;
int GetNumTileY(Camera camera)
int GetNumTileClusteredX(Camera camera)
return (camera.pixelHeight + (k_TileSize - 1)) / k_TileSize;
return (camera.pixelWidth + (LightDefinitions.TILE_SIZE_CLUSTERED - 1)) / LightDefinitions.TILE_SIZE_CLUSTERED;
}
int GetNumTileClusteredY(Camera camera)
{
return (camera.pixelHeight + (LightDefinitions.TILE_SIZE_CLUSTERED - 1)) / LightDefinitions.TILE_SIZE_CLUSTERED;
}
TileLightLoopProducer.TileSettings m_PassSettings;

public override void AllocResolutionDependentBuffers(int width, int height)
{
var nrTilesX = (width + k_TileSize - 1) / k_TileSize;
var nrTilesY = (height + k_TileSize - 1) / k_TileSize;
var nrTilesX = (width + LightDefinitions.TILE_SIZE_FPTL - 1) / LightDefinitions.TILE_SIZE_FPTL;
var nrTilesY = (height + LightDefinitions.TILE_SIZE_FPTL - 1) / LightDefinitions.TILE_SIZE_FPTL;
var nrTiles = nrTilesX * nrTilesY;
const int capacityUShortsPerTile = 32;
const int dwordsPerTile = (capacityUShortsPerTile + 1) >> 1; // room for 31 lights and a nrLights value.

if (m_PassSettings.enableClustered)
{
s_PerVoxelOffset = new ComputeBuffer((int)LightCategory.Count * (1 << k_Log2NumClusters) * nrTiles, sizeof(uint));
s_PerVoxelLightLists = new ComputeBuffer(NumLightIndicesPerClusteredTile() * nrTiles, sizeof(uint));
var nrClustersX = (width + LightDefinitions.TILE_SIZE_CLUSTERED - 1) / LightDefinitions.TILE_SIZE_CLUSTERED;
var nrClustersY = (height + LightDefinitions.TILE_SIZE_CLUSTERED - 1) / LightDefinitions.TILE_SIZE_CLUSTERED;
var nrClusterTiles = nrClustersX * nrClustersY;
s_PerVoxelOffset = new ComputeBuffer((int)LightCategory.Count * (1 << k_Log2NumClusters) * nrClusterTiles, sizeof(uint));
s_PerVoxelLightLists = new ComputeBuffer(NumLightIndicesPerClusteredTile() * nrClusterTiles, sizeof(uint));
s_PerTileLogBaseTweak = new ComputeBuffer(nrTiles, sizeof(float));
s_PerTileLogBaseTweak = new ComputeBuffer(nrClusterTiles, sizeof(float));
}
}

return shadowOutput.GetShadowSliceCountLightIndex(lightIndex);
}
public void GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int directionalShadowcount)
public bool GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int directionalShadowcount)
float diffuseDimmer = m_PassSettings.diffuseGlobalDimmer * additionalData.lightDimmer;
float specularDimmer = m_PassSettings.specularGlobalDimmer * additionalData.lightDimmer;
if (diffuseDimmer <= 0.0f && specularDimmer <= 0.0f)
return false;
// Light direction for directional is opposite to the forward direction
directionalLightData.forward = light.light.transform.forward;
directionalLightData.up = light.light.transform.up;

directionalLightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
directionalLightData.diffuseScale = additionalData.affectDiffuse ? diffuseDimmer : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? specularDimmer : 0.0f;
directionalLightData.invScaleX = 1.0f / light.light.transform.localScale.x;
directionalLightData.invScaleY = 1.0f / light.light.transform.localScale.y;
directionalLightData.cosAngle = 0.0f;

}
m_lightList.directionalLights.Add(directionalLightData);
return true;
public void GetLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int shadowCount)
float ComputeLinearDistanceFade(float distanceToCamera, float fadeDistance)
{
// Fade with distance calculation is just a linear fade from 90% of fade distance to fade distance. 90% arbitrarly chosen but should work well enough.
float distanceFadeNear = 0.9f * fadeDistance;
return 1.0f - Mathf.Clamp01((distanceToCamera - distanceFadeNear) / (fadeDistance - distanceFadeNear));
}
public bool GetLightData(ShadowSettings shadowSettings, Camera camera, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int shadowCount)
{
var lightData = new LightData();

lightData.angleOffset = 2.0f;
}
lightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
lightData.shadowDimmer = additionalData.shadowDimmer;
float distanceToCamera = (lightData.positionWS - camera.transform.position).magnitude;
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;
if (lightData.diffuseScale <= 0.0f && lightData.specularScale <= 0.0f)
return false;
lightData.IESIndex = -1;
lightData.cookieIndex = -1;

}
}
float shadowDistanceFade = ComputeLinearDistanceFade(distanceToCamera, additionalData.shadowFadeDistance);
lightData.shadowDimmer = additionalData.shadowDimmer * shadowDistanceFade;
bool hasShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
// In case lightData.shadowDimmer == 0.0 we need to avoid rendering the shadow map... see how it can be done with the culling (and more specifically, how can we do that BEFORE sending for shadows)
bool hasShadows = lightData.shadowDimmer > 0.0f && light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasNotReachMaxLimit = shadowCount + (lightData.lightType == GPULightType.Point ? 6 : 1) <= k_MaxShadowOnScreen;
// TODO: Read the comment about shadow limit/management at the beginning of this loop

}
m_lightList.lights.Add(lightData);
return true;
}
// TODO: we should be able to do this calculation only with LightData without VisibleLight light, but for now pass both

}
}
#endif
float oldSpecularGlobalDimmer = m_PassSettings.specularGlobalDimmer;
// Change some parameters in case of "special" rendering (can be preview, reflection, etc.
if(camera.cameraType == CameraType.Reflection)
{
m_PassSettings.specularGlobalDimmer = 0.0f;
}
// 1. Count the number of lights and sort all light by category, type and volume
int directionalLightcount = 0;

lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
++punctualLightcount;
break;
case LightType.Spot:

gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
++punctualLightcount;
break;
case LightType.Directional:

gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
++directionalLightcount;
break;
default:

lightCategory = LightCategory.Area;
gpuLightType = GPULightType.Rectangle;
lightVolumeType = LightVolumeType.Box;
++areaLightCount;
break;
case LightArchetype.Line:

gpuLightType = GPULightType.Line;
lightVolumeType = LightVolumeType.Box;
++areaLightCount;
break;
default:

// Directional rendering side, it is separated as it is always visible so no volume to handle here
if (gpuLightType == GPULightType.Directional)
{
GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref directionalShadowcount);
if (GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref directionalShadowcount))
directionalLightcount++;
#if (SHADOWS_ENABLED && SHADOWS_FIXSHADOWIDX)
// fix up shadow information

}
// Spot, point, rect, line light - Rendering side
GetLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref shadowCount);
// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], worldToView);
if(GetLightData(shadowSettings, camera, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref shadowCount))
{
if (lightCategory == LightCategory.Punctual)
punctualLightcount++;
else if (lightCategory == LightCategory.Area)
areaLightCount++;
else
Debug.Assert(false); // Should not be anything else here.
// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], worldToView);
}
#if (SHADOWS_ENABLED && SHADOWS_FIXSHADOWIDX)
// fix up shadow information

m_lightCount = m_lightList.lights.Count + m_lightList.envLights.Count;
Debug.Assert(m_lightList.bounds.Count == m_lightCount);
Debug.Assert(m_lightList.lightVolumes.Count == m_lightCount);
// Restore values after "special rendering"
m_PassSettings.specularGlobalDimmer = oldSpecularGlobalDimmer;
}
void VoxelLightListGeneration(CommandBuffer cmd, Camera camera, Matrix4x4 projscr, Matrix4x4 invProjscr, RenderTargetIdentifier cameraDepthBufferRT)

cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_logBaseBuffer", s_PerTileLogBaseTweak);
}
var numTilesX = GetNumTileX(camera);
var numTilesY = GetNumTileY(camera);
var numTilesX = GetNumTileClusteredX(camera);
var numTilesY = GetNumTileClusteredY(camera);
cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
}

var h = camera.pixelHeight;
var numTilesX = GetNumTileX(camera);
var numTilesY = GetNumTileY(camera);
var numBigTilesX = (w + 63) / 64;
var numBigTilesY = (h + 63) / 64;

cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vLightList", s_LightList);
if (m_PassSettings.enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vBigTileLightList", s_BigTileLightList);
var numTilesX = GetNumTileFtplX(camera);
var numTilesY = GetNumTileFtplY(camera);
cmd.DispatchCompute(buildPerTileLightListShader, s_GenListPerTileKernel, numTilesX, numTilesY, 1);
}

SetGlobalBuffer("_ShadowDatas", s_shadowDatas);
SetGlobalVectorArray("_DirShadowSplitSpheres", m_lightList.directionalShadowSplitSphereSqr);
SetGlobalInt("_NumTileX", GetNumTileX(camera));
SetGlobalInt("_NumTileY", GetNumTileY(camera));
SetGlobalInt("_NumTileFtplX", GetNumTileFtplX(camera));
SetGlobalInt("_NumTileFtplY", GetNumTileFtplY(camera));
SetGlobalInt("_NumTileClusteredX", GetNumTileClusteredX(camera));
SetGlobalInt("_NumTileClusteredY", GetNumTileClusteredY(camera));
if (m_PassSettings.enableBigTilePrepass)
SetGlobalBuffer("g_vBigTileLightList", s_BigTileLightList);

public override void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
LightingDebugSettings lightDebugSettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier stencilBuffer,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
bool outputSplitLightingForSSS, bool enableSSS)
{
var bUseClusteredForDeferred = !usingFptl;

}
#endif
using (new Utilities.ProfilingSample(m_PassSettings.disableTileAndCluster ? "SinglePass - Deferred Lighting Pass" : "TilePass - Deferred Lighting Pass", renderContext))
using (new Utilities.ProfilingSample(m_PassSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass", renderContext))
{
var cmd = new CommandBuffer();

// Must be done after setting up the compute shader above.
SetupRenderingForDebug(lightDebugSettings);
if (m_PassSettings.disableTileAndCluster)
if (!m_PassSettings.enableTileAndCluster)
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialMRT, hdCamera, colorBuffers, depthStencilBuffer);
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialSRT, hdCamera, colorBuffers[0], depthStencilBuffer);
if (!m_PassSettings.disableDeferredShadingInCompute)
if (m_PassSettings.enableComputeLightEvaluation)
int w = camera.pixelWidth;
int h = camera.pixelHeight;
int numTilesX = GetNumTileX(camera);
int numTilesY = GetNumTileY(camera);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_CameraDepthTexture", Shader.PropertyToID("_CameraDepthTexture"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_MainDepthTexture", depthStencilTexture);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture0", Shader.PropertyToID("_GBufferTexture0"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture1", Shader.PropertyToID("_GBufferTexture1"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture2", Shader.PropertyToID("_GBufferTexture2"));

cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_SkyTexture", skyTexture ? skyTexture : m_DefaultTexture2DArray);
// Since we need the stencil test, the compute path does not currently support SSS.
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "combinedLightingUAV", colorBuffers[0]);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "combinedLightingUAV", colorBuffers[0]);
// always do deferred lighting in blocks of 16x16 (not same as tiled light size)
int w = camera.pixelWidth;
int h = camera.pixelHeight;
int numTilesX = (w+15)/16;
int numTilesY = (h+15)/16;
cmd.DispatchCompute(shadeOpaqueShader, kernel, numTilesX, numTilesY, 1);
}
else

if (outputSplitLightingForSSS)
{
Utilities.SelectKeyword(m_DeferredDirectMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullScreen(cmd, m_DeferredDirectMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredDirectMaterialMRT, hdCamera, colorBuffers, depthStencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredIndirectMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredIndirectMaterialMRT, hdCamera, colorBuffers, depthStencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredDirectMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredDirectMaterialSRT, hdCamera, colorBuffers[0], depthStencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredIndirectMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredIndirectMaterialSRT, hdCamera, colorBuffers[0], depthStencilBuffer);
}
}
else

Utilities.SelectKeyword(m_DeferredAllMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialMRT, hdCamera, colorBuffers, depthStencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialSRT, hdCamera, colorBuffers[0], depthStencilBuffer);
}
}
}

var cmd = new CommandBuffer();
if (m_PassSettings.disableTileAndCluster)
if (!m_PassSettings.enableTileAndCluster)
{
cmd.name = "Forward pass";
cmd.EnableShaderKeyword("LIGHTLOOP_SINGLE_PASS");

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl


#define MAX_NR_BIGTILE_LIGHTS_PLUSONE (512)
#define VIEWPORT_SCALE_Z (1)
#define USE_LEFTHAND_CAMERASPACE (1)
#define TILE_SIZE_FPTL (16)
#define TILE_SIZE_CLUSTERED (32)
#define IS_CIRCULAR_SPOT_SHAPE (1)
#define HAS_COOKIE_TEXTURE (2)
#define IS_BOX_PROJECTED (4)

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


#include "TilePass.cs.hlsl"
uint _NumTileX;
uint _NumTileY;
// For FPTL
uint _NumTileFtplX;
uint _NumTileFtplY;
#define TILE_SIZE 16 // This is fixed
#ifdef USE_FPTL_LIGHTLIST
#define TILE_SIZE TILE_SIZE_FPTL
#endif
// Don't do a "#else" so we can catch error if including call don't setup thing correctly
#ifdef USE_CLUSTERED_LIGHTLIST
#define TILE_SIZE TILE_SIZE_CLUSTERED
#endif
#define DWORD_PER_TILE 16 // See dwordsPerTile in TilePass.cs, we have roomm for 31 lights and a number of light value all store on 16 bit (ushort)
// these uniforms are only needed for when OPAQUES_ONLY is NOT defined

//#endif
//#ifdef USE_CLUSTERED_LIGHTLIST
uint _NumTileClusteredX;
uint _NumTileClusteredY;
StructuredBuffer<uint> g_vLayeredOffsetsBuffer; // don't support Buffer yet in unity
StructuredBuffer<float> g_logBaseBuffer; // don't support Buffer yet in unity
//#endif

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


// LightLoop
// ----------------------------------------------------------------------------
void ApplyDebug(inout float3 diffuseLighting, inout float3 specularLighting)
void ApplyDebug(LightLoopContext lightLoopContext, float3 positionWS, inout float3 diffuseLighting, inout float3 specularLighting)
{
#ifdef LIGHTING_DEBUG
int lightDebugMode = (int)_DebugLightModeAndAlbedo.x;

{
diffuseLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_VISUALIZE_CASCADE)
{
specularLighting = float3(0.0, 0.0, 0.0);
const float3 s_CascadeColors[] = {
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#endif
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);
else
{
diffuseLighting = s_CascadeColors[shadowSplitIndex] * shadow;
}
}
#endif
}

int GetTileOffset(PositionInputs posInput, uint lightCategory)
{
uint2 tileIndex = posInput.unPositionSS / TILE_SIZE;
return (tileIndex.y + lightCategory * _NumTileY) * _NumTileX + tileIndex.x;
uint2 tileIndex = posInput.unPositionSS / TILE_SIZE_FPTL;
return (tileIndex.y + lightCategory * _NumTileFtplY) * _NumTileFtplX + tileIndex.x;
}
void GetCountAndStartTile(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)

void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
uint2 tileIndex = posInput.unPositionSS / TILE_SIZE;
uint2 tileIndex = posInput.unPositionSS / TILE_SIZE_CLUSTERED;
logBase = g_logBaseBuffer[tileIndex.y * _NumTileX + tileIndex.x];
logBase = g_logBaseBuffer[tileIndex.y * _NumTileClusteredX + tileIndex.x];
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileY + tileIndex.y) * _NumTileX + tileIndex.x;
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileClusteredY + tileIndex.y) * _NumTileClusteredX + tileIndex.x;
uint dataPair = g_vLayeredOffsetsBuffer[idx];
start = dataPair & 0x7ffffff;
lightCount = (dataPair >> 27) & 31;

diffuseLighting += bakeDiffuseLighting;
#endif
ApplyDebug(diffuseLighting, specularLighting);
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#else // LIGHTLOOP_SINGLE_PASS

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

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


static public void SetupLayersMappingKeywords(Material material)
{
// object scale affect tile
SetKeyword(material, "_LAYER_TILING_UNIFORM_SCALE", material.GetFloat(kObjectScaleAffectTile) > 0.0f);
SetKeyword(material, "_LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE", material.GetFloat(kObjectScaleAffectTile) > 0.0f);
// Blend mask
LayerUVBaseMapping UVBlendMaskMapping = (LayerUVBaseMapping)material.GetFloat(kUVBlendMask);

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


#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _LAYER_TILING_UNIFORM_SCALE
#pragma shader_feature _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
#pragma shader_feature _ _LAYER_MAPPING_PLANAR_BLENDMASK _LAYER_MAPPING_TRIPLANAR_BLENDMASK
#pragma shader_feature _ _LAYER_MAPPING_PLANAR0 _LAYER_MAPPING_TRIPLANAR0
#pragma shader_feature _ _LAYER_MAPPING_PLANAR1 _LAYER_MAPPING_TRIPLANAR1

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


_TessellationShapeFactor("Tessellation shape factor", Range(0.0, 1.0)) = 0.75 // Only use with Phong
_TessellationBackFaceCullEpsilon("Tessellation back face epsilon", Range(-1.0, 0.0)) = -0.25
[ToggleOff] _TessellationObjectScale("Tessellation object scale", Float) = 0.0
[ToggleOff] _TessellationTilingScale("Tessellation tiling scale", Float) = 1.0
// TODO: Handle culling mode for backface culling
}

// Default is _TESSELLATION_PHONG
#pragma shader_feature _ _TESSELLATION_DISPLACEMENT _TESSELLATION_DISPLACEMENT_PHONG
#pragma shader_feature _TESSELLATION_OBJECT_SCALE
#pragma shader_feature _TESSELLATION_TILING_SCALE
#pragma shader_feature _LAYER_TILING_UNIFORM_SCALE
#pragma shader_feature _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
#pragma shader_feature _ _LAYER_MAPPING_PLANAR_BLENDMASK _LAYER_MAPPING_TRIPLANAR_BLENDMASK
#pragma shader_feature _ _LAYER_MAPPING_PLANAR0 _LAYER_MAPPING_TRIPLANAR0
#pragma shader_feature _ _LAYER_MAPPING_PLANAR1 _LAYER_MAPPING_TRIPLANAR1

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


public static GUIContent tessellationShapeFactorText = new GUIContent("Shape factor", "Strength of Phong tessellation shape (lerp factor)");
public static GUIContent tessellationBackFaceCullEpsilonText = new GUIContent("Triangle culling Epsilon", "If -1.0 back face culling is enabled for tessellation, higher number mean more aggressive culling and better performance");
public static GUIContent tessellationObjectScaleText = new GUIContent("Enable object scale", "Tessellation displacement will take into account the object scale - Only work with uniform positive scale");
public static GUIContent tessellationTilingScaleText = new GUIContent("Enable tiling scale", "Tessellation displacement will take into account the tiling scale - Only work with uniform positive scale");
}
public enum TessellationMode

protected const string kTessellationBackFaceCullEpsilon = "_TessellationBackFaceCullEpsilon";
protected MaterialProperty tessellationObjectScale = null;
protected const string kTessellationObjectScale = "_TessellationObjectScale";
protected MaterialProperty tessellationTilingScale = null;
protected const string kTessellationTilingScale = "_TessellationTilingScale";
protected override void FindBaseMaterialProperties(MaterialProperty[] props)
{

tessellationShapeFactor = FindProperty(kTessellationShapeFactor, props, false);
tessellationBackFaceCullEpsilon = FindProperty(kTessellationBackFaceCullEpsilon, props, false);
tessellationObjectScale = FindProperty(kTessellationObjectScale, props, false);
tessellationTilingScale = FindProperty(kTessellationTilingScale, props, false);
}
void TessellationModePopup()

m_MaterialEditor.ShaderProperty(tessellationBackFaceCullEpsilon, StylesBaseLit.tessellationBackFaceCullEpsilonText);
}
m_MaterialEditor.ShaderProperty(tessellationObjectScale, StylesBaseLit.tessellationObjectScaleText);
m_MaterialEditor.ShaderProperty(tessellationTilingScale, StylesBaseLit.tessellationTilingScaleText);
EditorGUI.indentLevel--;
}
}

material.EnableKeyword("_TESSELLATION_DISPLACEMENT_PHONG");
}
bool tessellationObjectScaleEnable = material.GetFloat(kTessellationObjectScale) == 1.0;
bool tessellationObjectScaleEnable = material.GetFloat(kTessellationObjectScale) > 0.0;
bool tessellationTilingScaleEnable = material.GetFloat(kTessellationTilingScale) > 0.0;
SetKeyword(material, "_TESSELLATION_TILING_SCALE", tessellationTilingScaleEnable);
}
}

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


public float subsurfaceRadius;
public float thickness;
public int subsurfaceProfile;
public bool enableTransmission;
public bool enableTransmission; // Read from the SSS profile
public Vector3 transmittance;
// Clearcoat

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


#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_RADIUS (1042)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1043)
#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_PROFILE (1044)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMITTANCE (1045)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION (1045)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_NORMAL_WS (1047)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1048)

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


#endif
}
void ConfigureTexturingForSSS(inout BSDFData bsdfData)
{
#ifdef SSS_PRE_SCATTER_TEXTURING
bsdfData.diffuseColor = bsdfData.diffuseColor;
#elif SSS_POST_SCATTER_TEXTURING
bsdfData.diffuseColor = float3(1, 1, 1);
#else // combine pre-scatter and post-scatter texturing
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
#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).

bsdfData.fresnel0 = surfaceData.specularColor;
}
#ifdef OUTPUT_SPLIT_LIGHTING
ConfigureTexturingForSSS(bsdfData);
#endif
return bsdfData;
}

#endif
}
void DecodeFromGBuffer(
float4 DecodeGBuffer0(GBufferType0 encodedGBuffer0)
{
float4 decodedGBuffer0;
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
decodedGBuffer0.x = UnpackUIntToFloat(encodedGBuffer0.x, 8, 0);
decodedGBuffer0.y = UnpackUIntToFloat(encodedGBuffer0.x, 8, 8);
decodedGBuffer0.z = UnpackUIntToFloat(encodedGBuffer0.y, 8, 0);
decodedGBuffer0.w = UnpackUIntToFloat(encodedGBuffer0.y, 8, 8);
decodedGBuffer0.xyz = Gamma20ToLinear(encodedGBuffer0.xyz);
#else
decodedGBuffer0 = encodedGBuffer0;
#endif
return decodedGBuffer0;
}
void DecodeFromGBuffer(
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
GBufferType0 inGBufferU0,
GBufferType1 inGBufferU1,

#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
float4 inGBuffer0, inGBuffer1, inGBuffer2, inGBuffer3;
inGBuffer0.x = UnpackUIntToFloat(inGBufferU0.x, 8, 0);
inGBuffer0.y = UnpackUIntToFloat(inGBufferU0.x, 8, 8);
inGBuffer0.z = UnpackUIntToFloat(inGBufferU0.y, 8, 0);
inGBuffer0.w = UnpackUIntToFloat(inGBufferU0.y, 8, 8);
inGBuffer0.xyz = Gamma20ToLinear(inGBuffer0.xyz);
inGBuffer0 = DecodeGBuffer0(inGBufferU0);
inGBuffer2.x = UnpackUIntToFloat(inGBufferU1.x, 8, 0);
inGBuffer2.y = UnpackUIntToFloat(inGBufferU1.x, 8, 8);
inGBuffer2.z = UnpackUIntToFloat(inGBufferU1.y, 8, 0);

bakeDiffuseLighting = inGBuffer3.rgb;
#ifdef OUTPUT_SPLIT_LIGHTING
ConfigureTexturingForSSS(bsdfData);
#endif
ApplyDebugToBSDFData(bsdfData);
}

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


#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go futher in dev
//#pragma enable_d3d11_debug_symbols
// #pragma enable_d3d11_debug_symbols
//-------------------------------------------------------------------------------------
// Variant

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


input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
}
// Note: This function is call by both Per vertex and Per pixel displacement
float GetMaxDisplacement()
{
float maxDisplacement = 0.0;

#include "ShaderLibrary/PerPixelDisplacement.hlsl"
void ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
float ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
{
bool ppdEnable = false;
bool isPlanar = false;

PerPixelHeightDisplacementParam ppdParam;
float height; // final height processed
float NdotV;
// planar/triplanar
float2 uvXZ;
float2 uvXY;

if (isTriplanar)
{
float3 viewDirTS;
float planeHeight;
int numSteps;
// Perform a POM in each direction and modify appropriate texture coordinate

float2 offsetZY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
float2 offsetZY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, planeHeight);
height = layerTexCoord.triplanarWeights.x * planeHeight;
float2 offsetXZ = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
float2 offsetXZ = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, planeHeight);
height += layerTexCoord.triplanarWeights.y * planeHeight;
float2 offsetXY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
float2 offsetXY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, planeHeight);
height += layerTexCoord.triplanarWeights.z * planeHeight;
NdotV = 1; // TODO.
#ifdef SURFACE_GRADIENT
// The TBN is not normalize, normalize it to do per pixel displacement
#ifdef SURFACE_GRADIENT
// The TBN is not normalize, normalize it to do per pixel displacement
#else
float3x3 worldToTangent = input.worldToTangent;
#endif
#endif
NdotV = viewDirTS.z;
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, height);
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign.
float verticalDisplacement = maxHeight - height * maxHeight;
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap_ST.x, _BaseColorMap_ST.y));
return tilingScale * verticalDisplacement / NdotV;
return 0.0;
return (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap, sampler_HeightMap, layerTexCoord.base, lod).r - _HeightCenter) * _HeightAmplitude;
float height = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap, sampler_HeightMap, layerTexCoord.base, lod).r - _HeightCenter) * _HeightAmplitude;
#ifdef _TESSELLATION_TILING_SCALE
// When we change the tiling, we have want to conserve the ratio with the displacement (and this is consistent with per pixel displacement)
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap_ST.x, _BaseColorMap_ST.y));
height *= tilingScale;
#endif
return height;
}
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)

GetLayerTexCoord(input, layerTexCoord);
ApplyPerPixelDisplacement(input, V, layerTexCoord);
float depthOffset = 0.0;
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord);
ApplyDepthOffsetPositionInput(V, depthOffset, posInput);
ApplyDepthOffsetPositionInput(GetCameraForwardDir(), depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
// We perform the conversion to world of the normalTS outside of the GetSurfaceData

// On all layers (but not on blend mask) we can scale the tiling with object scale (only uniform supported)
// Note: the object scale doesn't affect planar/triplanar mapping as they already handle the object scale.
float tileObjectScale = 1.0;
#ifdef _LAYER_TILING_UNIFORM_SCALE
#ifdef _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
// Extract scaling from world transform
float4x4 worldTransform = GetObjectToWorldMatrix();
// assuming uniform scaling, take only the first column

input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
}
void ApplyTessellationTileScale(inout float height0, inout float height1, inout float height2, inout float height3)
{
// When we change the tiling, we have want to conserve the ratio with the displacement (and this is consistent with per pixel displacement)
#ifdef _TESSELLATION_TILING_SCALE
float tileObjectScale = 1.0;
#ifdef _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
// Extract scaling from world transform
float4x4 worldTransform = GetObjectToWorldMatrix();
// assuming uniform scaling, take only the first column
tileObjectScale = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#endif
height0 /= _LayerTiling0 * max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y);
#if !defined(_MAIN_LAYER_INFLUENCE_MODE)
height0 *= tileObjectScale; // We only affect layer0 in case we are not in influence mode (i.e we should not change the base object)
#endif
height1 /= tileObjectScale * _LayerTiling1 * max(_BaseColorMap1_ST.x, _BaseColorMap1_ST.y);
height2 /= tileObjectScale * _LayerTiling2 * max(_BaseColorMap2_ST.x, _BaseColorMap2_ST.y);
height3 /= tileObjectScale * _LayerTiling3 * max(_BaseColorMap3_ST.x, _BaseColorMap3_ST.y);
#endif
}
// This function is just syntaxic sugar to nullify height not used based on heightmap avaibility and layer
void SetEnabledHeightByLayer(inout float height0, inout float height1, inout float height2, inout float height3)
{

// Return the maximun amplitude use by all enabled heightmap
// use for tessellation culling and per pixel displacement
// TODO: For vertex displacement this should take into account the modification in ApplyTessellationTileScale but it should be conservative here (as long as tiling is not negative)
float GetMaxDisplacement()
{
float maxDisplacement = 0.0;

// - Blend Mask use same mapping as main layer (UVO, Planar, Triplanar)
// From these rules it mean that PPD is enable only if the user 1) ask for it, 2) if there is one heightmap enabled on active layer, 3) if mapping is the same for all layer respecting 2), 4) if mapping is UV0, planar or triplanar mapping
// Most contraint are handled by the inspector (i.e the UI) like the mapping constraint and is assumed in the shader.
void ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
float ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
{
bool ppdEnable = false;
bool isPlanar = false;

ppdParam.mainHeightInfluence = 0.0;
#endif
float height; // final height processed
float NdotV;
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)
{

// Apply to all layer that used triplanar
*/
height = 1;
NdotV = 1;
}
else
{

ppdParam.uv[3] = layerTexCoord.base3.uv;
#ifdef SURFACE_GRADIENT
// The TBN is not normalize, normalize it to do per pixel displacement
#ifdef SURFACE_GRADIENT
// The TBN is not normalize, normalize it to do per pixel displacement
#else
float3x3 worldToTangent = input.worldToTangent;
#endif
#endif
NdotV = viewDirTS.z;
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, height);
float4 planarWeight = float4( layerTexCoord.base0.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
float4 planarWeight = float4( layerTexCoord.base0.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
layerTexCoord.base1.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
layerTexCoord.base2.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
layerTexCoord.base3.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0);

layerTexCoord.base0.uv += offsetWeights.x * offset;
layerTexCoord.base1.uv += offsetWeights.y * offset;
layerTexCoord.base2.uv += offsetWeights.z * offset;

layerTexCoord.details2.uv += offsetWeights.z * offset;
layerTexCoord.details3.uv += offsetWeights.w * offset;
}
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign.
float verticalDisplacement = maxHeight - height * maxHeight;
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y));
return tilingScale * verticalDisplacement / NdotV;
return 0.0;
}
// Calculate displacement for per vertex displacement mapping

float height1 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1, lod).r - _LayerCenterOffset1) * _LayerHeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2, lod).r - _LayerCenterOffset2) * _LayerHeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3, lod).r - _LayerCenterOffset3) * _LayerHeightAmplitude3;
ApplyTessellationTileScale(height0, height1, height2, height3); // Only apply with per vertex displacement
SetEnabledHeightByLayer(height0, height1, height2, height3);
float heightResult = BlendLayeredScalar(height0, height1, height2, height3, weights);

ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(input, layerTexCoord);
ApplyPerPixelDisplacement(input, V, layerTexCoord);
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord);
float depthOffset = 0.0;
ApplyDepthOffsetPositionInput(V, depthOffset, posInput);
ApplyDepthOffsetPositionInput(GetCameraForwardDir(), depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
SurfaceData surfaceData0, surfaceData1, surfaceData2, surfaceData3;

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


float _TessellationShapeFactor;
float _TessellationBackFaceCullEpsilon;
float _TessellationObjectScale;
float _TessellationTilingScale;
#endif

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl


bool frustumCulled = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])unity_CameraWorldClipPlanes);
bool faceCull = false;
// We use the position of the primary (scene view) camera in order
// to have identical tessellation levels for both the scene view and
// shadow views. Otherwise, depth comparisons become meaningless!
float3 camPosWS = _WorldSpaceCameraPos;
faceCull = BackFaceCullTriangle(p0, p1, p2, _TessellationBackFaceCullEpsilon, _WorldSpaceCameraPos);
faceCull = BackFaceCullTriangle(p0, p1, p2, _TessellationBackFaceCullEpsilon, camPosWS);
}
#endif

// Distance based tessellation
if (_TessellationFactorMaxDistance > 0.0)
{
float3 distFactor = GetDistanceBasedTessFactor(p0, p1, p2, _WorldSpaceCameraPos, _TessellationFactorMinDistance, _TessellationFactorMaxDistance);
float3 distFactor = GetDistanceBasedTessFactor(p0, p1, p2, camPosWS, _TessellationFactorMinDistance, _TessellationFactorMaxDistance);
// We square the disance factor as it allow a better percptual descrease of vertex density.
tessFactor *= distFactor * distFactor;
}

#else
float2(0.0, 0.0),
#endif
input.positionWS,
input.positionWS,
input.normalWS,
layerTexCoord);

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


_TessellationShapeFactor("Tessellation shape factor", Range(0.0, 1.0)) = 0.75 // Only use with Phong
_TessellationBackFaceCullEpsilon("Tessellation back face epsilon", Range(-1.0, 0.0)) = -0.25
[ToggleOff] _TessellationObjectScale("Tessellation object scale", Float) = 0.0
[ToggleOff] _TessellationTilingScale("Tessellation tiling height scale", Float) = 1.0
// TODO: Handle culling mode for backface culling
}

#pragma only_renderers d3d11 ps4// TEMP: until we go futher in dev
// #pragma enable_d3d11_debug_symbols
//-------------------------------------------------------------------------------------
// Variant

// Default is _TESSELLATION_PHONG
#pragma shader_feature _ _TESSELLATION_DISPLACEMENT _TESSELLATION_DISPLACEMENT_PHONG
#pragma shader_feature _TESSELLATION_OBJECT_SCALE
#pragma shader_feature _TESSELLATION_TILING_SCALE
#pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR
#pragma shader_feature _NORMALMAP_TANGENT_SPACE

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


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
// #pragma enable_d3d11_debug_symbols
#pragma multi_compile _ FILTER_HORIZONTAL
#pragma shader_feature _ SSS_PRE_SCATTER_TEXTURING SSS_POST_SCATTER_TEXTURING
#pragma multi_compile _ FILTER_HORIZONTAL_AND_COMBINE
//-------------------------------------------------------------------------------------
// Include

#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#define UNITY_MATERIAL_LIT // Need to be defined before including Material.hlsl
#include "HDRenderPipeline/Material/Material.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs

#define N_SAMPLES 7
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
float4x4 _InvProjMatrix;
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
TEXTURE2D_FLOAT(_CameraDepthTexture);
TEXTURE2D(_GBufferTexture2);
TEXTURE2D(_IrradianceSource);
#ifndef SSS_PRE_SCATTER_TEXTURING
TEXTURE2D(_GBufferTexture0); // RGB = baseColor, A = spec. occlusion
#endif
TEXTURE2D(_GBufferTexture2); // R = SSS radius, G = SSS thickness, A = SSS profile
TEXTURE2D(_IrradianceSource); // RGB = irradiance on the back side of the object
//-------------------------------------------------------------------------------------
// Implementation

float invDistScale = rcp(distScale);
// Reconstruct the view-space position.
float rawDepth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r;
float rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).r;
float fragWidth = ddx(centerPosVS.x);
float fragheight = ddy(centerPosVS.y);
float fragWidth = ddx_fine(centerPosVS.x);
float fragheight = ddy_fine(centerPosVS.y);
#ifdef FILTER_HORIZONTAL
#ifdef FILTER_HORIZONTAL_AND_COMBINE
float stepSize = stepSizeX;
float2 unitDirection = float2(1, 0);
#else

#else
float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;
#endif
// Accumulate filtered irradiance (already weighted by (albedo / Pi)).
float3 totalIrradiance = sampleIrradiance * sampleWeight;
// Accumulate filtered irradiance.
float3 totalIrradiance = sampleWeight * sampleIrradiance;
// Make sure bilateral filtering does not cause energy loss.
// TODO: ask Morten if there is a better way to do this.

samplePosition = posInput.unPositionSS + scaledDirection * _FilterKernels[profileID][i].a;
sampleWeight = _FilterKernels[profileID][i].rgb;
rawDepth = LOAD_TEXTURE2D(_CameraDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
// Apply bilateral weighting.
// Ref #1: Skin Rendering by Pseudo–Separable Cross Bilateral Filtering.

sampleWeight *= exp(-zDistance * zDistance * halfRcpVariance);
totalIrradiance += sampleIrradiance * sampleWeight;
totalIrradiance += sampleWeight * sampleIrradiance;
#ifdef SSS_PRE_SCATTER_TEXTURING
float3 diffuseContrib = float3(1, 1, 1);
#elif SSS_POST_SCATTER_TEXTURING
float3 diffuseColor = DecodeGBuffer0(LOAD_TEXTURE2D(_GBufferTexture0, posInput.unPositionSS)).rgb;
float3 diffuseContrib = diffuseColor;
#else // combine pre-scatter and post-scatter texturing
float3 diffuseColor = DecodeGBuffer0(LOAD_TEXTURE2D(_GBufferTexture0, posInput.unPositionSS)).rgb;
float3 diffuseContrib = sqrt(diffuseColor);
#endif
#ifdef FILTER_HORIZONTAL_AND_COMBINE
return float4(diffuseContrib * totalIrradiance / totalWeight, 1.0);
#else
#endif
}
ENDHLSL
}

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassDebugViewMaterial.hlsl


#endif // TESSELLATION_ON
float4 Frag(PackedVaryingsToPS packedInput) : SV_Target
void Frag( PackedVaryingsToPS packedInput
, out float4 outColor : SV_Target
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);

if (!needLinearToSRGB)
result = SRGBToLinear(max(0, result));
return float4(result, 0.0);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.depthRaw;
#endif
outColor = float4(result, 1.0);
}

62
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


float4 unity_SHC;
CBUFFER_END
// Use the regular depth camera texture sampler for sampling this: sampler_CameraDepthTexture
TEXTURE2D_FLOAT(_CameraDepthTextureCopy);
SAMPLER2D(sampler_CameraDepthTextureCopy);
TEXTURE2D_FLOAT(_MainDepthTexture);
SAMPLER2D(sampler_MainDepthTexture);
// Main lightmap
TEXTURE2D(unity_Lightmap);

// ----------------------------------------------------------------------------
// TODO: move this to constant buffer by Pass
float4x4 _InvViewProjMatrix;
float4 _ScreenSize;
float4 _ScreenSize;
float4x4 _InvViewProjMatrix;
float4x4 _InvProjMatrix;
float4 _InvProjParam;
float4x4 GetWorldToViewMatrix()
{

return mul(GetWorldToHClipMatrix(), float4(positionWS, 1.0));
}
// Computes world space view direction, from object space position
float3 GetWorldSpaceNormalizeViewDir(float3 positionWS)
float3 GetCurrentCameraPosition()
float3 V = _WorldSpaceCameraPos.xyz - positionWS;
#if SHADERPASS != SHADERPASS_DEPTH_ONLY
return _WorldSpaceCameraPos;
#else
// TEMP: this is rather expensive. Then again, we need '_WorldSpaceCameraPos'
// to represent the position of the primary (scene view) camera in order to
// have identical tessellation levels for both the scene view and shadow views.
// Otherwise, depth comparisons become meaningless!
float4x4 viewMat = transpose(GetWorldToViewMatrix());
float3 rotCamPos = viewMat[3].xyz;
return mul((float3x3)viewMat, -rotCamPos);
#endif
}
// Uncomment this once the compiler bug is fixed.
// if (unity_OrthoParams.w == 1.0)
// {
// float4x4 M = GetWorldToViewMatrix();
// V = M[1].xyz;
// }
// Returns the forward direction of the current camera in the world space.
float3 GetCameraForwardDir()
{
float4x4 viewMat = GetWorldToViewMatrix();
return -viewMat[2].xyz;
}
return normalize(V);
// Computes the world space view direction (pointing towards the camera).
float3 GetWorldSpaceNormalizeViewDir(float3 positionWS)
{
#if SHADERPASS != SHADERPASS_DEPTH_ONLY
if (unity_OrthoParams.w == 0)
#else
// TODO: set 'unity_OrthoParams' during the shadow pass.
if (GetWorldToHClipMatrix()[3].x != 0 &&
GetWorldToHClipMatrix()[3].y != 0 &&
GetWorldToHClipMatrix()[3].z != 0 &&
GetWorldToHClipMatrix()[3].w != 1)
#endif
{
// Perspective
float3 V = GetCurrentCameraPosition() - positionWS;
return normalize(V);
}
else
{
// Orthographic
return -GetCameraForwardDir();
}
}
float3x3 CreateWorldToTangent(float3 normal, float3 tangent, float flipSign)

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl


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

#define GPUSHADOWTYPE_SPOT (1)
#define GPUSHADOWTYPE_DIRECTIONAL (2)
#define GPUSHADOWTYPE_MAX (3)
#define GPUSHADOWTYPE_UNKNOWN (3)
#define GPUSHADOWTYPE_ALL (3)
//
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowSampling: static fields
//
#define GPUSHADOWSAMPLING_PCF_1TAP (0)
#define GPUSHADOWSAMPLING_PCF_9TAPS_ADAPTIVE (1)
#define GPUSHADOWSAMPLING_VSM_1TAP (2)
#define GPUSHADOWSAMPLING_MSM_1TAP (3)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
// PackingRules = Exact

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs


var cmd = new CommandBuffer { name = "" };
if (!renderForCubemap)
{
cmd.SetGlobalTexture("_CameraDepthTexture", builtinParams.depthBuffer);
}
cmd.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_ProceduralSkyMaterial, 0, 0, properties);
builtinParams.renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

18
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl


uniform float _MiePhaseAnisotropy;
uniform float _MieExtinctionFactor;
SAMPLER2D(sampler_CameraDepthTexture);
#define SRL_BilinearSampler sampler_CameraDepthTexture // Used for all textures
SAMPLER2D(sampler_MainDepthTexture);
#define SRL_BilinearSampler sampler_MainDepthTexture // Used for all textures
TEXTURE2D_FLOAT(_CameraDepthTexture);
TEXTURE2D_FLOAT(_MainDepthTexture);
TEXTURE2D(_OcclusionTexture);
float HenyeyGreensteinPhase(float g, float cosTheta) {

#if defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP)
float4 baseUV = float4(uv.x, uv.y, 0.f, 0.f);
float cDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV, 0.f).r;
float cDepth = SAMPLE_TEXTURE2D_LOD(_CMainDepthTexture, SRL_BilinearSampler, baseUV, 0.f).r;
baseUV.xy = uv + _DepthTextureScaledTexelSize.zy; xDepth.x = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xy; xDepth.y = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xw; xDepth.z = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.zw; xDepth.w = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.zy; xDepth.x = SAMPLE_TEXTURE2D_LOD(_MainDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xy; xDepth.y = SAMPLE_TEXTURE2D_LOD(_MainDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xw; xDepth.z = SAMPLE_TEXTURE2D_LOD(_MainDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.zw; xDepth.w = SAMPLE_TEXTURE2D_LOD(_MainDepthTexture, SRL_BilinearSampler, baseUV);
xDepth.x = LinearEyeDepth(xDepth.x, _ZBufferParams);
xDepth.y = LinearEyeDepth(xDepth.y, _ZBufferParams);

#define SURFACE_SCATTER_APPLY(i, color) color += (i.worldPos + i.scatterCoords1.xyz + i.scatterCoords2.xyz) * 0.000001f
#endif
#endif //FILE_ATMOSPHERICSCATTERING
#endif //FILE_ATMOSPHERICSCATTERING

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader


#ifdef PERFORM_SKY_OCCLUSION_TEST
// Determine whether the sky is occluded by the scene geometry.
// Do not perform blending with the environment map if the sky is occluded.
float depthRaw = max(skyDepth, LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r);
float depthRaw = max(skyDepth, LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).r);
float skyTexWeight = (depthRaw > skyDepth) ? 0.0 : 1.0;
#else
float depthRaw = skyDepth;

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


get { return m_SkySettings; }
}
public Texture skyReflection { get { return m_SkyboxGGXCubemapRT; } }
protected Mesh BuildSkyMesh(Vector3 cameraPosition, Matrix4x4 cameraInvViewProjectionMatrix, bool forceUVBottom)
{
Vector4 vertData0 = new Vector4(-1.0f, -1.0f, 1.0f, 1.0f);

15
Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs


var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
var gpuVP = gpuProj * camera.worldToCameraMatrix;
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
Vector4 invProjectionParam = new Vector4(gpuProj.m20 / (gpuProj.m00 * gpuProj.m23),
gpuProj.m21 / (gpuProj.m11 * gpuProj.m23),
-1.0f / gpuProj.m23,
(-gpuProj.m22
+ gpuProj.m20 * gpuProj.m02 / gpuProj.m00
+ gpuProj.m21 * gpuProj.m12 / gpuProj.m11) / gpuProj.m23);
hdCamera.invProjectionParam = invProjectionParam;
return hdCamera;
}

material.SetVector("_ScreenSize", hdCamera.screenSize);
material.SetMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
material.SetVector("_ScreenSize", hdCamera.screenSize);
material.SetMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
material.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
material.SetVector("_InvProjParam", hdCamera.invProjectionParam);
}
// TEMP: These functions should be implemented C++ side, for now do it in C#

80
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


return float2(1.0 - 0.5 * INV_PI * atan2(dir.x, -dir.z), asin(dir.y) * INV_PI + 0.5);
}
float3 LatlongToDirectionCoordinate(float2 coord)
{
float theta = coord.y * PI;
float phi = (coord.x * 2.f * PI - PI*0.5f);
float cosTheta = cos(theta);
float sinTheta = sqrt(1.0f - min(1.0f, cosTheta*cosTheta));
float cosPhi = cos(phi);
float sinPhi = sin(phi);
float3 direction = float3(sinTheta*cosPhi, cosTheta, sinTheta*sinPhi);
direction.xy *= -1.0;
return direction;
}
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane)
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane).
// Does not correctly handle oblique view frustums.
// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane)
// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane).
// Does not correctly handle oblique view frustums.
// Z buffer to linear depth
// Z buffer to linear depth.
// Does not correctly handle oblique view frustums.
// Z buffer to linear depth.
// Correctly handles oblique view frustums. Only valid for projection matrices!
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
float LinearEyeDepth(float2 positionSS, float depthRaw, float4 invProjParam)
{
float4 positionCS = float4(positionSS * 2.0 - 1.0, depthRaw, 1.0);
float viewSpaceZ = rcp(dot(positionCS, invProjParam));
// The view space uses a right-handed coordinate system.
return -viewSpaceZ;
}
struct PositionInputs
{
// Normalize screen position (offset by 0.5)

float depthRaw; // raw depth from depth buffer
float depthVS;
float4 positionCS;
float3 positionWS;
};

// depthRaw and depthVS come directly form .zw of SV_Position
void UpdatePositionInput(float depthRaw, float depthVS, float3 positionWS, inout PositionInputs posInput)
{
posInput.depthRaw = depthRaw;
posInput.depthVS = depthVS;
// TODO: We revert for DX but maybe it is not the case of OGL ? Test the define ?
posInput.positionCS = float4((posInput.positionSS - 0.5) * float2(2.0, -2.0), depthRaw, 1.0) * depthVS; // depthVS is SV_Position.w
posInput.depthRaw = depthRaw;
posInput.depthVS = depthVS;
posInput.positionWS = positionWS;
}

// It may be necessary to flip the Y axis as the origin of the screen-space coordinate system
// of Direct3D is at the top left corner of the screen, with the Y axis pointing downwards.
void UpdatePositionInput(float depth, float4x4 invViewProjectionMatrix, float4x4 ViewProjectionMatrix,
void UpdatePositionInput(float depthRaw, float4x4 invViewProjMatrix, float4x4 viewProjMatrix,
posInput.depthRaw = depth;
posInput.depthRaw = depthRaw;
posInput.positionCS = float4(screenSpacePos * 2.0 - 1.0, depth, 1.0);
float4 hpositionWS = mul(invViewProjectionMatrix, posInput.positionCS);
float4 positionCS = float4(screenSpacePos * 2.0 - 1.0, depthRaw, 1.0);
float4 hpositionWS = mul(invViewProjMatrix, positionCS);
posInput.depthVS = mul(ViewProjectionMatrix, float4(posInput.positionWS, 1.0)).w;
posInput.positionCS *= posInput.depthVS;
posInput.depthVS = mul(viewProjMatrix, float4(posInput.positionWS, 1.0)).w;
float3 ComputeViewSpacePosition(float2 positionSS, float rawDepth, float4x4 invProjMatrix)
// It may be necessary to flip the Y axis as the origin of the screen-space coordinate system
// of Direct3D is at the top left corner of the screen, with the Y axis pointing downwards.
float3 ComputeViewSpacePosition(float2 positionSS, float depthRaw, float4x4 invProjMatrix, bool flipY = false)
float4 positionCS = float4(positionSS * 2.0 - 1.0, rawDepth, 1.0);
float2 screenSpacePos;
screenSpacePos.x = positionSS.x;
screenSpacePos.y = flipY ? 1.0 - positionSS.y : positionSS.y;
float4 positionCS = float4(screenSpacePos * 2.0 - 1.0, depthRaw, 1.0);
float4 positionVS = mul(invProjMatrix, positionCS);
// The view space uses a right-handed coordinate system.
positionVS.z = -positionVS.z;

// depthOffsetVS is always in the direction of the view vector (V)
void ApplyDepthOffsetPositionInput(float3 V, float depthOffsetVS, inout PositionInputs posInput)
// 'depthOffsetVS' is always along the forward direction 'camDirWS' pointing away from the camera.
void ApplyDepthOffsetPositionInput(float3 camDirWS, float depthOffsetVS, float4x4 viewProjMatrix, inout PositionInputs posInput)
posInput.depthVS += depthOffsetVS;
// TODO: it is an approx, need a correct value where we use projection matrix to reproject the depth from VS
posInput.depthRaw = posInput.positionCS.z / posInput.depthVS;
posInput.depthVS += depthOffsetVS;
posInput.positionWS += depthOffsetVS * camDirWS;
// TODO: Do we need to flip Y axis here on OGL ?
posInput.positionCS = float4(posInput.positionSS.xy * 2.0 - 1.0, posInput.depthRaw, 1.0) * posInput.depthVS;
// Just add the offset along the view vector is sufficiant for world position
posInput.positionWS += V * depthOffsetVS;
float4 positionCS = mul(viewProjMatrix, float4(posInput.positionWS, 1.0));
posInput.depthRaw = positionCS.z / positionCS.w;
}
// Generates a triangle in homogeneous clip space, s.t.

17
Assets/ScriptableRenderPipeline/ShaderLibrary/PerPixelDisplacement.hlsl


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

float pt1 = rayHeight;
float delta0 = pt0 - prevHeight;
float delta1 = pt1 - currHeight;
// Secant method to affine the search
// Ref: Faster Relief Mapping Using the Secant Method - Eric Risser
for (int i = 0; i < 5; ++i)

}
#else // regular POM intersection
//float pt1 = rayHeight;
//float pt1 = rayHeight;
//float delta0 = pt0 - prevHeight;
//float delta1 = pt1 - currHeight;
//float intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);

float ratio = delta0 / (delta0 + delta1);
float2 offset = texOffsetCurrent - ratio * texOffsetPerStep;
currHeight = ComputePerPixelHeightDisplacement(offset, lod, ppdParam);
outHeight = currHeight;
// Fade the effect with lod (allow to avoid pop when switching to a discrete LOD mesh)
offset *= (1.0 - saturate(lod - lodThreshold));

1
Assets/ScriptableRenderPipeline/common/TextureCache.cs


{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Repeat,
wrapModeV = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0
};

19
Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs


if (enableClustered)
{
s_PerVoxelOffset = new ComputeBuffer(LightDefinitions.NR_LIGHT_MODELS * (1 << k_Log2NumClusters) * nrTiles, sizeof(uint));
s_PerVoxelLightLists = new ComputeBuffer(NumLightIndicesPerClusteredTile() * nrTiles, sizeof(uint));
var tileSizeClust = LightDefinitions.TILE_SIZE_CLUSTERED;
var nrTilesClustX = (width + (tileSizeClust-1)) / tileSizeClust;
var nrTilesClustY = (height + (tileSizeClust-1)) / tileSizeClust;
var nrTilesClust = nrTilesClustX * nrTilesClustY;
s_PerVoxelOffset = new ComputeBuffer(LightDefinitions.NR_LIGHT_MODELS * (1 << k_Log2NumClusters) * nrTilesClust, sizeof(uint));
s_PerVoxelLightLists = new ComputeBuffer(NumLightIndicesPerClusteredTile() * nrTilesClust, sizeof(uint));
s_PerTileLogBaseTweak = new ComputeBuffer(nrTiles, sizeof(float));
s_PerTileLogBaseTweak = new ComputeBuffer(nrTilesClust, sizeof(float));
}
}

cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_logBaseBuffer", s_PerTileLogBaseTweak);
}
var numTilesX = (camera.pixelWidth + 15) / 16;
var numTilesY = (camera.pixelHeight + 15) / 16;
cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
var tileSizeClust = LightDefinitions.TILE_SIZE_CLUSTERED;
var nrTilesClustX = (camera.pixelWidth + (tileSizeClust-1)) / tileSizeClust;
var nrTilesClustY = (camera.pixelHeight + (tileSizeClust-1)) / tileSizeClust;
cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, nrTilesClustX, nrTilesClustY, 1);
}
void BuildPerTileLightLists(Camera camera, ScriptableRenderContext loop, int numLights, Matrix4x4 projscr, Matrix4x4 invProjscr)

3
Assets/ScriptableRenderPipeline/fptl/LightDefinitions.cs


public static int MAX_NR_BIGTILE_LIGHTS_PLUSONE = 512; // may be overkill but the footprint is 2 bits per pixel using uint16.
public static float VIEWPORT_SCALE_Z = 1.0f;
// must be either 16, 32 or 64. Could go higher in principle but big tiles in the pre-pass are already 64x64
public static int TILE_SIZE_CLUSTERED = 32;
// enable unity's original left-hand shader camera space (right-hand internally in unity).
public static int USE_LEFTHAND_CAMERASPACE = 0;

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


#define MAX_NR_LIGHTS_PER_CAMERA (1024)
#define MAX_NR_BIGTILE_LIGHTS_PLUSONE (512)
#define VIEWPORT_SCALE_Z (1)
#define TILE_SIZE_CLUSTERED (32)
#define USE_LEFTHAND_CAMERASPACE (0)
#define IS_CIRCULAR_SPOT_SHAPE (1)
#define HAS_COOKIE_TEXTURE (2)

5
Assets/ScriptableRenderPipeline/fptl/TiledLightingTemplate.hlsl


float3 ExecuteLightList(out uint numLightsProcessed, uint2 pixCoord, float3 vP, float3 vPw, float3 Vworld)
{
uint nrTilesX = (g_widthRT+15)/16; uint nrTilesY = (g_heightRT+15)/16;
uint2 tileIDX = pixCoord / 16;
GetCountAndStart(start, numLights, tileIDX, nrTilesX, nrTilesY, vP.z, DIRECT_LIGHT);
GetCountAndStart(start, numLights, pixCoord, vP.z, DIRECT_LIGHT);
numLightsProcessed = numLights; // mainly for debugging/heat maps
return ExecuteLightList(start, numLights, vP, vPw, Vworld);

17
Assets/ScriptableRenderPipeline/fptl/TiledLightingUtils.hlsl


StructuredBuffer<uint> g_vLightListGlobal; // don't support Buffer yet in unity
void GetCountAndStartOpaque(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth, uint model)
void GetCountAndStartOpaque(out uint uStart, out uint uNrLights, uint2 pixCoord, float linDepth, uint model)
uint tileSize = 16;
uint nrTilesX = ((uint) (g_widthRT+(tileSize-1)))/tileSize; uint nrTilesY = ((uint) (g_heightRT+(tileSize-1)))/tileSize;
uint2 tileIDX = pixCoord / tileSize;
const int tileOffs = (tileIDX.y+model*nrTilesY)*nrTilesX+tileIDX.x;
uNrLights = g_vLightListGlobal[ 16*tileOffs + 0]&0xffff;

#ifdef OPAQUES_ONLY
void GetCountAndStart(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth, uint model)
void GetCountAndStart(out uint uStart, out uint uNrLights, uint2 pixCoord, float linDepth, uint model)
GetCountAndStartOpaque(uStart, uNrLights, tileIDX, nrTilesX, nrTilesY, linDepth, model);
GetCountAndStartOpaque(uStart, uNrLights, pixCoord, linDepth, model);
}
uint FetchIndex(const uint tileOffs, const uint l)

StructuredBuffer<float> g_logBaseBuffer; // don't support Buffer yet in unity
void GetCountAndStart(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth, uint model)
void GetCountAndStart(out uint uStart, out uint uNrLights, uint2 pixCoord, float linDepth, uint model)
GetCountAndStartOpaque(uStart, uNrLights, tileIDX, nrTilesX, nrTilesY, linDepth, model);
GetCountAndStartOpaque(uStart, uNrLights, pixCoord, linDepth, model);
uint nrTilesX = ((uint) (g_widthRT+(TILE_SIZE_CLUSTERED-1))) / ((uint) TILE_SIZE_CLUSTERED);
uint nrTilesY = ((uint) (g_heightRT+(TILE_SIZE_CLUSTERED-1))) / ((uint) TILE_SIZE_CLUSTERED);
uint2 tileIDX = pixCoord / ((uint) TILE_SIZE_CLUSTERED);
float logBase = g_fClustBase;
if(g_isLogBaseBufferEnabled)
logBase = g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x];

5
Assets/ScriptableRenderPipeline/fptl/TiledReflectionTemplate.hlsl


float3 ExecuteReflectionList(out uint numReflectionProbesProcessed, uint2 pixCoord, float3 vP, float3 vNw, float3 Vworld, float smoothness)
{
uint nrTilesX = (g_widthRT+15)/16; uint nrTilesY = (g_heightRT+15)/16;
uint2 tileIDX = pixCoord / 16;
GetCountAndStart(start, numReflectionProbes, tileIDX, nrTilesX, nrTilesY, vP.z, REFLECTION_LIGHT);
GetCountAndStart(start, numReflectionProbes, pixCoord, vP.z, REFLECTION_LIGHT);
numReflectionProbesProcessed = numReflectionProbes; // mainly for debugging/heat maps
return ExecuteReflectionList(start, numReflectionProbes, vP, vNw, Vworld, smoothness);

23
Assets/ScriptableRenderPipeline/fptl/lightlistbuild-clustered.compute


#else
g_depth_tex.GetDimensions(iWidth, iHeight);
#endif
uint nrTilesX = (iWidth+15)/16;
uint nrTilesY = (iHeight+15)/16;
const uint log2TileSize = firstbithigh(TILE_SIZE_CLUSTERED);
uint nrTilesX = (iWidth+(TILE_SIZE_CLUSTERED-1))>>log2TileSize;
uint nrTilesY = (iHeight+(TILE_SIZE_CLUSTERED-1))>>log2TileSize;
uint2 viTilLL = 16*tileIDX;
uint2 viTilUR = min( viTilLL+uint2(16,16), uint2(iWidth, iHeight) ); // not width and height minus 1 since viTilUR represents the end of the tile corner.
uint2 viTilLL = TILE_SIZE_CLUSTERED*tileIDX;
uint2 viTilUR = min( viTilLL+uint2(TILE_SIZE_CLUSTERED,TILE_SIZE_CLUSTERED), uint2(iWidth, iHeight) ); // not width and height minus 1 since viTilUR represents the end of the tile corner.
if(t==0)
{

// establish min and max depth first
dpt_ma=0.0;
for(int idx=t; idx<256; idx+=NR_THREADS)
for(int idx=t; idx<(TILE_SIZE_CLUSTERED*TILE_SIZE_CLUSTERED); idx+=NR_THREADS)
uint2 uPixCrd = min( uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1) );
uint2 uPixCrd = min( uint2(viTilLL.x+(idx&(TILE_SIZE_CLUSTERED-1)), viTilLL.y+(idx>>log2TileSize)), uint2(iWidth-1, iHeight-1) );
#ifdef MSAA_ENABLED
for(int i=0; i<iNumSamplesMSAA; i++)
{

// build coarse list using AABB
#ifdef USE_TWO_PASS_TILED_LIGHTING
int NrBigTilesX = (nrTilesX+3)>>2;
const int bigTileIdx = (tileIDX.y>>2)*NrBigTilesX + (tileIDX.x>>2); // map the idx to 64x64 tiles
const uint log2BigTileToClustTileRatio = firstbithigh(64) - log2TileSize;
int NrBigTilesX = (nrTilesX+((1<<log2BigTileToClustTileRatio)-1))>>log2BigTileToClustTileRatio;
const int bigTileIdx = (tileIDX.y>>log2BigTileToClustTileRatio)*NrBigTilesX + (tileIDX.x>>log2BigTileToClustTileRatio); // map the idx to 64x64 tiles
int nrBigTileLights = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+0];
for(int l0=(int) t; l0<(int) nrBigTileLights; l0 += NR_THREADS)
{

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

#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
float halfTileSizeAtZDistOne = (TILE_SIZE_CLUSTERED/2)*onePixDiagDist; // scale by half a tile
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{

2
Assets/TestScenes/FPTL/Materials/Custom_NewSurfaceShader.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Custom_NewSurfaceShader
m_Shader: {fileID: 0}
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _EMISSION
m_LightmapFlags: 1
m_EnableInstancingVariants: 0

4
Assets/TestScenes/FPTL/Materials/gray.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: gray
m_Shader: {fileID: 0}
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: S_RECEIVE_SHADOWS S_SPECULAR_METALLIC _EMISSION
m_LightmapFlags: 1
m_EnableInstancingVariants: 0

- _GlossMapScale: 1
- _Glossiness: 0.825
- _GlossyReflections: 1
- _Metallic: 0
- _Metallic: 1
- _Mode: 0
- _OcclusionStrength: 1
- _OcclusionStrengthDirectDiffuse: 1

112
Assets/TestScenes/HDTest/CascadedShadowsTest.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_IndirectSpecularColor: {r: 0.21215841, g: 0.21215841, b: 0.21215841, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 39480640}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &44546677
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 44546679}
- component: {fileID: 44546678}
m_Layer: 0
m_Name: Scene Settings
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &44546678
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 44546677}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0e34c98127e05d340ba44a1d4a734454, type: 3}
m_Name:
m_EditorClassIdentifier:
m_CommonSettings: {fileID: 11400000, guid: 075f395cb6ba2534196f2ce83c32e633, type: 2}
m_SkySettings: {fileID: 11400000, guid: 622aa06566c087b41ac0edc80769f45f, type: 2}
--- !u!4 &44546679
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 44546677}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &58245422
GameObject:
m_ObjectHideFlags: 0

- {fileID: 451535687}
- {fileID: 2049083844}
m_Father: {fileID: 0}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &80788017
GameObject:

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2082161877}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &2100643537
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 2100643540}
- component: {fileID: 2100643539}
- component: {fileID: 2100643538}
m_Layer: 0
m_Name: SceneSettings
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2100643538
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2100643537}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name:
m_EditorClassIdentifier:
rotation: 0
exposure: 0
multiplier: 1
resolution: 256
updateMode: 0
updatePeriod: 0
skyHDRI: {fileID: 8900000, guid: 805167636edb6ce4fb580f8da1053bad, type: 3}
--- !u!114 &2100643539
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2100643537}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bc357c46587fc9d4cb8f311794d7d2f3, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Settings:
m_ShadowMaxDistance: 1000
m_ShadowCascadeCount: 4
m_ShadowCascadeSplit0: 0.05
m_ShadowCascadeSplit1: 0.2
m_ShadowCascadeSplit2: 0.3
m_ShadowNearPlaneOffset: 5
--- !u!4 &2100643540
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2100643537}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2115816428
GameObject:
m_ObjectHideFlags: 0

9
Assets/TestScenes/HDTest/CascadedShadowsTest/CommonSettings_Cascaded.asset


m_Name: CommonSettings_Cascaded
m_EditorClassIdentifier:
m_Settings:
m_ShadowMaxDistance: 450
m_ShadowMaxDistance: 800
m_ShadowCascadeSplit0: 0.015
m_ShadowCascadeSplit1: 0.05
m_ShadowCascadeSplit2: 0.2
m_ShadowCascadeSplit0: 0.05
m_ShadowCascadeSplit1: 0.2
m_ShadowCascadeSplit2: 0.3
m_ShadowNearPlaneOffset: 10

2
Assets/TestScenes/HDTest/CascadedShadowsTest/CommonSettings_Cascaded.asset.meta


fileFormatVersion: 2
guid: 075f395cb6ba2534196f2ce83c32e633
timeCreated: 1485858348
timeCreated: 1487264310
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000

2
Assets/TestScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Rock.mat


- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _HeightAmplitude: 0.09
- _HeightAmplitude: 0.8
- _HeightCenter: 0.5
- _HorizonFade: 1
- _MaterialID: 0

2
Assets/TestScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat


- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _HeightAmplitude: 0.17
- _HeightAmplitude: 1.27
- _HeightCenter: 0.5
- _HorizonFade: 1
- _MaterialID: 0

122
Assets/TestScenes/fptl/Materials/FwdMat.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: FwdMat
m_Shader: {fileID: 4800000, guid: ccaa200b3477a2a4cbc0fecd9fc2dde8, type: 3}
m_Shader: {fileID: 4800000, guid: 8f28d6dbfdba66d4dbae80224aca5669, type: 3}
m_EnableInstancingVariants: 0
disabledShaderPasses: []
serializedVersion: 2
serializedVersion: 3
- first:
name: _BumpMap
second:
- _BumpMap:
- first:
name: _DetailAlbedoMap
second:
- _DetailAlbedoMap:
- first:
name: _DetailMask
second:
- _DetailMask:
- first:
name: _DetailNormalMap
second:
- _DetailNormalMap:
- first:
name: _EmissionMap
second:
- _EmissionMap:
- first:
name: _MainTex
second:
- _MainTex:
- first:
name: _MetallicGlossMap
second:
- _MetallicGlossMap:
- first:
name: _OcclusionMap
second:
- _OcclusionMap:
- first:
name: _ParallaxMap
second:
- _ParallaxMap:
- first:
name: _SpecGlossMap
second:
- _SpecGlossMap:
- first:
name: _BumpScale
second: 1
- first:
name: _Cutoff
second: 0.5
- first:
name: _DetailNormalMapScale
second: 1
- first:
name: _DstBlend
second: 0
- first:
name: _GlossMapScale
second: 1
- first:
name: _Glossiness
second: 0.5
- first:
name: _GlossyReflections
second: 1
- first:
name: _Metallic
second: 0
- first:
name: _Mode
second: 0
- first:
name: _OcclusionStrength
second: 1
- first:
name: _Parallax
second: 0.02
- first:
name: _SmoothnessTextureChannel
second: 0
- first:
name: _SpecularHighlights
second: 1
- first:
name: _SrcBlend
second: 1
- first:
name: _UVSec
second: 0
- first:
name: _ZWrite
second: 1
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
- first:
name: _Color
second: {r: 1, g: 1, b: 1, a: 1}
- first:
name: _EmissionColor
second: {r: 0, g: 0, b: 0, a: 1}
- first:
name: _SpecColor
second: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}

9
ProjectSettings/GraphicsSettings.asset


m_DefaultRenderingPath: 1
m_DefaultMobileRenderingPath: 1
m_TierSettings:
- serializedVersion: 4
- serializedVersion: 5
m_BuildTarget: 1
m_Tier: 0
m_Settings:

useHDR: 1
useDetailNormalMap: 1
useCascadedShadowMaps: 1
prefer32BitShadowMaps: 0
- serializedVersion: 4
- serializedVersion: 5
m_BuildTarget: 1
m_Tier: 1
m_Settings:

useHDR: 1
useDetailNormalMap: 1
useCascadedShadowMaps: 1
prefer32BitShadowMaps: 0
- serializedVersion: 4
- serializedVersion: 5
m_BuildTarget: 1
m_Tier: 2
m_Settings:

useHDR: 1
useDetailNormalMap: 1
useCascadedShadowMaps: 1
prefer32BitShadowMaps: 0
useDitherMaskForAlphaBlendedShadows: 1
m_Automatic: 0
m_LightmapStripping: 0

718
ProjectSettings/InputManager.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!13 &1
InputManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Axes:
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton: a
altPositiveButton: d
gravity: 3
dead: .00100000005
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton: s
altPositiveButton: w
gravity: 3
dead: .00100000005
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: mouse 0
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: mouse 1
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: mouse 2
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: space
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse X
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: .100000001
snap: 0
invert: 0
type: 1
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse Y
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: .100000001
snap: 0
invert: 0
type: 1
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Mouse ScrollWheel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: .100000001
snap: 0
invert: 0
type: 1
axis: 2
joyNum: 0
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: .189999998
sensitivity: 1
snap: 0
invert: 0
type: 2
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: .189999998
sensitivity: 1
snap: 0
invert: 1
type: 2
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 0
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 1
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 2
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 3
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: enter
altNegativeButton:
altPositiveButton: space
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Cancel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 1000
dead: .00100000005
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!13 &1
InputManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Axes:
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton: q
altPositiveButton: d
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton: s
altPositiveButton: z
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: mouse 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: mouse 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: mouse 2
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: space
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse X
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Controller Right Stick X
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 1
dead: 0.2
sensitivity: 1
snap: 0
invert: 0
type: 2
axis: 3
joyNum: 0
- serializedVersion: 3
m_Name: Mouse Y
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Controller Right Stick Y
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 1
dead: 0.2
sensitivity: 1
snap: 0
invert: 1
type: 2
axis: 4
joyNum: 0
- serializedVersion: 3
m_Name: Mouse ScrollWheel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 2
joyNum: 0
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 0
type: 2
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 1
type: 2
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 0
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 1
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 2
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 3
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: enter
altNegativeButton:
altPositiveButton: space
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Cancel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Enable Debug Button 1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 8
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Enable Debug Button 2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 9
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Next
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton: joystick button 5
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Next
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: page down
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Previous
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton: joystick button 4
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Debug Previous
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: page up
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.1.0a1
m_EditorVersion: 2017.1.0a2

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


Shader "Hidden/HDRenderPipeline/DebugDisplayLatlong"
{
SubShader
{
Pass
{
ZWrite Off
ZTest Off
Blend One Zero
Cull Off
HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
TEXTURECUBE(_InputCubemap);
SAMPLERCUBE(sampler_InputCubemap);
float _Mipmap;
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.texcoord = GetFullScreenTriangleTexcoord(input.vertexID);// *_TextureScaleBias.xy + _TextureScaleBias.zw;
return output;
}
float4 Frag(Varyings input) : SV_Target
{
uint width, height, depth, mipCount;
width = height = depth = mipCount = 0;
_InputCubemap.GetDimensions(width, height, depth, mipCount);
mipCount = clamp(mipCount, 0, UNITY_SPECCUBE_LOD_STEPS);
return SAMPLE_TEXTURECUBE_LOD(_InputCubemap, sampler_InputCubemap, LatlongToDirectionCoordinate(input.texcoord.xy), _Mipmap * mipCount);
}
ENDHLSL
}
}
Fallback Off
}

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader.meta


fileFormatVersion: 2
guid: c1d1d149a043a5349ba367da6c2051ba
timeCreated: 1476053153
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

300
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs


using System;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public class SubsurfaceScatteringProfile
{
public const int numSamples = 7; // Must be an odd number
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev1;
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev2;
[SerializeField]
public float lerpWeight;
[SerializeField]
public bool enableTransmission;
[SerializeField]
public Vector2 thicknessRemap;
[SerializeField] [HideInInspector]
Vector4[] m_FilterKernel;
[SerializeField] [HideInInspector]
Vector3[] m_HalfRcpVariances;
[SerializeField] [HideInInspector]
Vector4 m_HalfRcpWeightedVariances;
// --- Public Methods ---
public SubsurfaceScatteringProfile()
{
stdDev1 = new Color(0.3f, 0.3f, 0.3f, 0.0f);
stdDev2 = new Color(0.6f, 0.6f, 0.6f, 0.0f);
lerpWeight = 0.5f;
enableTransmission = false;
thicknessRemap = new Vector2(0, 3);
UpdateKernelAndVarianceData();
}
public Vector4[] filterKernel
{
// Set via UpdateKernelAndVarianceData().
get { return m_FilterKernel; }
}
public Vector3[] halfRcpVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpVariances; }
}
public Vector4 halfRcpWeightedVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpWeightedVariances; }
}
public void UpdateKernelAndVarianceData()
{
if (m_FilterKernel == null)
{
m_FilterKernel = new Vector4[numSamples];
}
if (m_HalfRcpVariances == null)
{
m_HalfRcpVariances = new Vector3[2];
}
// 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� / (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.
// 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);
Vector3 weightSum = new Vector3(0, 0, 0);
// Importance sample the linear combination of two Gaussians.
for (uint i = 0; i < numSamples; i++)
{
float u = (i + 0.5f) / numSamples;
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, lerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, lerpWeight);
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);
// 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;
weightSum.x += m_FilterKernel[i].x;
weightSum.y += m_FilterKernel[i].y;
weightSum.z += m_FilterKernel[i].z;
}
// 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;
}
// 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);
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);
// 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);
}
// --- Private Methods ---
static float Gaussian(float x, float stdDev)
{
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
}
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
}
static float RationalApproximation(float t)
{
// 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);
}
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
{
float x;
if (p < 0.5)
{
// 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)));
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
}
[Serializable]
public class SubsurfaceScatteringSettings
{
public enum TexturingMode : int { PreScatter = 0, PostScatter = 1, PreAndPostScatter = 2, MaxValue = 2 };
public const int maxNumProfiles = 8;
public int numProfiles;
public TexturingMode texturingMode;
public int transmissionFlags;
public SubsurfaceScatteringProfile[] profiles;
public float[] thicknessRemaps;
public Vector4[] halfRcpVariancesAndLerpWeights;
public Vector4[] halfRcpWeightedVariances;
public Vector4[] filterKernels;
// --- Public Methods ---
public SubsurfaceScatteringSettings()
{
numProfiles = 1;
texturingMode = 0;
profiles = new SubsurfaceScatteringProfile[numProfiles];
for (int i = 0; i < numProfiles; i++)
{
profiles[i] = new SubsurfaceScatteringProfile();
}
OnValidate();
}
public void OnValidate()
{
if (profiles.Length > maxNumProfiles)
{
Array.Resize(ref profiles, maxNumProfiles);
}
numProfiles = profiles.Length;
texturingMode = (TexturingMode)Math.Max(0, Math.Min((int)texturingMode, (int)TexturingMode.MaxValue));
if (thicknessRemaps == null)
{
thicknessRemaps = new float[maxNumProfiles * 2];
}
if (halfRcpVariancesAndLerpWeights == null)
{
halfRcpVariancesAndLerpWeights = new Vector4[maxNumProfiles * 2];
}
if (halfRcpWeightedVariances == null)
{
halfRcpWeightedVariances = new Vector4[maxNumProfiles];
}
if (filterKernels == null)
{
filterKernels = new Vector4[maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
}
transmissionFlags = 0;
Color c = new Color();
for (int i = 0; i < numProfiles; i++)
{
transmissionFlags |= (profiles[i].enableTransmission ? 1 : 0) << i;
c.r = Mathf.Clamp(profiles[i].stdDev1.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].stdDev1.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(profiles[i].stdDev1.b, 0.05f, 2.0f);
c.a = 0.0f;
profiles[i].stdDev1 = c;
c.r = Mathf.Clamp(profiles[i].stdDev2.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].stdDev2.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(profiles[i].stdDev2.b, 0.05f, 2.0f);
c.a = 0.0f;
profiles[i].stdDev2 = c;
profiles[i].lerpWeight = Mathf.Clamp01(profiles[i].lerpWeight);
profiles[i].thicknessRemap.x = Mathf.Clamp(profiles[i].thicknessRemap.x, 0, profiles[i].thicknessRemap.y);
profiles[i].thicknessRemap.y = Mathf.Max(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y);
profiles[i].UpdateKernelAndVarianceData();
}
// Use the updated data to fill the cache.
for (int i = 0; i < numProfiles; i++)
{
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++)
{
filterKernels[n * i + j] = profiles[i].filterKernel[j];
}
}
}
}
}

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs.meta


fileFormatVersion: 2
guid: cccb0727e6924014ebb35773fbfed141
timeCreated: 1487685614
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/common/Camera.meta


fileFormatVersion: 2
guid: e99921594db38ce4cbb616f0ca87148d
folderAsset: yes
timeCreated: 1488370960
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

136
Assets/ScriptableRenderPipeline/common/Debugging.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Debugging : MonoBehaviour
{
private static bool m_DebugControlEnabled = false;
public static bool debugControlEnabled { get { return m_DebugControlEnabled; } }
private float m_DebugControlEnabledMsgTime = 3.0f;
private float m_DebugControlEnabledMsgTimer = 0.0f;
private bool m_DebugKeyUp1 = false;
private bool m_DebugKeyUp2 = false;
private bool m_CanReceiveInput = true;
private static List<string> m_DebugMessages = new List<string>();
private static string kEnableDebugBtn1 = "Enable Debug Button 1";
private static string kEnableDebugBtn2 = "Enable Debug Button 2";
private string[] m_RequiredInputButtons = { kEnableDebugBtn1, kEnableDebugBtn2 };
private bool m_Valid = true;
public static void PushDebugMessage(string message)
{
m_DebugMessages.Add(message);
}
static public bool CheckRequiredInputButtonMapping(string[] values)
{
bool inputsOk = true;
foreach(string value in values)
{
try
{
Input.GetButton(value);
}
catch
{
Debug.LogWarning(string.Format("Required input button mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
static public bool CheckRequiredInputAxisMapping(string[] values)
{
bool inputsOk = true;
foreach (string value in values)
{
try
{
Input.GetAxis(value);
}
catch
{
Debug.LogWarning(string.Format("Required input axis mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
void OnEnable()
{
m_Valid = CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
void Update()
{
if(m_Valid)
{
m_DebugControlEnabledMsgTimer += Time.deltaTime;
bool enableDebug = Input.GetButton(kEnableDebugBtn1) && Input.GetButton(kEnableDebugBtn2) || Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.Backspace);
if (m_CanReceiveInput && enableDebug)
{
m_DebugControlEnabled = !m_DebugControlEnabled;
m_DebugControlEnabledMsgTimer = 0.0f;
m_CanReceiveInput = false;
m_DebugKeyUp1 = false;
m_DebugKeyUp2 = false;
}
if (Input.GetButtonUp(kEnableDebugBtn1))
{
m_DebugKeyUp1 = true;
}
if (Input.GetButtonUp(kEnableDebugBtn2))
{
m_DebugKeyUp2 = true;
}
// For keyboard you want to be able to keep ctrl pressed.
if (Input.GetKeyUp(KeyCode.Backspace))
{
m_DebugKeyUp1 = m_DebugKeyUp2 = true;
}
m_CanReceiveInput = m_DebugKeyUp1 && m_DebugKeyUp2;
if (m_DebugControlEnabledMsgTimer < m_DebugControlEnabledMsgTime)
{
if (m_DebugControlEnabled)
PushDebugMessage("Debug Controls Enabled");
else
PushDebugMessage("Debug Controls Disabled");
}
}
}
void OnGUI()
{
using(new GUILayout.HorizontalScope())
{
GUILayout.Space(10.0f);
using(new GUILayout.VerticalScope())
{
GUILayout.Space(10.0f);
for (int i = 0; i < m_DebugMessages.Count; ++i)
{
GUILayout.Label(m_DebugMessages[i]);
}
}
}
// Make sure to clear only after all relevant events have occured.
if (Event.current.type == EventType.Repaint)
m_DebugMessages.Clear();
}
}

12
Assets/ScriptableRenderPipeline/common/Debugging.cs.meta


fileFormatVersion: 2
guid: fcb6090d644beb040a7853639fcffddb
timeCreated: 1488381065
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

20
Assets/TestScenes/HDTest/CascadedShadowsTest/HDRISkySettings_Cascaded.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name: HDRISkySettings_Cascaded
m_EditorClassIdentifier:
rotation: 0
exposure: 0
multiplier: 1
resolution: 256
updateMode: 0
updatePeriod: 0
skyHDRI: {fileID: 0}

9
Assets/TestScenes/HDTest/CascadedShadowsTest/HDRISkySettings_Cascaded.asset.meta


fileFormatVersion: 2
guid: 622aa06566c087b41ac0edc80769f45f
timeCreated: 1487264328
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

108
Assets/ScriptableRenderPipeline/common/Camera/CameraSwitcher.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraSwitcher : MonoBehaviour
{
public Camera[] m_Cameras;
private int m_CurrentCameraIndex = -1;
private Camera m_OriginalCamera = null;
private Vector3 m_OriginalCameraPosition;
private Quaternion m_OriginalCameraRotation;
private Camera m_CurrentCamera = null;
private float m_MessageDuration = 1.0f;
private float m_MessageTimer = 1000.0f;
private static string kDebugNext = "Debug Next";
private static string kDebugPrevious = "Debug Previous";
private string[] m_RequiredInputButtons = { kDebugNext, kDebugPrevious };
private bool m_Valid = true;
void OnEnable()
{
m_OriginalCamera = GetComponent<Camera>();
m_CurrentCamera = m_OriginalCamera;
m_Valid = Debugging.CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
int GetCameraCount()
{
return m_Cameras.Length + 1; // We need +1 for handling the original camera.
}
void NextCamera()
{
m_CurrentCameraIndex = (m_CurrentCameraIndex + 1) % GetCameraCount();
}
void PreviousCamera()
{
m_CurrentCameraIndex = m_CurrentCameraIndex - 1;
if (m_CurrentCameraIndex == -1)
m_CurrentCameraIndex = m_Cameras.Length;
}
Camera GetNextCamera()
{
if (m_CurrentCameraIndex == m_Cameras.Length)
return m_OriginalCamera;
else
return m_Cameras[m_CurrentCameraIndex];
}
void Update()
{
if (m_Valid && Debugging.debugControlEnabled && m_OriginalCamera != null)
{
m_MessageTimer += Time.deltaTime;
bool needUpdateCamera = false;
if (Input.GetButtonDown(kDebugNext))
{
NextCamera();
needUpdateCamera = true;
}
if (Input.GetButtonDown(kDebugPrevious))
{
PreviousCamera();
needUpdateCamera = true;
}
if (needUpdateCamera)
{
m_MessageTimer = 0.0f;
if(m_CurrentCamera == m_OriginalCamera)
{
m_OriginalCameraPosition = m_OriginalCamera.transform.position;
m_OriginalCameraRotation = m_OriginalCamera.transform.rotation;
}
m_CurrentCamera = GetNextCamera();
if(m_CurrentCamera != null)
{
// If we witch back to the original camera, put back the transform in it.
if (m_CurrentCamera == m_OriginalCamera)
{
m_OriginalCamera.transform.position = m_OriginalCameraPosition;
m_OriginalCamera.transform.rotation = m_OriginalCameraRotation;
}
transform.position = m_CurrentCamera.transform.position;
transform.rotation = m_CurrentCamera.transform.rotation;
}
}
if (m_MessageTimer < m_MessageDuration)
{
string cameraName = m_CurrentCamera != null ? m_CurrentCamera.name : "NULL";
string message = string.Format("Switching to camera : {0}", cameraName);
Debugging.PushDebugMessage(message);
}
}
}
}

12
Assets/ScriptableRenderPipeline/common/Camera/CameraSwitcher.cs.meta


fileFormatVersion: 2
guid: f52d1e5345c395641b482217c8804ff9
timeCreated: 1488380874
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

67
Assets/ScriptableRenderPipeline/common/Camera/FreeCamera.cs


using UnityEngine;
public class FreeCamera : MonoBehaviour
{
public float m_LookSpeedController = 120f;
public float m_LookSpeedMouse = 10.0f;
public float m_MoveSpeed = 50.0f;
public float m_Turbo = 10.0f;
private static string kMouseX = "Mouse X";
private static string kMouseY = "Mouse Y";
private static string kRightStickX = "Controller Right Stick X";
private static string kRightStickY = "Controller Right Stick Y";
private static string kVertical = "Vertical";
private static string kHorizontal = "Horizontal";
private string[] m_RequiredInputAxes = { kMouseX, kMouseY, kRightStickX, kRightStickY, kVertical, kHorizontal };
private bool m_Valid = true;
void OnEnable()
{
m_Valid = Debugging.CheckRequiredInputAxisMapping(m_RequiredInputAxes);
}
void Update()
{
if(m_Valid)
{
float inputRotateAxisX = 0.0f;
float inputRotateAxisY = 0.0f;
if (Input.GetMouseButton(1))
{
inputRotateAxisX = Input.GetAxis(kMouseX) * m_LookSpeedMouse;
inputRotateAxisY = Input.GetAxis(kMouseY) * m_LookSpeedMouse;
}
inputRotateAxisX += (Input.GetAxis(kRightStickX) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisY += (Input.GetAxis(kRightStickY) * m_LookSpeedController * Time.deltaTime);
float inputVertical = Input.GetAxis(kVertical);
float inputHorizontal = Input.GetAxis(kHorizontal);
bool moved = inputRotateAxisX != 0.0f || inputRotateAxisY != 0.0f || inputVertical != 0.0f || inputHorizontal != 0.0f;
if (moved)
{
float rotationX = transform.localEulerAngles.x;
float newRotationY = transform.localEulerAngles.y + inputRotateAxisX;
// Weird clamping code due to weird Euler angle mapping...
float newRotationX = (rotationX - inputRotateAxisY);
if (rotationX <= 90.0f && newRotationX >= 0.0f)
newRotationX = Mathf.Clamp(newRotationX, 0.0f, 90.0f);
if (rotationX >= 270.0f)
newRotationX = Mathf.Clamp(newRotationX, 270.0f, 360.0f);
transform.localRotation = Quaternion.Euler(newRotationX, newRotationY, transform.localEulerAngles.z);
float moveSpeed = Time.deltaTime * m_MoveSpeed;
if (Input.GetMouseButton(1))
moveSpeed *= Input.GetKey(KeyCode.LeftShift) ? m_Turbo : 1.0f;
else
moveSpeed *= Input.GetAxis("Fire1") > 0.0f ? m_Turbo : 1.0f;
transform.position += transform.forward * moveSpeed * inputVertical;
transform.position += transform.right * moveSpeed * inputHorizontal;
}
}
}
}

12
Assets/ScriptableRenderPipeline/common/Camera/FreeCamera.cs.meta


fileFormatVersion: 2
guid: 618b0e3f6c65dd247a4a016150006c57
timeCreated: 1488370968
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs.meta


fileFormatVersion: 2
guid: e9493dbe9d624704d9a80a75d52835b3
timeCreated: 1485361779
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

509
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs


using System;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public class SubsurfaceScatteringProfile
{
public const int numSamples = 7; // Must be an odd number
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev1;
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev2;
[SerializeField]
public float lerpWeight;
[SerializeField]
public bool enableTransmission;
[SerializeField]
public Vector2 thicknessRemap;
[SerializeField] [HideInInspector]
Vector4[] m_FilterKernel;
[SerializeField] [HideInInspector]
Vector3[] m_HalfRcpVariances;
[SerializeField] [HideInInspector]
Vector4 m_HalfRcpWeightedVariances;
// --- Public Methods ---
public SubsurfaceScatteringProfile()
{
stdDev1 = new Color(0.3f, 0.3f, 0.3f, 0.0f);
stdDev2 = new Color(0.6f, 0.6f, 0.6f, 0.0f);
lerpWeight = 0.5f;
enableTransmission = false;
thicknessRemap = new Vector2(0, 3);
UpdateKernelAndVarianceData();
}
public Vector4[] filterKernel
{
// Set via UpdateKernelAndVarianceData().
get { return m_FilterKernel; }
}
public Vector3[] halfRcpVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpVariances; }
}
public Vector4 halfRcpWeightedVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpWeightedVariances; }
}
public void UpdateKernelAndVarianceData()
{
if (m_FilterKernel == null)
{
m_FilterKernel = new Vector4[numSamples];
}
if (m_HalfRcpVariances == null)
{
m_HalfRcpVariances = new Vector3[2];
}
// 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� / (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.
// 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);
Vector3 weightSum = new Vector3(0, 0, 0);
// Importance sample the linear combination of two Gaussians.
for (uint i = 0; i < numSamples; i++)
{
float u = (i + 0.5f) / numSamples;
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, lerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, lerpWeight);
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);
// 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;
weightSum.x += m_FilterKernel[i].x;
weightSum.y += m_FilterKernel[i].y;
weightSum.z += m_FilterKernel[i].z;
}
// 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;
}
// 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);
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);
// 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);
}
// --- Private Methods ---
static float Gaussian(float x, float stdDev)
{
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
}
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
}
static float RationalApproximation(float t)
{
// 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);
}
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
{
float x;
if (p < 0.5)
{
// 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)));
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
}
public class SubsurfaceScatteringParameters : ScriptableObject
{
public const int maxNumProfiles = 8;
[SerializeField]
bool m_EnableSSS;
[SerializeField]
int m_NumProfiles;
[SerializeField]
int m_TransmissionFlags;
[SerializeField]
SubsurfaceScatteringProfile[] m_Profiles;
[SerializeField]
float[] m_ThicknessRemaps;
[SerializeField]
Vector4[] m_HalfRcpVariancesAndLerpWeights;
[SerializeField]
Vector4[] m_HalfRcpWeightedVariances;
[SerializeField]
Vector4[] m_FilterKernels;
// --- Public Methods ---
public SubsurfaceScatteringParameters()
{
m_EnableSSS = true;
m_NumProfiles = 1;
m_Profiles = new SubsurfaceScatteringProfile[m_NumProfiles];
for (int i = 0; i < m_NumProfiles; i++)
{
m_Profiles[i] = new SubsurfaceScatteringProfile();
}
OnValidate();
}
public bool enableSSS {
// Set via serialization.
get { return m_EnableSSS; }
}
public SubsurfaceScatteringProfile[] profiles {
// Set via serialization.
get { return m_Profiles; }
}
// Returns a bit mask s.t. the i-th bit indicates whether the i-th profile requires transmittance evaluation.
// Supplies '_TransmissionFlags' to Lit.hlsl.
public int transmissionFlags {
// Set during OnValidate().
get { return m_TransmissionFlags; }
}
// Supplies '_ThicknessRemaps' to Lit.hlsl.
public float[] thicknessRemaps
{
// Set during OnValidate().
get { return m_ThicknessRemaps; }
}
// Supplies '_HalfRcpVariancesAndLerpWeights' to Lit.hlsl.
public Vector4[] halfRcpVariancesAndLerpWeights {
// Set during OnValidate().
get { return m_HalfRcpVariancesAndLerpWeights; }
}
// Supplies '_HalfRcpWeightedVariances' to CombineSubsurfaceScattering.shader.
public Vector4[] halfRcpWeightedVariances {
// Set during OnValidate().
get { return m_HalfRcpWeightedVariances; }
}
// Supplies '_FilterKernels' to CombineSubsurfaceScattering.shader.
public Vector4[] filterKernels
{
// Set during OnValidate().
get { return m_FilterKernels; }
}
public void OnValidate()
{
if (m_Profiles.Length > maxNumProfiles)
{
Array.Resize(ref m_Profiles, maxNumProfiles);
}
m_NumProfiles = m_Profiles.Length;
m_TransmissionFlags = 0;
if (m_ThicknessRemaps == null)
{
m_ThicknessRemaps = new float[maxNumProfiles * 2];
}
if (m_HalfRcpVariancesAndLerpWeights == null)
{
m_HalfRcpVariancesAndLerpWeights = new Vector4[maxNumProfiles * 2];
}
if (m_HalfRcpWeightedVariances == null)
{
m_HalfRcpWeightedVariances = new Vector4[maxNumProfiles];
}
if (m_FilterKernels == null)
{
m_FilterKernels = new Vector4[maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
}
Color c = new Color();
for (int i = 0; i < m_NumProfiles; i++)
{
m_TransmissionFlags |= (m_Profiles[i].enableTransmission ? 1 : 0) << i;
c.r = Mathf.Clamp(m_Profiles[i].stdDev1.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(m_Profiles[i].stdDev1.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(m_Profiles[i].stdDev1.b, 0.05f, 2.0f);
c.a = 0.0f;
m_Profiles[i].stdDev1 = c;
c.r = Mathf.Clamp(m_Profiles[i].stdDev2.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(m_Profiles[i].stdDev2.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(m_Profiles[i].stdDev2.b, 0.05f, 2.0f);
c.a = 0.0f;
m_Profiles[i].stdDev2 = c;
m_Profiles[i].lerpWeight = Mathf.Clamp01(m_Profiles[i].lerpWeight);
m_Profiles[i].thicknessRemap.x = Mathf.Clamp(m_Profiles[i].thicknessRemap.x, 0, m_Profiles[i].thicknessRemap.y);
m_Profiles[i].thicknessRemap.y = Mathf.Max(m_Profiles[i].thicknessRemap.x, m_Profiles[i].thicknessRemap.y);
m_Profiles[i].UpdateKernelAndVarianceData();
}
// Use the updated data to fill the cache.
for (int i = 0; i < m_NumProfiles; i++)
{
m_ThicknessRemaps[2 * i] = m_Profiles[i].thicknessRemap.x;
m_ThicknessRemaps[2 * i + 1] = m_Profiles[i].thicknessRemap.y - m_Profiles[i].thicknessRemap.x;
m_HalfRcpVariancesAndLerpWeights[2 * i] = m_Profiles[i].halfRcpVariances[0];
m_HalfRcpVariancesAndLerpWeights[2 * i].w = 1.0f - m_Profiles[i].lerpWeight;
m_HalfRcpVariancesAndLerpWeights[2 * i + 1] = m_Profiles[i].halfRcpVariances[1];
m_HalfRcpVariancesAndLerpWeights[2 * i + 1].w = m_Profiles[i].lerpWeight;
m_HalfRcpWeightedVariances[i] = m_Profiles[i].halfRcpWeightedVariances;
for (int j = 0, n = SubsurfaceScatteringProfile.numSamples; j < n; j++)
{
m_FilterKernels[n * i + j] = m_Profiles[i].filterKernel[j];
}
}
}
}
public class SubsurfaceScatteringSettings : Singleton<SubsurfaceScatteringSettings>
{
SubsurfaceScatteringParameters settings { get; set; }
public static SubsurfaceScatteringParameters overrideSettings
{
get { return instance.settings; }
set { instance.settings = value; }
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(SubsurfaceScatteringParameters))]
public class SubsurfaceScatteringParametersEditor : Editor
{
private class Styles
{
public readonly GUIContent category = new GUIContent("Subsurface scattering parameters");
public readonly GUIContent[] profiles = new GUIContent[SubsurfaceScatteringParameters.maxNumProfiles] { 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 profilePreview0 = new GUIContent("Profile preview");
public readonly GUIContent profilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as radius increases to 1.");
public readonly GUIContent profilePreview2 = new GUIContent("Note that the intensity of the region in the center may be clamped.");
public readonly GUIContent transmittancePreview0 = new GUIContent("Transmittance preview");
public readonly GUIContent transmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object as thickness increases to 1.");
public readonly GUIContent numProfiles = new GUIContent("Number of profiles");
public readonly GUIContent profileStdDev1 = new GUIContent("Standard deviation #1", "Determines the shape of the 1st Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent profileStdDev2 = new GUIContent("Standard deviation #2", "Determines the shape of the 2nd Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent profileLerpWeight = new GUIContent("Filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent profileTransmission = new GUIContent("Enable transmission", "Toggles simulation of light passing through thin objects. Depends on the thickness of the material.");
public readonly GUIContent profileThicknessRemap = new GUIContent("Thickness remap", "Remaps the thickness parameter from [0, 1] to the desired range.");
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle (GUI.skin.label);
}
private static Styles s_Styles;
private SerializedProperty m_EnableSSS, m_Profiles, m_NumProfiles;
private Material m_ProfileMaterial, m_TransmittanceMaterial;
private RenderTexture[] m_ProfileImages, m_TransmittanceImages;
// --- Public Methods ---
private static Styles styles
{
get
{
if (s_Styles == null)
{
s_Styles = new Styles();
s_Styles.centeredMiniBoldLabel.alignment = TextAnchor.MiddleCenter;
s_Styles.centeredMiniBoldLabel.fontSize = 10;
s_Styles.centeredMiniBoldLabel.fontStyle = FontStyle.Bold;
}
return s_Styles;
}
}
void OnEnable()
{
m_EnableSSS = serializedObject.FindProperty("m_EnableSSS");
m_Profiles = serializedObject.FindProperty("m_Profiles");
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_TransmittanceMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileImages = new RenderTexture[SubsurfaceScatteringParameters.maxNumProfiles];
m_TransmittanceImages = new RenderTexture[SubsurfaceScatteringParameters.maxNumProfiles];
for (int i = 0; i < SubsurfaceScatteringParameters.maxNumProfiles; i++)
{
m_ProfileImages[i] = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImages[i] = new RenderTexture(16, 256, 0, RenderTextureFormat.DefaultHDR);
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.BeginChangeCheck();
// Validate the data before displaying it.
((SubsurfaceScatteringParameters)serializedObject.targetObject).OnValidate();
EditorGUILayout.LabelField(styles.category, EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_EnableSSS);
EditorGUILayout.PropertyField(m_NumProfiles, styles.numProfiles);
EditorGUILayout.PropertyField(m_Profiles);
if (m_Profiles.isExpanded)
{
EditorGUI.indentLevel++;
for (int i = 0, n = Math.Min(m_Profiles.arraySize, SubsurfaceScatteringParameters.maxNumProfiles); i < n; i++)
{
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.profiles[i]);
if (profile.isExpanded)
{
EditorGUI.indentLevel++;
SerializedProperty profileStdDev1 = profile.FindPropertyRelative("stdDev1");
SerializedProperty profileStdDev2 = profile.FindPropertyRelative("stdDev2");
SerializedProperty profileLerpWeight = profile.FindPropertyRelative("lerpWeight");
SerializedProperty profileTransmission = profile.FindPropertyRelative("enableTransmission");
SerializedProperty profileThicknessRemap = profile.FindPropertyRelative("thicknessRemap");
EditorGUILayout.PropertyField(profileStdDev1, styles.profileStdDev1);
EditorGUILayout.PropertyField(profileStdDev2, styles.profileStdDev2);
EditorGUILayout.PropertyField(profileLerpWeight, styles.profileLerpWeight);
EditorGUILayout.PropertyField(profileTransmission, styles.profileTransmission);
Vector2 thicknessRemap = profileThicknessRemap.vector2Value;
EditorGUILayout.LabelField("Min thickness: ", thicknessRemap.x.ToString());
EditorGUILayout.LabelField("Max thickness: ", thicknessRemap.y.ToString());
EditorGUILayout.MinMaxSlider(styles.profileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
profileThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.profilePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.profilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(styles.profilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImages[i], m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.transmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.transmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", profileThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImages[i], m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
}
EditorGUI.indentLevel--;
}
if (EditorGUI.EndChangeCheck())
{
// Serialization does not invoke setters, but does call OnValidate().
serializedObject.ApplyModifiedProperties();
}
}
}
#endif
}
正在加载...
取消
保存