浏览代码

Merge remote-tracking branch 'refs/remotes/origin/Unity-2017.3' into Add-Per-Pixel-scale

/stochastic_alpha_test
sebastienlagarde 7 年前
当前提交
df6297b3
共有 42 个文件被更改,包括 1462 次插入1362 次删除
  1. 4
      ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  2. 4
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  3. 68
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  4. 417
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.cs
  6. 17
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.cs
  7. 881
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs
  8. 5
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/EditorLightUtilities.cs
  9. 100
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  10. 8
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs
  11. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  12. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  13. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  14. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  15. 6
      ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs
  16. 10
      ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs
  17. 8
      ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  18. 16
      ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs
  19. 46
      ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  20. 4
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/HDRPAsset/HDRenderPipelineResourcesTest.asset
  21. 11
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs
  22. 268
      ScriptableRenderPipeline/Core/CoreUtils.cs
  23. 13
      ScriptableRenderPipeline/Core/CoreUtils.cs.meta
  24. 62
      ScriptableRenderPipeline/Core/Editor/PropertyFetcher.cs
  25. 13
      ScriptableRenderPipeline/Core/Editor/PropertyFetcher.cs.meta
  26. 41
      ScriptableRenderPipeline/Core/ProfilingSample.cs
  27. 13
      ScriptableRenderPipeline/Core/ProfilingSample.cs.meta
  28. 8
      ScriptableRenderPipeline/HDRenderPipeline/Camera.meta
  29. 51
      ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs
  30. 79
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs
  31. 13
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs.meta
  32. 221
      ScriptableRenderPipeline/HDRenderPipeline/Camera/HDCamera.cs
  33. 11
      ScriptableRenderPipeline/HDRenderPipeline/Camera/HDCamera.cs.meta
  34. 10
      ScriptableRenderPipeline/HDRenderPipeline/AdditionalData.meta
  35. 390
      ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
  36. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs.meta
  37. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Camera/HDAdditionalCameraData.cs.meta
  38. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs.meta
  39. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Camera/HDAdditionalCameraData.cs
  40. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs

4
ScriptableRenderPipeline/Core/Shadow/Shadow.cs


if (m_ActiveEntriesCount == 0)
return;
var profilingSample = new HDPipeline.Utilities.ProfilingSample(string.Format("Shadowmap{0}",m_TexSlot), cmd);
var profilingSample = new ProfilingSample(string.Format("Shadowmap{0}",m_TexSlot), cmd);
string cbName = "";
if (!string.IsNullOrEmpty( m_ShaderKeyword ) )

public override void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights)
{
using (new HDPipeline.Utilities.ProfilingSample("Render Shadows", cmd))
using (new ProfilingSample("Render Shadows", cmd))
{
foreach( var sm in m_Shadowmaps )
{

4
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


{
if (!isDebugViewMaterialInit)
{
List<RenderPipelineMaterial> materialList = Utilities.GetRenderPipelineMaterialList();
List<RenderPipelineMaterial> materialList = CoreUtils.GetRenderPipelineMaterialList();
// TODO: Share this code to retrieve deferred material with HDRenderPipeline
// Find first material that have non 0 Gbuffer count and assign it as deferredMaterial

{
None,
// Lighting
MinLightingFullScreenDebug,
MinLightingFullScreenDebug,
SSAO,
SSAOBeforeFiltering,
DeferredShadows,

68
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


using System.Reflection;
using System.Linq.Expressions;
using UnityEditor;
using UnityEditor.Experimental.Rendering;
//using EditorGUIUtility=UnityEditor.EditorGUIUtility;

SerializedProperty m_PointCookieSize = null;
SerializedProperty m_ReflectionCubemapSize = null;
private void InitializeProperties()
void InitializeProperties()
m_DefaultDiffuseMaterial = serializedObject.FindProperty("m_DefaultDiffuseMaterial");
m_DefaultShader = serializedObject.FindProperty("m_DefaultShader");
using (var p = new PropertyFetcher<HDRenderPipelineAsset>(serializedObject))
{
m_DefaultDiffuseMaterial = p.FindProperty("m_DefaultDiffuseMaterial");
m_DefaultShader = p.FindProperty("m_DefaultShader");
// Following way of getting property allow to handle change of properties name with serializations
// Tile settings
m_enableTileAndCluster = p.FindProperty(x => x.tileSettings.enableTileAndCluster);
m_enableComputeLightEvaluation = p.FindProperty(x => x.tileSettings.enableComputeLightEvaluation);
m_enableComputeLightVariants = p.FindProperty(x => x.tileSettings.enableComputeLightVariants);
m_enableComputeMaterialVariants = p.FindProperty(x => x.tileSettings.enableComputeMaterialVariants);
m_enableClustered = p.FindProperty(x => x.tileSettings.enableClustered);
m_enableFptlForOpaqueWhenClustered = p.FindProperty(x => x.tileSettings.enableFptlForOpaqueWhenClustered);
m_enableBigTilePrepass = p.FindProperty(x => x.tileSettings.enableBigTilePrepass);
// Tile settings
m_enableTileAndCluster = FindProperty(x => x.tileSettings.enableTileAndCluster);
m_enableComputeLightEvaluation = FindProperty(x => x.tileSettings.enableComputeLightEvaluation);
m_enableComputeLightVariants = FindProperty(x => x.tileSettings.enableComputeLightVariants);
m_enableComputeMaterialVariants = FindProperty(x => x.tileSettings.enableComputeMaterialVariants);
m_enableClustered = FindProperty(x => x.tileSettings.enableClustered);
m_enableFptlForOpaqueWhenClustered = FindProperty(x => x.tileSettings.enableFptlForOpaqueWhenClustered);
m_enableBigTilePrepass = FindProperty(x => x.tileSettings.enableBigTilePrepass);
// Shadow settings
m_ShadowAtlasWidth = p.FindProperty(x => x.shadowInitParams.shadowAtlasWidth);
m_ShadowAtlasHeight = p.FindProperty(x => x.shadowInitParams.shadowAtlasHeight);
// Shadow settings
m_ShadowAtlasWidth = FindProperty(x => x.shadowInitParams.shadowAtlasWidth);
m_ShadowAtlasHeight = FindProperty(x => x.shadowInitParams.shadowAtlasHeight);
// Texture settings
m_SpotCookieSize = p.FindProperty(x => x.textureSettings.spotCookieSize);
m_PointCookieSize = p.FindProperty(x => x.textureSettings.pointCookieSize);
m_ReflectionCubemapSize = p.FindProperty(x => x.textureSettings.reflectionCubemapSize);
// Texture settings
m_SpotCookieSize = FindProperty(x => x.textureSettings.spotCookieSize);
m_PointCookieSize = FindProperty(x => x.textureSettings.pointCookieSize);
m_ReflectionCubemapSize = FindProperty(x => x.textureSettings.reflectionCubemapSize);
// Rendering settings
m_RenderingUseForwardOnly = p.FindProperty(x => x.renderingSettings.useForwardRenderingOnly);
m_RenderingUseDepthPrepass = p.FindProperty(x => x.renderingSettings.useDepthPrepassWithDeferredRendering);
m_RenderingUseDepthPrepassAlphaTestOnly = p.FindProperty(x => x.renderingSettings.renderAlphaTestOnlyInDeferredPrepass);
// Rendering settings
m_RenderingUseForwardOnly = FindProperty(x => x.renderingSettings.useForwardRenderingOnly);
m_RenderingUseDepthPrepass = FindProperty(x => x.renderingSettings.useDepthPrepassWithDeferredRendering);
m_RenderingUseDepthPrepassAlphaTestOnly = FindProperty(x => x.renderingSettings.renderAlphaTestOnlyInDeferredPrepass);
// Subsurface Scattering Settings
// Old SSS Model >>>
m_UseDisneySSS = FindProperty(x => x.sssSettings.useDisneySSS);
// <<< Old SSS Model
m_Profiles = FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
SerializedProperty FindProperty<TValue>(Expression<Func<HDRenderPipelineAsset, TValue>> expr)
{
var path = Utilities.GetFieldPath(expr);
return serializedObject.FindProperty(path);
// Subsurface Scattering Settings
// Old SSS Model >>>
m_UseDisneySSS = p.FindProperty(x => x.sssSettings.useDisneySSS);
// <<< Old SSS Model
m_Profiles = p.FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
}
static void HackSetDirty(RenderPipelineAsset asset)

417
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


}
}
// This holds all the matrix data we need for rendering, including data from the previous frame
// (which is the main reason why we need to keep them around for a minimum of one frame).
// HDCameras are automatically created & updated from a source camera and will be destroyed if
// not used during a frame.
public class HDCamera
{
public Matrix4x4 viewMatrix;
public Matrix4x4 projMatrix;
public Matrix4x4 nonJitteredProjMatrix;
public Vector4 screenSize;
public Vector4[] frustumPlaneEquations;
public Camera camera;
public Matrix4x4 viewProjMatrix
{
get { return projMatrix * viewMatrix; }
}
public Matrix4x4 nonJitteredViewProjMatrix
{
get { return nonJitteredProjMatrix * viewMatrix; }
}
public bool isFirstFrame
{
get { return m_FirstFrame; }
}
public Vector4 invProjParam
{
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
get { var p = projMatrix; return new Vector4(p.m20 / (p.m00 * p.m23), p.m21 / (p.m11 * p.m23), -1.0f / p.m23, (-p.m22 + p.m20 * p.m02 / p.m00 + p.m21 * p.m12 / p.m11) / p.m23); }
}
// View-projection matrix from the previous frame.
public Matrix4x4 prevViewProjMatrix;
// We need to keep track of these when camera relative rendering is enabled so we can take
// camera translation into account when generating camera motion vectors
public Vector3 cameraPos;
public Vector3 prevCameraPos;
// The only way to reliably keep track of a frame change right now is to compare the frame
// count Unity gives us. We need this as a single camera could be rendered several times per
// frame and some matrices only have to be computed once. Realistically this shouldn't
// happen, but you never know...
int m_LastFrameActive;
// Always true for cameras that just got added to the pool - needed for previous matrices to
// avoid one-frame jumps/hiccups with temporal effects (motion blur, TAA...)
bool m_FirstFrame;
public HDCamera(Camera cam)
{
camera = cam;
frustumPlaneEquations = new Vector4[6];
Reset();
}
public void Update(PostProcessLayer postProcessLayer)
{
// If TAA is enabled projMatrix will hold a jittered projection matrix. The original,
// non-jittered projection matrix can be accessed via nonJitteredProjMatrix.
bool taaEnabled = camera.cameraType == CameraType.Game
&& Utilities.IsTemporalAntialiasingActive(postProcessLayer);
Matrix4x4 nonJitteredCameraProj = camera.projectionMatrix;
Matrix4x4 cameraProj = taaEnabled
? postProcessLayer.temporalAntialiasing.GetJitteredProjectionMatrix(camera)
: nonJitteredCameraProj;
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
Matrix4x4 gpuProj = GL.GetGPUProjectionMatrix(cameraProj, true); // Had to change this from 'false'
Matrix4x4 gpuView = camera.worldToCameraMatrix;
Matrix4x4 gpuNonJitteredProj = GL.GetGPUProjectionMatrix(nonJitteredCameraProj, true);
Vector3 pos = camera.transform.position;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Zero out the translation component.
gpuView.SetColumn(3, new Vector4(0, 0, 0, 1));
}
Matrix4x4 gpuVP = gpuNonJitteredProj * gpuView;
// A camera could be rendered multiple times per frame, only updates the previous view proj & pos if needed
if (m_LastFrameActive != Time.frameCount)
{
if (m_FirstFrame)
{
prevCameraPos = pos;
prevViewProjMatrix = gpuVP;
}
else
{
prevCameraPos = cameraPos;
prevViewProjMatrix = nonJitteredViewProjMatrix;
}
m_FirstFrame = false;
}
viewMatrix = gpuView;
projMatrix = gpuProj;
nonJitteredProjMatrix = gpuNonJitteredProj;
cameraPos = pos;
screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(viewProjMatrix);
for (int i = 0; i < 6; i++)
{
frustumPlaneEquations[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, planes[i].distance);
}
m_LastFrameActive = Time.frameCount;
}
public void Reset()
{
m_LastFrameActive = -1;
m_FirstFrame = true;
}
static Dictionary<Camera, HDCamera> m_Cameras = new Dictionary<Camera, HDCamera>();
static List<Camera> m_Cleanup = new List<Camera>(); // Recycled to reduce GC pressure
// Grab the HDCamera tied to a given Camera and update it.
public static HDCamera Get(Camera camera, PostProcessLayer postProcessLayer)
{
HDCamera hdcam;
if (!m_Cameras.TryGetValue(camera, out hdcam))
{
hdcam = new HDCamera(camera);
m_Cameras.Add(camera, hdcam);
}
hdcam.Update(postProcessLayer);
return hdcam;
}
// Look for any camera that hasn't been used in the last frame and remove them for the pool.
public static void CleanUnused()
{
int frameCheck = Time.frameCount - 1;
foreach (var kvp in m_Cameras)
{
if (kvp.Value.m_LastFrameActive != frameCheck)
m_Cleanup.Add(kvp.Key);
}
foreach (var cam in m_Cleanup)
m_Cameras.Remove(cam);
m_Cleanup.Clear();
}
public void SetupGlobalParams(CommandBuffer cmd)
{
cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, viewMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, viewMatrix.inverse);
cmd.SetGlobalMatrix(HDShaderIDs._ProjMatrix, projMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvProjMatrix, projMatrix.inverse);
cmd.SetGlobalMatrix(HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._ViewProjMatrix, viewProjMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvViewProjMatrix, viewProjMatrix.inverse);
cmd.SetGlobalVector(HDShaderIDs._InvProjParam, invProjParam);
cmd.SetGlobalVector(HDShaderIDs._ScreenSize, screenSize);
cmd.SetGlobalMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetGlobalVectorArray(HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
}
// Does not modify global settings. Used for shadows, low res. rendering, etc.
public void OverrideGlobalParams(Material material)
{
material.SetMatrix(HDShaderIDs._ViewMatrix, viewMatrix);
material.SetMatrix(HDShaderIDs._InvViewMatrix, viewMatrix.inverse);
material.SetMatrix(HDShaderIDs._ProjMatrix, projMatrix);
material.SetMatrix(HDShaderIDs._InvProjMatrix, projMatrix.inverse);
material.SetMatrix(HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
material.SetMatrix(HDShaderIDs._ViewProjMatrix, viewProjMatrix);
material.SetMatrix(HDShaderIDs._InvViewProjMatrix, viewProjMatrix.inverse);
material.SetVector(HDShaderIDs._InvProjParam, invProjParam);
material.SetVector(HDShaderIDs._ScreenSize, screenSize);
material.SetMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
material.SetVectorArray(HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
}
public void SetupComputeShader(ComputeShader cs, CommandBuffer cmd)
{
cmd.SetComputeMatrixParam(cs, HDShaderIDs._ViewMatrix, viewMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._InvViewMatrix, viewMatrix.inverse);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._ProjMatrix, projMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._InvProjMatrix, projMatrix.inverse);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._ViewProjMatrix, viewProjMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._InvViewProjMatrix, viewProjMatrix.inverse);
cmd.SetComputeVectorParam(cs, HDShaderIDs._InvProjParam, invProjParam);
cmd.SetComputeVectorParam(cs, HDShaderIDs._ScreenSize, screenSize);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetComputeVectorArrayParam(cs, HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
// Copy values set by Unity which are not configured in scripts.
cmd.SetComputeVectorParam(cs, HDShaderIDs.unity_OrthoParams, Shader.GetGlobalVector(HDShaderIDs.unity_OrthoParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ProjectionParams, Shader.GetGlobalVector(HDShaderIDs._ProjectionParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ScreenParams, Shader.GetGlobalVector(HDShaderIDs._ScreenParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ZBufferParams, Shader.GetGlobalVector(HDShaderIDs._ZBufferParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._WorldSpaceCameraPos, Shader.GetGlobalVector(HDShaderIDs._WorldSpaceCameraPos));
}
}
public class GBufferManager
{
public const int MaxGbuffer = 8;

private RenderTargetIdentifier m_CameraDepthBufferCopyRT;
private RenderTargetIdentifier m_CameraStencilBufferCopyRT;
private RenderTargetIdentifier m_HTileRT;
// Post-processing context and screen-space effects (recycled on every frame to avoid GC alloc)
readonly PostProcessRenderContext m_PostProcessContext;
readonly ScreenSpaceAmbientOcclusionEffect m_SsaoEffect;

m_Asset = asset;
// Scan material list and assign it
m_MaterialList = Utilities.GetRenderPipelineMaterialList();
m_MaterialList = CoreUtils.GetRenderPipelineMaterialList();
// Find first material that have non 0 Gbuffer count and assign it as deferredMaterial
m_DeferredMaterial = null;
foreach (RenderPipelineMaterial material in m_MaterialList)

CreateSssMaterials(sssSettings.useDisneySSS);
m_CopyStencilForSplitLighting = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CopyStencilForSplitLighting = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CopyStencilForRegularLighting = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CopyStencilForRegularLighting = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CameraMotionVectorsMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CameraMotionVectors");
m_CameraMotionVectorsMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/CameraMotionVectors");
InitializeDebugMaterials();

void InitializeDebugMaterials()
{
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugViewMaterialGBufferShader);
m_DebugDisplayLatlong = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugDisplayLatlongShader);
m_DebugFullScreen = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugFullScreenShader);
m_DebugViewMaterialGBuffer = CoreUtils.CreateEngineMaterial(m_Asset.renderPipelineResources.debugViewMaterialGBufferShader);
m_DebugDisplayLatlong = CoreUtils.CreateEngineMaterial(m_Asset.renderPipelineResources.debugDisplayLatlongShader);
m_DebugFullScreen = CoreUtils.CreateEngineMaterial(m_Asset.renderPipelineResources.debugFullScreenShader);
m_ErrorMaterial = Utilities.CreateEngineMaterial("Hidden/InternalErrorShader");
m_ErrorMaterial = CoreUtils.CreateEngineMaterial("Hidden/InternalErrorShader");
#endif
}

Utilities.Destroy(m_CombineLightingPass);
m_CombineLightingPass = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineLighting");
CoreUtils.Destroy(m_CombineLightingPass);
m_CombineLightingPass = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineLighting");
Utilities.Destroy(m_SssVerticalFilterPass);
m_SssVerticalFilterPass = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
CoreUtils.Destroy(m_SssVerticalFilterPass);
m_SssVerticalFilterPass = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
Utilities.Destroy(m_SssHorizontalFilterAndCombinePass);
m_SssHorizontalFilterAndCombinePass = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
CoreUtils.Destroy(m_SssHorizontalFilterAndCombinePass);
m_SssHorizontalFilterAndCombinePass = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
m_SssHorizontalFilterAndCombinePass.EnableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_SssHorizontalFilterAndCombinePass.SetFloat(HDShaderIDs._DstBlend, (float)BlendMode.One);
// <<< Old SSS Model

m_MaterialList.ForEach(material => material.Cleanup());
Utilities.Destroy(m_DebugViewMaterialGBuffer);
Utilities.Destroy(m_DebugDisplayLatlong);
Utilities.Destroy(m_DebugFullScreen);
CoreUtils.Destroy(m_DebugViewMaterialGBuffer);
CoreUtils.Destroy(m_DebugDisplayLatlong);
CoreUtils.Destroy(m_DebugFullScreen);
Utilities.Destroy(m_ErrorMaterial);
CoreUtils.Destroy(m_ErrorMaterial);
#endif
m_SkyManager.Cleanup();

public void PushGlobalParams(HDCamera hdCamera, CommandBuffer cmd, SubsurfaceScatteringSettings sssParameters)
{
using (new Utilities.ProfilingSample("Push Global Parameters", cmd))
using (new ProfilingSample("Push Global Parameters", cmd))
{
hdCamera.SetupGlobalParams(cmd);

private void CopyDepthBufferIfNeeded(CommandBuffer cmd)
{
using (new Utilities.ProfilingSample(NeedDepthBufferCopy() ? "Copy DepthBuffer" : "Set DepthBuffer", cmd))
using (new ProfilingSample(NeedDepthBufferCopy() ? "Copy DepthBuffer" : "Set DepthBuffer", cmd))
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", cmd))
using (new ProfilingSample("Copy depth-stencil buffer", cmd))
{
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthBufferCopyRT);
}

{
if (NeedStencilBufferCopy())
{
using (new Utilities.ProfilingSample("Copy StencilBuffer", cmd))
using (new ProfilingSample("Copy StencilBuffer", cmd))
Utilities.DrawFullScreen(cmd, m_CopyStencilForSplitLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
Utilities.DrawFullScreen(cmd, m_CopyStencilForRegularLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
CoreUtils.DrawFullScreen(cmd, m_CopyStencilForSplitLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
CoreUtils.DrawFullScreen(cmd, m_CopyStencilForRegularLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
cmd.ClearRandomWriteTargets();
}
}

// TODO: Add another path dedicated to planar reflection / real time cubemap that implement simpler lighting
// It is up to the users to only send unlit object for this camera path
using (new Utilities.ProfilingSample("Forward", cmd))
using (new ProfilingSample("Forward", cmd))
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor | ClearFlag.ClearDepth);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.Color | ClearFlag.Depth);
ShaderPassName[] arrayShaderPassName = { HDShaderPassNames.m_ForwardName };
RenderOpaqueRenderList(m_CullResults, camera, renderContext, cmd, arrayShaderPassName);
RenderTransparentRenderList(m_CullResults, camera, renderContext, cmd, arrayShaderPassName);

RenderGBuffer(m_CullResults, camera, renderContext, cmd);
// If full forward rendering, we did not do any rendering yet, so don't need to copy the buffer.
// If Deferred then the depth buffer is full (regular GBuffer + ForwardOnly depth prepass are done so we can copy it safely.
if (!m_Asset.renderingSettings.useForwardRenderingOnly)
{
CopyDepthBufferIfNeeded(cmd);
}
// In both forward and deferred, everything opaque should have been rendered at this point so we can safely copy the depth buffer for later processing.
CopyDepthBufferIfNeeded(cmd);
// Required for the SSS and the shader feature classification pass.
PrepareAndBindStencilTexture(cmd);

}
else
{
using (new Utilities.ProfilingSample("Build Light list and render shadows", cmd))
using (new ProfilingSample("Build Light list and render shadows", cmd))
{
// TODO: Everything here (SSAO, Shadow, Build light list, deffered shadow, material and light classification can be parallelize with Async compute)
m_SsaoEffect.Render(ssaoSettingsToUse, this, hdCamera, renderContext, cmd, m_Asset.renderingSettings.useForwardRenderingOnly);

RenderLightingDebug(hdCamera, cmd, m_CameraColorBufferRT, m_CurrentDebugDisplaySettings);
// If full forward rendering, we did just rendered everything, so we can copy the depth buffer
// If Deferred nothing needs copying anymore.
if (m_Asset.renderingSettings.useForwardRenderingOnly)
{
CopyDepthBufferIfNeeded(cmd);
}
RenderSky(hdCamera, cmd);
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.

// Planar and real time cubemap doesn't need post process and render in FP16
if (camera.cameraType == CameraType.Reflection)
{
using (new Utilities.ProfilingSample("Blit to final RT", cmd))
using (new ProfilingSample("Blit to final RT", cmd))
{
// Simple blit
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget);

void RenderOpaqueRenderList(CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
CommandBuffer cmd,
ShaderPassName passName,
RendererConfiguration rendererConfiguration = 0,
RenderQueueRange? inRenderQueueRange = null,

Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName[] passNames,
ShaderPassName[] passNames,
RenderQueueRange? inRenderQueueRange = null,
RenderStateBlock? stateBlock = null,
RenderQueueRange? inRenderQueueRange = null,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
{
if (!m_CurrentDebugDisplaySettings.renderingDebugSettings.displayOpaqueObjects)

{
drawSettings.SetShaderPassName(i, passNames[i]);
}
if (overrideMaterial != null)
{
drawSettings.SetOverrideMaterial(overrideMaterial, 0);

void RenderTransparentRenderList( CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
RendererConfiguration rendererConfiguration = 0,
RendererConfiguration rendererConfiguration = 0,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
{

void RenderTransparentRenderList( CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
void RenderTransparentRenderList( CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
ShaderPassName[] passNames,
RendererConfiguration rendererConfiguration = 0,
ShaderPassName[] passNames,
RendererConfiguration rendererConfiguration = 0,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
{

rendererConfiguration = rendererConfiguration,
sorting = { flags = SortFlags.CommonTransparent }
};
for (int i = 0; i < passNames.Length; ++i)
{
drawSettings.SetShaderPassName(i, passNames[i]);

// RenderDepthPrepass render both opaque and opaque alpha tested based on engine configuration.
// Forward only renderer: We always render everything
// Deferred renderer: We render a depth prepass only if engine request it. We can decide if we render everything or only opaque alpha tested object.
// Forward opaque with deferred renderer (ForwardOnlyOpaqueDepthOnly pass): We always render everything
// Forward opaque with deferred renderer (ForwardOnlyOpaqueDepthOnly pass): We always render everything
void RenderDepthPrepass(CullResults cull, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
// Guidelines: To be able to switch from deferred to forward renderer we need to have forward opaque material with both DepthOnly and ForwardOnlyOpaqueDepthOnly pass.

if (addDepthPrepass == false && addForwardOnlyOpaqueDepthPrepass == false)
return;
using (new Utilities.ProfilingSample(addDepthPrepass ? "Depth Prepass" : "Depth Prepass forward opaque ", cmd))
using (new ProfilingSample(addDepthPrepass ? "Depth Prepass" : "Depth Prepass forward opaque ", cmd))
{
// Default depth prepass (forward and deferred) will render all opaque geometry.
RenderQueueRange renderQueueRange = RenderQueueRange.opaque;

// We render first the opaque object as opaque alpha tested are more costly to render and could be reject by early-z (but not Hi-z as it is disable with clip instruction)
// This is handeled automatically with the RenderQueue value (OpaqueAlphaTested have a different value and thus are sorted after Opaque)
Utilities.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
CoreUtils.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, addDepthPrepass ? HDShaderPassNames.m_DepthOnlyName : HDShaderPassNames.m_ForwardOnlyOpaqueDepthOnlyName, 0, renderQueueRange);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, addDepthPrepass ? HDShaderPassNames.m_DepthOnlyName : HDShaderPassNames.m_ForwardOnlyOpaqueDepthOnlyName, 0, renderQueueRange);
}
}

if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
return;
using (new Utilities.ProfilingSample(m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled() ? "GBufferDebugDisplay" : "GBuffer", cmd))
using (new ProfilingSample(m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled() ? "GBufferDebugDisplay" : "GBuffer", cmd))
Utilities.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
CoreUtils.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferDebugDisplayName, Utilities.kRendererConfigurationBakedLighting, RenderQueueRange.opaque, m_DepthStateOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferDebugDisplayName, HDUtils.k_RendererConfigurationBakedLighting, RenderQueueRange.opaque, m_DepthStateOpaque);
}
else
{

RenderQueueRange rangeOpaqueAlphaTest = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
// When using depth prepass for opaque alpha test only we need to use regular depth test for normal opaque objects.
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferName, Utilities.kRendererConfigurationBakedLighting, rangeOpaqueNoAlphaTest, m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass ? m_DepthStateOpaque : m_DepthStateOpaqueWithPrepass);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferName, HDUtils.k_RendererConfigurationBakedLighting, rangeOpaqueNoAlphaTest, m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass ? m_DepthStateOpaque : m_DepthStateOpaqueWithPrepass);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferWithPrepassName, Utilities.kRendererConfigurationBakedLighting, rangeOpaqueAlphaTest, m_DepthStateOpaqueWithPrepass);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferWithPrepassName, HDUtils.k_RendererConfigurationBakedLighting, rangeOpaqueAlphaTest, m_DepthStateOpaqueWithPrepass);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferName, Utilities.kRendererConfigurationBakedLighting, RenderQueueRange.opaque, m_DepthStateOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferName, HDUtils.k_RendererConfigurationBakedLighting, RenderQueueRange.opaque, m_DepthStateOpaque);
}
}
}

{
using (new Utilities.ProfilingSample("DisplayDebug ViewMaterial", cmd))
using (new ProfilingSample("DisplayDebug ViewMaterial", cmd))
using (new Utilities.ProfilingSample("DebugViewMaterialGBuffer", cmd))
using (new ProfilingSample("DebugViewMaterialGBuffer", cmd))
Utilities.DrawFullScreen(cmd, m_DebugViewMaterialGBuffer, m_CameraColorBufferRT);
CoreUtils.DrawFullScreen(cmd, m_DebugViewMaterialGBuffer, m_CameraColorBufferRT);
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, Utilities.kClearAll, Color.black);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.All, Color.black);
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.m_ForwardDisplayDebugName, Utilities.kRendererConfigurationBakedLighting);
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.m_ForwardDisplayDebugName, HDUtils.k_RendererConfigurationBakedLighting);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.m_ForwardDisplayDebugName, Utilities.kRendererConfigurationBakedLighting);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.m_ForwardDisplayDebugName, HDUtils.k_RendererConfigurationBakedLighting);
using (new Utilities.ProfilingSample("Blit DebugView Material Debug", cmd))
using (new ProfilingSample("Blit DebugView Material Debug", cmd))
{
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget);
}

if (!m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission || m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
return;
using (new Utilities.ProfilingSample("Subsurface Scattering", cmd))
using (new ProfilingSample("Subsurface Scattering", cmd))
{
if (sssSettings.useDisneySSS)
{

cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
// Combine diffuse and specular lighting into 'm_CameraColorBufferRT'.
Utilities.DrawFullScreen(cmd, m_CombineLightingPass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
CoreUtils.DrawFullScreen(cmd, m_CombineLightingPass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
}
else
{

m_SssVerticalFilterPass.SetVectorArray(HDShaderIDs._HalfRcpWeightedVariances, sssParameters.halfRcpWeightedVariances);
// Perform the vertical SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
Utilities.DrawFullScreen(cmd, m_SssVerticalFilterPass, m_CameraFilteringBufferRT, m_CameraDepthStencilBufferRT);
CoreUtils.DrawFullScreen(cmd, m_SssVerticalFilterPass, m_CameraFilteringBufferRT, m_CameraDepthStencilBufferRT);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
m_SssHorizontalFilterAndCombinePass.SetVectorArray(HDShaderIDs._WorldScales, sssParameters.worldScales);

Utilities.DrawFullScreen(cmd, m_SssHorizontalFilterAndCombinePass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
CoreUtils.DrawFullScreen(cmd, m_SssHorizontalFilterAndCombinePass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
}
}
}

profileName = addForwardPass ? (renderOpaque ? "Forward Opaque" : "Forward Transparent") : "Forward Only Opaque";
}
using (new Utilities.ProfilingSample(profileName, cmd))
using (new ProfilingSample(profileName, cmd))
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
m_LightLoop.RenderForward(camera, cmd, renderOpaque);

if (renderOpaque)
{
// Forward opaque material always have a prepass (whether or not we use deferred) so we pass the right depth state here.
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, arrayNames, Utilities.kRendererConfigurationBakedLighting, null, m_DepthStateOpaqueWithPrepass);
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, arrayNames, HDUtils.k_RendererConfigurationBakedLighting, null, m_DepthStateOpaqueWithPrepass);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, arrayNames, Utilities.kRendererConfigurationBakedLighting);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, arrayNames, HDUtils.k_RendererConfigurationBakedLighting);
}
}
}

void RenderForwardError(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd, bool renderOpaque)
{
using (new Utilities.ProfilingSample("Render Forward Error", cmd))
using (new ProfilingSample("Render Forward Error", cmd))
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
ShaderPassName[] arrayNames = { HDShaderPassNames.m_AlwaysName, HDShaderPassNames.m_ForwardBaseName, HDShaderPassNames.m_DeferredName, HDShaderPassNames.m_PrepassBaseName, HDShaderPassNames.m_VertexName, HDShaderPassNames.m_VertexLMRGBMName, HDShaderPassNames.m_VertexLMName };

void RenderVelocity(CullResults cullResults, HDCamera hdcam, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
using (new Utilities.ProfilingSample("Velocity", cmd))
using (new ProfilingSample("Velocity", cmd))
{
// If opaque velocity have been render during GBuffer no need to render it here
// TODO: Currently we can't render velocity vector into GBuffer, neither during forward pass (in case of forward opaque), so it is always a separate pass

m_CameraMotionVectorsMaterial.SetVector(HDShaderIDs._CameraPosDiff, hdcam.prevCameraPos - hdcam.cameraPos);
cmd.GetTemporaryRT(m_VelocityBuffer, w, h, 0, FilterMode.Point, Builtin.GetVelocityBufferFormat(), Builtin.GetVelocityBufferReadWrite());
Utilities.DrawFullScreen(cmd, m_CameraMotionVectorsMaterial, m_VelocityBufferRT, null, 0);
CoreUtils.DrawFullScreen(cmd, m_CameraMotionVectorsMaterial, m_VelocityBufferRT, null, 0);
cmd.SetRenderTarget(m_VelocityBufferRT, m_CameraDepthStencilBufferRT);
RenderOpaqueRenderList(cullResults, hdcam.camera, renderContext, cmd, HDShaderPassNames.m_MotionVectorsName, RendererConfiguration.PerObjectMotionVectors);

if (!m_CurrentDebugDisplaySettings.renderingDebugSettings.enableDistortion)
return;
using (new Utilities.ProfilingSample("Distortion", cmd))
using (new ProfilingSample("Distortion", cmd))
{
int w = camera.pixelWidth;
int h = camera.pixelHeight;

void RenderPostProcesses(Camera camera, CommandBuffer cmd, PostProcessLayer layer)
{
using (new Utilities.ProfilingSample("Post-processing", cmd))
using (new ProfilingSample("Post-processing", cmd))
if (Utilities.IsPostProcessingActive(layer))
if (CoreUtils.IsPostProcessingActive(layer))
{
cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, GetDepthTexture());
cmd.SetGlobalTexture(HDShaderIDs._CameraMotionVectorsTexture, m_VelocityBufferRT);

if (camera.camera.cameraType == CameraType.Reflection || camera.camera.cameraType == CameraType.Preview)
return;
using (new Utilities.ProfilingSample("Render Debug", cmd))
using (new ProfilingSample("Render Debug", cmd))
Utilities.SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget, m_CameraDepthStencilBufferRT);
CoreUtils.SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget, m_CameraDepthStencilBufferRT);
// First render full screen debug texture
if (m_CurrentDebugDisplaySettings.fullScreenDebugMode != FullScreenDebugMode.None && m_FullScreenDebugPushed)

m_DebugFullScreen.SetFloat(HDShaderIDs._FullScreenDebugMode, (float)m_CurrentDebugDisplaySettings.fullScreenDebugMode);
Utilities.DrawFullScreen(cmd, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
CoreUtils.DrawFullScreen(cmd, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
}
// Then overlays

m_SharedPropertyBlock.SetFloat(HDShaderIDs._Mipmap, lightingDebug.skyReflectionMipmap);
cmd.SetViewport(new Rect(x, y, overlaySize, overlaySize));
cmd.DrawProcedural(Matrix4x4.identity, m_DebugDisplayLatlong, 0, MeshTopology.Triangles, 3, 1, m_SharedPropertyBlock);
Utilities.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, camera.camera.pixelWidth);
HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, camera.camera.pixelWidth);
}
m_LightLoop.RenderDebugOverlay(camera.camera, cmd, m_CurrentDebugDisplaySettings, ref x, ref y, overlaySize, camera.camera.pixelWidth);

void InitAndClearBuffer(HDCamera camera, CommandBuffer cmd)
{
using (new Utilities.ProfilingSample("InitAndClearBuffer", cmd))
using (new ProfilingSample("InitAndClearBuffer", cmd))
using (new Utilities.ProfilingSample("InitGBuffers and clear Depth/Stencil", cmd))
using (new ProfilingSample("InitGBuffers and clear Depth/Stencil", cmd))
{
// Init buffer
// With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).

m_gbufferManager.InitGBuffers(w, h, cmd);
}
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearDepth);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.Depth);
using (new Utilities.ProfilingSample("Clear SSS diffuse target", cmd))
using (new ProfilingSample("Clear SSS diffuse target", cmd))
Utilities.SetRenderTarget(cmd, m_CameraSssDiffuseLightingBufferRT, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_CameraSssDiffuseLightingBufferRT, ClearFlag.Color, Color.black);
}
// Old SSS Model >>>

using (new Utilities.ProfilingSample("Clear SSS filtering target", cmd))
using (new ProfilingSample("Clear SSS filtering target", cmd))
Utilities.SetRenderTarget(cmd, m_CameraFilteringBuffer, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_CameraFilteringBuffer, ClearFlag.Color, Color.black);
}
}
// <<< Old SSS Model

using (new Utilities.ProfilingSample("Clear stencil texture", cmd))
using (new ProfilingSample("Clear stencil texture", cmd))
Utilities.SetRenderTarget(cmd, m_CameraStencilBufferCopyRT, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_CameraStencilBufferCopyRT, ClearFlag.Color, Color.black);
using (new Utilities.ProfilingSample("Clear HTile", cmd))
using (new ProfilingSample("Clear HTile", cmd))
Utilities.SetRenderTarget(cmd, m_HTileRT, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_HTileRT, ClearFlag.Color, Color.black);
}
}

// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// Clear the HDR target
using (new Utilities.ProfilingSample("Clear HDR target", cmd))
using (new ProfilingSample("Clear HDR target", cmd))
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.Color, Color.black);
using (new Utilities.ProfilingSample("Clear GBuffer", cmd))
using (new ProfilingSample("Clear GBuffer", cmd))
Utilities.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT, ClearFlag.Color, Color.black);
}
}
// END TEMP

2
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.cs


static void CreateHDRenderPipeline()
{
var instance = CreateInstance<HDRenderPipelineAsset>();
AssetDatabase.CreateAsset(instance, Utilities.GetHDRenderPipelinePath() + "HDRenderPipelineAsset.asset");
AssetDatabase.CreateAsset(instance, HDUtils.GetHDRenderPipelinePath() + "HDRenderPipelineAsset.asset");
// If it exist, load renderPipelineResources
instance.renderPipelineResources = AssetDatabase.LoadAssetAtPath<RenderPipelineResources>(RenderPipelineResources.GetRenderPipelineResourcesPath());

17
ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.cs


return RenderTextureFormat.Default;
}
public ScreenSpaceAmbientOcclusionEffect()
{}
m_Material = Utilities.CreateEngineMaterial(renderPipelineResources.screenSpaceAmbientOcclusionShader);
m_Material = CoreUtils.CreateEngineMaterial(renderPipelineResources.screenSpaceAmbientOcclusionShader);
m_Material.hideFlags = HideFlags.DontSave;
}

m_Material.SetFloat(Uniforms._Downsample, 1.0f / downsize);
m_Material.SetFloat(Uniforms._SampleCount, settings.sampleCount);
using (new Utilities.ProfilingSample("Screenspace ambient occlusion", cmd))
using (new ProfilingSample("Screenspace ambient occlusion", cmd))
Utilities.DrawFullScreen(cmd, m_Material, Uniforms._TempTex1, null, 0);
CoreUtils.DrawFullScreen(cmd, m_Material, Uniforms._TempTex1, null, 0);
Utilities.DrawFullScreen(cmd, m_Material, Uniforms._TempTex2, null, 1);
CoreUtils.DrawFullScreen(cmd, m_Material, Uniforms._TempTex2, null, 1);
Utilities.DrawFullScreen(cmd, m_Material, Uniforms._TempTex1, null, 2);
CoreUtils.DrawFullScreen(cmd, m_Material, Uniforms._TempTex1, null, 2);
Utilities.DrawFullScreen(cmd, m_Material, HDShaderIDs._AmbientOcclusionTexture, null, 3);
CoreUtils.DrawFullScreen(cmd, m_Material, HDShaderIDs._AmbientOcclusionTexture, null, 3);
cmd.ReleaseTemporaryRT(Uniforms._TempTex1);
// Setup texture for lighting pass (automatic of unity)

public void Cleanup()
{
Utilities.Destroy(m_Material);
CoreUtils.Destroy(m_Material);
}
}
}

881
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using UnityEditor.Experimental.Rendering;
using System.Linq;
[CustomEditorForRenderPipeline(typeof(Light), typeof(HDRenderPipelineAsset))]
// TODO: Simplify this editor once we can target 2018.1
public class HDLightEditor : Editor
[CustomEditorForRenderPipeline(typeof(Light), typeof(HDRenderPipelineAsset))]
sealed partial class HDLightEditor : LightEditor
// Original light editor
SerializedProperty m_Type;
SerializedProperty m_Range;
SerializedProperty m_SpotAngle;
SerializedProperty m_CookieSize;
SerializedProperty m_Color;
SerializedProperty m_Intensity;
SerializedProperty m_BounceIntensity;
SerializedProperty m_ColorTemperature;
SerializedProperty m_UseColorTemperature;
SerializedProperty m_Cookie;
SerializedProperty m_ShadowsType;
SerializedProperty m_ShadowsStrength;
SerializedProperty m_ShadowsResolution;
SerializedProperty m_ShadowsBias;
SerializedProperty m_ShadowsNormalBias;
SerializedProperty m_ShadowsNearPlane;
SerializedProperty m_Flare;
SerializedProperty m_RenderMode;
SerializedProperty m_CullingMask;
SerializedProperty m_Lightmapping;
SerializedProperty m_AreaSizeX;
SerializedProperty m_AreaSizeY;
SerializedProperty m_BakedShadowRadius;
SerializedProperty m_BakedShadowAngle;
sealed class SerializedBaseData
{
public SerializedProperty type;
public SerializedProperty range;
public SerializedProperty spotAngle;
public SerializedProperty cookie;
public SerializedProperty cookieSize;
public SerializedProperty color;
public SerializedProperty intensity;
public SerializedProperty bounceIntensity;
public SerializedProperty colorTemperature;
public SerializedProperty useColorTemperature;
public SerializedProperty shadowsType;
public SerializedProperty shadowsBias;
public SerializedProperty shadowsNormalBias;
public SerializedProperty shadowsNearPlane;
public SerializedProperty lightmapping;
public SerializedProperty areaSizeX;
public SerializedProperty areaSizeY;
public SerializedProperty bakedShadowRadius;
public SerializedProperty bakedShadowAngle;
}
sealed class SerializedLightData
{
public SerializedProperty spotInnerPercent;
public SerializedProperty lightDimmer;
public SerializedProperty fadeDistance;
public SerializedProperty affectDiffuse;
public SerializedProperty affectSpecular;
public SerializedProperty lightTypeExtent;
public SerializedProperty spotLightShape;
public SerializedProperty shapeLength;
public SerializedProperty shapeWidth;
public SerializedProperty shapeRadius;
public SerializedProperty maxSmoothness;
public SerializedProperty applyRangeAttenuation;
// Editor stuff
public SerializedProperty useOldInspector;
public SerializedProperty showFeatures;
public SerializedProperty showAdditionalSettings;
}
// HD Light editor part
SerializedObject additionalDataSerializedObject;
SerializedObject shadowDataSerializedObject;
sealed class SerializedShadowData
{
public SerializedProperty dimmer;
public SerializedProperty fadeDistance;
public SerializedProperty cascadeCount;
public SerializedProperty cascadeRatios;
public SerializedProperty cascadeBorders;
public SerializedProperty resolution;
}
SerializedProperty m_SpotInnerPercent;
SerializedProperty m_LightDimmer;
SerializedProperty m_FadeDistance;
SerializedProperty m_AffectDiffuse;
SerializedProperty m_AffectSpecular;
SerializedProperty m_LightTypeExtent;
SerializedProperty m_SpotLightShape;
SerializedProperty m_ShapeLength;
SerializedProperty m_ShapeWidth;
SerializedProperty m_ShapeRadius;
SerializedProperty m_MaxSmoothness;
SerializedProperty m_ApplyRangeAttenuation;
SerializedObject m_SerializedAdditionalLightData;
SerializedObject m_SerializedAdditionalShadowData;
// Extra data for GUI only
SerializedProperty m_UseOldInspector;
SerializedProperty m_ShowAdditionalSettings;
SerializedBaseData m_BaseData;
SerializedLightData m_AdditionalLightData;
SerializedShadowData m_AdditionalShadowData;
SerializedProperty m_ShadowDimmer;
SerializedProperty m_ShadowFadeDistance;
SerializedProperty m_ShadowCascadeCount;
SerializedProperty m_ShadowCascadeRatios;
SerializedProperty m_ShadowCascadeBorders;
SerializedProperty m_ShadowResolution;
// Copied over from teh original LightEditor class. Will go away once we can target 2018.1
bool m_TypeIsSame { get { return !m_BaseData.type.hasMultipleDifferentValues; } }
bool m_LightmappingTypeIsSame { get { return !m_BaseData.lightmapping.hasMultipleDifferentValues; } }
bool m_IsCompletelyBaked { get { return m_BaseData.lightmapping.intValue == 2; } }
bool m_IsRealtime { get { return m_BaseData.lightmapping.intValue == 4; } }
Light light { get { return serializedObject.targetObject as Light; } }
Texture m_Cookie { get { return m_BaseData.cookie.objectReferenceValue as Texture; } }
bool m_BakingWarningValue { get { return !Lightmapping.bakedGI && m_LightmappingTypeIsSame && !m_IsRealtime; } }
bool m_BounceWarningValue
{
get
{
return m_TypeIsSame && (light.type == LightType.Point || light.type == LightType.Spot) &&
m_LightmappingTypeIsSame && m_IsRealtime && !m_BaseData.bounceIntensity.hasMultipleDifferentValues
&& m_BaseData.bounceIntensity.floatValue > 0.0f;
}
}
public bool cookieWarningValue
{
get
{
return m_TypeIsSame && light.type == LightType.Spot &&
!m_BaseData.cookie.hasMultipleDifferentValues && m_Cookie && m_Cookie.wrapMode != TextureWrapMode.Clamp;
}
}
// This enum below is LightType enum + LightTypeExtent enum
public enum LightShape
// LightType + LightTypeExtent combined
enum LightShape
//Area, <= offline type of Unity not dispay in our case but reuse for GI of our area light
//Area, <= offline base type not displayed in our case but used for GI of our area light
// Sphere,
// Disc,
//Sphere,
//Disc,
// LightShape is use for displaying UI only. The processing code must use LightTypeExtent and LightType
// Used for UI only; the processing code must use LightTypeExtent and LightType
private Light light { get { return target as Light; } }
// Note: There is no Lightmapping enum, the code C# side must use int
// Light.h file: int m_Lightmapping; ///< enum { Dynamic=4, Stationary=1, Static=2 }
// Lighting.h file:
// enum LightmapBakeType (not accessible in C#)
//{
// kLightRealtime = 1 << 2, // Light is realtime
// kLightBaked = 1 << 1, // light will always be fully baked
// kLightMixed = 1 << 0, // depends on selected LightmapMixedBakeMode
//};
// This mean that m_Lightmapping.enumValueIndex is enum { Mixed=0, Baked=1, Realtime=2 }
enum LightMappingType
void OnEnable()
Mixed,
Baked,
Realtime
}
// Get & automatically add additional HD data if not present
var lightData = GetAdditionalData<HDAdditionalLightData>();
var shadowData = GetAdditionalData<AdditionalShadowData>();
m_SerializedAdditionalLightData = new SerializedObject(lightData);
m_SerializedAdditionalShadowData = new SerializedObject(shadowData);
protected class Styles
{
public static GUIContent CookieSizeX = new GUIContent("CookieSizeX", "");
public static GUIContent CookieSizeY = new GUIContent("CookieSizeY", "");
// Grab all the serialized data we need
m_BaseData = new SerializedBaseData
{
type = serializedObject.FindProperty("m_Type"),
range = serializedObject.FindProperty("m_Range"),
spotAngle = serializedObject.FindProperty("m_SpotAngle"),
cookie = serializedObject.FindProperty("m_Cookie"),
cookieSize = serializedObject.FindProperty("m_CookieSize"),
color = serializedObject.FindProperty("m_Color"),
intensity = serializedObject.FindProperty("m_Intensity"),
bounceIntensity = serializedObject.FindProperty("m_BounceIntensity"),
colorTemperature = serializedObject.FindProperty("m_ColorTemperature"),
useColorTemperature = serializedObject.FindProperty("m_UseColorTemperature"),
shadowsType = serializedObject.FindProperty("m_Shadows.m_Type"),
shadowsBias = serializedObject.FindProperty("m_Shadows.m_Bias"),
shadowsNormalBias = serializedObject.FindProperty("m_Shadows.m_NormalBias"),
shadowsNearPlane = serializedObject.FindProperty("m_Shadows.m_NearPlane"),
lightmapping = serializedObject.FindProperty("m_Lightmapping"),
areaSizeX = serializedObject.FindProperty("m_AreaSize.x"),
areaSizeY = serializedObject.FindProperty("m_AreaSize.y"),
bakedShadowRadius = serializedObject.FindProperty("m_ShadowRadius"),
bakedShadowAngle = serializedObject.FindProperty("m_ShadowAngle")
};
public static GUIContent ShapeLengthLine = new GUIContent("Length", "Length of the line light");
public static GUIContent ShapeLengthRect = new GUIContent("SizeX", "SizeX of the rectangle light");
public static GUIContent ShapeWidthRect = new GUIContent("SizeY", "SizeY of the rectangle light");
using (var o = new PropertyFetcher<HDAdditionalLightData>(m_SerializedAdditionalLightData))
m_AdditionalLightData = new SerializedLightData
{
spotInnerPercent = o.FindProperty(x => x.m_InnerSpotPercent),
lightDimmer = o.FindProperty(x => x.lightDimmer),
fadeDistance = o.FindProperty(x => x.fadeDistance),
affectDiffuse = o.FindProperty(x => x.affectDiffuse),
affectSpecular = o.FindProperty(x => x.affectSpecular),
lightTypeExtent = o.FindProperty(x => x.lightTypeExtent),
spotLightShape = o.FindProperty(x => x.spotLightShape),
shapeLength = o.FindProperty(x => x.shapeLength),
shapeWidth = o.FindProperty(x => x.shapeWidth),
shapeRadius = o.FindProperty(x => x.shapeRadius),
maxSmoothness = o.FindProperty(x => x.maxSmoothness),
applyRangeAttenuation = o.FindProperty(x => x.applyRangeAttenuation),
public static GUIContent ShapeLengthPyramid = new GUIContent("SizeX", "");
public static GUIContent ShapeWidthPyramid = new GUIContent("SizeY", "");
public static GUIContent ShapeLengthBox = new GUIContent("SizeX", "");
public static GUIContent ShapeWidthBox = new GUIContent("SizeY", "");
public static GUIContent MaxSmoothness = new GUIContent("MaxSmoothness", "Very low cost way of faking spherical area lighting. This will modify the roughness of the material lit. This is useful when the specular highlight is too small or too sharp.");
public static GUIContent SpotLightShape = new GUIContent("SpotLightShape", "The shape use for the spotlight. Has an impact on the cookie transformation and light angular attenuation.");
// Editor stuff
useOldInspector = o.FindProperty(x => x.useOldInspector),
showFeatures = o.FindProperty(x => x.featuresFoldout),
showAdditionalSettings = o.FindProperty(x => x.showAdditionalSettings)
};
public static GUIContent SpotAngle = new GUIContent("Spot Angle", "Controls the angle in degrees at the base of a Spot light's cone.");
public static GUIContent SpotInnerPercent = new GUIContent("Spot Inner Percent", "Controls size of the angular attenuation in percent of the base angle of the Spot light's cone.");
// TODO: Review this once AdditionalShadowData is refactored
using (var o = new PropertyFetcher<AdditionalShadowData>(m_SerializedAdditionalShadowData))
m_AdditionalShadowData = new SerializedShadowData
{
dimmer = o.FindProperty(x => x.shadowDimmer),
fadeDistance = o.FindProperty(x => x.shadowFadeDistance),
cascadeCount = o.FindProperty("shadowCascadeCount"),
cascadeRatios = o.FindProperty("shadowCascadeRatios"),
cascadeBorders = o.FindProperty("shadowCascadeBorders"),
resolution = o.FindProperty(x => x.shadowResolution)
};
}
public static GUIContent Color = new GUIContent("Color", "Controls the color being emitted by the light.");
public static GUIContent Intensity = new GUIContent("Intensity", "Controls the brightness of the light. Light color is multiplied by this value.");
public static GUIContent Range = new GUIContent("Range", "Controls how far the light is emitted from the center of the object.");
public static GUIContent LightmappingMode = new GUIContent("Mode", "Specifies the light mode used to determine if and how a light will be baked. Possible modes are Baked, Mixed, and Realtime.");
public static GUIContent BounceIntensity = new GUIContent("Indirect Multiplier", "Controls the intensity of indirect light being contributed to the scene. A value of 0 will cause Realtime lights to be removed from realtime global illumination and Baked and Mixed lights to no longer emit indirect lighting. Has no effect when both Realtime and Baked Global Illumination are disabled.");
public static GUIContent Cookie = new GUIContent("Cookie", "Specifies the Texture projected by the light. Spotlights require 2D texture and pointlights require texture cube.");
public static GUIContent BakedShadowRadius = new GUIContent("Baked Shadow Radius", "Controls the amount of artificial softening applied to the edges of shadows cast by the Point or Spot light.");
public static GUIContent BakedShadowAngle = new GUIContent("Baked Shadow Angle", "Controls the amount of artificial softening applied to the edges of shadows cast by directional lights.");
public static GUIContent ShadowResolution = new GUIContent("Resolution", "Controls the rendered resolution of the shadow maps. A higher resolution will increase the fidelity of shadows at the cost of GPU performance and memory usage.");
public static GUIContent ShadowBias = new GUIContent("Bias", "Controls the distance at which the shadows will be pushed away from the light. Useful for avoiding false self-shadowing artifacts.");
public static GUIContent ShadowNormalBias = new GUIContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts.");
public static GUIContent ShadowNearPlane = new GUIContent("Near Plane", "Controls the value for the near clip plane when rendering shadows. Currently clamped to 0.1 units or 1% of the lights range property, whichever is lower.");
public static GUIContent ShadowCascadeCount = new GUIContent("ShadowCascadeCount", "");
public static GUIContent[] ShadowCascadeRatios = new GUIContent[6] { new GUIContent("Cascade 1"), new GUIContent("Cascade 2"), new GUIContent("Cascade 3"), new GUIContent("Cascade 4"), new GUIContent("Cascade 5"), new GUIContent("Cascade 6") };
public static GUIContent AffectDiffuse = new GUIContent("AffectDiffuse", "This will disable diffuse lighting for this light. Doesn't save performance, diffuse lighting is still computed.");
public static GUIContent AffectSpecular = new GUIContent("AffectSpecular", "This will disable specular lighting for this light. Doesn't save performance, specular lighting is still computed.");
public static GUIContent FadeDistance = new GUIContent("FadeDistance", "The distance at which the light will smoothly fade before being culled to minimize popping.");
public static GUIContent LightDimmer = new GUIContent("LightDimmer", "Aim to be used with script, timeline or animation. It allows dimming one or multiple lights of heterogeneous intensity easily (without needing to know the intensity of each light).");
public static GUIContent ApplyRangeAttenuation = new GUIContent("ApplyRangeAttenuation", "Allows disabling range attenuation. This is useful indoor (like a room) to avoid having to setup a large range for a light to get correct inverse square attenuation that may leak out of the indoor");
public static GUIContent ShadowFadeDistance = new GUIContent("ShadowFadeDistance", "The shadow will fade at distance ShadowFadeDistance before being culled to minimize popping.");
public static GUIContent ShadowDimmer = new GUIContent("ShadowDimmer", "Aim to be use with script, timeline or animation. It allows dimming one or multiple shadows. This can also be used as an optimization to fit in shadow budget manually and minimize popping.");
public override void OnInspectorGUI()
{
m_SerializedAdditionalLightData.Update();
m_SerializedAdditionalShadowData.Update();
public static GUIContent DisabledLightWarning = new GUIContent("Lighting has been disabled in at least one Scene view. Any changes applied to lights in the Scene will not be updated in these views until Lighting has been enabled again.");
public static GUIContent CookieWarning = new GUIContent("Cookie textures for spot lights must be set to clamp. Repeat is not supported.");
public static GUIContent IndirectBounceShadowWarning = new GUIContent("Realtime indirect bounce shadowing is not supported for Spot and Point lights.");
public static GUIContent BakingWarning = new GUIContent("Light mode is currently overridden to Realtime mode. Enable Baked Global Illumination to use Mixed or Baked light modes.");
// Temporary toggle to go back to the old editor & separated additional datas
bool useOldInspector = m_AdditionalLightData.useOldInspector.boolValue;
public static string lightShapeText = "LightShape";
public static readonly string[] lightShapeNames = Enum.GetNames(typeof(LightShape));
if (GUILayout.Button("Toggle default light editor"))
useOldInspector = !useOldInspector;
public static string lightmappingModeText = "Mode";
public static readonly string[] lightmappingModeNames = Enum.GetNames(typeof(LightMappingType));
}
m_AdditionalLightData.useOldInspector.boolValue = useOldInspector;
static Styles s_Styles;
if (useOldInspector)
{
DrawDefaultInspector();
ApplyAdditionalComponentsVisibility(false);
m_SerializedAdditionalShadowData.ApplyModifiedProperties();
m_SerializedAdditionalLightData.ApplyModifiedProperties();
return;
}
// Should match same colors in GizmoDrawers.cpp!
static Color kGizmoLight = new Color(254 / 255f, 253 / 255f, 136 / 255f, 128 / 255f);
static Color kGizmoDisabledLight = new Color(135 / 255f, 116 / 255f, 50 / 255f, 128 / 255f);
// New editor
ApplyAdditionalComponentsVisibility(true);
CheckStyles();
private bool typeIsSame { get { return !m_Type.hasMultipleDifferentValues; } }
private Texture cookie { get { return m_Cookie.objectReferenceValue as Texture; } }
serializedObject.Update();
private bool lightmappingTypeIsSame { get { return !m_Lightmapping.hasMultipleDifferentValues; } }
ResolveLightShape();
private bool isRealtime { get { return m_Lightmapping.enumValueIndex == (int)LightMappingType.Realtime; } }
DrawFoldout(m_AdditionalLightData.showFeatures, "Features", DrawFeatures);
DrawFoldout(m_BaseData.type, "Shape", DrawShape);
DrawFoldout(m_BaseData.intensity, "Light", DrawLightSettings);
private bool isBakedOrMixed { get { return !isRealtime; } }
if (m_BaseData.shadowsType.enumValueIndex != (int)LightShadows.None)
DrawFoldout(m_BaseData.shadowsType, "Shadows", DrawShadows);
private bool bakingWarningValue { get { return !Lightmapping.bakedGI && lightmappingTypeIsSame && isBakedOrMixed; } }
EditorLightUtilities.DrawSplitter();
EditorGUILayout.Space();
private bool cookieWarningValue
{
get
{
return typeIsSame && light.type == LightType.Spot &&
!m_Cookie.hasMultipleDifferentValues && cookie && cookie.wrapMode != TextureWrapMode.Clamp;
}
}
private bool bounceWarningValue
{
get
{
return typeIsSame && (light.type == LightType.Point || light.type == LightType.Spot) &&
lightmappingTypeIsSame && isRealtime && !m_BounceIntensity.hasMultipleDifferentValues && m_BounceIntensity.floatValue > 0.0f && m_ShadowsType.enumValueIndex != (int)LightShadows.None;
}
m_SerializedAdditionalShadowData.ApplyModifiedProperties();
m_SerializedAdditionalLightData.ApplyModifiedProperties();
serializedObject.ApplyModifiedProperties();
private void OnEnable()
void DrawFoldout(SerializedProperty foldoutProperty, string title, Action func)
m_Type = serializedObject.FindProperty("m_Type");
m_Range = serializedObject.FindProperty("m_Range");
m_SpotAngle = serializedObject.FindProperty("m_SpotAngle");
m_CookieSize = serializedObject.FindProperty("m_CookieSize");
m_Color = serializedObject.FindProperty("m_Color");
m_Intensity = serializedObject.FindProperty("m_Intensity");
m_BounceIntensity = serializedObject.FindProperty("m_BounceIntensity");
m_ColorTemperature = serializedObject.FindProperty("m_ColorTemperature");
m_UseColorTemperature = serializedObject.FindProperty("m_UseColorTemperature");
m_Cookie = serializedObject.FindProperty("m_Cookie");
m_ShadowsType = serializedObject.FindProperty("m_Shadows.m_Type");
m_ShadowsStrength = serializedObject.FindProperty("m_Shadows.m_Strength");
m_ShadowsResolution = serializedObject.FindProperty("m_Shadows.m_Resolution");
m_ShadowsBias = serializedObject.FindProperty("m_Shadows.m_Bias");
m_ShadowsNormalBias = serializedObject.FindProperty("m_Shadows.m_NormalBias");
m_ShadowsNearPlane = serializedObject.FindProperty("m_Shadows.m_NearPlane");
m_Flare = serializedObject.FindProperty("m_Flare");
m_RenderMode = serializedObject.FindProperty("m_RenderMode");
m_CullingMask = serializedObject.FindProperty("m_CullingMask");
m_Lightmapping = serializedObject.FindProperty("m_Lightmapping");
m_AreaSizeX = serializedObject.FindProperty("m_AreaSize.x");
m_AreaSizeY = serializedObject.FindProperty("m_AreaSize.y");
m_BakedShadowRadius = serializedObject.FindProperty("m_ShadowRadius");
m_BakedShadowAngle = serializedObject.FindProperty("m_ShadowAngle");
EditorLightUtilities.DrawSplitter();
// Automatically add HD data if not present
// We need to handle multiSelection. To do this we need to get the array of selection and assign it to additionalDataSerializedObject
// additionalDataSerializedObject must be see as an array of selection in all following operation (this is transparent)
bool state = foldoutProperty.isExpanded;
state = EditorLightUtilities.DrawHeaderFoldout(title, state);
var additionalDatas = this.targets.Select(t => (t as Component).GetComponent<HDAdditionalLightData>()).ToArray();
var shadowDatas = this.targets.Select(t => (t as Component).GetComponent<AdditionalShadowData>()).ToArray();
for (int i = 0; i < additionalDatas.Length; ++i)
{
if (additionalDatas[i] == null)
{
additionalDatas[i] = Undo.AddComponent<HDAdditionalLightData>((targets[i] as Component).gameObject);
}
}
for (int i = 0; i < shadowDatas.Length; ++i)
if (state)
if (shadowDatas[i] == null)
{
shadowDatas[i] = Undo.AddComponent<AdditionalShadowData>((targets[i] as Component).gameObject);
}
EditorGUI.indentLevel++;
func();
EditorGUI.indentLevel--;
GUILayout.Space(2f);
additionalDataSerializedObject = new SerializedObject(additionalDatas);
shadowDataSerializedObject = new SerializedObject(shadowDatas);
// Additional data
m_SpotInnerPercent = additionalDataSerializedObject.FindProperty("m_InnerSpotPercent");
m_LightDimmer = additionalDataSerializedObject.FindProperty("lightDimmer");
m_FadeDistance = additionalDataSerializedObject.FindProperty("fadeDistance");
m_AffectDiffuse = additionalDataSerializedObject.FindProperty("affectDiffuse");
m_AffectSpecular = additionalDataSerializedObject.FindProperty("affectSpecular");
m_LightTypeExtent = additionalDataSerializedObject.FindProperty("lightTypeExtent");
m_SpotLightShape = additionalDataSerializedObject.FindProperty("spotLightShape");
m_ShapeLength = additionalDataSerializedObject.FindProperty("shapeLength");
m_ShapeWidth = additionalDataSerializedObject.FindProperty("shapeWidth");
m_ShapeRadius = additionalDataSerializedObject.FindProperty("shapeRadius");
m_MaxSmoothness = additionalDataSerializedObject.FindProperty("maxSmoothness");
m_ApplyRangeAttenuation = additionalDataSerializedObject.FindProperty("applyRangeAttenuation");
// Editor only
m_UseOldInspector = additionalDataSerializedObject.FindProperty("useOldInspector");
m_ShowAdditionalSettings = additionalDataSerializedObject.FindProperty("showAdditionalSettings");
// Shadow data
m_ShadowDimmer = shadowDataSerializedObject.FindProperty("shadowDimmer");
m_ShadowFadeDistance = shadowDataSerializedObject.FindProperty("shadowFadeDistance");
m_ShadowCascadeCount = shadowDataSerializedObject.FindProperty("shadowCascadeCount");
m_ShadowCascadeRatios = shadowDataSerializedObject.FindProperty("shadowCascadeRatios");
m_ShadowCascadeBorders = shadowDataSerializedObject.FindProperty("shadowCascadeBorders");
m_ShadowResolution = shadowDataSerializedObject.FindProperty("shadowResolution");
foldoutProperty.isExpanded = state;
void ResolveLightShape()
void DrawFeatures()
// When we do multiple selection we must not avoid to chose a type, else it may corrupt light
if (m_Type.hasMultipleDifferentValues)
{
m_LightShape = (LightShape)(-1);
EditorGUILayout.PropertyField(m_AdditionalLightData.showAdditionalSettings);
return;
}
bool disabledScope = m_IsCompletelyBaked
|| m_LightShape == LightShape.Line
|| m_LightShape == LightShape.Rectangle;
if (m_LightTypeExtent.enumValueIndex == (int)LightTypeExtent.Punctual)
using (new EditorGUI.DisabledScope(disabledScope))
switch ((LightType)m_Type.enumValueIndex)
{
case LightType.Directional:
m_LightShape = LightShape.Directional;
break;
case LightType.Point:
m_LightShape = LightShape.Point;
break;
case LightType.Spot:
m_LightShape = LightShape.Spot;
break;
}
}
else
{
switch ((LightTypeExtent)m_LightTypeExtent.enumValueIndex)
{
case LightTypeExtent.Rectangle:
m_LightShape = LightShape.Rectangle;
break;
case LightTypeExtent.Line:
m_LightShape = LightShape.Line;
break;
}
bool shadowsEnabled = EditorGUILayout.Toggle(new GUIContent("Enable Shadows"), m_BaseData.shadowsType.enumValueIndex != 0);
m_BaseData.shadowsType.enumValueIndex = shadowsEnabled ? (int)LightShadows.Hard : (int)LightShadows.None;
void LigthShapeGUI()
void DrawShape()
m_LightShape = (LightShape)EditorGUILayout.Popup(Styles.lightShapeText, (int)m_LightShape, Styles.lightShapeNames);
m_LightShape = (LightShape)EditorGUILayout.Popup(s_Styles.shape, (int)m_LightShape, s_Styles.shapeNames);
// LightShape is HD specific, it need to drive LightType from the original LightType when it make sense, so the GI is still in sync with the light shape
// LightShape is HD specific, it need to drive LightType from the original LightType
// when it make sense, so the GI is still in sync with the light shape
m_Type.enumValueIndex = (int)LightType.Directional;
m_LightTypeExtent.enumValueIndex = (int)LightTypeExtent.Punctual;
m_BaseData.type.enumValueIndex = (int)LightType.Directional;
m_AdditionalLightData.lightTypeExtent.enumValueIndex = (int)LightTypeExtent.Punctual;
m_Type.enumValueIndex = (int)LightType.Point;
m_LightTypeExtent.enumValueIndex = (int)LightTypeExtent.Punctual;
EditorGUILayout.PropertyField(m_MaxSmoothness, Styles.MaxSmoothness);
m_BaseData.type.enumValueIndex = (int)LightType.Point;
m_AdditionalLightData.lightTypeExtent.enumValueIndex = (int)LightTypeExtent.Punctual;
EditorGUILayout.PropertyField(m_AdditionalLightData.maxSmoothness, s_Styles.maxSmoothness);
m_Type.enumValueIndex = (int)LightType.Spot;
m_LightTypeExtent.enumValueIndex = (int)LightTypeExtent.Punctual;
EditorGUILayout.PropertyField(m_SpotLightShape, Styles.SpotLightShape);
//Cone Spot
if (m_SpotLightShape.enumValueIndex == (int)SpotLightShape.Cone)
m_BaseData.type.enumValueIndex = (int)LightType.Spot;
m_AdditionalLightData.lightTypeExtent.enumValueIndex = (int)LightTypeExtent.Punctual;
EditorGUILayout.PropertyField(m_AdditionalLightData.spotLightShape, s_Styles.spotLightShape);
var spotLightShape = (SpotLightShape)m_AdditionalLightData.spotLightShape.enumValueIndex;
// Cone Spot
if (spotLightShape == SpotLightShape.Cone)
EditorGUILayout.Slider(m_SpotAngle, 1f, 179f, Styles.SpotAngle);
EditorGUILayout.Slider(m_SpotInnerPercent, 0f, 100f, Styles.SpotInnerPercent);
EditorGUILayout.Slider(m_BaseData.spotAngle, 0f, 179.9f, s_Styles.spotAngle);
EditorGUILayout.Slider(m_AdditionalLightData.spotInnerPercent, 0f, 100f, s_Styles.spotInnerPercent);
if (m_SpotLightShape.enumValueIndex == (int)SpotLightShape.Pyramid)
else if (spotLightShape == SpotLightShape.Pyramid)
EditorGUILayout.Slider(m_ShapeLength, 0.01f, 10, Styles.ShapeLengthPyramid);
EditorGUILayout.Slider(m_ShapeWidth, 0.01f, 10, Styles.ShapeWidthPyramid);
EditorGUILayout.Slider(m_AdditionalLightData.shapeLength, 0.01f, 10f, s_Styles.shapeLengthPyramid);
EditorGUILayout.Slider(m_AdditionalLightData.shapeWidth, 0.01f, 10f, s_Styles.shapeWidthPyramid);
if (m_SpotLightShape.enumValueIndex == (int)SpotLightShape.Box)
else if (spotLightShape == SpotLightShape.Box)
EditorGUILayout.PropertyField(m_ShapeLength, Styles.ShapeLengthBox);
EditorGUILayout.PropertyField(m_ShapeWidth, Styles.ShapeWidthBox);
EditorGUILayout.PropertyField(m_AdditionalLightData.shapeLength, s_Styles.shapeLengthBox);
EditorGUILayout.PropertyField(m_AdditionalLightData.shapeWidth, s_Styles.shapeWidthBox);
EditorGUILayout.PropertyField(m_MaxSmoothness, Styles.MaxSmoothness);
EditorGUILayout.PropertyField(m_AdditionalLightData.maxSmoothness, s_Styles.maxSmoothness);
//m_Type.enumValueIndex = (int)LightType.Area;
m_Type.enumValueIndex = (int)LightType.Point;
m_LightTypeExtent.enumValueIndex = (int)LightTypeExtent.Rectangle;
EditorGUILayout.PropertyField(m_ShapeLength, Styles.ShapeLengthRect);
EditorGUILayout.PropertyField(m_ShapeWidth, Styles.ShapeWidthRect);
m_AreaSizeX.floatValue = m_ShapeLength.floatValue;
m_AreaSizeY.floatValue = m_ShapeWidth.floatValue;
m_ShadowsType.enumValueIndex = (int)LightShadows.None;
//m_BaseData.type.enumValueIndex = (int)LightType.Area;
m_BaseData.type.enumValueIndex = (int)LightType.Point;
m_AdditionalLightData.lightTypeExtent.enumValueIndex = (int)LightTypeExtent.Rectangle;
EditorGUILayout.PropertyField(m_AdditionalLightData.shapeLength, s_Styles.shapeLengthRect);
EditorGUILayout.PropertyField(m_AdditionalLightData.shapeWidth, s_Styles.shapeWidthRect);
m_BaseData.areaSizeX.floatValue = m_AdditionalLightData.shapeLength.floatValue;
m_BaseData.areaSizeY.floatValue = m_AdditionalLightData.shapeWidth.floatValue;
m_BaseData.shadowsType.enumValueIndex = (int)LightShadows.None;
//m_Type.enumValueIndex = (int)LightType.Area;
m_Type.enumValueIndex = (int)LightType.Point;
m_LightTypeExtent.enumValueIndex = (int)LightTypeExtent.Line;
EditorGUILayout.PropertyField(m_ShapeLength, Styles.ShapeLengthLine);
//m_BaseData.type.enumValueIndex = (int)LightType.Area;
m_BaseData.type.enumValueIndex = (int)LightType.Point;
m_AdditionalLightData.lightTypeExtent.enumValueIndex = (int)LightTypeExtent.Line;
EditorGUILayout.PropertyField(m_AdditionalLightData.shapeLength, s_Styles.shapeLengthLine);
m_AreaSizeX.floatValue = m_ShapeLength.floatValue;
m_AreaSizeY.floatValue = 0.01f;
m_ShadowsType.enumValueIndex = (int)LightShadows.None;
m_BaseData.areaSizeX.floatValue = m_AdditionalLightData.shapeLength.floatValue;
m_BaseData.areaSizeY.floatValue = 0.01f;
m_BaseData.shadowsType.enumValueIndex = (int)LightShadows.None;
break;
case (LightShape)(-1):

}
}
void LightGUI()
void DrawLightSettings()
EditorGUILayout.PropertyField(m_Color, Styles.Color);
EditorGUILayout.PropertyField(m_Intensity, Styles.Intensity);
EditorGUILayout.PropertyField(m_BounceIntensity, Styles.BounceIntensity);
// Indirect shadows warning (Should be removed when we support realtime indirect shadows)
if (bounceWarningValue)
if (GraphicsSettings.lightsUseLinearIntensity && GraphicsSettings.lightsUseColorTemperature)
EditorGUILayout.HelpBox(Styles.IndirectBounceShadowWarning.text, MessageType.Info);
EditorGUILayout.PropertyField(m_BaseData.useColorTemperature, s_Styles.useColorTemperature);
if (m_BaseData.useColorTemperature.boolValue)
{
const float kMinKelvin = 1000f;
const float kMaxKelvin = 20000f;
EditorGUILayout.LabelField(s_Styles.color);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(m_BaseData.color, s_Styles.colorFilter);
EditorGUILayout.Slider(m_BaseData.colorTemperature, kMinKelvin, kMaxKelvin, s_Styles.colorTemperature);
EditorGUI.indentLevel -= 1;
}
else EditorGUILayout.PropertyField(m_BaseData.color, s_Styles.color);
EditorGUILayout.PropertyField(m_Range, Styles.Range);
else EditorGUILayout.PropertyField(m_BaseData.color, s_Styles.color);
// We need to overwrite the name of the default enum that doesn't make any sense
// EditorGUILayout.PropertyField(m_Lightmapping, Styles.LightmappingMode);
m_Lightmapping.enumValueIndex = EditorGUILayout.Popup(Styles.lightmappingModeText, (int)m_Lightmapping.enumValueIndex, Styles.lightmappingModeNames);
EditorGUILayout.PropertyField(m_BaseData.intensity, s_Styles.intensity);
EditorGUILayout.PropertyField(m_BaseData.bounceIntensity, s_Styles.lightBounceIntensity);
// Indirect shadows warning (Should be removed when we support realtime indirect shadows)
if (m_BounceWarningValue)
EditorGUILayout.HelpBox(s_Styles.indirectBounceShadowWarning.text, MessageType.Info);
EditorGUILayout.PropertyField(m_BaseData.range, s_Styles.range);
EditorGUILayout.PropertyField(m_BaseData.lightmapping, s_Styles.lightmappingMode);
if (bakingWarningValue)
{
EditorGUILayout.HelpBox(Styles.BakingWarning.text, MessageType.Info);
}
if (m_BakingWarningValue)
EditorGUILayout.HelpBox(s_Styles.bakingWarning.text, MessageType.Info);
// no cookie with area light (maybe in future textured area light ?)
if (!(m_LightShape == LightShape.Rectangle) && !(m_LightShape == LightShape.Line))
// No cookie with area light (maybe in future textured area light ?)
if (m_LightShape != LightShape.Rectangle && m_LightShape != LightShape.Line)
EditorGUILayout.PropertyField(m_Cookie, Styles.Cookie);
EditorGUILayout.PropertyField(m_BaseData.cookie, s_Styles.cookie);
// When directional light use a cookie, it can control the size
if (m_LightShape == LightShape.Directional)
{
EditorGUILayout.Slider(m_ShapeLength, 0.01f, 10, Styles.CookieSizeX);
EditorGUILayout.Slider(m_ShapeWidth, 0.01f, 10, Styles.CookieSizeY);
}
// Warn on spotlights if the cookie is set to repeat
{
// warn on spotlights if the cookie is set to repeat
EditorGUILayout.HelpBox(Styles.CookieWarning.text, MessageType.Warning);
}
}
}
EditorGUILayout.HelpBox(s_Styles.cookieWarning.text, MessageType.Warning);
void ShadowsGUI()
{
if (m_ShadowsType.enumValueIndex != (int)LightShadows.None)
{
if (m_Lightmapping.enumValueIndex == (int)LightMappingType.Baked)
{
switch ((LightType)m_Type.enumValueIndex)
{
case LightType.Directional:
EditorGUILayout.PropertyField(m_BakedShadowAngle, Styles.BakedShadowAngle);
break;
case LightType.Spot:
case LightType.Point:
EditorGUILayout.PropertyField(m_BakedShadowRadius, Styles.BakedShadowRadius);
break;
}
}
else
// When directional light use a cookie, it can control the size
if (m_Cookie != null && m_LightShape == LightShape.Directional)
EditorGUILayout.PropertyField(m_ShadowResolution, Styles.ShadowResolution);
EditorGUILayout.Slider(m_ShadowsBias, 0.001f, 1, Styles.ShadowBias);
EditorGUILayout.Slider(m_ShadowsNormalBias, 0.001f, 1, Styles.ShadowNormalBias);
EditorGUILayout.Slider(m_ShadowsNearPlane, 0.01f, 10, Styles.ShadowNearPlane);
EditorGUILayout.Slider(m_AdditionalLightData.shapeLength, 0.01f, 10f, s_Styles.cookieSizeX);
EditorGUILayout.Slider(m_AdditionalLightData.shapeWidth, 0.01f, 10f, s_Styles.cookieSizeY);
}
void ShadowsCascadeGUI()
{
UnityEditor.EditorGUI.BeginChangeCheck();
EditorGUILayout.IntSlider(m_ShadowCascadeCount, 1, 4, Styles.ShadowCascadeCount);
if (UnityEditor.EditorGUI.EndChangeCheck())
if (m_AdditionalLightData.showAdditionalSettings.boolValue)
m_ShadowCascadeRatios.arraySize = m_ShadowCascadeCount.intValue - 1;
m_ShadowCascadeBorders.arraySize = m_ShadowCascadeCount.intValue;
}
for (int i = 0; i < m_ShadowCascadeRatios.arraySize; i++)
{
UnityEditor.EditorGUILayout.Slider(m_ShadowCascadeRatios.GetArrayElementAtIndex(i), 0.0f, 1.0f, Styles.ShadowCascadeRatios[i]);
EditorGUILayout.LabelField("Additional Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_AdditionalLightData.affectDiffuse, s_Styles.affectDiffuse);
EditorGUILayout.PropertyField(m_AdditionalLightData.affectSpecular, s_Styles.affectSpecular);
EditorGUILayout.PropertyField(m_AdditionalLightData.fadeDistance, s_Styles.fadeDistance);
EditorGUILayout.PropertyField(m_AdditionalLightData.lightDimmer, s_Styles.lightDimmer);
EditorGUILayout.PropertyField(m_AdditionalLightData.applyRangeAttenuation, s_Styles.applyRangeAttenuation);
EditorGUI.indentLevel--;
void AdditionalSettingsGUI()
void DrawShadows()
// Currently culling mask is not working with HD
// EditorGUILayout.LabelField(new GUIContent("General"), EditorStyles.boldLabel);
// EditorGUILayout.PropertyField(m_CullingMask);
EditorGUILayout.LabelField(new GUIContent("Light"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_AffectDiffuse, Styles.AffectDiffuse);
EditorGUILayout.PropertyField(m_AffectSpecular, Styles.AffectSpecular);
EditorGUILayout.PropertyField(m_FadeDistance, Styles.FadeDistance);
EditorGUILayout.PropertyField(m_LightDimmer, Styles.LightDimmer);
EditorGUILayout.PropertyField(m_ApplyRangeAttenuation, Styles.ApplyRangeAttenuation);
if (m_ShadowsType.enumValueIndex != (int)LightShadows.None && m_Lightmapping.enumValueIndex != (int)LightMappingType.Baked)
if (m_IsCompletelyBaked)
EditorGUILayout.LabelField(new GUIContent("Shadows"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_ShadowFadeDistance, Styles.ShadowFadeDistance);
EditorGUILayout.PropertyField(m_ShadowDimmer, Styles.ShadowDimmer);
switch ((LightType)m_BaseData.type.enumValueIndex)
{
case LightType.Directional:
EditorGUILayout.Slider(m_BaseData.bakedShadowAngle, 0f, 90f, s_Styles.bakedShadowAngle);
break;
case LightType.Spot:
case LightType.Point:
EditorGUILayout.PropertyField(m_BaseData.bakedShadowRadius, s_Styles.bakedShadowRadius);
break;
}
return;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_AdditionalShadowData.resolution, s_Styles.shadowResolution);
EditorGUILayout.Slider(m_BaseData.shadowsBias, 0.001f, 1f, s_Styles.shadowBias);
EditorGUILayout.Slider(m_BaseData.shadowsNormalBias, 0.001f, 1f, s_Styles.shadowNormalBias);
EditorGUILayout.Slider(m_BaseData.shadowsNearPlane, 0.01f, 10f, s_Styles.shadowNearPlane);
// Sanity check
if (additionalDataSerializedObject == null || shadowDataSerializedObject == null)
if (m_BaseData.type.enumValueIndex != (int)LightType.Directional)
additionalDataSerializedObject.Update();
shadowDataSerializedObject.Update();
ResolveLightShape();
if (GUILayout.Button("Toggle light editor"))
using (var scope = new EditorGUI.ChangeCheckScope())
m_UseOldInspector.boolValue = !m_UseOldInspector.boolValue;
}
EditorGUILayout.IntSlider(m_AdditionalShadowData.cascadeCount, 1, 4, s_Styles.shadowCascadeCount);
EditorGUILayout.Space();
if (m_UseOldInspector.boolValue)
{
base.DrawDefaultInspector();
ApplyAdditionalComponentsVisibility(false);
serializedObject.ApplyModifiedProperties();
// It is required to save m_UseOldInspector value
additionalDataSerializedObject.ApplyModifiedProperties();
shadowDataSerializedObject.ApplyModifiedProperties(); // Should not be needed but if we do some change, could be, so let it here.
return;
if (scope.changed)
{
int len = m_AdditionalShadowData.cascadeCount.intValue;
m_AdditionalShadowData.cascadeRatios.arraySize = len - 1;
m_AdditionalShadowData.cascadeBorders.arraySize = len;
}
ApplyAdditionalComponentsVisibility(true);
// Light features
EditorGUILayout.LabelField(new GUIContent("Light features"), EditorStyles.boldLabel);
// Do not display option for shadow if we are fully bake
if (m_Lightmapping.enumValueIndex != (int)LightMappingType.Baked)
using (var scope = new EditorGUI.ChangeCheckScope())
if (EditorGUILayout.Toggle(new GUIContent("Enable Shadow"), m_ShadowsType.enumValueIndex != 0))
m_ShadowsType.enumValueIndex = (int)LightShadows.Hard;
else
m_ShadowsType.enumValueIndex = (int)LightShadows.None;
}
// Draw each field first...
int arraySize = m_AdditionalShadowData.cascadeRatios.arraySize;
for (int i = 0; i < arraySize; i++)
EditorGUILayout.Slider(m_AdditionalShadowData.cascadeRatios.GetArrayElementAtIndex(i), 0f, 1f, s_Styles.shadowCascadeRatios[i]);
EditorGUI.indentLevel--;
if (scope.changed)
{
// ...then clamp values to avoid out of bounds cascade ratios
for (int i = 0; i < arraySize; i++)
{
var ratios = m_AdditionalShadowData.cascadeRatios;
var ratioProp = ratios.GetArrayElementAtIndex(i);
float val = ratioProp.floatValue;
// Allow to display the arrow for reduce/expand correctly
EditorGUI.indentLevel = 1;
if (i > 0)
{
var prevRatioProp = ratios.GetArrayElementAtIndex(i - 1);
float prevVal = prevRatioProp.floatValue;
val = Mathf.Max(val, prevVal);
}
// LightShape
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_Type.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Shape", m_Type.isExpanded);
EditorGUI.indentLevel++;
if (i < arraySize - 1)
{
var nextRatioProp = ratios.GetArrayElementAtIndex(i + 1);
float nextVal = nextRatioProp.floatValue;
val = Mathf.Min(val, nextVal);
}
if (m_Type.isExpanded)
{
LigthShapeGUI();
ratioProp.floatValue = val;
}
}
// Light
EditorLightUtilities.DrawSplitter();
m_Intensity.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Light", m_Intensity.isExpanded);
EditorGUI.indentLevel++;
if (m_Intensity.isExpanded)
if (m_AdditionalLightData.showAdditionalSettings.boolValue)
LightGUI();
EditorGUILayout.LabelField("Additional Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_AdditionalShadowData.fadeDistance, s_Styles.shadowFadeDistance);
EditorGUILayout.PropertyField(m_AdditionalShadowData.dimmer, s_Styles.shadowDimmer);
EditorGUI.indentLevel--;
}
// Shadows
if (m_ShadowsType.enumValueIndex != (int)LightShadows.None)
{
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_ShadowsType.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Shadow", m_ShadowsType.isExpanded);
EditorGUI.indentLevel++;
// Internal utilities
void ApplyAdditionalComponentsVisibility(bool hide)
{
var flags = hide ? HideFlags.HideInInspector : HideFlags.None;
if (m_ShadowsType.isExpanded)
{
ShadowsGUI();
}
foreach (var t in m_SerializedAdditionalLightData.targetObjects)
((HDAdditionalLightData)t).hideFlags = flags;
// shadow cascade
if (m_Type.enumValueIndex == (int)LightType.Directional && m_Lightmapping.enumValueIndex != (int)LightMappingType.Baked)
{
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_ShadowCascadeCount.isExpanded = EditorLightUtilities.DrawHeaderFoldout("ShadowCascades", m_ShadowCascadeCount.isExpanded);
EditorGUI.indentLevel++;
foreach (var t in m_SerializedAdditionalShadowData.targetObjects)
((AdditionalShadowData)t).hideFlags = flags;
}
if (m_ShadowCascadeCount.isExpanded)
{
ShadowsCascadeGUI();
}
}
}
void ResolveLightShape()
{
var type = m_BaseData.type;
// AdditionalSettings
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_ShowAdditionalSettings.boolValue = EditorLightUtilities.DrawHeaderFoldout("Additional Settings", m_ShowAdditionalSettings.boolValue);
EditorGUI.indentLevel++;
if (m_ShowAdditionalSettings.boolValue)
// Special case for multi-selection: don't resolve light shape or it'll corrupt lights
if (type.hasMultipleDifferentValues)
AdditionalSettingsGUI();
m_LightShape = (LightShape)(-1);
return;
EditorGUI.indentLevel = 0; // Reset the value that we have init to 1
var lightTypeExtent = (LightTypeExtent)m_AdditionalLightData.lightTypeExtent.enumValueIndex;
if (SceneView.lastActiveSceneView != null && SceneView.lastActiveSceneView.m_SceneLighting == false)
if (lightTypeExtent == LightTypeExtent.Punctual)
EditorGUILayout.HelpBox(Styles.DisabledLightWarning.text, MessageType.Warning);
switch ((LightType)type.enumValueIndex)
{
case LightType.Directional:
m_LightShape = LightShape.Directional;
break;
case LightType.Point:
m_LightShape = LightShape.Point;
break;
case LightType.Spot:
m_LightShape = LightShape.Spot;
break;
}
}
else
{
switch (lightTypeExtent)
{
case LightTypeExtent.Rectangle:
m_LightShape = LightShape.Rectangle;
break;
case LightTypeExtent.Line:
m_LightShape = LightShape.Line;
break;
}
serializedObject.ApplyModifiedProperties();
additionalDataSerializedObject.ApplyModifiedProperties();
shadowDataSerializedObject.ApplyModifiedProperties();
void ApplyAdditionalComponentsVisibility(bool hide)
// TODO: Move this to a generic EditorUtilities class
T[] GetAdditionalData<T>()
where T : Component
var additionalData = light.GetComponent<HDAdditionalLightData>();
var shadowData = light.GetComponent<AdditionalShadowData>();
// Handles multi-selection
var data = targets.Cast<Component>()
.Select(t => t.GetComponent<T>())
.ToArray();
for (int i = 0; i < data.Length; i++)
{
if (data[i] == null)
data[i] = Undo.AddComponent<T>(((Component)targets[i]).gameObject);
}
additionalData.hideFlags = hide ? HideFlags.HideInInspector : HideFlags.None;
shadowData.hideFlags = hide ? HideFlags.HideInInspector : HideFlags.None;
return data;
}
}
}

5
ScriptableRenderPipeline/HDRenderPipeline/Lighting/EditorLightUtilities.cs


var nearDiscDistance = Mathf.Cos(Mathf.Deg2Rad * spotlight.spotAngle / 2) * spotlight.shadowNearPlane;
var nearDiscRadius = spotlight.shadowNearPlane * Mathf.Sin(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
//Draw Range disc
Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * rangeDiscDistance, spotlight.gameObject.transform.forward, rangeDiscRadius, false, 1);
//Draw Lines

public static void DrawArealightGizmo(Light arealight)
{
var RectangleSize = new Vector3(arealight.areaSize.x, arealight.areaSize.y, 0);
Gizmos.matrix = arealight.transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, RectangleSize);

public static void DrawSplitter()
{
EditorGUILayout.Space();
var rect = GUILayoutUtility.GetRect(1f, 1f);
// Splitter rect should be full-width

100
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


s_TileList = null;
s_TileFeatureFlags = null;
m_DeferredAllMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredAllMaterialSRT = CoreUtils.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredAllMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredAllMaterialSRT.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.RegularLighting);

m_DeferredAllMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredAllMaterialMRT = CoreUtils.CreateEngineMaterial(m_Resources.deferredShader);
m_DeferredAllMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredAllMaterialMRT.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.SplitLighting);

m_SingleDeferredMaterialSRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_SingleDeferredMaterialSRT = CoreUtils.CreateEngineMaterial(m_Resources.deferredShader);
m_SingleDeferredMaterialSRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialSRT.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.RegularLighting);

m_SingleDeferredMaterialMRT = Utilities.CreateEngineMaterial(m_Resources.deferredShader);
m_SingleDeferredMaterialMRT = CoreUtils.CreateEngineMaterial(m_Resources.deferredShader);
m_SingleDeferredMaterialMRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialMRT.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.SplitLighting);

m_DebugViewTilesMaterial = Utilities.CreateEngineMaterial(m_Resources.debugViewTilesShader);
m_DebugViewTilesMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugViewTilesShader);
m_DefaultTexture2DArray = new Texture2DArray(1, 1, 1, TextureFormat.ARGB32, false);
m_DefaultTexture2DArray.SetPixels32(new Color32[1] { new Color32(128, 128, 128, 128) }, 0);

UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
#endif
Utilities.SafeRelease(s_DirectionalLightDatas);
Utilities.SafeRelease(s_LightDatas);
Utilities.SafeRelease(s_EnvLightDatas);
Utilities.SafeRelease(s_shadowDatas);
CoreUtils.SafeRelease(s_DirectionalLightDatas);
CoreUtils.SafeRelease(s_LightDatas);
CoreUtils.SafeRelease(s_EnvLightDatas);
CoreUtils.SafeRelease(s_shadowDatas);
if (m_CubeReflTexArray != null)
{

ReleaseResolutionDependentBuffers();
Utilities.SafeRelease(s_AABBBoundsBuffer);
Utilities.SafeRelease(s_ConvexBoundsBuffer);
Utilities.SafeRelease(s_LightVolumeDataBuffer);
Utilities.SafeRelease(s_DispatchIndirectBuffer);
CoreUtils.SafeRelease(s_AABBBoundsBuffer);
CoreUtils.SafeRelease(s_ConvexBoundsBuffer);
CoreUtils.SafeRelease(s_LightVolumeDataBuffer);
CoreUtils.SafeRelease(s_DispatchIndirectBuffer);
Utilities.SafeRelease(s_GlobalLightListAtomic);
CoreUtils.SafeRelease(s_GlobalLightListAtomic);
Utilities.Destroy(m_DeferredAllMaterialSRT);
Utilities.Destroy(m_DeferredAllMaterialMRT);
CoreUtils.Destroy(m_DeferredAllMaterialSRT);
CoreUtils.Destroy(m_DeferredAllMaterialMRT);
Utilities.Destroy(m_DebugViewTilesMaterial);
CoreUtils.Destroy(m_DebugViewTilesMaterial);
Utilities.Destroy(m_SingleDeferredMaterialSRT);
Utilities.Destroy(m_SingleDeferredMaterialMRT);
CoreUtils.Destroy(m_SingleDeferredMaterialSRT);
CoreUtils.Destroy(m_SingleDeferredMaterialMRT);
}
public void NewFrame()

public void ReleaseResolutionDependentBuffers()
{
Utilities.SafeRelease(s_LightList);
Utilities.SafeRelease(s_TileList);
Utilities.SafeRelease(s_TileFeatureFlags);
CoreUtils.SafeRelease(s_LightList);
CoreUtils.SafeRelease(s_TileList);
CoreUtils.SafeRelease(s_TileFeatureFlags);
Utilities.SafeRelease(s_PerVoxelLightLists);
Utilities.SafeRelease(s_PerVoxelOffset);
Utilities.SafeRelease(s_PerTileLogBaseTweak);
CoreUtils.SafeRelease(s_PerVoxelLightLists);
CoreUtils.SafeRelease(s_PerVoxelOffset);
CoreUtils.SafeRelease(s_PerTileLogBaseTweak);
Utilities.SafeRelease(s_BigTileLightList);
CoreUtils.SafeRelease(s_BigTileLightList);
}
int NumLightIndicesPerClusteredTile()

// Debug.Assert(additionalData == null, "Missing HDAdditionalData on a light - Should have been create by HDLightEditor");
if (additionalData == null)
return;
return;
LightCategory lightCategory = LightCategory.Count;
GPULightType gpuLightType = GPULightType.Point;

case LightTypeExtent.Line:
if (areaLightCount >= k_MaxAreaLightsOnScreen)
continue;
continue;
gpuLightType = GPULightType.Line;
lightVolumeType = LightVolumeType.Box;
break;

sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
}
Utilities.QuickSort(sortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
CoreUtils.QuickSort(sortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
// TODO: Refactor shadow management
// The good way of managing shadow:

}
// Not necessary yet but call it for future modification with sphere influence volume
Utilities.QuickSort(sortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
CoreUtils.QuickSort(sortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex)
{

public void PushGlobalParams(Camera camera, CommandBuffer cmd, ComputeShader computeShader, int kernelIndex, bool forceClustered = false)
{
using (new Utilities.ProfilingSample("Push Global Parameters", cmd))
using (new ProfilingSample("Push Global Parameters", cmd))
{
// Shadows
m_ShadowMgr.SyncData();

private void SetupDebugDisplayMode(bool debugDisplayEnable)
{
Utilities.SetKeyword(m_DeferredAllMaterialSRT, "DEBUG_DISPLAY", debugDisplayEnable);
Utilities.SetKeyword(m_DeferredAllMaterialMRT, "DEBUG_DISPLAY", debugDisplayEnable);
Utilities.SetKeyword(m_SingleDeferredMaterialSRT, "DEBUG_DISPLAY", debugDisplayEnable);
Utilities.SetKeyword(m_SingleDeferredMaterialMRT, "DEBUG_DISPLAY", debugDisplayEnable);
CoreUtils.SetKeyword(m_DeferredAllMaterialSRT, "DEBUG_DISPLAY", debugDisplayEnable);
CoreUtils.SetKeyword(m_DeferredAllMaterialMRT, "DEBUG_DISPLAY", debugDisplayEnable);
CoreUtils.SetKeyword(m_SingleDeferredMaterialSRT, "DEBUG_DISPLAY", debugDisplayEnable);
CoreUtils.SetKeyword(m_SingleDeferredMaterialMRT, "DEBUG_DISPLAY", debugDisplayEnable);
}
public void RenderLightingDebug(HDCamera hdCamera, CommandBuffer cmd, RenderTargetIdentifier colorBuffer, DebugDisplaySettings debugDisplaySettings)

return;
using (new Utilities.ProfilingSample("Tiled Lighting Debug", cmd))
using (new ProfilingSample("Tiled Lighting Debug", cmd))
{
bool bUseClusteredForDeferred = !usingFptl;

m_DebugViewTilesMaterial.EnableKeyword("SHOW_LIGHT_CATEGORIES");
m_DebugViewTilesMaterial.DisableKeyword("SHOW_FEATURE_VARIANTS");
Utilities.DrawFullScreen(cmd, m_DebugViewTilesMaterial, 0, colorBuffer);
CoreUtils.DrawFullScreen(cmd, m_DebugViewTilesMaterial, 0, colorBuffer);
}
SetGlobalPropertyRedirect(null, 0, null);
}

if (m_CurrentSunLight == null)
return;
using (new Utilities.ProfilingSample("Deferred Directional", cmd))
using (new ProfilingSample("Deferred Directional", cmd))
{
hdCamera.SetupComputeShader(deferredDirectionalShadowComputeShader, cmd);
m_ShadowMgr.BindResources(cmd, deferredDirectionalShadowComputeShader, s_deferredDirectionalShadowKernel);

string singlePassName = "SinglePass - Deferred Lighting Pass";
string SinglePassMRTName = "SinglePass - Deferred Lighting Pass MRT";
using (new Utilities.ProfilingSample(m_TileSettings.enableTileAndCluster ?
using (new ProfilingSample(m_TileSettings.enableTileAndCluster ?
(options.outputSplitLighting ? tilePassMRTName : tilePassName) :
(options.outputSplitLighting ? SinglePassMRTName : singlePassName), cmd))
{

// This is a debug brute force renderer to debug tile/cluster which render all the lights
if (options.outputSplitLighting)
{
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialMRT, colorBuffers, depthStencilBuffer);
CoreUtils.DrawFullScreen(cmd, m_SingleDeferredMaterialMRT, colorBuffers, depthStencilBuffer);
}
else
{

m_SingleDeferredMaterialSRT.SetInt(HDShaderIDs._StencilCmp, (int)CompareFunction.Equal);
}
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialSRT, colorBuffers[0], depthStencilBuffer);
CoreUtils.DrawFullScreen(cmd, m_SingleDeferredMaterialSRT, colorBuffers[0], depthStencilBuffer);
}
}
else

if (options.outputSplitLighting)
{
Utilities.SelectKeyword(m_DeferredAllMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialMRT, colorBuffers, depthStencilBuffer);
CoreUtils.SelectKeyword(m_DeferredAllMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
CoreUtils.DrawFullScreen(cmd, m_DeferredAllMaterialMRT, colorBuffers, depthStencilBuffer);
}
else
{

m_DeferredAllMaterialSRT.SetInt(HDShaderIDs._StencilCmp, (int)CompareFunction.Equal);
}
Utilities.SelectKeyword(m_DeferredAllMaterialSRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialSRT, colorBuffers[0], depthStencilBuffer);
CoreUtils.SelectKeyword(m_DeferredAllMaterialSRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
CoreUtils.DrawFullScreen(cmd, m_DeferredAllMaterialSRT, colorBuffers[0], depthStencilBuffer);
}
}
}

// Note: if we use render opaque with deferred tiling we need to render a opaque depth pass for these opaque objects
if (!m_TileSettings.enableTileAndCluster)
{
using (new Utilities.ProfilingSample("Forward pass", cmd))
using (new ProfilingSample("Forward pass", cmd))
{
cmd.EnableShaderKeyword("LIGHTLOOP_SINGLE_PASS");
cmd.DisableShaderKeyword("LIGHTLOOP_TILE_PASS");

// Only opaques can use FPTL, transparent must use clustered!
bool useFptl = renderOpaque && usingFptl;
using (new Utilities.ProfilingSample(useFptl ? "Forward Tiled pass" : "Forward Clustered pass", cmd))
using (new ProfilingSample(useFptl ? "Forward Tiled pass" : "Forward Clustered pass", cmd))
{
// say that we want to use tile of single loop
cmd.EnableShaderKeyword("LIGHTLOOP_TILE_PASS");

public void RenderDebugOverlay(Camera camera, CommandBuffer cmd, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width)
{
LightingDebugSettings lightingDebug = debugDisplaySettings.lightingDebugSettings;
using (new Utilities.ProfilingSample("Display Shadows", cmd))
using (new ProfilingSample("Display Shadows", cmd))
{
if (lightingDebug.shadowDebugMode == ShadowMapDebugMode.VisualizeShadowMap)
{

for (uint i = 0; i < faceCount; ++i)
{
m_ShadowMgr.DisplayShadow(cmd, index, i, x, y, overlaySize, overlaySize, lightingDebug.shadowMinValue, lightingDebug.shadowMaxValue);
Utilities.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, camera.pixelWidth);
HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, camera.pixelWidth);
}
}
}

Utilities.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, camera.pixelWidth);
HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, camera.pixelWidth);
}
}
}

8
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs


void ClearVolumetricLightingBuffers(CommandBuffer cmd, bool isFirstFrame)
{
using (new Utilities.ProfilingSample("Clear volumetric lighting buffers", cmd))
using (new ProfilingSample("Clear volumetric lighting buffers", cmd))
Utilities.SetRenderTarget(cmd, m_VolumetricLightingBufferCurrentFrameRT, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_VolumetricLightingBufferCurrentFrameRT, ClearFlag.Color, Color.black);
Utilities.SetRenderTarget(cmd, m_VolumetricLightingBufferAccumulated, ClearFlag.ClearColor, Color.black);
CoreUtils.SetRenderTarget(cmd, m_VolumetricLightingBufferAccumulated, ClearFlag.Color, Color.black);
}
}
}

{
if (!SetGlobalVolumeProperties(m_VolumetricLightingEnabled, cmd, m_VolumetricLightingCS)) { return; }
using (new Utilities.ProfilingSample("VolumetricLighting", cmd))
using (new ProfilingSample("VolumetricLighting", cmd))
{
bool enableClustered = m_Asset.tileSettings.enableClustered && m_Asset.tileSettings.enableTileAndCluster;

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


public readonly GUIContent useHeightBasedBlendText = new GUIContent("Use Height Based Blend", "Layer will be blended with the underlying layer based on the height.");
public readonly GUIContent useMainLayerInfluenceModeText = new GUIContent("Main Layer Influence", "Switch between regular layers mode and base/layers mode");
public readonly GUIContent opacityAsDensityText = new GUIContent("Use Opacity as Density", "Use Opacity as Density.");
public readonly GUIContent opacityAsDensityText = new GUIContent("Use Opacity map as Density map", "Use opacity map as (alpha channel of base color) as Density map.");
public readonly GUIContent inheritBaseNormalText = new GUIContent("Normal influence", "Inherit the normal from the base layer.");
public readonly GUIContent inheritBaseHeightText = new GUIContent("Heightmap influence", "Inherit the height from the base layer.");
public readonly GUIContent inheritBaseColorText = new GUIContent("BaseColor influence", "Inherit the base color from the base layer.");

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


public override void Build(RenderPipelineResources renderPipelineResources)
{
m_InitPreFGD = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/PreIntegratedFGD");
m_InitPreFGD = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/PreIntegratedFGD");
// For DisneyDiffuse integration values goes from (0.5 to 1.53125). GGX need 0 to 1. Use float format.
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear);

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

if (m_isInit)
return;
using (new Utilities.ProfilingSample("Init PreFGD", cmd))
using (new ProfilingSample("Init PreFGD", cmd))
Utilities.DrawFullScreen(cmd, m_InitPreFGD, new RenderTargetIdentifier(m_PreIntegratedFGD));
CoreUtils.DrawFullScreen(cmd, m_InitPreFGD, new RenderTargetIdentifier(m_PreIntegratedFGD));
}
m_isInit = true;
}

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


surfaceData.baseColor = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).rgb * ADD_IDX(_BaseColor).rgb;
#ifdef _DETAIL_MAP_IDX
surfaceData.baseColor *= LerpWhiteTo(2.0 * saturate(detailAlbedo * ADD_IDX(_DetailAlbedoScale)), detailMask);
surfaceData.baseColor *= LerpWhiteTo(2.0 * detailAlbedo, detailMask * ADD_IDX(_DetailAlbedoScale));
// we saturate to avoid to have a smoothness value above 1
surfaceData.baseColor = saturate(surfaceData.baseColor);
#endif
surfaceData.specularOcclusion = 1.0; // Will be setup outside of this function

#endif
#ifdef _DETAIL_MAP_IDX
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * saturate(detailSmoothness * ADD_IDX(_DetailSmoothnessScale)), detailMask);
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * detailSmoothness, detailMask * ADD_IDX(_DetailSmoothnessScale));
// we saturate to avoid to have a smoothness value above 1
surfaceData.perceptualSmoothness = saturate(surfaceData.perceptualSmoothness);
#endif
// MaskMap is RGBA: Metallic, Ambient Occlusion (Optional), emissive Mask (Optional), Smoothness

6
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


// <<< Old SSS Model
// These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawSssProfile");
m_TransmittanceMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawSssProfile");
m_TransmittanceMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileImage = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImage = new RenderTexture( 16, 256, 0, RenderTextureFormat.DefaultHDR);

m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, r);
m_ProfileMaterial.SetVector(HDShaderIDs._ShapeParam, S);
// Old SSS Model >>>
Utilities.SelectKeyword(m_ProfileMaterial, "SSS_MODEL_DISNEY", "SSS_MODEL_BASIC", useDisneySSS);
CoreUtils.SelectKeyword(m_ProfileMaterial, "SSS_MODEL_DISNEY", "SSS_MODEL_BASIC", useDisneySSS);
// Apply the three-sigma rule, and rescale.
float s = (1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE;
float rMax = Mathf.Max(m_ScatterDistance1.colorValue.r, m_ScatterDistance1.colorValue.g, m_ScatterDistance1.colorValue.b,

6
ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs


#if UNITY_EDITOR
public static string GetRenderPipelineResourcesPath()
{
return Utilities.GetHDRenderPipelinePath() + "RenderPipelineResources/HDRenderPipelineResources.asset";
return HDUtils.GetHDRenderPipelinePath() + "RenderPipelineResources/HDRenderPipelineResources.asset";
}
// TODO skybox/cubemap

{
var instance = CreateInstance<RenderPipelineResources>();
string HDRenderPipelinePath = Utilities.GetHDRenderPipelinePath();
string HDRenderPipelinePath = HDUtils.GetHDRenderPipelinePath();
instance.debugDisplayLatlongShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(HDRenderPipelinePath + "Debug/DebugDisplayLatlong.Shader");
instance.debugViewMaterialGBufferShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(HDRenderPipelinePath + "Debug/DebugViewMaterialGBuffer.Shader");

instance.buildPerVoxelLightListShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/lightlistbuild-clustered.compute");
instance.buildMaterialFlagsShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/materialflags.compute");
instance.deferredComputeShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/Deferred.compute");
instance.deferredDirectionalShadowComputeShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/DeferredDirectionalShadow.compute");
// SceneSettings

10
ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs


public override void Build()
{
m_SkyHDRIMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyHDRI");
m_SkyHDRIMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyHDRI");
Utilities.Destroy(m_SkyHDRIMaterial);
CoreUtils.Destroy(m_SkyHDRIMaterial);
}
public override void SetRenderTargets(BuiltinSkyParameters builtinParams)

Utilities.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer);
CoreUtils.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer);
Utilities.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer, builtinParams.depthBuffer);
CoreUtils.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer, builtinParams.depthBuffer);
}
}

MaterialPropertyBlock properties = new MaterialPropertyBlock();
properties.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
Utilities.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, properties, renderForCubemap ? 0 : 1);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, properties, renderForCubemap ? 0 : 1);
}
public override bool IsSkyValid()

8
ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs


public override void Build()
{
m_ProceduralSkyMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyProcedural");
m_ProceduralSkyMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyProcedural");
Utilities.Destroy(m_ProceduralSkyMaterial);
CoreUtils.Destroy(m_ProceduralSkyMaterial);
}
public override bool IsSkyValid()

{
// We do not bind the depth buffer as a depth-stencil target since it is
// bound as a color texture which is then sampled from within the shader.
Utilities.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer);
CoreUtils.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer);
}
void SetKeywords(BuiltinSkyParameters builtinParams, ProceduralSkySettings param, bool renderForCubemap)

// Set shader constants.
SetUniforms(builtinParams, m_ProceduralSkySettings, renderForCubemap, ref properties);
Utilities.DrawFullScreen(builtinParams.commandBuffer, m_ProceduralSkyMaterial, properties);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_ProceduralSkyMaterial, properties);
}
}
}

16
ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs


if (!m_GgxConvolveMaterial)
{
m_GgxConvolveMaterial = Utilities.CreateEngineMaterial(m_RenderPipelinesResources.GGXConvolve);
m_GgxConvolveMaterial = CoreUtils.CreateEngineMaterial(m_RenderPipelinesResources.GGXConvolve);
}
if (!m_GgxIblSampleData)

m_ComputeGgxIblSampleDataCS.SetTexture(m_ComputeGgxIblSampleDataKernel, "output", m_GgxIblSampleData);
using (new Utilities.ProfilingSample("Compute GGX IBL Sample Data", cmd))
using (new ProfilingSample("Compute GGX IBL Sample Data", cmd))
cmd.DispatchCompute(m_ComputeGgxIblSampleDataCS, m_ComputeGgxIblSampleDataKernel, 1, 1, 1);
cmd.DispatchCompute(m_ComputeGgxIblSampleDataCS, m_ComputeGgxIblSampleDataKernel, 1, 1, 1);
}
}
}

props.SetFloat("_Level", mip);
props.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
Utilities.SetRenderTarget(cmd, target, ClearFlag.ClearNone, mip, (CubemapFace)face);
Utilities.DrawFullScreen(cmd, m_GgxConvolveMaterial, props);
CoreUtils.SetRenderTarget(cmd, target, ClearFlag.None, mip, (CubemapFace)face);
CoreUtils.DrawFullScreen(cmd, m_GgxConvolveMaterial, props);
}
cmd.EndSample(sampleName);
}

int numRows = conditionalCdf.height;
using (new Utilities.ProfilingSample("Build Probability Tables", cmd))
using (new ProfilingSample("Build Probability Tables", cmd))
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_ConditionalDensitiesKernel, numRows, 1, 1);
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_MarginalRowDensitiesKernel, 1, 1, 1);
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_ConditionalDensitiesKernel, numRows, 1, 1);
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_MarginalRowDensitiesKernel, 1, 1, 1);
}
m_GgxConvolveMaterial.EnableKeyword("USE_MIS");

46
ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs


if ((m_SkyboxCubemapRT != null) && (m_SkyboxCubemapRT.width != resolution))
{
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
Utilities.Destroy(m_SkyboxMarginalRowCdfRT);
Utilities.Destroy(m_SkyboxConditionalCdfRT);
CoreUtils.Destroy(m_SkyboxCubemapRT);
CoreUtils.Destroy(m_SkyboxGGXCubemapRT);
CoreUtils.Destroy(m_SkyboxMarginalRowCdfRT);
CoreUtils.Destroy(m_SkyboxConditionalCdfRT);
m_SkyboxCubemapRT = null;
m_SkyboxGGXCubemapRT = null;

m_faceWorldToViewMatrixMatrices[i] = worldToView;
m_facePixelCoordToViewDirMatrices[i] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, screenSize, worldToView, true);
m_faceCameraInvViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj).inverse;
m_faceCameraInvViewProjectionMatrix[i] = HDUtils.GetViewProjectionMatrix(lookAt, cubeProj).inverse;
}
}

m_iblFilterGgx = new IBLFilterGGX(renderPipelinesResources);
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial(renderPipelinesResources.skyboxCubemap);
m_StandardSkyboxMaterial = CoreUtils.CreateEngineMaterial(renderPipelinesResources.skyboxCubemap);
m_BlitCubemapMaterial = Utilities.CreateEngineMaterial(renderPipelinesResources.blitCubemap);
m_BlitCubemapMaterial = CoreUtils.CreateEngineMaterial(renderPipelinesResources.blitCubemap);
m_CurrentUpdateTime = 0.0f;
}

Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
Utilities.Destroy(m_SkyboxMarginalRowCdfRT);
Utilities.Destroy(m_SkyboxConditionalCdfRT);
CoreUtils.Destroy(m_StandardSkyboxMaterial);
CoreUtils.Destroy(m_SkyboxCubemapRT);
CoreUtils.Destroy(m_SkyboxGGXCubemapRT);
CoreUtils.Destroy(m_SkyboxMarginalRowCdfRT);
CoreUtils.Destroy(m_SkyboxConditionalCdfRT);
if (m_Renderer != null)
m_Renderer.Cleanup();

builtinParams.colorBuffer = target;
builtinParams.depthBuffer = BuiltinSkyParameters.nullRT;
Utilities.SetRenderTarget(builtinParams.commandBuffer, target, ClearFlag.ClearNone, 0, (CubemapFace)i);
CoreUtils.SetRenderTarget(builtinParams.commandBuffer, target, ClearFlag.None, 0, (CubemapFace)i);
m_Renderer.RenderSky(builtinParams, skySettings, true);
}

for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(cmd, dest, ClearFlag.ClearNone, 0, (CubemapFace)i);
CoreUtils.SetRenderTarget(cmd, dest, ClearFlag.None, 0, (CubemapFace)i);
propertyBlock.SetTexture("_MainTex", source);
propertyBlock.SetFloat("_faceIndex", (float)i);
cmd.DrawProcedural(Matrix4x4.identity, m_BlitCubemapMaterial, 0, MeshTopology.Triangles, 3, 1, propertyBlock);

private void RenderCubemapGGXConvolution(CommandBuffer cmd, BuiltinSkyParameters builtinParams, SkySettings skyParams, Texture input, RenderTexture target)
{
using (new Utilities.ProfilingSample("Update Env: GGX Convolution", cmd))
using (new ProfilingSample("Update Env: GGX Convolution", cmd))
{
int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f);
if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1))

}
// Copy the first mip
using (new Utilities.ProfilingSample("Copy Original Mip", cmd))
using (new ProfilingSample("Copy Original Mip", cmd))
{
for (int f = 0; f < 6; f++)
{

using (new Utilities.ProfilingSample("GGX Convolution", cmd))
using (new ProfilingSample("GGX Convolution", cmd))
{
if (m_useMIS && m_iblFilterGgx.SupportMIS)
{

// We need one frame delay for this update to work since DynamicGI.UpdateEnvironment is executed directly but the renderloop is not (so we need to wait for the sky texture to be rendered first)
if (m_NeedLowLevelUpdateEnvironment)
{
using (new Utilities.ProfilingSample("DynamicGI.UpdateEnvironment", cmd))
using (new ProfilingSample("DynamicGI.UpdateEnvironment", cmd))
{
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);

(skySettings.updateMode == EnvironementUpdateMode.Realtime && m_CurrentUpdateTime > skySettings.updatePeriod)
)
{
using (new Utilities.ProfilingSample("Sky Environment Pass", cmd))
using (new ProfilingSample("Sky Environment Pass", cmd))
using (new Utilities.ProfilingSample("Update Env: Generate Lighting Cubemap", cmd))
using (new ProfilingSample("Update Env: Generate Lighting Cubemap", cmd))
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
// Note that m_SkyboxCubemapRT is created with auto-generate mipmap, it mean that here we have also our mipmap correctly box filtered for importance sampling.

{
if (m_SkyParametersHash != 0)
{
using (new Utilities.ProfilingSample("Reset Sky Environment", cmd))
using (new ProfilingSample("Reset Sky Environment", cmd))
Utilities.ClearCubemap(cmd, m_SkyboxCubemapRT, Color.black);
CoreUtils.ClearCubemap(cmd, m_SkyboxCubemapRT, Color.black);
RenderCubemapGGXConvolution(cmd, m_BuiltinParameters, skySettings, m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT);
m_SkyParametersHash = 0;

public void RenderSky(HDCamera camera, Light sunLight, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, CommandBuffer cmd)
{
using (new Utilities.ProfilingSample("Sky Pass", cmd))
using (new ProfilingSample("Sky Pass", cmd))
{
if (IsSkyValid())
{

4
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/HDRPAsset/HDRenderPipelineResourcesTest.asset


deferredShader: {fileID: 4800000, guid: 00dd221e34a6ab349a1196b0f2fab693, type: 3}
screenSpaceAmbientOcclusionShader: {fileID: 4800000, guid: cf0db7f5267ad944dbf4326b7102c9ca,
type: 3}
subsurfaceScatteringCS: {fileID: 0}
volumetricLightingCS: {fileID: 0}
clearDispatchIndirectShader: {fileID: 7200000, guid: fc1f553acb80a6446a32d33e403d0656,
type: 3}
buildDispatchIndirectShader: {fileID: 7200000, guid: 4eb1b418be7044c40bb5200496c50f14,

buildMaterialFlagsShader: {fileID: 7200000, guid: fb3eda953cd6e634e877fb777be2cd08,
type: 3}
deferredComputeShader: {fileID: 7200000, guid: 0b64f79746d2daf4198eaf6eab9af259,
type: 3}
deferredDirectionalShadowComputeShader: {fileID: 7200000, guid: fbde6fae193b2a94e9fd97c163c204f4,
type: 3}
cameraMotionVectors: {fileID: 4800000, guid: 035941b63024d1943af48811c1db20d9, type: 3}
blitCubemap: {fileID: 4800000, guid: d05913e251bed7a4992c921c62e1b647, type: 3}

11
ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
// This enum extent the original LightType enum with new light type from HD
public enum LightTypeExtent
{
public enum LightTypeExtent
{
// Sphere,
// Sphere,
// Disc,
};

return Mathf.Clamp(m_InnerSpotPercent, 0.0f, 100.0f) / 100.0f;
}
[Range(0.0f, 1.0f)]
[Range(0.0f, 1.0f)]
public float lightDimmer = 1.0f;
// Not used for directional lights.

[FormerlySerializedAs("lightWidth")]
public float shapeWidth = 0.5f;
// Only for Sphere/Disc
// Only for Sphere/Disc
public float shapeRadius = 0.0f;
// Only for Spot/Point - use to cheaply fake specular spherical area light

// This is specific for the LightEditor GUI and not use at runtime
public bool useOldInspector = false;
public bool featuresFoldout = true;
public bool showAdditionalSettings = true; // TODO: Maybe we can remove if if we decide to always show additional settings
#if UNITY_EDITOR

268
ScriptableRenderPipeline/Core/CoreUtils.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
namespace UnityEngine.Experimental.Rendering
{
using UnityObject = UnityEngine.Object;
[Flags]
public enum ClearFlag
{
None = 0,
Color = 1,
Depth = 2,
All = Depth | Color
}
public static class CoreUtils
{
public static List<RenderPipelineMaterial> GetRenderPipelineMaterialList()
{
var baseType = typeof(RenderPipelineMaterial);
var assembly = baseType.Assembly;
var types = assembly.GetTypes()
.Where(t => t.IsSubclassOf(baseType))
.Select(Activator.CreateInstance)
.Cast<RenderPipelineMaterial>()
.ToList();
// Note: If there is a need for an optimization in the future of this function, user can
// simply fill the materialList manually by commenting the code abode and returning a
// custom list of materials they use in their game.
//
// return new List<RenderPipelineMaterial>
// {
// new Lit(),
// new Unlit(),
// ...
// };
return types;
}
// Render Target Management.
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
cmd.SetRenderTarget(buffer, miplevel, cubemapFace);
if (clearFlag != ClearFlag.None)
cmd.ClearRenderTarget((clearFlag & ClearFlag.Depth) != 0, (clearFlag & ClearFlag.Color) != 0, clearColor);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.None, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(cmd, buffer, clearFlag, Color.black, miplevel, cubemapFace);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(cmd, colorBuffer, depthBuffer, ClearFlag.None, Color.black, miplevel, cubemapFace);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(cmd, colorBuffer, depthBuffer, clearFlag, Color.black, miplevel, cubemapFace);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace);
if (clearFlag != ClearFlag.None)
cmd.ClearRenderTarget((clearFlag & ClearFlag.Depth) != 0, (clearFlag & ClearFlag.Color) != 0, clearColor);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer)
{
SetRenderTarget(cmd, colorBuffers, depthBuffer, ClearFlag.None, Color.black);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.None)
{
SetRenderTarget(cmd, colorBuffers, depthBuffer, clearFlag, Color.black);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor)
{
cmd.SetRenderTarget(colorBuffers, depthBuffer);
if (clearFlag != ClearFlag.None)
cmd.ClearRenderTarget((clearFlag & ClearFlag.Depth) != 0, (clearFlag & ClearFlag.Color) != 0, clearColor);
}
public static void ClearCubemap(CommandBuffer cmd, RenderTargetIdentifier buffer, Color clearColor)
{
for(int i = 0; i < 6; ++i)
SetRenderTarget(cmd, buffer, ClearFlag.Color, Color.black, 0, (CubemapFace)i);
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier colorBuffer,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
commandBuffer.SetRenderTarget(colorBuffer);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthStencilBuffer,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
commandBuffer.SetRenderTarget(colorBuffer, depthStencilBuffer);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
commandBuffer.SetRenderTarget(colorBuffers, depthStencilBuffer);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}
// Important: the first RenderTarget must be created with 0 depth bits!
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier[] colorBuffers,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
// It is currently not possible to have MRT without also setting a depth target.
// To work around this deficiency of the CommandBuffer.SetRenderTarget() API,
// we pass the first color target as the depth target. If it has 0 depth bits,
// no depth target ends up being bound.
DrawFullScreen(commandBuffer, material, colorBuffers, colorBuffers[0], properties, shaderPassId);
}
// Post-processing misc
public static bool IsPostProcessingActive(PostProcessLayer layer)
{
return layer != null
&& layer.enabled;
}
public static bool IsTemporalAntialiasingActive(PostProcessLayer layer)
{
return IsPostProcessingActive(layer)
&& layer.antialiasingMode == PostProcessLayer.Antialiasing.TemporalAntialiasing
&& layer.temporalAntialiasing.IsSupported();
}
// Unity specifics
public static Material CreateEngineMaterial(string shaderPath)
{
var mat = new Material(Shader.Find(shaderPath))
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static Material CreateEngineMaterial(Shader shader)
{
var mat = new Material(shader)
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public static void SelectKeyword(Material material, string keyword1, string keyword2, bool enableFirst)
{
material.EnableKeyword(enableFirst ? keyword1 : keyword2);
material.DisableKeyword(enableFirst ? keyword2 : keyword1);
}
public static void SelectKeyword(Material material, string[] keywords, int enabledKeywordIndex)
{
material.EnableKeyword(keywords[enabledKeywordIndex]);
for (int i = 0; i < keywords.Length; i++)
{
if (i != enabledKeywordIndex)
material.DisableKeyword(keywords[i]);
}
}
public static void Destroy(UnityObject obj)
{
if (obj != null)
{
#if UNITY_EDITOR
if (Application.isPlaying)
UnityObject.Destroy(obj);
else
UnityObject.DestroyImmediate(obj);
#else
UnityObject.Destroy(obj);
#endif
}
}
public static void SafeRelease(ComputeBuffer buffer)
{
if (buffer != null)
buffer.Release();
}
// Just a sort function that doesn't allocate memory
// Note: Shoud be repalc by a radix sort for positive integer
public static int Partition(uint[] numbers, int left, int right)
{
uint pivot = numbers[left];
while (true)
{
while (numbers[left] < pivot)
left++;
while (numbers[right] > pivot)
right--;
if (left < right)
{
uint temp = numbers[right];
numbers[right] = numbers[left];
numbers[left] = temp;
}
else
{
return right;
}
}
}
public static void QuickSort(uint[] arr, int left, int right)
{
// For Recusrion
if (left < right)
{
int pivot = Partition(arr, left, right);
if (pivot > 1)
QuickSort(arr, left, pivot - 1);
if (pivot + 1 < right)
QuickSort(arr, pivot + 1, right);
}
}
}
}

13
ScriptableRenderPipeline/Core/CoreUtils.cs.meta


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

62
ScriptableRenderPipeline/Core/Editor/PropertyFetcher.cs


using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using UnityEngine.Assertions;
namespace UnityEditor.Experimental.Rendering
{
public class PropertyFetcher<T> : IDisposable
{
public readonly SerializedObject obj;
public PropertyFetcher(SerializedObject obj)
{
Assert.IsNotNull(obj);
this.obj = obj;
}
public SerializedProperty FindProperty(string str)
{
return obj.FindProperty(str);
}
public SerializedProperty FindProperty<TValue>(Expression<Func<T, TValue>> expr)
{
// Get the field path as a string
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.MemberAccess:
me = expr.Body as MemberExpression;
break;
default:
throw new InvalidOperationException();
}
var members = new List<string>();
while (me != null)
{
members.Add(me.Member.Name);
me = me.Expression as MemberExpression;
}
var sb = new StringBuilder();
for (int i = members.Count - 1; i >= 0; i--)
{
sb.Append(members[i]);
if (i > 0) sb.Append('.');
}
var path = sb.ToString();
// Fetch the SerializedProperty using Unity's method
return obj.FindProperty(path);
}
public void Dispose()
{
// Nothing to do here, still needed so we can rely on the using/IDisposable pattern
}
}
}

13
ScriptableRenderPipeline/Core/Editor/PropertyFetcher.cs.meta


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

41
ScriptableRenderPipeline/Core/ProfilingSample.cs


using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering
{
public struct ProfilingSample : IDisposable
{
public readonly CommandBuffer cmd;
public readonly string name;
bool m_Disposed;
public ProfilingSample(string name, CommandBuffer cmd)
{
this.cmd = cmd;
this.name = name;
m_Disposed = false;
cmd.BeginSample(name);
}
public void Dispose()
{
Dispose(true);
}
// Protected implementation of Dispose pattern.
void Dispose(bool disposing)
{
if (m_Disposed)
return;
// As this is a struct, it could have been initialized using an empty constructor so we
// need to make sure `cmd` isn't null to avoid a crash. Switching to a class would fix
// this but will generate garbage on every frame (and this struct is used quite a lot).
if (disposing && cmd != null)
cmd.EndSample(name);
m_Disposed = true;
}
}
}

13
ScriptableRenderPipeline/Core/ProfilingSample.cs.meta


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

8
ScriptableRenderPipeline/HDRenderPipeline/Camera.meta


fileFormatVersion: 2
guid: 275a6feef8046494a9924c559b1a2b38
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

51
ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs


#if UNITY_EDITOR
using System.IO;
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class HDUtils
{
#if UNITY_EDITOR
public static string GetHDRenderPipelinePath()
{
// User can create their own directory for SRP, so we need to find the current path that they use.
// We know that DefaultHDMaterial exist and we know where it is, let's use that to find the current directory.
var guid = AssetDatabase.FindAssets("DefaultHDMaterial t:material");
string path = AssetDatabase.GUIDToAssetPath(guid[0]);
path = Path.GetDirectoryName(path); // Asset is in HDRenderPipeline/RenderPipelineResources/DefaultHDMaterial.mat
path = path.Replace("RenderPipelineResources", ""); // Keep only path with HDRenderPipeline
return path;
}
#endif
public const RendererConfiguration k_RendererConfigurationBakedLighting = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume;
public static Matrix4x4 GetViewProjectionMatrix(Matrix4x4 worldToViewMatrix, Matrix4x4 projectionMatrix)
{
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
var gpuProj = GL.GetGPUProjectionMatrix(projectionMatrix, false);
var gpuVP = gpuProj * worldToViewMatrix * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API.
return gpuVP;
}
// Helper to help to display debug info on screen
static float s_OverlayLineHeight = -1.0f;
public static void NextOverlayCoord(ref float x, ref float y, float overlayWidth, float overlayHeight, float width)
{
x += overlayWidth;
s_OverlayLineHeight = Mathf.Max(overlayHeight, s_OverlayLineHeight);
// Go to next line if it goes outside the screen.
if (x + overlayWidth > width)
{
x = 0;
y -= s_OverlayLineHeight;
s_OverlayLineHeight = -1.0f;
}
}
}
}

79
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs


using System;
using System.Linq;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
// TODO: Missing UI tooltips
partial class HDLightEditor
{
sealed class Styles
{
// Base
public readonly GUIContent range = new GUIContent("Range", "Controls how far the light is emitted from the center of the object.");
public readonly GUIContent color = new GUIContent("Color", "Controls the color being emitted by the light.");
public readonly GUIContent spotAngle = new GUIContent("Angle", "Controls the angle in degrees at the base of a Spot light's cone.");
public readonly GUIContent useColorTemperature = new GUIContent("Use Color Temperature", "Choose between RGB and temperature mode for light's color.");
public readonly GUIContent colorFilter = new GUIContent("Filter", "A colored gel can be put in front of the light source to tint the light.");
public readonly GUIContent colorTemperature = new GUIContent("Temperature", "Also known as CCT (Correlated color temperature). The color temperature of the electromagnetic radiation emitted from an ideal black body is defined as its surface temperature in Kelvin. White is 6500K");
public readonly GUIContent intensity = new GUIContent("Intensity", "Controls the brightness of the light. Light color is multiplied by this value.");
public readonly GUIContent lightmappingMode = new GUIContent("Mode", "Specifies the light mode used to determine if and how a light will be baked. Possible modes are Baked, Mixed, and Realtime.");
public readonly GUIContent lightBounceIntensity = new GUIContent("Indirect Multiplier", "Controls the intensity of indirect light being contributed to the scene. A value of 0 will cause Realtime lights to be removed from realtime global illumination and Baked and Mixed lights to no longer emit indirect lighting. Has no effect when both Realtime and Baked Global Illumination are disabled.");
public readonly GUIContent cookie = new GUIContent("Cookie", "Specifies the Texture mask to cast shadows, create silhouettes, or patterned illumination for the light.");
public readonly GUIContent cookieSizeX = new GUIContent("Size X", "Controls the size of the cookie mask currently assigned to the light.");
public readonly GUIContent cookieSizeY = new GUIContent("Size Y", "Controls the size of the cookie mask currently assigned to the light.");
public readonly GUIContent shadowBias = new GUIContent("Bias", "Controls the distance at which the shadows will be pushed away from the light. Useful for avoiding false self-shadowing artifacts.");
public readonly GUIContent shadowNormalBias = new GUIContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts.");
public readonly GUIContent shadowNearPlane = new GUIContent("Near Plane", "Controls the value for the near clip plane when rendering shadows. Currently clamped to 0.1 units or 1% of the lights range property, whichever is lower.");
public readonly GUIContent bakedShadowRadius = new GUIContent("Baked Shadow Radius", "Controls the amount of artificial softening applied to the edges of shadows cast by the Point or Spot light.");
public readonly GUIContent bakedShadowAngle = new GUIContent("Baked Shadow Angle", "Controls the amount of artificial softening applied to the edges of shadows cast by directional lights.");
public readonly GUIContent bakingWarning = new GUIContent("Light mode is currently overridden to Realtime mode. Enable Baked Global Illumination to use Mixed or Baked light modes.");
public readonly GUIContent indirectBounceShadowWarning = new GUIContent("Realtime indirect bounce shadowing is not supported for Spot and Point lights.");
public readonly GUIContent cookieWarning = new GUIContent("Cookie textures for spot lights should be set to clamp, not repeat, to avoid artifacts.");
// Additional light data
public readonly GUIContent maxSmoothness = new GUIContent("Max Smoothness", "Very low cost way of faking spherical area lighting. This will modify the roughness of the material lit. This is useful when the specular highlight is too small or too sharp.");
public readonly GUIContent affectDiffuse = new GUIContent("Affect Diffuse", "This will disable diffuse lighting for this light. Doesn't save performance, diffuse lighting is still computed.");
public readonly GUIContent affectSpecular = new GUIContent("Affect Specular", "This will disable specular lighting for this light. Doesn't save performance, specular lighting is still computed.");
public readonly GUIContent lightDimmer = new GUIContent("Dimmer", "Aim to be used with script, timeline or animation. It allows dimming one or multiple lights of heterogeneous intensity easily (without needing to know the intensity of each light).");
public readonly GUIContent fadeDistance = new GUIContent("Fade Distance", "The distance at which the light will smoothly fade before being culled to minimize popping.");
public readonly GUIContent spotInnerPercent = new GUIContent("Inner Percent", "Controls size of the angular attenuation in percent of the base angle of the Spot light's cone.");
public readonly GUIContent spotLightShape = new GUIContent("Shape", "The shape use for the spotlight. Has an impact on the cookie transformation and light angular attenuation.");
public readonly GUIContent shapeLengthLine = new GUIContent("Length", "Length of the line light");
public readonly GUIContent shapeLengthRect = new GUIContent("Size X", "SizeX of the rectangle light");
public readonly GUIContent shapeWidthRect = new GUIContent("Size Y", "SizeY of the rectangle light");
public readonly GUIContent shapeLengthPyramid = new GUIContent("Size X", "");
public readonly GUIContent shapeWidthPyramid = new GUIContent("Size Y", "");
public readonly GUIContent shapeLengthBox = new GUIContent("Size X", "");
public readonly GUIContent shapeWidthBox = new GUIContent("Size Y", "");
public readonly GUIContent applyRangeAttenuation = new GUIContent("Apply Range Attenuation", "Allows disabling range attenuation. This is useful indoor (like a room) to avoid having to setup a large range for a light to get correct inverse square attenuation that may leak out of the indoor");
public readonly GUIContent shape = new GUIContent("Type", "Specifies the current type of light. Possible types are Directional, Spot, Point, Rectangle and Line lights.");
public readonly GUIContent[] shapeNames;
// Additional shadow data
public readonly GUIContent shadowCascadeCount = new GUIContent("Cascade Count", "");
public readonly GUIContent[] shadowCascadeRatios = { new GUIContent("Cascade 1"), new GUIContent("Cascade 2"), new GUIContent("Cascade 3") };
public readonly GUIContent shadowResolution = new GUIContent("Resolution", "Controls the rendered resolution of the shadow maps. A higher resolution will increase the fidelity of shadows at the cost of GPU performance and memory usage.");
public readonly GUIContent shadowFadeDistance = new GUIContent("Fade Distance", "The shadow will fade at distance ShadowFadeDistance before being culled to minimize popping.");
public readonly GUIContent shadowDimmer = new GUIContent("Dimmer", "Aim to be use with script, timeline or animation. It allows dimming one or multiple shadows. This can also be used as an optimization to fit in shadow budget manually and minimize popping.");
public Styles()
{
shapeNames = Enum.GetNames(typeof(LightShape))
.Select(x => new GUIContent(x))
.ToArray();
}
}
static Styles s_Styles;
// Can't use a static initializer in case we need to create GUIStyle in the Styles class as
// these can only be created with an active GUI rendering context
void CheckStyles()
{
if (s_Styles == null)
s_Styles = new Styles();
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs.meta


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

221
ScriptableRenderPipeline/HDRenderPipeline/Camera/HDCamera.cs


using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
// This holds all the matrix data we need for rendering, including data from the previous frame
// (which is the main reason why we need to keep them around for a minimum of one frame).
// HDCameras are automatically created & updated from a source camera and will be destroyed if
// not used during a frame.
public class HDCamera
{
public Matrix4x4 viewMatrix;
public Matrix4x4 projMatrix;
public Matrix4x4 nonJitteredProjMatrix;
public Vector4 screenSize;
public Vector4[] frustumPlaneEquations;
public Camera camera;
public Matrix4x4 viewProjMatrix
{
get { return projMatrix * viewMatrix; }
}
public Matrix4x4 nonJitteredViewProjMatrix
{
get { return nonJitteredProjMatrix * viewMatrix; }
}
public bool isFirstFrame
{
get { return m_FirstFrame; }
}
public Vector4 invProjParam
{
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
get { var p = projMatrix; return new Vector4(p.m20 / (p.m00 * p.m23), p.m21 / (p.m11 * p.m23), -1.0f / p.m23, (-p.m22 + p.m20 * p.m02 / p.m00 + p.m21 * p.m12 / p.m11) / p.m23); }
}
// View-projection matrix from the previous frame.
public Matrix4x4 prevViewProjMatrix;
// We need to keep track of these when camera relative rendering is enabled so we can take
// camera translation into account when generating camera motion vectors
public Vector3 cameraPos;
public Vector3 prevCameraPos;
// The only way to reliably keep track of a frame change right now is to compare the frame
// count Unity gives us. We need this as a single camera could be rendered several times per
// frame and some matrices only have to be computed once. Realistically this shouldn't
// happen, but you never know...
int m_LastFrameActive;
// Always true for cameras that just got added to the pool - needed for previous matrices to
// avoid one-frame jumps/hiccups with temporal effects (motion blur, TAA...)
bool m_FirstFrame;
public HDCamera(Camera cam)
{
camera = cam;
frustumPlaneEquations = new Vector4[6];
Reset();
}
public void Update(PostProcessLayer postProcessLayer)
{
// If TAA is enabled projMatrix will hold a jittered projection matrix. The original,
// non-jittered projection matrix can be accessed via nonJitteredProjMatrix.
bool taaEnabled = camera.cameraType == CameraType.Game
&& CoreUtils.IsTemporalAntialiasingActive(postProcessLayer);
Matrix4x4 nonJitteredCameraProj = camera.projectionMatrix;
Matrix4x4 cameraProj = taaEnabled
? postProcessLayer.temporalAntialiasing.GetJitteredProjectionMatrix(camera)
: nonJitteredCameraProj;
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
Matrix4x4 gpuProj = GL.GetGPUProjectionMatrix(cameraProj, true); // Had to change this from 'false'
Matrix4x4 gpuView = camera.worldToCameraMatrix;
Matrix4x4 gpuNonJitteredProj = GL.GetGPUProjectionMatrix(nonJitteredCameraProj, true);
Vector3 pos = camera.transform.position;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Zero out the translation component.
gpuView.SetColumn(3, new Vector4(0, 0, 0, 1));
}
Matrix4x4 gpuVP = gpuNonJitteredProj * gpuView;
// A camera could be rendered multiple times per frame, only updates the previous view proj & pos if needed
if (m_LastFrameActive != Time.frameCount)
{
if (m_FirstFrame)
{
prevCameraPos = pos;
prevViewProjMatrix = gpuVP;
}
else
{
prevCameraPos = cameraPos;
prevViewProjMatrix = nonJitteredViewProjMatrix;
}
m_FirstFrame = false;
}
viewMatrix = gpuView;
projMatrix = gpuProj;
nonJitteredProjMatrix = gpuNonJitteredProj;
cameraPos = pos;
screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(viewProjMatrix);
for (int i = 0; i < 6; i++)
{
frustumPlaneEquations[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, planes[i].distance);
}
m_LastFrameActive = Time.frameCount;
}
public void Reset()
{
m_LastFrameActive = -1;
m_FirstFrame = true;
}
static Dictionary<Camera, HDCamera> m_Cameras = new Dictionary<Camera, HDCamera>();
static List<Camera> m_Cleanup = new List<Camera>(); // Recycled to reduce GC pressure
// Grab the HDCamera tied to a given Camera and update it.
public static HDCamera Get(Camera camera, PostProcessLayer postProcessLayer)
{
HDCamera hdcam;
if (!m_Cameras.TryGetValue(camera, out hdcam))
{
hdcam = new HDCamera(camera);
m_Cameras.Add(camera, hdcam);
}
hdcam.Update(postProcessLayer);
return hdcam;
}
// Look for any camera that hasn't been used in the last frame and remove them for the pool.
public static void CleanUnused()
{
int frameCheck = Time.frameCount - 1;
foreach (var kvp in m_Cameras)
{
if (kvp.Value.m_LastFrameActive != frameCheck)
m_Cleanup.Add(kvp.Key);
}
foreach (var cam in m_Cleanup)
m_Cameras.Remove(cam);
m_Cleanup.Clear();
}
public void SetupGlobalParams(CommandBuffer cmd)
{
cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, viewMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, viewMatrix.inverse);
cmd.SetGlobalMatrix(HDShaderIDs._ProjMatrix, projMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvProjMatrix, projMatrix.inverse);
cmd.SetGlobalMatrix(HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._ViewProjMatrix, viewProjMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvViewProjMatrix, viewProjMatrix.inverse);
cmd.SetGlobalVector(HDShaderIDs._InvProjParam, invProjParam);
cmd.SetGlobalVector(HDShaderIDs._ScreenSize, screenSize);
cmd.SetGlobalMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetGlobalVectorArray(HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
}
// Does not modify global settings. Used for shadows, low res. rendering, etc.
public void OverrideGlobalParams(Material material)
{
material.SetMatrix(HDShaderIDs._ViewMatrix, viewMatrix);
material.SetMatrix(HDShaderIDs._InvViewMatrix, viewMatrix.inverse);
material.SetMatrix(HDShaderIDs._ProjMatrix, projMatrix);
material.SetMatrix(HDShaderIDs._InvProjMatrix, projMatrix.inverse);
material.SetMatrix(HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
material.SetMatrix(HDShaderIDs._ViewProjMatrix, viewProjMatrix);
material.SetMatrix(HDShaderIDs._InvViewProjMatrix, viewProjMatrix.inverse);
material.SetVector(HDShaderIDs._InvProjParam, invProjParam);
material.SetVector(HDShaderIDs._ScreenSize, screenSize);
material.SetMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
material.SetVectorArray(HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
}
public void SetupComputeShader(ComputeShader cs, CommandBuffer cmd)
{
cmd.SetComputeMatrixParam(cs, HDShaderIDs._ViewMatrix, viewMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._InvViewMatrix, viewMatrix.inverse);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._ProjMatrix, projMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._InvProjMatrix, projMatrix.inverse);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._ViewProjMatrix, viewProjMatrix);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._InvViewProjMatrix, viewProjMatrix.inverse);
cmd.SetComputeVectorParam(cs, HDShaderIDs._InvProjParam, invProjParam);
cmd.SetComputeVectorParam(cs, HDShaderIDs._ScreenSize, screenSize);
cmd.SetComputeMatrixParam(cs, HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetComputeVectorArrayParam(cs, HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
// Copy values set by Unity which are not configured in scripts.
cmd.SetComputeVectorParam(cs, HDShaderIDs.unity_OrthoParams, Shader.GetGlobalVector(HDShaderIDs.unity_OrthoParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ProjectionParams, Shader.GetGlobalVector(HDShaderIDs._ProjectionParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ScreenParams, Shader.GetGlobalVector(HDShaderIDs._ScreenParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ZBufferParams, Shader.GetGlobalVector(HDShaderIDs._ZBufferParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._WorldSpaceCameraPos, Shader.GetGlobalVector(HDShaderIDs._WorldSpaceCameraPos));
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/Camera/HDCamera.cs.meta


fileFormatVersion: 2
guid: fc3be78d851339943a523c1ffaae1c6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/AdditionalData.meta


fileFormatVersion: 2
guid: 969f45cd0fa680646a77e82d620ba21d
folderAsset: yes
timeCreated: 1498051186
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

390
ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs


using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using UnityEngine.Rendering;
using UnityObject = UnityEngine.Object;
using System.Reflection;
using UnityEngine.Rendering.PostProcessing;
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Flags]
public enum ClearFlag
{
ClearNone = 0,
ClearColor = 1,
ClearDepth = 2
}
public class Utilities
{
#if UNITY_EDITOR
public static string GetHDRenderPipelinePath()
{
// User can create their own directory for SRP, so we need to find the current path that they use.
// We know that DefaultHDMaterial exist and we know where it is, let's use that to find the current directory.
var guid = AssetDatabase.FindAssets("DefaultHDMaterial t:material");
string path = AssetDatabase.GUIDToAssetPath(guid[0]);
path = Path.GetDirectoryName(path); // Asset is in HDRenderPipeline/RenderPipelineResources/DefaultHDMaterial.mat
path = path.Replace("RenderPipelineResources", ""); // Keep only path with HDRenderPipeline
return path;
}
#endif
public static List<RenderPipelineMaterial> GetRenderPipelineMaterialList()
{
List<RenderPipelineMaterial> materialList = new List<RenderPipelineMaterial>();
var baseType = typeof(RenderPipelineMaterial);
var assembly = baseType.Assembly;
System.Type[] types = assembly.GetTypes();
foreach (System.Type type in types)
{
if (type.IsSubclassOf(baseType))
{
// Create an instance object of the given type
var obj = (RenderPipelineMaterial)Activator.CreateInstance(type);
materialList.Add(obj);
}
}
// Note: If there is a need for an optimization in the future of this function, user can simply fill the materialList manually by commenting the code abode and
// adding to the list material they used in their game.
// materialList.Add(new Lit());
// materialList.Add(new Unlit());
// ...
return materialList;
}
public const RendererConfiguration kRendererConfigurationBakedLighting = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume;
// Render Target Management.
public const ClearFlag kClearAll = ClearFlag.ClearDepth | ClearFlag.ClearColor;
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
cmd.SetRenderTarget(buffer, miplevel, cubemapFace);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.ClearNone, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(cmd, buffer, clearFlag, Color.black, miplevel, cubemapFace);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(cmd, colorBuffer, depthBuffer, ClearFlag.ClearNone, Color.black, miplevel, cubemapFace);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(cmd, colorBuffer, depthBuffer, clearFlag, Color.black, miplevel, cubemapFace);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer)
{
SetRenderTarget(cmd, colorBuffers, depthBuffer, ClearFlag.ClearNone, Color.black);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.ClearNone)
{
SetRenderTarget(cmd, colorBuffers, depthBuffer, clearFlag, Color.black);
}
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor)
{
cmd.SetRenderTarget(colorBuffers, depthBuffer);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
}
public static void ClearCubemap(CommandBuffer cmd, RenderTargetIdentifier buffer, Color clearColor)
{
for(int i = 0 ; i < 6 ; ++i)
{
SetRenderTarget(cmd, buffer, ClearFlag.ClearColor, Color.black, 0, (CubemapFace)i);
}
}
// Post-processing misc
public static bool IsPostProcessingActive(PostProcessLayer layer)
{
return layer != null
&& layer.enabled;
}
public static bool IsTemporalAntialiasingActive(PostProcessLayer layer)
{
return IsPostProcessingActive(layer)
&& layer.antialiasingMode == PostProcessLayer.Antialiasing.TemporalAntialiasing
&& layer.temporalAntialiasing.IsSupported();
}
// Miscellanous
public static Material CreateEngineMaterial(string shaderPath)
{
var mat = new Material(Shader.Find(shaderPath))
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static Material CreateEngineMaterial(Shader shader)
{
var mat = new Material(shader)
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static void Destroy(UnityObject obj)
{
if (obj != null)
{
#if UNITY_EDITOR
if (Application.isPlaying)
UnityObject.Destroy(obj);
else
UnityObject.DestroyImmediate(obj);
#else
UnityObject.Destroy(obj);
#endif
}
}
public static void SafeRelease(ComputeBuffer buffer)
{
if (buffer != null)
buffer.Release();
}
public static string GetFieldPath<TType, TValue>(Expression<Func<TType, TValue>> expr)
{
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
var ue = expr.Body as UnaryExpression;
me = (ue != null ? ue.Operand : null) as MemberExpression;
break;
default:
me = expr.Body as MemberExpression;
break;
}
var members = new List<string>();
while (me != null)
{
members.Add(me.Member.Name);
me = me.Expression as MemberExpression;
}
var sb = new StringBuilder();
for (int i = members.Count - 1; i >= 0; i--)
{
sb.Append(members[i]);
if (i > 0) sb.Append('.');
}
return sb.ToString();
}
public struct ProfilingSample
: IDisposable
{
bool disposed;
CommandBuffer cmd;
string name;
public ProfilingSample(string _name, CommandBuffer _cmd)
{
cmd = _cmd;
disposed = false;
name = _name;
cmd.BeginSample(name);
}
public void Dispose()
{
Dispose(true);
}
// Protected implementation of Dispose pattern.
void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
cmd.EndSample(name);
}
disposed = true;
}
}
public static Matrix4x4 GetViewProjectionMatrix(Matrix4x4 worldToViewMatrix, Matrix4x4 projectionMatrix)
{
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
var gpuProj = GL.GetGPUProjectionMatrix(projectionMatrix, false);
var gpuVP = gpuProj * worldToViewMatrix * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API.
return gpuVP;
}
public static void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public static void SelectKeyword(Material material, string keyword1, string keyword2, bool enableFirst)
{
material.EnableKeyword(enableFirst ? keyword1 : keyword2);
material.DisableKeyword(enableFirst ? keyword2 : keyword1);
}
public static void SelectKeyword(Material material, string[] keywords, int enabledKeywordIndex)
{
material.EnableKeyword(keywords[enabledKeywordIndex]);
for (int i = 0; i < keywords.Length; i++)
{
if (i != enabledKeywordIndex)
{
material.DisableKeyword(keywords[i]);
}
}
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier colorBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
commandBuffer.SetRenderTarget(colorBuffer);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthStencilBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
commandBuffer.SetRenderTarget(colorBuffer, depthStencilBuffer);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
commandBuffer.SetRenderTarget(colorBuffers, depthStencilBuffer);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
// Important: the first RenderTarget must be created with 0 depth bits!
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier[] colorBuffers,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
// It is currently not possible to have MRT without also setting a depth target.
// To work around this deficiency of the CommandBuffer.SetRenderTarget() API,
// we pass the first color target as the depth target. If it has 0 depth bits,
// no depth target ends up being bound.
DrawFullScreen(commandBuffer, material, colorBuffers, colorBuffers[0], properties, shaderPassID);
}
// Helper to help to display debug info on screen
static float overlayLineHeight = -1.0f;
public static void NextOverlayCoord(ref float x, ref float y, float overlayWidth, float overlayHeight, float width)
{
x += overlayWidth;
overlayLineHeight = Mathf.Max(overlayHeight, overlayLineHeight);
// Go to next line if it goes outside the screen.
if (x + overlayWidth > width)
{
x = 0;
y -= overlayLineHeight;
overlayLineHeight = -1.0f;
}
}
// Just a sort function that doesn't allocate memory
// Note: Shoud be repalc by a radix sort for positive integer
static public int Partition(uint[] numbers, int left, int right)
{
uint pivot = numbers[left];
while (true)
{
while (numbers[left] < pivot)
left++;
while (numbers[right] > pivot)
right--;
if (left < right)
{
uint temp = numbers[right];
numbers[right] = numbers[left];
numbers[left] = temp;
}
else
{
return right;
}
}
}
static public void QuickSort(uint[] arr, int left, int right)
{
// For Recusrion
if (left < right)
{
int pivot = Partition(arr, left, right);
if (pivot > 1)
QuickSort(arr, left, pivot - 1);
if (pivot + 1 < right)
QuickSort(arr, pivot + 1, right);
}
}
}
}

/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs.meta → /ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs.meta

/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalCameraData.cs.meta → /ScriptableRenderPipeline/HDRenderPipeline/Camera/HDAdditionalCameraData.cs.meta

/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs.meta → /ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs.meta

/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalCameraData.cs → /ScriptableRenderPipeline/HDRenderPipeline/Camera/HDAdditionalCameraData.cs

/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs → /ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs

正在加载...
取消
保存