浏览代码

Merge branch 'master' into LightweightPipeline

# Conflicts:
#	Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader
/RenderPassXR_Sandbox
Felipe Lira 7 年前
当前提交
7d62ca8f
共有 569 个文件被更改,包括 4273 次插入2637 次删除
  1. 2
      Assets/GraphicsTests/Framework/Editor/TestFramework.cs
  2. 4
      Assets/GraphicsTests/RenderPipeline/HDRenderPipeline/HDRPAsset/HDRenderPipelineResourcesTest.asset
  3. 108
      Assets/ScriptableRenderPipeline/BasicRenderPipeline/BasicRenderPipeline.cs
  4. 4
      Assets/ScriptableRenderPipeline/BasicRenderPipeline/BasicRenderPipelineShader.shader
  5. 11
      Assets/ScriptableRenderPipeline/Core/Shadow/AdditionalShadowData.cs
  6. 67
      Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  7. 4
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs
  8. 12
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs.hlsl
  9. 56
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowUtilities.cs
  10. 5
      Assets/ScriptableRenderPipeline/Core/Shadow/VectorArray.cs
  11. 71
      Assets/ScriptableRenderPipeline/Core/TextureCache.cs
  12. 42
      Assets/ScriptableRenderPipeline/Fptl/ClusteredUtils.h
  13. 11
      Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs
  14. 2
      Assets/ScriptableRenderPipeline/Fptl/LightDefinitions.cs.hlsl
  15. 10
      Assets/ScriptableRenderPipeline/Fptl/LightingConvexHullUtils.hlsl
  16. 16
      Assets/ScriptableRenderPipeline/Fptl/LightingTemplate.hlsl
  17. 24
      Assets/ScriptableRenderPipeline/Fptl/LightingUtils.hlsl
  18. 6
      Assets/ScriptableRenderPipeline/Fptl/ShadowDispatch.hlsl
  19. 26
      Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-bigtile.compute
  20. 26
      Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-clustered.compute
  21. 17
      Assets/ScriptableRenderPipeline/Fptl/lightlistbuild.compute
  22. 11
      Assets/ScriptableRenderPipeline/Fptl/scrbound.compute
  23. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs
  24. 91
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  25. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  26. 39
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.hlsl
  27. 124
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugFullScreen.shader
  28. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugViewMaterialGBuffer.shader
  29. 42
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugViewTiles.shader
  30. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/LightingDebugPanel.cs
  31. 39
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  32. 518
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  33. 613
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset
  34. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.cs
  35. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.shader
  36. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusionSettings.cs
  37. 18
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader
  38. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Forward.hlsl
  39. 64
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  40. 180
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  41. 42
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ClusteredUtils.hlsl
  42. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/LightingConvexHullUtils.hlsl
  43. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  44. 713
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  45. 22
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  46. 36
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  47. 306
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  48. 14
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/builddispatchindirect.compute
  49. 43
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-bigtile.compute
  50. 43
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-clustered.compute
  51. 37
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild.compute
  52. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/materialflags.compute
  53. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/scrbound.compute
  54. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Builtin/BuiltinData.hlsl
  55. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit.meta
  56. 325
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  57. 67
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  58. 65
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  59. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  60. 308
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  61. 61
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  62. 67
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  63. 843
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  64. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  65. 215
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  66. 24
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  67. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  68. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  69. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  70. 225
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader
  71. 122
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/FoliageSSSProfile.asset
  72. 156
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset
  73. 197
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  74. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  75. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs
  76. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader
  77. 42
      Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/CameraMotionVectors.shader
  78. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/HDRenderPipelineResources.asset
  79. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs
  80. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawSssProfile.shader
  81. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader
  82. 3
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettings.cs
  83. 11
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
  84. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassVelocity.hlsl
  85. 3
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  86. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs
  87. 191
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs
  88. 21
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  89. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkySettings.cs
  90. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
  91. 96
      Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  92. 7
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader
  93. 2
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc
  94. 7
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightUnlit.shader
  95. 1
      Assets/ScriptableRenderPipeline/ShaderLibrary/API/D3D11.hlsl
  96. 1
      Assets/ScriptableRenderPipeline/ShaderLibrary/API/Metal.hlsl
  97. 1
      Assets/ScriptableRenderPipeline/ShaderLibrary/API/PSSL.hlsl
  98. 21
      Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl
  99. 33
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  100. 28
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl

2
Assets/GraphicsTests/Framework/Editor/TestFramework.cs


yield return null;
}
while (Lightmapping.isRunning)
while (UnityEditor.Lightmapping.isRunning)
{
yield return null;
}

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


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

108
Assets/ScriptableRenderPipeline/BasicRenderPipeline/BasicRenderPipeline.cs


using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.XR;
// Very basic scriptable rendering loop example:
// - Use with BasicRenderPipelineShader.shader (the loop expects "BasicPass" pass type to exist)

[ExecuteInEditMode]
public class BasicRenderPipeline : RenderPipelineAsset
{
public bool UseIntermediateRenderTargetBlit;
#if UNITY_EDITOR
[UnityEditor.MenuItem("RenderPipeline/Create BasicRenderPipeline")]
static void CreateBasicRenderPipeline()

protected override IRenderPipeline InternalCreatePipeline()
{
return new BasicRenderPipelineInstance();
return new BasicRenderPipelineInstance(UseIntermediateRenderTargetBlit);
bool useIntermediateBlit;
public BasicRenderPipelineInstance()
{
useIntermediateBlit = false;
}
public BasicRenderPipelineInstance(bool useIntermediate)
{
useIntermediateBlit = useIntermediate;
}
BasicRendering.Render(renderContext, cameras);
BasicRendering.Render(renderContext, cameras, useIntermediateBlit);
static void ConfigureAndBindIntermediateRenderTarget(ScriptableRenderContext context, Camera cam, bool stereoEnabled, out RenderTargetIdentifier intermediateRTID, out bool isRTTexArray)
{
var intermediateRT = Shader.PropertyToID("_IntermediateTarget");
intermediateRTID = new RenderTargetIdentifier(intermediateRT);
isRTTexArray = false;
var bindIntermediateRTCmd = CommandBufferPool.Get("Bind intermediate RT");
if (stereoEnabled)
{
RenderTextureDescriptor xrDesc = XRSettings.eyeTextureDesc;
xrDesc.depthBufferBits = 24;
if (xrDesc.dimension == TextureDimension.Tex2DArray)
isRTTexArray = true;
bindIntermediateRTCmd.GetTemporaryRT(intermediateRT, xrDesc, FilterMode.Point);
}
else
{
int w = cam.pixelWidth;
int h = cam.pixelHeight;
bindIntermediateRTCmd.GetTemporaryRT(intermediateRT, w, h, 24, FilterMode.Point, RenderTextureFormat.Default, RenderTextureReadWrite.Default, 1, true);
}
if (isRTTexArray)
bindIntermediateRTCmd.SetRenderTarget(intermediateRTID, 0, CubemapFace.Unknown, -1); // depthSlice == -1 => bind all slices
else
bindIntermediateRTCmd.SetRenderTarget(intermediateRTID);
context.ExecuteCommandBuffer(bindIntermediateRTCmd);
CommandBufferPool.Release(bindIntermediateRTCmd);
}
static void BlitFromIntermediateToCameraTarget(ScriptableRenderContext context, RenderTargetIdentifier intermediateRTID, bool isRTTexArray)
{
var blitIntermediateRTCmd = CommandBufferPool.Get("Copy intermediate RT to default RT");
if (isRTTexArray)
{
// Currently, Blit does not allow specification of a slice in a texture array.
// It can use the CurrentActive render texture's bound slices, so we use that
// as a temporary workaround.
blitIntermediateRTCmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, 0, CubemapFace.Unknown, -1);
blitIntermediateRTCmd.Blit(intermediateRTID, BuiltinRenderTextureType.CurrentActive);
}
else
blitIntermediateRTCmd.Blit(intermediateRTID, BuiltinRenderTextureType.CameraTarget);
context.ExecuteCommandBuffer(blitIntermediateRTCmd);
CommandBufferPool.Release(blitIntermediateRTCmd);
}
public static void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras)
public static void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras, bool useIntermediateBlitPath)
bool stereoEnabled = XRSettings.isDeviceActive;
if (!CullResults.GetCullingParameters(camera, out cullingParams))
// Stereo-aware culling parameters are configured to perform a single cull for both eyes
if (!CullResults.GetCullingParameters(camera, stereoEnabled, out cullingParams))
continue;
CullResults cull = new CullResults();
CullResults.Cull(ref cullingParams, context, ref cull);

context.SetupCameraProperties(camera);
// If stereo is enabled, we also configure stereo matrices, viewports, and XR device render targets
context.SetupCameraProperties(camera, stereoEnabled);
// Draws in-between [Start|Stop]MultiEye are stereo-ized by engine
if (stereoEnabled)
context.StartMultiEye(camera);
RenderTargetIdentifier intermediateRTID = new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive);
bool isIntermediateRTTexArray = false;
if (useIntermediateBlitPath)
{
ConfigureAndBindIntermediateRenderTarget(context, camera, stereoEnabled, out intermediateRTID, out isIntermediateRTTexArray);
}
// clear depth buffer
var cmd = CommandBufferPool.Get();

settings.sorting.flags = SortFlags.CommonTransparent;
settings.inputFilter.SetQueuesTransparent();
context.DrawRenderers(ref settings);
if (useIntermediateBlitPath)
{
BlitFromIntermediateToCameraTarget(context, intermediateRTID, isIntermediateRTTexArray);
}
if (stereoEnabled)
{
context.StopMultiEye(camera);
// StereoEndRender will reset state on the camera to pre-Stereo settings,
// and invoke XR based events/callbacks.
context.StereoEndRender(camera);
}
context.Submit();
}

4
Assets/ScriptableRenderPipeline/BasicRenderPipeline/BasicRenderPipelineShader.shader


#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma shader_feature _METALLICGLOSSMAP
#include "UnityCG.cginc"
#include "UnityStandardBRDF.cginc"

float3 positionWS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float4 hpos : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
float4 _MainTex_ST;

v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
o.hpos = UnityObjectToClipPos(v.vertex);
o.positionWS = mul(unity_ObjectToWorld, v.vertex).xyz;

11
Assets/ScriptableRenderPipeline/Core/Shadow/AdditionalShadowData.cs


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

private ShadowData[] shadowDatas = new ShadowData[0];
public int cascadeCount { get { return shadowCascadeCount; } }
public void GetShadowCascades(out int cascadeCount, out float[] cascadeRatios) { cascadeCount = shadowCascadeCount; cascadeRatios = shadowCascadeRatios; }
public void GetShadowCascades(out int cascadeCount, out float[] cascadeRatios, out float[] cascadeBorders) { cascadeCount = shadowCascadeCount; cascadeRatios = shadowCascadeRatios; cascadeBorders = shadowCascadeBorders; }
public void GetShadowAlgorithm(out int algorithm, out int variant, out int precision) { algorithm = shadowAlgorithm; variant = shadowVariant; precision = shadowPrecision; }
public void SetShadowAlgorithm(int algorithm, int variant, int precision, int format, int[] data)
{

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

m_ShadowDatas = serializedObject.FindProperty( "shadowDatas" );
m_ShadowCascadeCount = serializedObject.FindProperty( "shadowCascadeCount" );
m_ShadowCascadeRatios = serializedObject.FindProperty( "shadowCascadeRatios" );
m_ShadowCascadeBorders = serializedObject.FindProperty( "shadowCascadeBorders" );
}
public override void OnInspectorGUI()
{

int newcnt = m_ShadowCascadeCount.intValue <= 0 ? 1 : (m_ShadowCascadeCount.intValue > kMaxCascades ? kMaxCascades : m_ShadowCascadeCount.intValue);
m_ShadowCascadeCount.intValue = newcnt;
m_ShadowCascadeRatios.arraySize = newcnt-1;
m_ShadowCascadeBorders.arraySize = newcnt;
}
for (int i = 0; i < m_ShadowCascadeBorders.arraySize; i++)
{
UnityEditor.EditorGUILayout.Slider( m_ShadowCascadeBorders.GetArrayElementAtIndex( i ), 0.0f, 1.0f, new GUIContent( "Transition " + i ) );
}
UnityEditor.EditorGUI.indentLevel--;
}

67
Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs


protected uint[] m_TmpWidths = new uint[ShadowmapBase.ShadowRequest.k_MaxFaceCount];
protected uint[] m_TmpHeights = new uint[ShadowmapBase.ShadowRequest.k_MaxFaceCount];
protected Vector4[] m_TmpSplits = new Vector4[k_MaxCascadesInShader];
protected float[] m_TmpScales = new float[((k_MaxCascadesInShader+3)/4)*4];
protected float[] m_TmpBorders = new float[((k_MaxCascadesInShader+3)/4)*4];
protected ShadowAlgoVector m_SupportedAlgorithms = new ShadowAlgoVector( 0, false );
protected Material m_DebugMaterial = null;

public bool IsValid() { return viewport.width > 0 && viewport.height > 0; }
}
protected struct CachedEntry : IComparable<CachedEntry>
protected class CachedEntry : IComparable<CachedEntry>
{
public Key key;
public Data current;

int cascadeCnt = 0;
float[] cascadeRatios = null;
float[] cascadeBorders = null;
if( sr.shadowType == GPUShadowType.Directional )
{
AdditionalShadowData asd = lights[sr.index].light.GetComponent<AdditionalShadowData>();

asd.GetShadowCascades( out cascadeCnt, out cascadeRatios );
asd.GetShadowCascades( out cascadeCnt, out cascadeRatios, out cascadeBorders );
}

// per light information, so not all fields contain valid data.
// Shader code must make sure to read per face data from per face entries.
sd.texelSizeRcp = new Vector2( m_WidthRcp, m_HeightRcp );
sd.texelSizeRcp = new Vector4( m_WidthRcp, m_HeightRcp, 1.0f / widths[0], 1.0f / heights[0] );
sd.PackShadowType( sr.shadowType, sanitizedAlgo );
sd.payloadOffset = payload.Count();
entries.AddUnchecked( sd );

}
// read
float texelSizeX = 1.0f, texelSizeY = 1.0f;
Matrix4x4 vp;
Matrix4x4 vp, invvp;
vp = ShadowUtils.ExtractPointLightMatrix( lights[sr.index], key.faceIdx, 2.0f, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData );
vp = ShadowUtils.ExtractPointLightMatrix( lights[sr.index], key.faceIdx, 2.0f, out ce.current.view, out ce.current.proj, out invvp, out ce.current.lightDir, out ce.current.splitData );
vp = ShadowUtils.ExtractSpotLightMatrix( lights[sr.index], out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData );
vp = ShadowUtils.ExtractSpotLightMatrix( lights[sr.index], out ce.current.view, out ce.current.proj, out invvp, out ce.current.lightDir, out ce.current.splitData );
vp = ShadowUtils.ExtractDirectionalLightMatrix( lights[sr.index], key.faceIdx, cascadeCnt, cascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int) sr.index );
vp = ShadowUtils.ExtractDirectionalLightMatrix( lights[sr.index], key.faceIdx, cascadeCnt, cascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out invvp, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int) sr.index );
{
int face = (int)key.faceIdx;
texelSizeX = 2.0f / ce.current.proj.m00;
texelSizeY = 2.0f / ce.current.proj.m11;
m_TmpScales[face] = Mathf.Max( texelSizeX, texelSizeY );
m_TmpBorders[face] = cascadeBorders[face];
}
vp = Matrix4x4.identity; // should never happen, though
vp = invvp = Matrix4x4.identity; // should never happen, though
if (cameraRelativeRendering)
{
Vector3 camPosWS = camera.transform.position;

m_EntryCache[ceIdx] = ce;
sd.worldToShadow = vp.transpose; // apparently we need to transpose matrices that are sent to HLSL
sd.shadowToWorld = invvp.transpose;
sd.textureSize = new Vector4( m_Width, m_Height, ce.current.viewport.width, ce.current.viewport.height );
sd.texelSizeRcp = new Vector4( m_WidthRcp, m_HeightRcp, 1.0f / ce.current.viewport.width, 1.0f / ce.current.viewport.height );
sd.PackShadowmapId( m_TexSlot, m_SampSlot, ce.current.slice );
sd.PackShadowType( sr.shadowType, sanitizedAlgo );

// Returns how many entries will be written into the payload buffer per light.
virtual protected uint ReservePayload( ShadowRequest sr )
{
uint payloadSize = sr.shadowType == GPUShadowType.Directional ? k_MaxCascadesInShader : 0;
uint payloadSize = sr.shadowType == GPUShadowType.Directional ? (k_MaxCascadesInShader + ((uint)m_TmpScales.Length / 4) + ((uint)m_TmpBorders.Length / 4)) : 0;
payloadSize += ShadowUtils.ExtractAlgorithm( sr.shadowAlgorithm ) == ShadowAlgorithm.PCF ? 1u : 0;
return payloadSize;
}

{
sp.Set( m_TmpSplits[i] );
payload[payloadOffset] = sp;
}
for( int i = 0; i < m_TmpScales.Length; i += 4 )
{
sp.Set( m_TmpScales[i+0], m_TmpScales[i+1], m_TmpScales[i+2], m_TmpScales[i+3] );
payload[payloadOffset] = sp;
payloadOffset++;
}
for( int i = 0; i < m_TmpBorders.Length; i += 4 )
{
sp.Set( m_TmpBorders[i+0], m_TmpBorders[i+1], m_TmpBorders[i+2], m_TmpBorders[i+3] );
payload[payloadOffset] = sp;
payloadOffset++;
}
}
ShadowAlgorithm algo; ShadowVariant vari; ShadowPrecision prec;

ShadowDataVector shadowVector = m_ShadowCtxt.shadowDatas;
ShadowPayloadVector payloadVector = m_ShadowCtxt.payloads;
m_ShadowIndices.Reset( m_TmpRequests.Count() );
AllocateShadows( frameId, camera, cameraRelativeRendering, lights, totalGranted, ref m_TmpRequests, ref m_ShadowIndices, ref shadowVector, ref payloadVector );
if (!AllocateShadows(frameId, camera, cameraRelativeRendering, lights, totalGranted, ref m_TmpRequests, ref m_ShadowIndices, ref shadowVector, ref payloadVector))
{
shadowRequestsCount = 0;
return;
}
Debug.Assert( m_TmpRequests.Count() == m_ShadowIndices.Count() );
m_ShadowCtxt.shadowDatas = shadowVector;
m_ShadowCtxt.payloads = payloadVector;

m_TmpSortKeys.ExtractTo( ref shadowRequests, (long idx) => { return (int) idx; } );
}
protected override void AllocateShadows( FrameId frameId, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload )
protected override bool AllocateShadows( FrameId frameId, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload )
{
ShadowData sd = new ShadowData();
shadowDatas.Reserve( totalGranted );

GPUShadowType shadowtype = GetShadowLightType(l);
// current bias value range is way too large, so scale by 0.01 for now until we've decided whether to actually keep this value or not.
sd.bias = 0.01f * (SystemInfo.usesReversedZBuffer ? l.shadowBias : -l.shadowBias);
sd.normalBias = 100.0f * l.shadowNormalBias;
sd.normalBias = 2.0f * l.shadowNormalBias;
shadowIndices.AddUnchecked( (int) shadowDatas.Count() );

smidx++;
}
if( smidx == k_MaxShadowmapPerType )
throw new ArgumentException("The requested shadows do not fit into any shadowmap.");
{
Debug.LogError("The requested shadows do not fit into any shadowmap.");
return false;
}
}
// final step for shadowmaps that only gather data during the previous loop and do the actual allocation once they have all the data.

throw new ArgumentException( "Shadow allocation failed in the ReserveFinalize step." );
{
Debug.LogError("Shadow allocation failed in the ReserveFinalize step." );
return false;
}
return true;
}
public override void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights)

4
Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs


{
// shadow texture related params (need to be set by ShadowmapBase and derivatives)
public Matrix4x4 worldToShadow; // to light space matrix
public Matrix4x4 shadowToWorld; // from light space matrix
public Vector4 textureSize; // the shadowmap's size in x and y. xy is texture relative, zw is viewport relative.
public Vector4 texelSizeRcp; // reciprocal of the shadowmap's texel size in x and y. xy is texture relative, zw is viewport relative.
public uint id; // packed texture id, sampler id and slice idx
public uint shadowType; // determines the shadow algorithm, i.e. which map to sample and how to interpret the data

// prune the shadow requests - may modify shadowRequests and shadowsCountshadowRequestsCount
protected abstract void PruneShadowCasters( Camera camera, List<VisibleLight> lights, ref VectorArray<int> shadowRequests, ref VectorArray<ShadowmapBase.ShadowRequest> requestsGranted, out uint totalRequestCount );
// allocate the shadow requests in the shadow map, only is called if shadowsCount > 0 - may modify shadowRequests and shadowsCount
protected abstract void AllocateShadows( FrameId frameId, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
protected abstract bool AllocateShadows( FrameId frameId, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
public abstract uint GetShadowMapCount();
public abstract uint GetShadowMapSliceCount(uint shadowMapIndex);

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


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

struct ShadowData
{
float4x4 worldToShadow;
float4x4 shadowToWorld;
float4 textureSize;
float4 texelSizeRcp;
uint id;
uint shadowType;

{
return value.worldToShadow;
}
float4x4 GetShadowToWorld(ShadowData value)
{
return value.shadowToWorld;
}
}
float4 GetTextureSize(ShadowData value)
{
return value.textureSize;
}
float4 GetTexelSizeRcp(ShadowData value)
{

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


}
public class ShadowUtils
{
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
public static void InvertView( ref Matrix4x4 view, out Matrix4x4 invview )
{
invview = Matrix4x4.zero;
invview.m00 = view.m00; invview.m01 = view.m10; invview.m02 = view.m20;
invview.m10 = view.m01; invview.m11 = view.m11; invview.m12 = view.m21;
invview.m20 = view.m02; invview.m21 = view.m12; invview.m22 = view.m22;
invview.m33 = 1.0f;
invview.m03 = -(invview.m00 * view.m03 + invview.m01 * view.m13 + invview.m02 * view.m23);
invview.m13 = -(invview.m10 * view.m03 + invview.m11 * view.m13 + invview.m12 * view.m23);
invview.m23 = -(invview.m20 * view.m03 + invview.m21 * view.m13 + invview.m22 * view.m23);
}
public static void InvertOrthographic( ref Matrix4x4 proj, ref Matrix4x4 view, out Matrix4x4 vpinv )
{
Matrix4x4 invview;
InvertView( ref view, out invview );
Matrix4x4 invproj = Matrix4x4.zero;
invproj.m00 = 1.0f / proj.m00;
invproj.m11 = 1.0f / proj.m11;
invproj.m22 = 1.0f / proj.m22;
invproj.m33 = 1.0f;
invproj.m03 = proj.m03 * invproj.m00;
invproj.m13 = proj.m13 * invproj.m11;
invproj.m23 = - proj.m23 * invproj.m22;
vpinv = invview * invproj;
}
public static void InvertPerspective( ref Matrix4x4 proj, ref Matrix4x4 view, out Matrix4x4 vpinv )
{
Matrix4x4 invview;
InvertView(ref view, out invview);
Matrix4x4 invproj = Matrix4x4.zero;
invproj.m00 = 1.0f / proj.m00;
invproj.m03 = proj.m02 * invproj.m00;
invproj.m11 = 1.0f / proj.m11;
invproj.m13 = proj.m12 * invproj.m11;
invproj.m22 = 0.0f;
invproj.m23 = -1.0f;
invproj.m33 = proj.m22 / proj.m23;
invproj.m32 = invproj.m33 / proj.m22;
vpinv = invview * invproj;
}
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData )
{
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );

float fov = vl.spotAngle;
proj = Matrix4x4.Perspective(fov, 1.0f, znear, zfar);
// and the compound
InvertPerspective( ref proj, ref view, out vpinverse );
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData )
{
Debug.Assert( faceIdx <= (uint) CubemapFace.NegativeZ, "Tried to extract cubemap face " + faceIdx + "." );

float nearPlane = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
proj = Matrix4x4.Perspective( 90.0f + fovBias, 1.0f, nearPlane, farPlane );
// and the compound
InvertPerspective( ref proj, ref view, out vpinverse );
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, float[] splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, float[] splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
{
Debug.Assert( width == height, "Currently the cascaded shadow mapping code requires square cascades." );
splitData = new ShadowSplitData();

ratios[i] = splitRatio[i];
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, ratios, (int) width, nearPlaneOffset, out view, out proj, out splitData );
// and the compound
InvertOrthographic( ref proj, ref view, out vpinverse );
return proj * view;
}

5
Assets/ScriptableRenderPipeline/Core/Shadow/VectorArray.cs


{
for (idx = 0; idx < m_count; ++idx)
{
T obj = this[idx];
if (compareDelegate(ref designator, ref obj))
if (compareDelegate(ref designator, ref m_array[m_offset + idx]))
return true;
}
idx = k_InvalidIdx;

{
for (idx = 0; idx < m_count; ++idx)
{
if (this[idx].Equals(designator))
if (m_array[m_offset + idx].Equals(designator))
return true;
}
idx = k_InvalidIdx;

71
Assets/ScriptableRenderPipeline/Core/TextureCache.cs


if (!TextureCache.supportsCubemapArrayTextures)
{
if (!m_CubeBlitMaterial) m_CubeBlitMaterial = new Material(Shader.Find("Hidden/CubeToPano"));
if (!m_CubeBlitMaterial) m_CubeBlitMaterial = new Material(Shader.Find("Hidden/CubeToPano")) { hideFlags = HideFlags.HideAndDontSave };
int panoWidthTop = 4 * width;
int panoHeightTop = 2 * width;

m_StagingRTs = new RenderTexture[m_NumPanoMipLevels];
for (int m = 0; m < m_NumPanoMipLevels; m++)
{
m_StagingRTs[m] = new RenderTexture(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), 0, RenderTextureFormat.ARGBHalf);
m_StagingRTs[m] = new RenderTexture(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), 0, RenderTextureFormat.ARGBHalf) { hideFlags = HideFlags.HideAndDontSave };
}
if (m_CubeBlitMaterial)

{
protected int m_NumMipLevels;
static int s_GlobalTextureCacheVersion = 0;
int m_TextureCacheVersion = 0;
#if UNITY_EDITOR
static int s_TextureCacheIdGenerator = 0;
int m_TextureCacheId = 0;
#if UNITY_EDITOR
static bool s_ForceReinjectGlobalFirst = false;
static bool s_ForceReinjectGlobalSecond = false;
static int s_GlobalSecondSetByTexCacheID = -1;
// here we receive the in-editor updated textures. These must be reinjected into
// any texture cache which has a stale copy of it. However, we don't have a this-pointer to the texture cache
// so instead we defer this to NewFrame() where we force reinject.
// Ideally we'd build up a list here of textures which are to be reinjected but unfortunately the texture we receive
// is an intermediate one and not the final compressed one. So instead we will have to reinject all in NewFrame().
s_GlobalTextureCacheVersion++;
s_ForceReinjectGlobalFirst = true;
s_ForceReinjectGlobalSecond = false;
s_GlobalSecondSetByTexCacheID = -1;
#endif
#endif
public static bool isMobileBuildTarget
{

{
sliceIndex = m_LocatorInSliceArray[texId];
bFoundAvailOrExistingSlice = true;
#if UNITY_EDITOR
if(m_TextureCacheVersion!=s_GlobalTextureCacheVersion)
{
m_TextureCacheVersion++;
Debug.Assert(m_TextureCacheVersion <= s_GlobalTextureCacheVersion);
bSwapSlice = true; // force a reinject.
}
#endif
//assert(m_SliceArray[sliceIndex].TexID==TexID);
}

//for(int q=1; q<m_numTextures; q++)
// assert(m_SliceArray[m_SortedIdxArray[q-1]].CountLRU>=m_SliceArray[m_SortedIdxArray[q]].CountLRU);
#if UNITY_EDITOR
// one or more textures got updated in editor. Unfortunately we do not know exactly which since
// OnPostprocessTexture() receives intermediate uncompressed textures. So we will have to reinject all slices to force an update.
if(s_ForceReinjectGlobalSecond && s_GlobalSecondSetByTexCacheID==m_TextureCacheId)
{
s_ForceReinjectGlobalSecond = false;
s_GlobalSecondSetByTexCacheID = -1;
}
if(s_ForceReinjectGlobalFirst)
{
s_ForceReinjectGlobalSecond = true;
s_GlobalSecondSetByTexCacheID = m_TextureCacheId;
s_ForceReinjectGlobalFirst = false;
}
if(s_ForceReinjectGlobalSecond)
{
// all texture caches must loop through and force a reinject on all entries when this is true.
for(int i = 0; i < m_NumTextures; i++)
{
var texID = m_SliceArray[i].texId;
if(texID!=g_InvalidTexID)
{
Texture texture = (Texture) EditorUtility.InstanceIDToObject((int) texID);
if(texture!=null) TransferToSlice(i, texture);
}
}
}
#endif
}
protected TextureCache()

#if UNITY_EDITOR
m_TextureCacheId = s_TextureCacheIdGenerator; // assign an ID so we can tell the caches apart
++s_TextureCacheIdGenerator; // static/global
#endif
}
public virtual void TransferToSlice(int sliceIndex, Texture texture)

42
Assets/ScriptableRenderPipeline/Fptl/ClusteredUtils.h


return geomSeries / (g_fFarPlane - g_fNearPlane);
}
float LogBase(float x, float b)
{
return log2(x) / log2(b);
}
int SnapToClusterIdxFlex(float z_in, float suggestedBase, bool logBasePerTile)
{
#if USE_LEFTHAND_CAMERASPACE

#endif
float userscale = g_fClustScale;
if (logBasePerTile)
userscale = GetScaleFromBase(suggestedBase);
//float userscale = g_fClustScale;
//if (logBasePerTile)
// userscale = GetScaleFromBase(suggestedBase);
const float dist = max(0, z - g_fNearPlane);
return (int)clamp(log2(dist * userscale * (suggestedBase - 1.0f) + 1) / log2(suggestedBase), 0.0, (float)((1 << g_iLog2NumClusters) - 1));
//const float dist = max(0, z - g_fNearPlane);
//return (int)clamp(log2(dist * userscale * (suggestedBase - 1.0f) + 1) / log2(suggestedBase), 0.0, (float)((1 << g_iLog2NumClusters) - 1));
const int C = 1 << g_iLog2NumClusters;
const float rangeFittedDistance = max(0, z - g_fNearPlane) / (g_fFarPlane - g_fNearPlane);
return (int)clamp( LogBase( lerp(1.0, PositivePow(suggestedBase, (float) C), rangeFittedDistance), suggestedBase), 0.0, (float) (C - 1));
}
int SnapToClusterIdx(float z_in, float suggestedBase)

{
float res;
float userscale = g_fClustScale;
if (logBasePerTile)
userscale = GetScaleFromBase(suggestedBase);
//float userscale = g_fClustScale;
//if (logBasePerTile)
// userscale = GetScaleFromBase(suggestedBase);
//float dist = (PositivePow(suggestedBase, (float)k) - 1.0) / (userscale * (suggestedBase - 1.0f));
//res = dist + g_fNearPlane;
const float C = (float)(1 << g_iLog2NumClusters);
float rangeFittedDistance = (PositivePow(suggestedBase, (float)k) - 1.0) / (PositivePow(suggestedBase, C) - 1.0);
res = lerp(g_fNearPlane, g_fFarPlane, rangeFittedDistance);
float dist = (PositivePow(suggestedBase, (float)k) - 1.0) / (userscale * (suggestedBase - 1.0f));
res = dist + g_fNearPlane;
#if USE_LEFTHAND_CAMERASPACE
return res;

float SuggestLogBase50(float tileFarPlane)
{
const float C = (float)(1 << g_iLog2NumClusters);
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1.0 + sqrt(max(0.0, 1.0 - 4.0 * normDist * (1.0 - normDist)))) / (2.0 * normDist), 2.0 / C); //
float rangeFittedDistance = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1.0 + sqrt(max(0.0, 1.0 - 4.0 * rangeFittedDistance * (1.0 - rangeFittedDistance)))) / (2.0 * rangeFittedDistance), 2.0 / C); //
return max(g_fClustBase, suggested_base);
}

const float C = (float)(1 << g_iLog2NumClusters);
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1 / 2.3) * max(0.0, (0.8 / normDist) - 1), 4.0 / (C * 2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
float rangeFittedDistance = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1 / 2.3) * max(0.0, (0.8 / rangeFittedDistance) - 1), 4.0 / (C * 2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
return max(g_fClustBase, suggested_base);
}

11
Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs


cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);
cmd.DispatchCompute(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, 1, 1, 1);
bool isOrthographic = camera.orthographic;
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, "g_mScrProjection", projscr);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, "g_mInvScrProjection", invProjscr);

var cmd = CommandBufferPool.Get("Build light list" );
bool isOrthographic = camera.orthographic;
// generate screen-space AABBs (used for both fptl and clustered).
if (numLights != 0)
{

var projh = temp * proj;
var invProjh = projh.inverse;
cmd.SetComputeIntParam(buildScreenAABBShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildScreenAABBShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildScreenAABBShader, "g_mProjection", projh);
cmd.SetComputeMatrixParam(buildScreenAABBShader, "g_mInvProjection", invProjh);

// enable coarse 2D pass on 64x64 tiles (used for both fptl and clustered).
if (enableBigTilePrepass)
{
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParams(buildPerBigTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildPerBigTileLightListShader, "g_mScrProjection", projscr);

if (usingFptl) // optimized for opaques only
{
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParams(buildPerTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, "g_mScrProjection", projscr);

void PushGlobalParams(Camera camera, ScriptableRenderContext loop, Matrix4x4 viewToWorld, Matrix4x4 scrProj, Matrix4x4 incScrProj, int numDirLights)
{
var cmd = CommandBufferPool.Get("Push Global Parameters");
bool isOrthographic = camera.orthographic;
cmd.SetGlobalFloat("g_isOrthographic", (float) (isOrthographic ? 1 : 0));
cmd.SetGlobalFloat("g_widthRT", (float)camera.pixelWidth);
cmd.SetGlobalFloat("g_heightRT", (float)camera.pixelHeight);

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


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

10
Assets/ScriptableRenderPipeline/Fptl/LightingConvexHullUtils.hlsl


return float4(vN, -dot(vN,p0));
}
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen, float sphRadiusIn)
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen_in, float sphRadiusIn, bool isOrthographic)
float3 V = dir; // ray direction down center of tile (does not need to be normalized).
float3 V = float3(isOrthographic ? 0.0 : dir.x, isOrthographic ? 0.0 : dir.y, dir.z); // ray direction down center of tile (does not need to be normalized).
float3 sphCen = float3(sphCen_in.x - (isOrthographic ? dir.x : 0.0), sphCen_in.y - (isOrthographic ? dir.y : 0.0), sphCen_in.z);
#if 1
float3 maxZdir = float3(-sphCen.z*sphCen.x, -sphCen.z*sphCen.y, sphCen.x*sphCen.x + sphCen.y*sphCen.y); // cross(sphCen,cross(Zaxis,sphCen))

// enlarge sphere so it overlaps the center of the tile assuming it overlaps the tile to begin with.
#if USE_LEFTHAND_CAMERASPACE
float sphRadius = sphRadiusIn + (sphCen.z+offs)*halfTileSizeAtZDistOne;
float s = sphCen.z+offs;
float sphRadius = sphRadiusIn - (sphCen.z-offs)*halfTileSizeAtZDistOne;
float s = -(sphCen.z-offs);
float sphRadius = sphRadiusIn + (isOrthographic ? 1.0 : s)*halfTileSizeAtZDistOne;
float a = dot(V,V);
float CdotV = dot(sphCen,V);

16
Assets/ScriptableRenderPipeline/Fptl/LightingTemplate.hlsl


DirectionalLight lightData = g_dirLightData[i];
float atten = 1;
UnityLight light;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.lightAxisZ).xyz;
float shadow = GetDirectionalShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, 0.0.xxx);
float shadow = GetDirectionalShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, normalize(light.dir.xyz));
UnityLight light;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.lightAxisZ).xyz;
ints += EvalMaterial(light, ind);
}

}
atten *= angularAtt.w*(fProjVec>0.0); // finally apply this to the dist att.
UnityLight light;
light.dir.xyz = mul((float3x3) g_mViewToWorld, vL).xyz; //unity_CameraToWorld
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, 0.0.xxx);
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, float4(normalize(light.dir.xyz), dist));
UnityLight light;
light.dir.xyz = mul((float3x3) g_mViewToWorld, vL).xyz; //unity_CameraToWorld
ints += EvalMaterial(light, ind);

[branch]
if (shadowIdx >= 0)
{
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, vLw);
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, float4(vLw, dist));
atten *= shadow;
}

24
Assets/ScriptableRenderPipeline/Fptl/LightingUtils.hlsl


uniform float4x4 g_mInvScrProjection;
uniform uint g_isOrthographic;
uniform uint g_widthRT;
uniform uint g_heightRT;

float fSx = g_mScrProjection[0].x;
//float fCx = g_mScrProjection[2].x;
float fCx = g_mScrProjection[0].z;
float fSy = g_mScrProjection[1].y;
//float fCy = g_mScrProjection[2].y;
float fCy = g_mScrProjection[1].z;
bool isOrthographic = g_isOrthographic!=0;
float fSx = g_mScrProjection[0].x;
float fSy = g_mScrProjection[1].y;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetLinearZFromSVPosW(float posW)

float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
{
// todo (simplify): m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;

6
Assets/ScriptableRenderPipeline/Fptl/ShadowDispatch.hlsl


SamplerComparisonState compSamp = shadowContext.compSamplers[0];
uint algo = GPUSHADOWALGORITHM_PCF_9TAP;
return EvalShadow_CascadedDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_CascadedDepth_Blend( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )

// example of overriding punctual lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L )
{
// example for choosing the same algo
Texture2DArray tex = shadowContext.tex2DArray[0];

}
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L, float2 unPositionSS )
{
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}

26
Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-bigtile.compute


#define MAX_NR_BIGTILE_LIGHTS (MAX_NR_BIGTILE_LIGHTS_PLUSONE-1)
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;

float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[lightsListLDS[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
lightsListLDS[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection == 0 ? vP0 : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
#if USE_LEFTHAND_CAMERASPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection == 0 ? edgeSectionZero : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
}
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR)

26
Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-clustered.compute


#define PERFORM_SPHERICAL_INTERSECTION_TESTS
#define CONV_HULL_TEST_ENABLED
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;

float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
coarseList[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection==0 ? vP0 : (((iSwizzle&0x2)==0 ? 1.0f : (-1.0f))*((iSwizzle&0x1)==(iSwizzle>>1) ? float3(1,0,0) : float3(0,1,0)));
#if USE_LEFTHAND_CAMERASPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection==0 ? edgeSectionZero : (((iSwizzle&0x2)==0 ? 1.0f : (-1.0f))*((iSwizzle&0x1)==(iSwizzle>>1) ? float3(1,0,0) : float3(0,1,0)));
}
int CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)

17
Assets/ScriptableRenderPipeline/Fptl/lightlistbuild.compute


#define PERFORM_SPHERICAL_INTERSECTION_TESTS
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;

float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lightData = g_data[prunedList[l]];
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius, g_isOrthographic!=0) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);

11
Assets/ScriptableRenderPipeline/Fptl/scrbound.compute


#include "ShaderBase.h"
#include "LightDefinitions.cs.hlsl"
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvProjection;
uniform float4x4 g_mProjection;

}
else
{
//if((center.z+radius)<0.0)
if( length(center)>radius)
if(g_isOrthographic==0 && length(center)>radius)
{
float2 vMi, vMa;
bool2 bMi, bMa;

vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy;
}
else if(g_isOrthographic!=0)
{
float2 vMi = mul(g_mProjection, float4(center.xyz-radius,1)).xy; // no division needed for ortho
float2 vMa = mul(g_mProjection, float4(center.xyz+radius,1)).xy; // no division needed for ortho
vMin.xy = max(vMin.xy, vMi);
vMax.xy = min(vMax.xy, vMa);
}
#if USE_LEFTHAND_CAMERASPACE

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs


namespace UnityEngine.Experimental.Rendering
{
public enum LightArchetype { Punctual, Area, Projector };
public enum LightArchetype { Punctual, Area };
public enum SpotLightShape { Cone, Pyramid, Box };
//@TODO: We should continuously move these values
// into the engine when we can see them being generally useful

public bool affectSpecular = true;
public LightArchetype archetype = LightArchetype.Punctual;
public SpotLightShape spotLightShape = SpotLightShape.Cone; // Note: Only for Spotlight, should be hide for other light
[Range(0.0f, 20.0f)]
public float lightLength = 0.0f; // Area & projector lights

[Range(0.0f, 1.0f)]
public float maxSmoothness = 1.0f; // this is use with punctual light to fake an area lights
public bool applyRangeAttenuation = true; // If true, we apply the smooth attenuation factor on the range attenuation to get 0 value, else the attenuation is juste inverse square and never reach 0
}
}

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


public static string kFullScreenDebugMode = "Fullscreen Debug Mode";
public static string kDisplaySkyReflectionDebug = "Display Sky Reflection";
public static string kSkyReflectionMipmapDebug = "Sky Reflection Mipmap";
public static string kTileDebug = "Tile Debug By Category";
public FullScreenDebugMode fullScreenDebugMode = FullScreenDebugMode.None;
public MaterialDebugSettings materialDebugSettings = new MaterialDebugSettings();
public LightingDebugSettings lightingDebugSettings = new LightingDebugSettings();

public static int[] debugViewEngineValues = null;
public static GUIContent[] debugViewMaterialVaryingStrings = null;
public static int[] debugViewMaterialVaryingValues = null;
public static GUIContent[] debugViewMaterialPropertiesStrings = null;
public static int[] debugViewMaterialPropertiesValues = null;
public static GUIContent[] lightingFullScreenDebugStrings = null;
public static int[] lightingFullScreenDebugValues = null;
public static GUIContent[] renderingFullScreenDebugStrings = null;
public static int[] renderingFullScreenDebugValues = null;
public DebugDisplaySettings()
{

materialDebugSettings.SetDebugViewVarying(value);
}
public void SetDebugViewProperties(Attributes.DebugViewProperties value)
{
if (value != 0)
lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
materialDebugSettings.SetDebugViewProperties(value);
}
public void SetDebugViewGBuffer(int value)
{
if (value != 0)

DebugMenuManager.instance.AddDebugItem<int>("Material", "Material",() => materialDebugSettings.debugViewMaterial, (value) => SetDebugViewMaterial((int)value), DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewMaterialStrings, DebugDisplaySettings.debugViewMaterialValues));
DebugMenuManager.instance.AddDebugItem<int>("Material", "Engine",() => materialDebugSettings.debugViewEngine, (value) => SetDebugViewEngine((int)value), DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewEngineStrings, DebugDisplaySettings.debugViewEngineValues));
DebugMenuManager.instance.AddDebugItem<Attributes.DebugViewVarying>("Material", "Attributes",() => materialDebugSettings.debugViewVarying, (value) => SetDebugViewVarying((Attributes.DebugViewVarying)value));
DebugMenuManager.instance.AddDebugItem<Attributes.DebugViewProperties>("Material", "Properties", () => materialDebugSettings.debugViewProperties, (value) => SetDebugViewProperties((Attributes.DebugViewProperties)value));
DebugMenuManager.instance.AddDebugItem<int>("Material", "GBuffer",() => materialDebugSettings.debugViewGBuffer, (value) => SetDebugViewGBuffer((int)value), DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.debugViewMaterialGBufferStrings, DebugDisplaySettings.debugViewMaterialGBufferValues));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, bool>(kEnableShadowDebug, () => lightingDebugSettings.enableShadows, (value) => lightingDebugSettings.enableShadows = (bool)value);

DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, uint>(kShadowAtlasIndexDebug, () => lightingDebugSettings.shadowAtlasIndex, (value) => lightingDebugSettings.shadowAtlasIndex = (uint)value, DebugItemFlag.None, new DebugItemHandlerShadowAtlasIndex(1));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kShadowMinValueDebug, () => lightingDebugSettings.shadowMinValue, (value) => lightingDebugSettings.shadowMinValue = (float)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kShadowMaxValueDebug, () => lightingDebugSettings.shadowMaxValue, (value) => lightingDebugSettings.shadowMaxValue = (float)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, FullScreenDebugMode>(kFullScreenDebugMode, () => lightingDebugSettings.fullScreenDebugMode, (value) => lightingDebugSettings.fullScreenDebugMode = (FullScreenDebugMode)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, int>(kFullScreenDebugMode, () => (int)fullScreenDebugMode, (value) => fullScreenDebugMode = (FullScreenDebugMode)value, DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.lightingFullScreenDebugStrings, DebugDisplaySettings.lightingFullScreenDebugValues));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, DebugLightingMode>(kLightingDebugMode, () => lightingDebugSettings.debugLightingMode, (value) => SetDebugLightingMode((DebugLightingMode)value));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, bool>(kOverrideSmoothnessDebug, () => lightingDebugSettings.overrideSmoothness, (value) => lightingDebugSettings.overrideSmoothness = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kOverrideSmoothnessValueDebug, () => lightingDebugSettings.overrideSmoothnessValue, (value) => lightingDebugSettings.overrideSmoothnessValue = (float)value, DebugItemFlag.None, new DebugItemHandlerFloatMinMax(0.0f, 1.0f));

DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, TilePass.TileSettings.TileDebug>(kTileDebug,() => lightingDebugSettings.tileDebugByCategory, (value) => lightingDebugSettings.tileDebugByCategory = (TilePass.TileSettings.TileDebug)value);
DebugMenuManager.instance.AddDebugItem<int>("Rendering", kFullScreenDebugMode, () => (int)fullScreenDebugMode, (value) => fullScreenDebugMode = (FullScreenDebugMode)value, DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.renderingFullScreenDebugStrings, DebugDisplaySettings.renderingFullScreenDebugValues));
}
public void OnValidate()

index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewVarying), debugViewMaterialVaryingStrings, debugViewMaterialVaryingValues, "", ref index);
// Properties debug
var propertiesNames = Enum.GetNames(typeof(Attributes.DebugViewProperties));
debugViewMaterialPropertiesStrings = new GUIContent[propertiesNames.Length];
debugViewMaterialPropertiesValues = new int[propertiesNames.Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewProperties), debugViewMaterialPropertiesStrings, debugViewMaterialPropertiesValues, "", ref index);
// Gbuffer debug
var gbufferNames = Enum.GetNames(typeof(Attributes.DebugViewGbuffer));
debugViewMaterialGBufferStrings = new GUIContent[gbufferNames.Length + bsdfDataDeferredType.GetFields().Length];

FillWithProperties(typeof(Lit.BSDFData), debugViewMaterialGBufferStrings, debugViewMaterialGBufferValues, "", ref index);
// Lighting Full Screen Debug
FillFullScreenDebugEnum(ref lightingFullScreenDebugStrings, ref lightingFullScreenDebugValues, FullScreenDebugMode.MinLightingFullScreenDebug, FullScreenDebugMode.MaxLightingFullScreenDebug);
FillFullScreenDebugEnum(ref renderingFullScreenDebugStrings, ref renderingFullScreenDebugValues, FullScreenDebugMode.MinRenderingFullScreenDebug, FullScreenDebugMode.MaxRenderingFullScreenDebug);
void FillFullScreenDebugEnum(ref GUIContent[] strings, ref int[] values, FullScreenDebugMode min, FullScreenDebugMode max)
{
int count = max - min - 1;
strings = new GUIContent[count + 1];
values = new int[count + 1];
strings[0] = new GUIContent(FullScreenDebugMode.None.ToString());
values[0] = (int)FullScreenDebugMode.None;
int index = 1;
for (int i = (int)min + 1; i < (int)max; ++i)
{
strings[index] = new GUIContent(((FullScreenDebugMode)i).ToString());
values[index] = i;
index++;
}
}
namespace Attributes
{

Depth = DebugViewVarying.VertexColorAlpha + 1,
BakeDiffuseLightingWithAlbedoPlusEmissive,
}
// Number must be contiguous
[GenerateHLSL]
public enum DebugViewProperties
{
None = 0,
Tessellation = DebugViewGbuffer.BakeDiffuseLightingWithAlbedoPlusEmissive + 1,
PerPixelDisplacement,
DepthOffset,
Lightmap,
}
}
[Serializable]

public int debugViewEngine { get { return m_DebugViewEngine; } }
public Attributes.DebugViewVarying debugViewVarying { get { return m_DebugViewVarying; } }
public Attributes.DebugViewProperties debugViewProperties { get { return m_DebugViewProperties; } }
Attributes.DebugViewProperties m_DebugViewProperties = Attributes.DebugViewProperties.None;
int m_DebugViewGBuffer = 0; // Can't use GBuffer enum here because the values are actually split between this enum and values from Lit.BSDFData
public int GetDebugMaterialIndex()

// They are all mutually exclusive so return the sum will return the right index.
return m_DebugViewGBuffer + m_DebugViewMaterial + m_DebugViewEngine + (int)m_DebugViewVarying;
return m_DebugViewGBuffer + m_DebugViewMaterial + m_DebugViewEngine + (int)m_DebugViewVarying + (int)m_DebugViewProperties;
}
public void DisableMaterialDebug()

m_DebugViewVarying = Attributes.DebugViewVarying.None;
m_DebugViewProperties = Attributes.DebugViewProperties.None;
m_DebugViewGBuffer = 0;
}

DisableMaterialDebug();
m_DebugViewVarying = value;
}
public void SetDebugViewProperties(Attributes.DebugViewProperties value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewProperties = value;
}
public void SetDebugViewGBuffer(int value)
{

}
public bool IsDebugGBufferEnabled()
{
return m_DebugViewGBuffer != 0;
}
return (m_DebugViewEngine != 0 || m_DebugViewMaterial != 0 || m_DebugViewVarying != Attributes.DebugViewVarying.None || m_DebugViewGBuffer != 0);
return (m_DebugViewEngine != 0 || m_DebugViewMaterial != 0 || m_DebugViewVarying != Attributes.DebugViewVarying.None || m_DebugViewProperties != Attributes.DebugViewProperties.None || m_DebugViewGBuffer != 0);
}
}

public enum FullScreenDebugMode
{
None,
// Lighting
MinLightingFullScreenDebug,
MaxLightingFullScreenDebug,
// Rendering
MinRenderingFullScreenDebug,
MotionVectors,
NanTracker,
MaxRenderingFullScreenDebug
}
[Serializable]

public uint shadowAtlasIndex = 0;
public float shadowMinValue = 0.0f;
public float shadowMaxValue = 1.0f;
public FullScreenDebugMode fullScreenDebugMode = FullScreenDebugMode.None;
public bool overrideSmoothness = false;
public float overrideSmoothnessValue = 0.5f;

public float skyReflectionMipmap = 0.0f;
public TilePass.TileSettings.TileDebug tileDebugByCategory = TilePass.TileSettings.TileDebug.None;
public void OnValidate()
{

19
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl


#define DEBUGVIEWGBUFFER_BAKE_DIFFUSE_LIGHTING_WITH_ALBEDO_PLUS_EMISSIVE (11)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Attributes.DebugViewProperties: static fields
//
#define DEBUGVIEWPROPERTIES_NONE (0)
#define DEBUGVIEWPROPERTIES_TESSELLATION (12)
#define DEBUGVIEWPROPERTIES_PER_PIXEL_DISPLACEMENT (13)
#define DEBUGVIEWPROPERTIES_DEPTH_OFFSET (14)
#define DEBUGVIEWPROPERTIES_LIGHTMAP (15)
//
#define FULLSCREENDEBUGMODE_SSAO (1)
#define FULLSCREENDEBUGMODE_SSAOBEFORE_FILTERING (2)
#define FULLSCREENDEBUGMODE_MIN_LIGHTING_FULL_SCREEN_DEBUG (1)
#define FULLSCREENDEBUGMODE_SSAO (2)
#define FULLSCREENDEBUGMODE_SSAOBEFORE_FILTERING (3)
#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (4)
#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (5)
#define FULLSCREENDEBUGMODE_MOTION_VECTORS (6)
#define FULLSCREENDEBUGMODE_NAN_TRACKER (7)
#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (8)
#endif

39
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.hlsl


float4 _DebugLightingAlbedo; // xyz = albedo for diffuse, w unused
float4 _DebugLightingSmoothness; // x == bool override, y == override value
void GetPropertiesDataDebug(uint paramId, inout float3 result, inout bool needLinearToSRGB)
{
switch (paramId)
{
case DEBUGVIEWPROPERTIES_TESSELLATION:
#ifdef TESSELLATION_ON
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_PER_PIXEL_DISPLACEMENT:
#ifdef _PER_PIXEL_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_DEPTH_OFFSET:
#ifdef _DEPTHOFFSET_ON // Caution: This define is related to a shader features (But it may become a standard features for HD
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_LIGHTMAP:
#if defined(LIGHTMAP_ON) || defined (DIRLIGHTMAP_COMBINED) || defined(DYNAMICLIGHTMAP_ON)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
}
}
#endif

124
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugFullScreen.shader


#include "../../ShaderLibrary/Common.hlsl"
#include "../Debug/DebugDisplay.cs.hlsl"
#include "../ShaderVariables.hlsl"
TEXTURE2D(_DebugFullScreenTexture);
SAMPLER2D(sampler_DebugFullScreenTexture);

return output;
}
// Motion vector debug utilities
// >>>
float DistanceToLine(float2 p, float2 p1, float2 p2)
{
float2 center = (p1 + p2) * 0.5;
float len = length(p2 - p1);
float2 dir = (p2 - p1) / len;
float2 rel_p = p - center;
return dot(rel_p, float2(dir.y, -dir.x));
}
float DistanceToSegment(float2 p, float2 p1, float2 p2)
{
float2 center = (p1 + p2) * 0.5;
float len = length(p2 - p1);
float2 dir = (p2 - p1) / len;
float2 rel_p = p - center;
float dist1 = abs(dot(rel_p, float2(dir.y, -dir.x)));
float dist2 = abs(dot(rel_p, dir)) - 0.5 * len;
return max(dist1, dist2);
}
float DrawArrow(float2 texcoord, float body, float head, float height, float linewidth, float antialias)
{
float w = linewidth / 2.0 + antialias;
float2 start = -float2(body / 2.0, 0.0);
float2 end = float2(body / 2.0, 0.0);
// Head: 3 lines
float d1 = DistanceToLine(texcoord, end, end - head * float2(1.0, -height));
float d2 = DistanceToLine(texcoord, end - head * float2(1.0, height), end);
float d3 = texcoord.x - end.x + head;
// Body: 1 segment
float d4 = DistanceToSegment(texcoord, start, end - float2(linewidth, 0.0));
float d = min(max(max(d1, d2), -d3), d4);
return d;
}
float2 SampleMotionVectors(float2 coords)
{
#if UNITY_UV_STARTS_AT_TOP
coords.y = 1.0 - coords.y;
#endif
float2 mv = SAMPLE_TEXTURE2D(_DebugFullScreenTexture, sampler_DebugFullScreenTexture, coords).xy;
#if UNITY_UV_STARTS_AT_TOP
mv.y *= -1.0;
#endif
return mv;
}
// <<<
float4 Frag(Varyings input) : SV_Target
{
// SSAO

if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_SSAOBEFORE_FILTERING)
{
return 1.0f - SAMPLE_TEXTURE2D(_DebugFullScreenTexture, sampler_DebugFullScreenTexture, input.texcoord).xxxx;
}
if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_NAN_TRACKER)
{
#if UNITY_UV_STARTS_AT_TOP
input.texcoord.y = 1.0 - input.texcoord.y;
#endif
float4 color = SAMPLE_TEXTURE2D(_DebugFullScreenTexture, sampler_DebugFullScreenTexture, input.texcoord);
if (any(isnan(color)) || any(isinf(color)))
{
color = float4(1.0, 0.0, 1.0, 1.0);
}
else
{
// Dim the color buffer so we can see NaNs & Infs better
color.rgb *= 0.25;
}
return color;
}
if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_MOTION_VECTORS)
{
float2 mv = SampleMotionVectors(input.texcoord);
// Background color intensity - keep this low unless you want to make your eyes bleed
const float kIntensity = 0.15;
// Map motion vector direction to color wheel (hue between 0 and 360deg)
float phi = atan2(mv.x, mv.y);
float hue = (phi / PI + 1.0) * 0.5;
float r = abs(hue * 6.0 - 3.0) - 1.0;
float g = 2.0 - abs(hue * 6.0 - 2.0);
float b = 2.0 - abs(hue * 6.0 - 4.0);
float3 color = saturate(float3(r, g, b) * kIntensity);
// Grid subdivisions - should be dynamic
const float kGrid = 64.0;
// Arrow grid (aspect ratio is kept)
float rows = floor(kGrid * _ScreenParams.y / _ScreenParams.x);
float cols = kGrid;
float2 size = _ScreenParams.xy / float2(cols, rows);
float body = min(size.x, size.y) / 1.4142135623730951; // sqrt(2)
float2 texcoord = input.positionCS.xy;
float2 center = (floor(texcoord / size) + 0.5) * size;
texcoord -= center;
// Sample the center of the cell to get the current arrow vector
float2 arrow_coord = center / _ScreenParams.xy;
float2 mv_arrow = SampleMotionVectors(arrow_coord);
// Skip empty motion
float d = 0.0;
if (any(mv_arrow))
{
// Rotate the arrow according to the direction
mv_arrow = normalize(mv_arrow);
float2x2 rot = float2x2(mv_arrow.x, -mv_arrow.y, mv_arrow.y, mv_arrow.x);
texcoord = mul(rot, texcoord);
d = DrawArrow(texcoord, body, 0.25 * body, 0.5, 2.0, 1.0);
d = 1.0 - saturate(d);
}
return float4(color + d.xxx, 1.0);
}
return float4(0.0, 0.0, 0.0, 0.0);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugViewMaterialGBuffer.shader


Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha // We will lerp only the values that are valid
HLSLPROGRAM
#pragma target 4.5

// CAUTION: In case deferred lighting need to support various lighting model statically, we will require to do multicompile with different define like UNITY_MATERIAL_LIT
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../ShaderConfig.cs.hlsl"
#include "../ShaderVariables.hlsl"
#define DEBUG_DISPLAY
#include "../Debug/DebugDisplay.hlsl"

42
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugViewTiles.shader


#pragma fragment Frag
#define LIGHTLOOP_TILE_PASS
#define LIGHTLOOP_TILE_ALL
#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#pragma multi_compile SHOW_LIGHT_CATEGORIES SHOW_FEATURE_VARIANTS

// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../ShaderConfig.cs.hlsl"
#include "../ShaderVariables.hlsl"
#include "../Lighting/Lighting.hlsl" // This include Material.hlsl

StructuredBuffer<uint> g_TileList;
Buffer<uint> g_DispatchIndirectBuffer;
struct VSOut
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
float4 Pos : SV_POSITION;
int Variant : TEXCOORD0;
float4 positionCS : SV_POSITION;
int variant : TEXCOORD0;
VSOut Vert(uint vertexID : SV_VertexID)
Varyings Vert(uint vertexID : SV_VertexID)
{
uint quadIndex = vertexID / 6;
uint quadVertex = vertexID - quadIndex * 6;

float2 clipCoord = (pixelCoord / _ScreenParams.xy) * 2.0 - 1.0;
clipCoord.y *= -1;
VSOut Out;
Out.Pos = float4(clipCoord, 0, 1.0);
Out.Variant = variant;
return Out;
Varyings output;
output.positionCS = float4(clipCoord, 0, 1.0);
output.variant = variant;
return output;
VSOut Vert(float3 positionOS : POSITION)
Varyings Vert(Attributes input)
VSOut Out;
Out.Pos = TransformWorldToHClip(TransformObjectToWorld(positionOS));
Out.Variant = 0;
return Out;
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.variant = 0; // unused
return output;
}
#endif

return color;
}
float4 Frag(float4 positionCS : SV_POSITION, int Variant : TEXCOORD0) : SV_Target
float4 Frag(Varyings input) : SV_Target
PositionInputs posInput = GetPositionInput(positionCS.xy, _ScreenSize.zw, uint2(positionCS.xy) / GetTileSize());
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, uint2(input.positionCS.xy) / GetTileSize());
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);

n += count;
}
}
if(n == 0) n = -1;
if (n == 0)
n = -1;
n = Variant;
n = input.variant;
#endif
float4 result = float4(0.0, 0.0, 0.0, 0.0);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/LightingDebugPanel.cs


m_DebugPanel.GetDebugItem(DebugDisplaySettings.kFullScreenDebugMode).handler.OnEditorGUI();
m_DebugPanel.GetDebugItem(DebugDisplaySettings.kTileDebug).handler.OnEditorGUI();
DebugItem displaySkyReflecItem = m_DebugPanel.GetDebugItem(DebugDisplaySettings.kDisplaySkyReflectionDebug);
displaySkyReflecItem.handler.OnEditorGUI();
if ((bool)displaySkyReflecItem.GetValue())

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


// Tile pass Settings
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop Settings");
public readonly GUIContent enableTileAndCluster = new GUIContent("Enable tile/clustered", "Toggle");
public readonly GUIContent enableSplitLightEvaluation = new GUIContent("Split light and reflection evaluation", "Toggle");
public readonly GUIContent enableComputeLightEvaluation = new GUIContent("Enable Compute Light Evaluation", "Toggle");
public readonly GUIContent enableComputeLightVariants = new GUIContent("Enable Compute Light Variants", "Toggle");
public readonly GUIContent enableComputeMaterialVariants = new GUIContent("Enable Compute Material Variants", "Toggle");

SerializedProperty m_enableClustered;
SerializedProperty m_enableFptlForOpaqueWhenClustered;
SerializedProperty m_enableBigTilePrepass;
SerializedProperty m_tileDebugByCategory;
// Rendering Settings
SerializedProperty m_RenderingUseForwardOnly = null;

// Tile settings
m_enableTileAndCluster = FindProperty(x => x.tileSettings.enableTileAndCluster);
m_enableSplitLightEvaluation = FindProperty(x => x.tileSettings.enableSplitLightEvaluation);
m_enableComputeLightEvaluation = FindProperty(x => x.tileSettings.enableComputeLightEvaluation);
m_enableComputeLightVariants = FindProperty(x => x.tileSettings.enableComputeLightVariants);
m_enableComputeMaterialVariants = FindProperty(x => x.tileSettings.enableComputeMaterialVariants);

m_tileDebugByCategory = FindProperty(x => x.tileSettings.tileDebugByCategory);
// Shadow settings
m_ShadowAtlasWidth = FindProperty(x => x.shadowInitParams.shadowAtlasWidth);

EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_enableTileAndCluster, styles.enableTileAndCluster);
EditorGUILayout.PropertyField(m_enableSplitLightEvaluation, styles.enableSplitLightEvaluation);
EditorGUILayout.PropertyField(m_enableComputeLightEvaluation, styles.enableComputeLightEvaluation);
EditorGUILayout.PropertyField(m_enableComputeLightVariants, styles.enableComputeLightVariants);
EditorGUILayout.PropertyField(m_enableComputeMaterialVariants, styles.enableComputeMaterialVariants);
EditorGUILayout.PropertyField(m_enableClustered, styles.enableClustered);
EditorGUILayout.PropertyField(m_enableFptlForOpaqueWhenClustered, styles.enableFptlForOpaqueWhenClustered);
EditorGUILayout.PropertyField(m_enableBigTilePrepass, styles.enableBigTilePrepass);
EditorGUILayout.PropertyField(m_tileDebugByCategory, styles.tileDebugByCategory);
if (m_enableTileAndCluster.boolValue)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_enableBigTilePrepass, styles.enableBigTilePrepass);
EditorGUILayout.PropertyField(m_enableClustered, styles.enableClustered);
// Tag: SUPPORT_COMPUTE_CLUSTER_OPAQUE - Uncomment this if you want to do cluster opaque with compute shader (by default we support only fptl on opaque)
// if (m_enableClustered.boolValue)
if (m_enableClustered.boolValue && !m_enableComputeLightEvaluation.boolValue)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_enableFptlForOpaqueWhenClustered, styles.enableFptlForOpaqueWhenClustered);
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(m_enableComputeLightEvaluation, styles.enableComputeLightEvaluation);
if (m_enableComputeLightEvaluation.boolValue)
{
// Tag: SUPPORT_COMPUTE_CLUSTER_OPAQUE - Uncomment this if you want to do cluster opaque with compute shader (by default we support only fptl on opaque)
m_enableFptlForOpaqueWhenClustered.boolValue = true; // Force fptl to be always true if compute evaluation is enable
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_enableComputeLightVariants, styles.enableComputeLightVariants);
EditorGUILayout.PropertyField(m_enableComputeMaterialVariants, styles.enableComputeMaterialVariants);
EditorGUI.indentLevel--;
}
}
if (EditorGUI.EndChangeCheck())
{

518
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


{
public Matrix4x4 viewMatrix;
public Matrix4x4 projMatrix;
public Matrix4x4 nonJitteredProjMatrix;
public Vector4 screenSize;
public Vector4[] frustumPlaneEquations;
public Camera camera;

get { return projMatrix * viewMatrix; }
}
public Matrix4x4 nonJitteredViewProjMatrix
{
get { return nonJitteredProjMatrix * viewMatrix; }
}
public Vector4 invProjParam
{
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.

// 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

Reset();
}
public void Update()
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;
Matrix4x4 gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true); // Had to change this from 'false'
Matrix4x4 gpuProj = GL.GetGPUProjectionMatrix(cameraProj, true); // Had to change this from 'false'
Matrix4x4 gpuNonJitteredProj = GL.GetGPUProjectionMatrix(nonJitteredCameraProj, true);
Vector3 pos = camera.transform.position;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{

Matrix4x4 gpuVP = gpuProj * gpuView;
Matrix4x4 gpuVP = gpuNonJitteredProj * gpuView;
// A camera could be rendered multiple time per frame, only updates the previous viewproj if needed
// A camera could be rendered multiple times per frame, only updates the previous view proj & pos if needed
prevViewProjMatrix = !m_FirstFrame
? viewProjMatrix
: gpuVP;
if (m_FirstFrame)
{
prevCameraPos = pos;
prevViewProjMatrix = gpuVP;
}
else
{
prevCameraPos = cameraPos;
prevViewProjMatrix = nonJitteredViewProjMatrix;
}
m_FirstFrame = false;
}

nonJitteredProjMatrix = gpuNonJitteredProj;
cameraPos = pos;
screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(viewProjMatrix);

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)
public static HDCamera Get(Camera camera, PostProcessLayer postProcessLayer)
{
HDCamera hdcam;

m_Cameras.Add(camera, hdcam);
}
hdcam.Update();
hdcam.Update(postProcessLayer);
return hdcam;
}

public void SetupGlobalParams(CommandBuffer cmd)
{
cmd.SetGlobalMatrix("_ViewMatrix", viewMatrix);
cmd.SetGlobalMatrix("_InvViewMatrix", viewMatrix.inverse);
cmd.SetGlobalMatrix("_ProjMatrix", projMatrix);
cmd.SetGlobalMatrix("_InvProjMatrix", projMatrix.inverse);
cmd.SetGlobalMatrix("_ViewProjMatrix", viewProjMatrix);
cmd.SetGlobalMatrix("_InvViewProjMatrix", viewProjMatrix.inverse);
cmd.SetGlobalVector("_InvProjParam", invProjParam);
cmd.SetGlobalVector("_ScreenSize", screenSize);
cmd.SetGlobalMatrix("_PrevViewProjMatrix", prevViewProjMatrix);
cmd.SetGlobalVectorArray("_FrustumPlanes", frustumPlaneEquations);
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);
material.SetMatrix("_ViewMatrix", viewMatrix);
material.SetMatrix("_InvViewMatrix", viewMatrix.inverse);
material.SetMatrix("_ProjMatrix", projMatrix);
material.SetMatrix("_InvProjMatrix", projMatrix.inverse);
material.SetMatrix("_ViewProjMatrix", viewProjMatrix);
material.SetMatrix("_InvViewProjMatrix", viewProjMatrix.inverse);
material.SetVector("_InvProjParam", invProjParam);
material.SetVector("_ScreenSize", screenSize);
material.SetMatrix("_PrevViewProjMatrix", prevViewProjMatrix);
material.SetVectorArray("_FrustumPlanes", frustumPlaneEquations);
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);
cmd.SetComputeMatrixParam(cs, "_ViewMatrix", viewMatrix);
cmd.SetComputeMatrixParam(cs, "_InvViewMatrix", viewMatrix.inverse);
cmd.SetComputeMatrixParam(cs, "_ProjMatrix", projMatrix);
cmd.SetComputeMatrixParam(cs, "_InvProjMatrix", projMatrix.inverse);
cmd.SetComputeMatrixParam(cs, "_ViewProjMatrix", viewProjMatrix);
cmd.SetComputeMatrixParam(cs, "_InvViewProjMatrix", viewProjMatrix.inverse);
cmd.SetComputeVectorParam(cs, "_InvProjParam", invProjParam);
cmd.SetComputeVectorParam(cs, "_ScreenSize", screenSize);
cmd.SetComputeMatrixParam(cs, "_PrevViewProjMatrix", prevViewProjMatrix);
cmd.SetComputeVectorArrayParam(cs, "_FrustumPlanes", frustumPlaneEquations);
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));
}
}

readonly GBufferManager m_gbufferManager = new GBufferManager();
Material m_CopyStencilForSplitLighting;
Material m_CopyStencilForRegularLighting;
Material m_FilterAndCombineSubsurfaceScattering;
ComputeShader m_SubsurfaceScatteringCS { get { return m_Asset.renderPipelineResources.subsurfaceScatteringCS; } }
int m_SubsurfaceScatteringKernel;
Material m_CombineLightingPass;
Material m_FilterSubsurfaceScattering;
Material m_SssVerticalFilterPass;
Material m_SssHorizontalFilterAndCombinePass;
// <<< Old SSS Model
Material m_CameraMotionVectorsMaterial;

// Various buffer
readonly int m_CameraColorBuffer;
readonly int m_CameraSubsurfaceBuffer;
readonly int m_CameraSssDiffuseLightingBuffer;
// Old SSS Model >>>
readonly int m_CameraFilteringBuffer;
// <<< Old SSS Model

// 'm_CameraColorBuffer' does not contain diffuse lighting of SSS materials until the SSS pass.
// It is stored within 'm_CameraSubsurfaceBufferRT'.
// 'm_CameraColorBuffer' does not contain diffuse lighting of SSS materials until the SSS pass. It is stored within 'm_CameraSssDiffuseLightingBuffer'.
readonly RenderTargetIdentifier m_CameraSubsurfaceBufferRT;
readonly RenderTargetIdentifier m_CameraSssDiffuseLightingBufferRT;
// Old SSS Model >>>
readonly RenderTargetIdentifier m_CameraFilteringBufferRT;
// <<< Old SSS Model

private RenderTexture m_CameraDepthStencilBuffer = null;
private RenderTexture m_CameraDepthStencilBufferCopy = null;
private RenderTexture m_CameraDepthBufferCopy = null;
private RenderTexture m_CameraStencilBufferCopy = null;
private RenderTexture m_HTile = null; // If the hardware does not expose it, we compute our own, optimized to only contain the SSS bit
private RenderTargetIdentifier m_CameraDepthStencilBufferCopyRT;
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;

// Currently we use only 2 bits to identify the kind of lighting that is expected from the render pipeline
// Usage is define in LightDefinitions.cs
[Flags]
public enum StencilBits
public enum StencilBitMask
Lighting = 3, // 0
All = 255 // 0xFF
Clear = 0, // 0x0
Lighting = 3, // 0x3 - 2 bit
All = 255 // 0xFF - 8 bit
}
// Detect when windows size is changing

readonly ShadowSettings m_ShadowSettings = new ShadowSettings();
// Debugging
MaterialPropertyBlock m_SharedPropertyBlock = new MaterialPropertyBlock();
public DebugDisplaySettings m_DebugDisplaySettings = new DebugDisplaySettings();
private int m_DebugFullScreenTempRT;
private bool m_FullScreenDebugPushed = false;

get { return m_Asset.sssSettings; }
}
private CommonSettings.Settings m_CommonSettings = CommonSettings.Settings.s_Defaultsettings;
private SkySettings m_SkySettings = null;

// TODO: Handle the case of no Gbuffer material
// TODO: I comment the assert here because m_DeferredMaterial for whatever reasons contain the correct class but with a "null" in the name instead of the real name and then trigger the assert
// whereas it work. Don't know what is hapening, DebugDisplay use the same code and name is correct there.
// whereas it work. Don't know what is happening, DebugDisplay use the same code and name is correct there.
m_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
m_CameraSubsurfaceBuffer = Shader.PropertyToID("_CameraSubsurfaceTexture");
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraSubsurfaceBufferRT = new RenderTargetIdentifier(m_CameraSubsurfaceBuffer);
m_CameraColorBuffer = HDShaderIDs._CameraColorTexture;
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraSssDiffuseLightingBuffer = HDShaderIDs._CameraSssDiffuseLightingBuffer;
m_CameraSssDiffuseLightingBufferRT = new RenderTargetIdentifier(m_CameraSssDiffuseLightingBuffer);
m_CameraFilteringBuffer = HDShaderIDs._CameraFilteringBuffer;
m_CameraFilteringBufferRT = new RenderTargetIdentifier(m_CameraFilteringBuffer);
// Old SSS Model >>>
m_CameraFilteringBuffer = Shader.PropertyToID("_CameraFilteringBuffer");
m_CameraFilteringBufferRT = new RenderTargetIdentifier(m_CameraFilteringBuffer);
// <<< Old SSS Model
m_CameraMotionVectorsMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CameraMotionVectors");
m_CopyStencilForSplitLighting = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CopyStencilForSplitLighting.EnableKeyword("EXPORT_HTILE");
m_CopyStencilForSplitLighting.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.SplitLighting);
m_CopyStencilForRegularLighting = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CopyStencilForRegularLighting.DisableKeyword("EXPORT_HTILE");
m_CopyStencilForRegularLighting.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.RegularLighting);
m_CameraMotionVectorsMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CameraMotionVectors");
InitializeDebugMaterials();

m_gbufferManager.SetBufferDescription(gbufferIndex, "_GBufferTexture" + gbufferIndex, RTFormat[gbufferIndex], RTReadWrite[gbufferIndex]);
}
m_VelocityBuffer = Shader.PropertyToID("_VelocityTexture");
m_VelocityBuffer = HDShaderIDs._VelocityTexture;
if (ShaderConfig.s_VelocityInGbuffer == 1)
{
// If velocity is in GBuffer then it is in the last RT. Assign a different name to it.

m_VelocityBufferRT = new RenderTargetIdentifier(m_VelocityBuffer);
m_DistortionBuffer = Shader.PropertyToID("_DistortionTexture");
m_DistortionBuffer = HDShaderIDs._DistortionTexture;
m_DistortionBufferRT = new RenderTargetIdentifier(m_DistortionBuffer);
m_MaterialList.ForEach(material => material.Build(asset.renderPipelineResources));

m_SsaoEffect.Build(asset.renderPipelineResources);
m_DebugDisplaySettings.RegisterDebug();
m_DebugFullScreenTempRT = Shader.PropertyToID("_DebugFullScreenTexture");
m_DebugFullScreenTempRT = HDShaderIDs._DebugFullScreenTexture;
}
void InitializeDebugMaterials()

m_DebugFullScreen = Utilities.CreateEngineMaterial(m_Asset.renderPipelineResources.debugFullScreenShader);
}
// Old SSS Model >>>
Utilities.Destroy(m_FilterSubsurfaceScattering);
m_FilterSubsurfaceScattering = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineSubsurfaceScattering");
Utilities.SelectKeyword(m_FilterSubsurfaceScattering, "SSS_MODEL_DISNEY", "SSS_MODEL_BASIC", useDisneySSS);
m_FilterSubsurfaceScattering.DisableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_FilterSubsurfaceScattering.SetFloat("_DstBlend", (float)BlendMode.Zero);
m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel("SubsurfaceScattering");
Utilities.Destroy(m_CombineLightingPass);
m_CombineLightingPass = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineLighting");
// Old SSS Model >>>
Utilities.Destroy(m_SssVerticalFilterPass);
m_SssVerticalFilterPass = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
m_SssVerticalFilterPass.DisableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_SssVerticalFilterPass.SetFloat(HDShaderIDs._DstBlend, (float)BlendMode.Zero);
Utilities.Destroy(m_FilterAndCombineSubsurfaceScattering);
m_FilterAndCombineSubsurfaceScattering = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineSubsurfaceScattering");
Utilities.SelectKeyword(m_FilterAndCombineSubsurfaceScattering, "SSS_MODEL_DISNEY", "SSS_MODEL_BASIC", useDisneySSS);
m_FilterAndCombineSubsurfaceScattering.EnableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_FilterAndCombineSubsurfaceScattering.SetFloat("_DstBlend", (float)BlendMode.One);
Utilities.Destroy(m_SssHorizontalFilterAndCombinePass);
m_SssHorizontalFilterAndCombinePass = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
m_SssHorizontalFilterAndCombinePass.EnableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
m_SssHorizontalFilterAndCombinePass.SetFloat(HDShaderIDs._DstBlend, (float)BlendMode.One);
// <<< Old SSS Model
// <<< Old SSS Model
public void OnSceneLoad()
{

};
#endif
void CreateDepthBuffer(Camera camera)
void CreateDepthStencilBuffer(Camera camera)
{
if (m_CameraDepthStencilBuffer != null)
{

if (NeedDepthBufferCopy())
{
if (m_CameraDepthStencilBufferCopy != null)
if (m_CameraDepthBufferCopy != null)
m_CameraDepthStencilBufferCopy.Release();
m_CameraDepthBufferCopy.Release();
m_CameraDepthStencilBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthStencilBufferCopy.filterMode = FilterMode.Point;
m_CameraDepthStencilBufferCopy.Create();
m_CameraDepthStencilBufferCopyRT = new RenderTargetIdentifier(m_CameraDepthStencilBufferCopy);
m_CameraDepthBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthBufferCopy.filterMode = FilterMode.Point;
m_CameraDepthBufferCopy.Create();
m_CameraDepthBufferCopyRT = new RenderTargetIdentifier(m_CameraDepthBufferCopy);
}
if (NeedStencilBufferCopy())
{
if (m_CameraStencilBufferCopy != null)
{
m_CameraStencilBufferCopy.Release();
}
m_CameraStencilBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); // DXGI_FORMAT_R8_UINT is not supported by Unity
m_CameraStencilBufferCopy.filterMode = FilterMode.Point;
m_CameraStencilBufferCopy.Create();
m_CameraStencilBufferCopyRT = new RenderTargetIdentifier(m_CameraStencilBufferCopy);
}
if (NeedHTileCopy())
{
if (m_HTile!= null)
{
m_HTile.Release();
}
// We use 8x8 tiles in order to match the native GCN HTile as closely as possible.
m_HTile = new RenderTexture((camera.pixelWidth + 7) / 8, (camera.pixelHeight + 7) / 8, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); // DXGI_FORMAT_R8_UINT is not supported by Unity
m_HTile.filterMode = FilterMode.Point;
m_HTile.enableRandomWrite = true;
m_HTile.Create();
m_HTileRT = new RenderTargetIdentifier(m_HTile);
}
}

if (resolutionChanged || m_CameraDepthStencilBuffer == null)
{
CreateDepthBuffer(camera);
CreateDepthStencilBuffer(camera);
}
if (resolutionChanged || m_LightLoop.NeedResize())

if (m_SkyManager.IsSkyValid())
{
m_SkyManager.SetGlobalSkyTexture();
Shader.SetGlobalInt("_EnvLightSkyEnabled", 1);
Shader.SetGlobalInt(HDShaderIDs._EnvLightSkyEnabled, 1);
Shader.SetGlobalInt("_EnvLightSkyEnabled", 0);
Shader.SetGlobalInt(HDShaderIDs._EnvLightSkyEnabled, 0);
Shader.SetGlobalInt( "_EnableSSSAndTransmission", m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission ? 1 : 0);
Shader.SetGlobalInt( "_TexturingModeFlags", (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt( "_TransmissionFlags", (int)sssParameters.transmissionFlags);
cmd.SetGlobalFloatArray( "_ThicknessRemaps", sssParameters.thicknessRemaps);
// We are currently supporting two different SSS mode: Jimenez (with 2-Gaussian profile) and Disney
// We have added the ability to switch between each other for subsurface scattering, but for transmittance this is more tricky as we need to add
// shader variant for forward, gbuffer and deferred shader. We want to avoid this.
// So for transmittance we use Disney profile formulation (that we know is more correct) in both case, and in the case of Jimenez we hack the parameters with 2-Gaussian parameters (Ideally we should fit but haven't find good fit) so it approximately match.
// Note: Jimenez SSS is in cm unit whereas Disney is in mm unit making an inconsistency here to compare model side by side
cmd.SetGlobalVectorArray("_ShapeParams", sssParameters.useDisneySSS ? sssParameters.shapeParams : sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalVectorArray("_TransmissionTints", sssParameters.transmissionTints);
Shader.SetGlobalInt( HDShaderIDs._EnableSSSAndTransmission, m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission ? 1 : 0);
Shader.SetGlobalInt( HDShaderIDs._TexturingModeFlags, (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt( HDShaderIDs._TransmissionFlags, (int)sssParameters.transmissionFlags);
Shader.SetGlobalInt( HDShaderIDs._UseDisneySSS, sssParameters.useDisneySSS ? 1 : 0);
cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetGlobalVectorArray(HDShaderIDs._HalfRcpVariancesAndWeights, sssParameters.halfRcpVariancesAndWeights);
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTints, sssParameters.transmissionTints);
}
}

return SystemInfo.graphicsDeviceType != GraphicsDeviceType.PlayStation4;
}
Texture GetDepthTexture()
bool NeedStencilBufferCopy()
{
// Currently, Unity does not offer a way to bind the stencil buffer as a texture in a compute shader.
// Therefore, it's manually copied using a pixel shader.
return m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission || LightLoop.GetFeatureVariantsEnabled(m_Asset.tileSettings);
}
bool NeedHTileCopy()
{
// Currently, Unity does not offer a way to access the GCN HTile even on PS4 and Xbox One.
// Therefore, it's computed in a pixel shader, and optimized to only contain the SSS bit.
return m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission;
}
RenderTargetIdentifier GetDepthTexture()
if (NeedDepthBufferCopy())
return m_CameraDepthStencilBufferCopy;
else
return m_CameraDepthStencilBuffer;
return NeedDepthBufferCopy() ? m_CameraDepthBufferCopy : m_CameraDepthStencilBuffer;
}
RenderTargetIdentifier GetStencilTexture()
{
return NeedStencilBufferCopy() ? m_CameraStencilBufferCopyRT : m_CameraDepthStencilBufferRT;
}
RenderTargetIdentifier GetHTile()
{
// Currently, Unity does not offer a way to access the GCN HTile.
return m_HTileRT;
}
private void CopyDepthBufferIfNeeded(CommandBuffer cmd)

{
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", cmd))
{
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthStencilBufferCopyRT);
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthBufferCopyRT);
cmd.SetGlobalTexture("_MainDepthTexture", GetDepthTexture());
cmd.SetGlobalTexture(HDShaderIDs._MainDepthTexture, GetDepthTexture());
private void PrepareAndBindStencilTexture(CommandBuffer cmd)
{
if (NeedStencilBufferCopy())
{
using (new Utilities.ProfilingSample("Copy StencilBuffer", cmd))
{
cmd.SetRandomWriteTarget(1, GetHTile());
// Our method of exporting the stencil requires one pass per unique stencil value.
Utilities.DrawFullScreen(cmd, m_CopyStencilForSplitLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
Utilities.DrawFullScreen(cmd, m_CopyStencilForRegularLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
cmd.ClearRandomWriteTargets();
}
}
cmd.SetGlobalTexture(HDShaderIDs._HTile, GetHTile());
cmd.SetGlobalTexture(HDShaderIDs._StencilTexture, GetStencilTexture());
}
public void UpdateCommonSettings()
{
var commonSettings = commonSettingsToUse;

renderContext.SetupCameraProperties(camera);
HDCamera hdCamera = HDCamera.Get(camera);
var postProcessLayer = camera.GetComponent<PostProcessLayer>();
HDCamera hdCamera = HDCamera.Get(camera, postProcessLayer);
PushGlobalParams(hdCamera, cmd, m_Asset.sssSettings);
// TODO: Find a correct place to bind these material textures

CopyDepthBufferIfNeeded(cmd);
}
// Required for the SSS and the shader feature classification pass.
PrepareAndBindStencilTexture(cmd);
if (m_DebugDisplaySettings.IsDebugMaterialDisplayEnabled())
{
RenderDebugViewMaterial(m_CullResults, hdCamera, renderContext, cmd);

m_LightLoop.PrepareLightsForGPU(m_ShadowSettings, m_CullResults, camera);
m_LightLoop.RenderShadows(renderContext, cmd, m_CullResults);
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
m_LightLoop.BuildGPULightLists(camera, cmd, m_CameraDepthStencilBufferRT);
m_LightLoop.BuildGPULightLists(camera, cmd, m_CameraDepthStencilBufferRT, GetStencilTexture());
}
// Caution: We require sun light here as some sky use the sun light to render, mean UpdateSkyEnvironment

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

RenderLightingDebug(hdCamera, cmd, m_CameraColorBufferRT);
RenderLightingDebug(hdCamera, cmd, m_CameraColorBufferRT, m_DebugDisplaySettings);
// If full forward rendering, we did just rendered everything, so we can copy the depth buffer
// If Deferred nothing needs copying anymore.

// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForward(m_CullResults, camera, renderContext, cmd, false);
PushFullScreenDebugTexture(cmd, m_CameraColorBuffer, camera, renderContext, FullScreenDebugMode.NanTracker);
// Planar and real time cubemap doesn't need post process and render in FP16
if (camera.cameraType == CameraType.Reflection)

// Instead we chose to apply distortion at the end after we cumulate distortion vector and desired blurriness. This
RenderDistortion(m_CullResults, camera, renderContext, cmd);
RenderPostProcesses(camera, cmd);
RenderPostProcesses(camera, cmd, postProcessLayer);
}
}

void RenderDepthPrepass(CullResults cull, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
// If we are forward only we will do a depth prepass
// TODO: Depth prepass should be enabled based on light loop settings. LightLoop define if they need a depth prepass + forward only...
if (!m_Asset.renderingSettings.useDepthPrepass)
if (!m_Asset.renderingSettings.useDepthPrepass)
// TODO: front to back for opaque and by materal for opaque tested when we split in two
// TODO: front to back for opaque and by material for opaque tested when we split in two
Utilities.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, "DepthOnly");
}

{
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{
}
string passName = m_DebugDisplaySettings.IsDebugDisplayEnabled() ? "GBufferDebugDisplay" : "GBuffer";

{
using (new Utilities.ProfilingSample("DisplayDebug ViewMaterial", cmd))
{
// Render Opaque forward
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, Utilities.kClearAll, Color.black);
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, "ForwardDisplayDebug", Utilities.kRendererConfigurationBakedLighting);
// Render GBuffer opaque
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
if(m_DebugDisplaySettings.materialDebugSettings.IsDebugGBufferEnabled() && !m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
// TODO: Bind depth textures
cmd.Blit(null, m_CameraColorBufferRT, m_DebugViewMaterialGBuffer, 0);
Utilities.DrawFullScreen(cmd, m_DebugViewMaterialGBuffer, m_CameraColorBufferRT);
// Render forward transparent
else
Utilities.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, Utilities.kClearAll, Color.black);
// Render Opaque forward
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, "ForwardDisplayDebug", Utilities.kRendererConfigurationBakedLighting);
// Render forward transparent
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, "ForwardDisplayDebug", Utilities.kRendererConfigurationBakedLighting);
}
}

return;
}
RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSubsurfaceBufferRT };
RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSssDiffuseLightingBufferRT };
RenderTargetIdentifier depthTexture = GetDepthTexture();
// Output split lighting for materials asking for it (via stencil buffer)
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, new RenderTargetIdentifier(GetDepthTexture()), true);
// Output split lighting for materials asking for it (masked in the stencil buffer)
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, true);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, new RenderTargetIdentifier(GetDepthTexture()), false);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, false);
void CombineSubsurfaceScattering(HDCamera hdCamera, CommandBuffer cmd, SubsurfaceScatteringSettings sssParameters)
void SubsurfaceScatteringPass(HDCamera hdCamera, CommandBuffer cmd, SubsurfaceScatteringSettings sssParameters)
{
// Currently, forward-rendered objects do not output split lighting required for the SSS pass.
if (!m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission || m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())

{
if (sssSettings.useDisneySSS)
{
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT); // Cannot set a RT on a material
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_WorldScales", sssParameters.worldScales);
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_FilterKernelsNearField", sssParameters.filterKernelsNearField);
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_FilterKernelsFarField", sssParameters.filterKernelsFarField);
hdCamera.SetupComputeShader(m_SubsurfaceScatteringCS, cmd);
cmd.SetComputeIntParam( m_SubsurfaceScatteringCS, HDShaderIDs._TexturingModeFlags, sssParameters.texturingModeFlags);
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._WorldScales, sssParameters.worldScales);
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._FilterKernels, sssParameters.filterKernels);
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture0, m_gbufferManager.GetGBuffers()[0]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture1, m_gbufferManager.GetGBuffers()[1]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture2, m_gbufferManager.GetGBuffers()[2]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture3, m_gbufferManager.GetGBuffers()[3]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._StencilTexture, GetStencilTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._HTile, GetHTile());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._IrradianceSource, m_CameraSssDiffuseLightingBufferRT);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBufferRT);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraFilteringBuffer, m_CameraFilteringBufferRT);
// Perform the SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
//
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
Utilities.DrawFullScreen(cmd, m_FilterAndCombineSubsurfaceScattering, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
// Combine diffuse and specular lighting into 'm_CameraColorBufferRT'.
Utilities.DrawFullScreen(cmd, m_CombineLightingPass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
// Perform the vertical SSS filtering pass.
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT); // Cannot set a RT on a material
m_FilterSubsurfaceScattering.SetFloatArray("_WorldScales", sssParameters.worldScales);
m_FilterSubsurfaceScattering.SetVectorArray("_FilterKernelsBasic", sssParameters.filterKernelsBasic);
m_FilterSubsurfaceScattering.SetVectorArray("_HalfRcpWeightedVariances", sssParameters.halfRcpWeightedVariances);
Utilities.DrawFullScreen(cmd, m_FilterSubsurfaceScattering, m_CameraFilteringBufferRT, m_CameraDepthStencilBufferRT);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraSssDiffuseLightingBufferRT); // Cannot set a RT on a material
m_SssVerticalFilterPass.SetVectorArray(HDShaderIDs._WorldScales, sssParameters.worldScales);
m_SssVerticalFilterPass.SetVectorArray(HDShaderIDs._FilterKernelsBasic, sssParameters.filterKernelsBasic);
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);
// Perform the horizontal SSS filtering pass, and combine diffuse and specular lighting.
cmd.SetGlobalTexture("_IrradianceSource", m_CameraFilteringBufferRT); // Cannot set a RT on a material
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_WorldScales", sssParameters.worldScales);
m_FilterAndCombineSubsurfaceScattering.SetVectorArray("_FilterKernelsBasic", sssParameters.filterKernelsBasic);
m_FilterAndCombineSubsurfaceScattering.SetVectorArray("_HalfRcpWeightedVariances", sssParameters.halfRcpWeightedVariances);
Utilities.DrawFullScreen(cmd, m_FilterAndCombineSubsurfaceScattering, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
m_SssHorizontalFilterAndCombinePass.SetVectorArray(HDShaderIDs._WorldScales, sssParameters.worldScales);
m_SssHorizontalFilterAndCombinePass.SetVectorArray(HDShaderIDs._FilterKernelsBasic, sssParameters.filterKernelsBasic);
m_SssHorizontalFilterAndCombinePass.SetVectorArray(HDShaderIDs._HalfRcpWeightedVariances, sssParameters.halfRcpWeightedVariances);
// Perform the horizontal SSS filtering pass, and combine diffuse and specular lighting into 'm_CameraColorBufferRT'.
Utilities.DrawFullScreen(cmd, m_SssHorizontalFilterAndCombinePass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
}
}
}

return m_SkyManager.ExportSkyToTexture();
}
void RenderLightingDebug(HDCamera camera, CommandBuffer cmd, RenderTargetIdentifier colorBuffer)
void RenderLightingDebug(HDCamera camera, CommandBuffer cmd, RenderTargetIdentifier colorBuffer, DebugDisplaySettings debugDisplaySettings)
m_LightLoop.RenderLightingDebug(camera, cmd, colorBuffer);
m_LightLoop.RenderLightingDebug(camera, cmd, colorBuffer, debugDisplaySettings);
// TODO: Currently we can't render opaque object forward when deferred is enabled
// miss option
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && renderOpaque)
return;

int w = (int)hdcam.screenSize.x;
int h = (int)hdcam.screenSize.y;
m_CameraMotionVectorsMaterial.SetVector(HDShaderIDs._CameraPosDiff, hdcam.prevCameraPos - hdcam.cameraPos);
cmd.Blit(BuiltinRenderTextureType.None, m_VelocityBufferRT, m_CameraMotionVectorsMaterial, 0);
Utilities.DrawFullScreen(cmd, m_CameraMotionVectorsMaterial, m_VelocityBufferRT, null, 0);
PushFullScreenDebugTexture(cmd, m_VelocityBuffer, hdcam.camera, renderContext, FullScreenDebugMode.MotionVectors);
}
}

}
}
void RenderPostProcesses(Camera camera, CommandBuffer cmd)
void RenderPostProcesses(Camera camera, CommandBuffer cmd, PostProcessLayer layer)
var postProcessLayer = camera.GetComponent<PostProcessLayer>();
if (postProcessLayer != null && postProcessLayer.enabled)
if (Utilities.IsPostProcessingActive(layer))
cmd.SetGlobalTexture("_CameraDepthTexture", GetDepthTexture());
cmd.SetGlobalTexture("_CameraMotionVectorsTexture", m_VelocityBufferRT);
cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, GetDepthTexture());
cmd.SetGlobalTexture(HDShaderIDs._CameraMotionVectorsTexture, m_VelocityBufferRT);
var context = m_PostProcessContext;
context.Reset();

context.sourceFormat = RenderTextureFormat.ARGBHalf;
context.flip = true;
postProcessLayer.Render(context);
layer.Render(context);
}
else
{

Vector4 debugAlbedo = new Vector4(lightingDebugSettings.debugLightingAlbedo.r, lightingDebugSettings.debugLightingAlbedo.g, lightingDebugSettings.debugLightingAlbedo.b, 0.0f);
Vector4 debugSmoothness = new Vector4(lightingDebugSettings.overrideSmoothness ? 1.0f : 0.0f, lightingDebugSettings.overrideSmoothnessValue, 0.0f, 0.0f);
Shader.SetGlobalInt("_DebugViewMaterial", (int)m_DebugDisplaySettings.GetDebugMaterialIndex());
Shader.SetGlobalInt("_DebugLightingMode", (int)m_DebugDisplaySettings.GetDebugLightingMode());
Shader.SetGlobalVector("_DebugLightingAlbedo", debugAlbedo);
Shader.SetGlobalVector("_DebugLightingSmoothness", debugSmoothness);
Shader.SetGlobalInt(HDShaderIDs._DebugViewMaterial, (int)m_DebugDisplaySettings.GetDebugMaterialIndex());
Shader.SetGlobalInt(HDShaderIDs._DebugLightingMode, (int)m_DebugDisplaySettings.GetDebugLightingMode());
Shader.SetGlobalVector(HDShaderIDs._DebugLightingAlbedo, debugAlbedo);
Shader.SetGlobalVector(HDShaderIDs._DebugLightingSmoothness, debugSmoothness);
if(debugMode == m_DebugDisplaySettings.lightingDebugSettings.fullScreenDebugMode)
if(debugMode == m_DebugDisplaySettings.fullScreenDebugMode)
{
m_FullScreenDebugPushed = true; // We need this flag because otherwise if no fullscreen debug is pushed, when we render the result in RenderDebug the temporary RT will not exist.
cb.GetTemporaryRT(m_DebugFullScreenTempRT, camera.pixelWidth, camera.pixelHeight, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);

MaterialPropertyBlock m_SharedPropertyBlock = new MaterialPropertyBlock();
void RenderDebug(HDCamera camera, CommandBuffer cmd)
{
// We don't want any overlay for these kind of rendering

Utilities.SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget, m_CameraDepthStencilBufferRT);
// First render full screen debug texture
if(m_DebugDisplaySettings.lightingDebugSettings.fullScreenDebugMode != FullScreenDebugMode.None && m_FullScreenDebugPushed)
if(m_DebugDisplaySettings.fullScreenDebugMode != FullScreenDebugMode.None && m_FullScreenDebugPushed)
cmd.SetGlobalTexture("_DebugFullScreenTexture", m_DebugFullScreenTempRT);
m_DebugFullScreen.SetFloat("_FullScreenDebugMode", (float)m_DebugDisplaySettings.lightingDebugSettings.fullScreenDebugMode);
cmd.SetGlobalTexture(HDShaderIDs._DebugFullScreenTexture, m_DebugFullScreenTempRT);
m_DebugFullScreen.SetFloat(HDShaderIDs._FullScreenDebugMode, (float)m_DebugDisplaySettings.fullScreenDebugMode);
Utilities.DrawFullScreen(cmd, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
}

if (lightingDebug.displaySkyReflection)
{
Texture skyReflection = m_SkyManager.skyReflection;
m_SharedPropertyBlock.SetTexture("_InputCubemap", skyReflection);
m_SharedPropertyBlock.SetFloat("_Mipmap", lightingDebug.skyReflectionMipmap);
m_SharedPropertyBlock.SetTexture(HDShaderIDs._InputCubemap, skyReflection);
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);

int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraSubsurfaceBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
// Old SSS Model >>>
cmd.GetTemporaryRT(m_CameraFilteringBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
// <<< Old SSS Model
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraSssDiffuseLightingBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraFilteringBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{

// Clear the diffuse SSS lighting target
using (new Utilities.ProfilingSample("Clear SSS diffuse target", cmd))
{
Utilities.SetRenderTarget(cmd, m_CameraSubsurfaceBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
Utilities.SetRenderTarget(cmd, m_CameraSssDiffuseLightingBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
// Clear the SSS filtering target
using (new Utilities.ProfilingSample("Clear SSS filtering target", cmd))
if (!sssSettings.useDisneySSS)
Utilities.SetRenderTarget(cmd, m_CameraFilteringBuffer, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
// Clear the SSS filtering target
using (new Utilities.ProfilingSample("Clear SSS filtering target", cmd))
{
Utilities.SetRenderTarget(cmd, m_CameraFilteringBuffer, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
}
if (NeedStencilBufferCopy())
{
using (new Utilities.ProfilingSample("Clear stencil texture", cmd))
{
Utilities.SetRenderTarget(cmd, m_CameraStencilBufferCopyRT, ClearFlag.ClearColor, Color.black);
}
}
if (NeedHTileCopy())
{
using (new Utilities.ProfilingSample("Clear HTile", cmd))
{
Utilities.SetRenderTarget(cmd, m_HTileRT, ClearFlag.ClearColor, 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.

613
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset


useForwardRenderingOnly: 0
useDepthPrepass: 0
sssSettings:
numProfiles: 4
numProfiles: 2
- {fileID: 11400000, guid: b378ec8b14e770f48a085d537053adfe, type: 2}
- {fileID: 11400000, guid: 02c3836a8d1b4544a97f00fa528bb487, type: 2}
- {fileID: 11400000, guid: 15cd040d2fa59074d90956ea9badbee8, type: 2}
- {fileID: 11400000, guid: d6ee4403015766f4093158d69216c0bf, type: 2}
texturingModeFlags: 1
transmissionFlags: 5460
thicknessRemaps:
- {x: 0, y: 12.031147, z: 0, w: 0}
- {x: 0, y: 0.2873168, z: 0, w: 0}
- {x: 0, y: 5, z: 0, w: 0}
- {x: 0, y: 12.031147, z: 0, w: 0}
- {x: 0, y: 12.031147, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
worldScales:
- {x: 1, y: 0, z: 0, w: 0}
- {x: 1, y: 0, z: 0, w: 0}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
shapeParams:
- {x: 1.3192612, y: 3.1152647, z: 4.9751244, w: 7.84603}
- {x: 1.3203883, y: 1.4268992, z: 4.0812, w: 7.839332}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
transmissionTints:
- {x: 0.1892157, y: 0.08039216, z: 0.050000004, w: 0.25}
- {x: 0.25, y: 0.25, z: 0.25, w: 0.25}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 0, y: 0, z: 0, w: 0}
filterKernels:
- {x: 0.013865918, y: 1.5345725, z: 0.03667902, w: 1.5654991}
- {x: 0.04211352, y: 1.5729346, z: 0.11374626, w: 1.6734134}
- {x: 0.07107388, y: 1.6130018, z: 0.19626758, w: 1.7949444}
- {x: 0.100779116, y: 1.6548817, z: 0.28494877, w: 1.9325867}
- {x: 0.13126306, y: 1.6986896, z: 0.38062802, w: 2.0894418}
- {x: 0.16256203, y: 1.7445502, z: 0.48430943, w: 2.2694077}
- {x: 0.1947145, y: 1.7925992, z: 0.59720695, w: 2.4774427}
- {x: 0.22776169, y: 1.8429838, z: 0.72080237, w: 2.7199378}
- {x: 0.26174724, y: 1.8958628, z: 0.8569269, w: 3.005264}
- {x: 0.29671827, y: 1.9514104, z: 1.007873, w: 3.3445888}
- {x: 0.33272493, y: 2.0098157, z: 1.1765549, w: 3.7531407}
- {x: 0.369821, y: 2.0712852, z: 1.3667475, w: 4.252257}
- {x: 0.40806437, y: 2.1360447, z: 1.5834517, w: 4.872841}
- {x: 0.44751683, y: 2.2043417, z: 1.8334827, w: 5.6615734}
- {x: 0.48824534, y: 2.276447, z: 2.126473, w: 6.692844}
- {x: 0.5303216, y: 2.3526597, z: 2.4767098, w: 8.093767}
- {x: 0.5738235, y: 2.433308, z: 2.9068332, w: 10.102725}
- {x: 0.61883456, y: 2.5187542, z: 3.4562516, w: 13.228675}
- {x: 0.665446, y: 2.609401, z: 4.2041187, w: 18.793621}
- {x: 0.713756, y: 2.7056925, z: 5.3538504, w: 31.646347}
- {x: 0.763872, y: 2.808125, z: 7.84603, w: 95.44374}
- {x: 0.8159103, y: 2.91725, z: 0, w: 1}
- {x: 0.8699981, y: 3.0336854, z: 0, w: 1}
- {x: 0.9262747, y: 3.1581244, z: 0, w: 1}
- {x: 0.98489225, y: 3.2913465, z: 0, w: 1}
- {x: 1.0460185, y: 3.434234, z: 0, w: 1}
- {x: 1.1098381, y: 3.5877857, z: 0, w: 1}
- {x: 1.1765549, y: 3.7531407, z: 0, w: 1}
- {x: 1.2463952, y: 3.9316032, z: 0, w: 1}
- {x: 1.319611, y: 4.124672, z: 0, w: 1}
- {x: 1.3964823, y: 4.3340797, z: 0, w: 1}
- {x: 1.4773248, y: 4.561845, z: 0, w: 1}
- {x: 1.5624928, y: 4.810328, z: 0, w: 1}
- {x: 1.6523882, y: 5.082317, z: 0, w: 1}
- {x: 1.747467, y: 5.381122, z: 0, w: 1}
- {x: 1.8482518, y: 5.710715, z: 0, w: 1}
- {x: 1.9553448, y: 6.0759025, z: 0, w: 1}
- {x: 2.069445, y: 6.482568, z: 0, w: 1}
- {x: 2.1913698, y: 6.9379897, z: 0, w: 1}
- {x: 2.3220856, y: 7.4513016, z: 0, w: 1}
- {x: 2.4627466, y: 8.0341215, z: 0, w: 1}
- {x: 2.614747, y: 8.701484, z: 0, w: 1}
- {x: 2.7797952, y: 9.473195, z: 0, w: 1}
- {x: 2.9600194, y: 10.375936, z: 0, w: 1}
- {x: 3.1581159, y: 11.446505, z: 0, w: 1}
- {x: 3.3775842, y: 12.737201, z: 0, w: 1}
- {x: 3.6230793, y: 14.324919, z: 0, w: 1}
- {x: 3.9009922, y: 16.327562, z: 0, w: 1}
- {x: 4.220452, y: 18.935623, z: 0, w: 1}
- {x: 4.5951686, y: 22.478209, z: 0, w: 1}
- {x: 5.047148, y: 27.57712, z: 0, w: 1}
- {x: 5.615129, y: 35.564823, z: 0, w: 1}
- {x: 6.3776174, y: 49.90625, z: 0, w: 1}
- {x: 7.5374603, y: 83.30668, z: 0, w: 1}
- {x: 10.03481, y: 250.11497, z: 0, w: 1}
- {x: 0.013854082, y: 1.5332626, z: 0.036647703, w: 1.5641627}
- {x: 0.04207757, y: 1.5715919, z: 0.113649175, w: 1.671985}
- {x: 0.07101321, y: 1.611625, z: 0.19610003, w: 1.7934121}
- {x: 0.10069309, y: 1.653469, z: 0.28470552, w: 1.9309369}
- {x: 0.13115102, y: 1.6972395, z: 0.38030306, w: 2.0876582}
- {x: 0.16242325, y: 1.743061, z: 0.48389605, w: 2.2674706}
- {x: 0.19454831, y: 1.791069, z: 0.5966971, w: 2.4753277}
- {x: 0.22756726, y: 1.8414105, z: 0.72018707, w: 2.717616}
- {x: 0.2615238, y: 1.8942443, z: 0.85619545, w: 3.0026984}
- {x: 0.29646498, y: 1.9497447, z: 1.0070126, w: 3.3417335}
- {x: 0.33244094, y: 2.0081, z: 1.1755506, w: 3.749937}
- {x: 0.36950532, y: 2.069517, z: 1.3655809, w: 4.248627}
- {x: 0.40771604, y: 2.1342213, z: 1.5821002, w: 4.868682}
- {x: 0.44713485, y: 2.2024598, z: 1.8319175, w: 5.6567397}
- {x: 0.48782852, y: 2.274504, z: 2.1246579, w: 6.6871305}
- {x: 0.5298689, y: 2.3506513, z: 2.4745958, w: 8.086858}
- {x: 0.5733336, y: 2.4312308, z: 2.9043517, w: 10.094101}
- {x: 0.6183063, y: 2.5166042, z: 3.4533012, w: 13.217383}
- {x: 0.66487795, y: 2.6071734, z: 4.20053, w: 18.777578}
- {x: 0.71314675, y: 2.703383, z: 5.349281, w: 31.61934}
- {x: 0.76321995, y: 2.805728, z: 7.839332, w: 95.36225}
- {x: 0.81521386, y: 2.9147599, z: 0, w: 1}
- {x: 0.86925554, y: 3.031096, z: 0, w: 1}
- {x: 0.92548406, y: 3.1554284, z: 0, w: 1}
- {x: 0.9840515, y: 3.288537, z: 0, w: 1}
- {x: 1.0451256, y: 3.431302, z: 0, w: 1}
- {x: 1.1088905, y: 3.5847225, z: 0, w: 1}
- {x: 1.1755506, y: 3.749937, z: 0, w: 1}
- {x: 1.2453312, y: 3.9282467, z: 0, w: 1}
- {x: 1.3184844, y: 4.1211514, z: 0, w: 1}
- {x: 1.3952904, y: 4.3303804, z: 0, w: 1}
- {x: 1.4760638, y: 4.5579505, z: 0, w: 1}
- {x: 1.5611593, y: 4.8062224, z: 0, w: 1}
- {x: 1.650978, y: 5.0779796, z: 0, w: 1}
- {x: 1.7459753, y: 5.3765287, z: 0, w: 1}
- {x: 1.8466738, y: 5.7058387, z: 0, w: 1}
- {x: 1.9536757, y: 6.070716, z: 0, w: 1}
- {x: 2.0676782, y: 6.4770336, z: 0, w: 1}
- {x: 2.189499, y: 6.9320674, z: 0, w: 1}
- {x: 2.3201032, y: 7.4449396, z: 0, w: 1}
- {x: 2.4606442, y: 8.027264, z: 0, w: 1}
- {x: 2.612515, y: 8.694056, z: 0, w: 1}
- {x: 2.777422, y: 9.465107, z: 0, w: 1}
- {x: 2.9574924, y: 10.367077, z: 0, w: 1}
- {x: 3.1554203, y: 11.436736, z: 0, w: 1}
- {x: 3.3747015, y: 12.726331, z: 0, w: 1}
- {x: 3.6199868, y: 14.312694, z: 0, w: 1}
- {x: 3.897662, y: 16.313623, z: 0, w: 1}
- {x: 4.2168484, y: 18.919455, z: 0, w: 1}
- {x: 4.5912457, y: 22.459015, z: 0, w: 1}
- {x: 5.042839, y: 27.553566, z: 0, w: 1}
- {x: 5.610336, y: 35.534466, z: 0, w: 1}
- {x: 6.3721733, y: 49.863647, z: 0, w: 1}
- {x: 7.53103, y: 83.235695, z: 0, w: 1}
- {x: 10.026244, y: 249.90146, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
halfRcpWeightedVariances:
- {x: 2.4691355, y: 12.5, z: 12.5, w: 2.4691355}
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
halfRcpVariancesAndWeights:
- {x: 0.5, y: 1.125, z: 1.125, w: 2}
- {x: 0.125, y: 1.125, z: 1.125, w: 2}
- {x: 0.5, y: 0.5, z: 0.5, w: 2}
- {x: 0.125, y: 0.125, z: 0.125, w: 2}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
filterKernelsBasic:
- {x: 0.09090909, y: 0.21162307, z: 0.21162307, w: -0.000000048879357}
- {x: 0.09090909, y: 0.18990478, z: 0.18990478, w: -0.11381993}
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: -0.23580086}
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: -0.37865555}
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: -0.57677805}
- {x: 0.09090909, y: 2.9458339e-10, z: 2.9458339e-10, w: -1.3907351}
- {x: 0.09090909, y: 0.18990476, z: 0.18990476, w: 0.11382001}
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: 0.23580086}
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: 0.37865555}
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: 0.57677805}
- {x: 0.09090909, y: 2.9456845e-10, z: 2.9456845e-10, w: 1.3907368}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.11381993}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -1.3907351}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.11382001}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 1.3907368}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
enableSplitLightEvaluation: 1
enableComputeLightEvaluation: 0
enableComputeLightVariants: 0
enableComputeMaterialVariants: 0
enableComputeLightEvaluation: 1
enableComputeLightVariants: 1
enableComputeMaterialVariants: 1
tileDebugByCategory: 0
shadowInitParams:
shadowAtlasWidth: 4096
shadowAtlasHeight: 4096

reflectionCubemapSize: 128
m_DefaultDiffuseMaterial: {fileID: 0}
m_DefaultShader: {fileID: 0}
m_DefaultDiffuseMaterial: {fileID: 2100000, guid: 73c176f402d2c2f4d929aa5da7585d17,
type: 2}
m_DefaultShader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}

15
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.cs


internal static readonly int _Downsample = Shader.PropertyToID("_Downsample");
internal static readonly int _SampleCount = Shader.PropertyToID("_SampleCount");
internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
internal static readonly int _AOBuffer = Shader.PropertyToID("_AmbientOcclusionTexture");
internal static readonly int _TempTex1 = Shader.PropertyToID("_TempTex1");
internal static readonly int _TempTex2 = Shader.PropertyToID("_TempTex2");
}

// If SSAO is disable, simply put a white 1x1 texture
if (settings.enable == false || isForward)
{
cmd.SetGlobalTexture(Uniforms._AOBuffer, UnityEngine.Rendering.PostProcessing.RuntimeUtilities.blackTexture); // Neutral is black, see the comment in the shaders
cmd.SetGlobalTexture(HDShaderIDs._AmbientOcclusionTexture, UnityEngine.Rendering.PostProcessing.RuntimeUtilities.blackTexture); // Neutral is black, see the comment in the shaders
cmd.SetGlobalFloat(HDShaderIDs._AmbientOcclusionDirectLightStrenght, 0.0f);
return;
}

cmd.ReleaseTemporaryRT(Uniforms._TempTex2);
// Final filtering
cmd.GetTemporaryRT(Uniforms._AOBuffer, width, height, 0, kFilter, GetAOBufferFormat(), kRWMode);
cmd.GetTemporaryRT(HDShaderIDs._AmbientOcclusionTexture, width, height, 0, kFilter, GetAOBufferFormat(), kRWMode);
Utilities.DrawFullScreen(cmd, m_Material, Uniforms._AOBuffer, null, 3);
Utilities.DrawFullScreen(cmd, m_Material, HDShaderIDs._AmbientOcclusionTexture, null, 3);
// Setup texture for lighting pass (automagic of unity)
cmd.SetGlobalTexture("_AmbientOcclusionTexture", Uniforms._AOBuffer);
hdRP.PushFullScreenDebugTexture(cmd, Uniforms._AOBuffer, hdCamera.camera, renderContext, FullScreenDebugMode.SSAO);
// Setup texture for lighting pass (automatic of unity)
cmd.SetGlobalTexture(HDShaderIDs._AmbientOcclusionTexture, HDShaderIDs._AmbientOcclusionTexture);
cmd.SetGlobalFloat(HDShaderIDs._AmbientOcclusionDirectLightStrenght, settings.affectDirectLigthingStrenght);
hdRP.PushFullScreenDebugTexture(cmd, HDShaderIDs._AmbientOcclusionTexture, hdCamera.camera, renderContext, FullScreenDebugMode.SSAO);
}
}

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.shader


HLSLINCLUDE
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#define UNITY_MATERIAL_LIT // Needs to be defined before including Material.hlsl

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusionSettings.cs


[SerializeField]
bool m_Enable;
[SerializeField, Range(0, 1)]
float m_AffectDirectLigthingStrenght;
[SerializeField, Range(0, 2)]
float m_Intensity;
[SerializeField]

bool m_Downsampling;
public bool enable { set { m_Enable = value; } get { return m_Enable; } }
public float affectDirectLigthingStrenght { set { m_AffectDirectLigthingStrenght = value; OnValidate(); } get { return m_AffectDirectLigthingStrenght; } }
public float intensity { set { m_Intensity = value; OnValidate(); } get { return m_Intensity; } }
public float radius { set { m_Radius = value; OnValidate(); } get { return m_Radius; } }
public int sampleCount { set { m_SampleCount = value; OnValidate(); } get { return m_SampleCount; } }

{
m_AffectDirectLigthingStrenght = Mathf.Clamp(m_AffectDirectLigthingStrenght, 0, 1);
m_Intensity = Mathf.Clamp(m_Intensity, 0, 2);
m_Radius = Mathf.Max(0, m_Radius);
m_SampleCount = Mathf.Clamp(m_SampleCount, 1, 32);

{
m_Enable = false,
m_AffectDirectLigthingStrenght = 0.0f,
m_Intensity = 1.0f,
m_Radius = 0.5f,
m_SampleCount = 8,

18
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader


// Chose supported lighting architecture in case of deferred rendering
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS
// TODO: Workflow problem here, I would like to only generate variant for the LIGHTLOOP_TILE_PASS case, not the LIGHTLOOP_SINGLE_PASS case. This must be on lightloop side and include here.... (Can we codition
#pragma multi_compile LIGHTLOOP_TILE_DIRECT LIGHTLOOP_TILE_INDIRECT LIGHTLOOP_TILE_ALL
#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
// Split lighting is utilized during the SSS pass.

// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../ShaderConfig.cs.hlsl"
#include "../ShaderVariables.hlsl"
#include "../Lighting/Lighting.hlsl" // This include Material.hlsl

Outputs Frag(Varyings input)
{
// This need to stay in sync with deferred.compute
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, uint2(input.positionCS.xy) / GetTileSize());
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;

#ifdef OUTPUT_SPLIT_LIGHTING
outputs.specularLighting = float4(specularLighting, 1.0);
outputs.diffuseLighting = diffuseLighting;
#if defined(LIGHTLOOP_TILE_INDIRECT) || defined(LIGHTLOOP_TILE_ALL)
// We SSSSS is enabled with use split lighting.
// SSSSS algorithm need to know which pixels contribute to SSS and which doesn't. We could use the stencil for that but it mean that it will increase the cost of SSSSS
// A simpler solution is to add a slight contribution here that isn't visible (here we chose fp16 min (which is also fp11 and fp10 min).
// The SSSSS algorithm will check if diffuse lighting is black and discard the pixel if it is the case
outputs.diffuseLighting.r = max(outputs.diffuseLighting.r, HFLT_MIN);
#endif
// We SSSSS is enabled with use split lighting.
// SSSSS algorithm need to know which pixels contribute to SSS and which doesn't. We could use the stencil for that but it mean that it will increase the cost of SSSSS
// A simpler solution is to add a slight contribution here that isn't visible (here we chose fp16 min (which is also fp11 and fp10 min).
// The SSSSS algorithm will check if diffuse lighting is black and discard the pixel if it is the case
outputs.diffuseLighting.r = max(outputs.diffuseLighting.r, HFLT_MIN);
#else
outputs.combinedLighting = float4(diffuseLighting + specularLighting, 1.0);
#endif

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Forward.hlsl


// No USE_FPTL_LIGHTLIST as we are in forward and this use the cluster path (but cluster path can use the tile light list for opaque)
#define USE_CLUSTERED_LIGHTLIST
#define LIGHTLOOP_TILE_ALL

64
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


public enum GPULightType
{
Directional,
ProjectorBox,
ProjectorOrtho,
Line, // Keep Line lights before Rectangle. This is needed because of a compiler bug (see LightLoop.hlsl)
Line,
// Currently not supported in real time (just use for reference)
Sphere,
Disk,

// These structures share between C# and hlsl need to be align on float4, so we pad them.
[GenerateHLSL]
public struct LightData
public struct DirectionalLightData
public float invSqrAttenuationRadius;
public bool tileCookie;
public float angleScale; // Spot light
public int shadowIndex; // -1 if unused
public float angleOffset; // Spot light
public Vector3 up;
public float diffuseScale;
public int cookieIndex; // -1 if unused
public Vector3 right;
public Vector3 right; // Rescaled by (2 / lightLength)
public float shadowDimmer;
// index are -1 if not used
public int shadowIndex;
public int IESIndex;
public int cookieIndex;
public Vector2 size; // Used by area, projector and spot lights; x = cot(outerHalfAngle) for spot lights
public GPULightType lightType;
public float unused;
public Vector3 up; // Rescaled by (2 / lightWidth)
public float diffuseScale;
public struct DirectionalLightData
public struct LightData
public Vector3 forward;
public float diffuseScale;
public Vector3 up;
public float invScaleY;
public Vector3 right;
public float invScaleX;
public bool tileCookie;
public float invSqrAttenuationRadius;
public float specularScale;
// Sun disc size
public float cosAngle; // Distance to the disk
public float sinAngle; // Disk radius
public Vector3 forward;
public Vector3 right; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / lightLength)
public float specularScale;
public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by * (2 / lightWidth)
public float diffuseScale;
public float angleScale; // Spot light
public float angleOffset; // Spot light
public float shadowDimmer;
public int unused0;
public Vector2 size; // Used by area, frustum projector and spot lights (x = cot(outerHalfAngle))
public GPULightType lightType;
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.
[GenerateHLSL]

180
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


// UnityEngine.Experimental.Rendering.HDPipeline.GPULightType: static fields
//
#define GPULIGHTTYPE_DIRECTIONAL (0)
#define GPULIGHTTYPE_SPOT (1)
#define GPULIGHTTYPE_POINT (2)
#define GPULIGHTTYPE_PROJECTOR_ORTHO (3)
#define GPULIGHTTYPE_PROJECTOR_BOX (1)
#define GPULIGHTTYPE_SPOT (2)
#define GPULIGHTTYPE_POINT (3)
#define GPULIGHTTYPE_RECTANGLE (5)
#define GPULIGHTTYPE_LINE (6)
#define GPULIGHTTYPE_LINE (5)
#define GPULIGHTTYPE_RECTANGLE (6)
#define GPULIGHTTYPE_SPHERE (7)
#define GPULIGHTTYPE_DISK (8)
#define GPULIGHTTYPE_HEMISPHERE (9)

#define STENCILLIGHTINGUSAGE_SPLIT_LIGHTING (1)
#define STENCILLIGHTINGUSAGE_REGULAR_LIGHTING (2)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.LightData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData
struct LightData
struct DirectionalLightData
float invSqrAttenuationRadius;
bool tileCookie;
float angleScale;
int shadowIndex;
float angleOffset;
int cookieIndex;
float3 right;
float specularScale;
float3 right;
float specularScale;
float shadowDimmer;
int shadowIndex;
int IESIndex;
int cookieIndex;
float2 size;
int lightType;
float unused;
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.LightData
struct DirectionalLightData
struct LightData
float3 forward;
float diffuseScale;
float3 up;
float invScaleY;
float3 right;
float invScaleX;
bool tileCookie;
float invSqrAttenuationRadius;
float specularScale;
float cosAngle;
float sinAngle;
float3 forward;
float3 right;
float specularScale;
float3 up;
float diffuseScale;
float angleScale;
float angleOffset;
float shadowDimmer;
int unused0;
float2 size;
int lightType;
float minRoughness;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData

};
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.LightData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData
float3 GetPositionWS(LightData value)
float3 GetPositionWS(DirectionalLightData value)
float GetInvSqrAttenuationRadius(LightData value)
bool GetTileCookie(DirectionalLightData value)
return value.invSqrAttenuationRadius;
return value.tileCookie;
float3 GetColor(LightData value)
float3 GetColor(DirectionalLightData value)
float GetAngleScale(LightData value)
int GetShadowIndex(DirectionalLightData value)
return value.angleScale;
return value.shadowIndex;
float3 GetForward(LightData value)
float3 GetForward(DirectionalLightData value)
float GetAngleOffset(LightData value)
{
return value.angleOffset;
}
float3 GetUp(LightData value)
int GetCookieIndex(DirectionalLightData value)
return value.up;
return value.cookieIndex;
float GetDiffuseScale(LightData value)
{
return value.diffuseScale;
}
float3 GetRight(LightData value)
float3 GetRight(DirectionalLightData value)
float GetSpecularScale(LightData value)
float GetSpecularScale(DirectionalLightData value)
float GetShadowDimmer(LightData value)
float3 GetUp(DirectionalLightData value)
return value.shadowDimmer;
return value.up;
int GetShadowIndex(LightData value)
float GetDiffuseScale(DirectionalLightData value)
return value.shadowIndex;
return value.diffuseScale;
int GetIESIndex(LightData value)
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.LightData
//
float3 GetPositionWS(LightData value)
return value.IESIndex;
return value.positionWS;
int GetCookieIndex(LightData value)
float GetInvSqrAttenuationRadius(LightData value)
return value.cookieIndex;
return value.invSqrAttenuationRadius;
float2 GetSize(LightData value)
float3 GetColor(LightData value)
return value.size;
return value.color;
int GetLightType(LightData value)
int GetShadowIndex(LightData value)
return value.lightType;
return value.shadowIndex;
float GetUnused(LightData value)
{
return value.unused;
}
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData
//
float3 GetForward(DirectionalLightData value)
float3 GetForward(LightData value)
float GetDiffuseScale(DirectionalLightData value)
int GetCookieIndex(LightData value)
return value.diffuseScale;
}
float3 GetUp(DirectionalLightData value)
{
return value.up;
return value.cookieIndex;
float GetInvScaleY(DirectionalLightData value)
float3 GetRight(LightData value)
return value.invScaleY;
return value.right;
float3 GetRight(DirectionalLightData value)
float GetSpecularScale(LightData value)
return value.right;
return value.specularScale;
float GetInvScaleX(DirectionalLightData value)
float3 GetUp(LightData value)
return value.invScaleX;
return value.up;
float3 GetPositionWS(DirectionalLightData value)
float GetDiffuseScale(LightData value)
return value.positionWS;
return value.diffuseScale;
bool GetTileCookie(DirectionalLightData value)
float GetAngleScale(LightData value)
return value.tileCookie;
return value.angleScale;
float3 GetColor(DirectionalLightData value)
float GetAngleOffset(LightData value)
return value.color;
return value.angleOffset;
float GetSpecularScale(DirectionalLightData value)
float GetShadowDimmer(LightData value)
return value.specularScale;
return value.shadowDimmer;
float GetCosAngle(DirectionalLightData value)
int GetUnused0(LightData value)
return value.cosAngle;
return value.unused0;
float GetSinAngle(DirectionalLightData value)
float2 GetSize(LightData value)
return value.sinAngle;
return value.size;
int GetShadowIndex(DirectionalLightData value)
int GetLightType(LightData value)
return value.shadowIndex;
return value.lightType;
int GetCookieIndex(DirectionalLightData value)
float GetMinRoughness(LightData value)
return value.cookieIndex;
return value.minRoughness;
}
//

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


return geomSeries / (g_fFarPlane - g_fNearPlane);
}
float LogBase(float x, float b)
{
return log2(x) / log2(b);
}
int SnapToClusterIdxFlex(float z_in, float suggestedBase, bool logBasePerTile)
{
#if USE_LEFT_HAND_CAMERA_SPACE

#endif
float userscale = g_fClustScale;
if (logBasePerTile)
userscale = GetScaleFromBase(suggestedBase);
//float userscale = g_fClustScale;
//if (logBasePerTile)
// userscale = GetScaleFromBase(suggestedBase);
const float dist = max(0, z - g_fNearPlane);
return (int)clamp(log2(dist * userscale * (suggestedBase - 1.0f) + 1) / log2(suggestedBase), 0.0, (float)((1 << g_iLog2NumClusters) - 1));
//const float dist = max(0, z - g_fNearPlane);
//return (int)clamp(log2(dist * userscale * (suggestedBase - 1.0f) + 1) / log2(suggestedBase), 0.0, (float)((1 << g_iLog2NumClusters) - 1));
const int C = 1 << g_iLog2NumClusters;
const float rangeFittedDistance = max(0, z - g_fNearPlane) / (g_fFarPlane - g_fNearPlane);
return (int)clamp( LogBase( lerp(1.0, PositivePow(suggestedBase, (float) C), rangeFittedDistance), suggestedBase), 0.0, (float)(C - 1));
}
int SnapToClusterIdx(float z_in, float suggestedBase)

{
float res;
float userscale = g_fClustScale;
if (logBasePerTile)
userscale = GetScaleFromBase(suggestedBase);
//float userscale = g_fClustScale;
//if (logBasePerTile)
// userscale = GetScaleFromBase(suggestedBase);
//float dist = (PositivePow(suggestedBase, (float)k) - 1.0) / (userscale * (suggestedBase - 1.0f));
//res = dist + g_fNearPlane;
const float C = (float)(1 << g_iLog2NumClusters);
float rangeFittedDistance = (PositivePow(suggestedBase, (float)k) - 1.0) / (PositivePow(suggestedBase, C) - 1.0);
res = lerp(g_fNearPlane, g_fFarPlane, rangeFittedDistance);
float dist = (PositivePow(suggestedBase, (float)k) - 1.0) / (userscale * (suggestedBase - 1.0f));
res = dist + g_fNearPlane;
#if USE_LEFT_HAND_CAMERA_SPACE
return res;

float SuggestLogBase50(float tileFarPlane)
{
const float C = (float)(1 << g_iLog2NumClusters);
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1.0 + sqrt(max(0.0, 1.0 - 4.0 * normDist * (1.0 - normDist)))) / (2.0 * normDist), 2.0 / C); //
float rangeFittedDistance = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1.0 + sqrt(max(0.0, 1.0 - 4.0 * rangeFittedDistance * (1.0 - rangeFittedDistance)))) / (2.0 * rangeFittedDistance), 2.0 / C); //
return max(g_fClustBase, suggested_base);
}

const float C = (float)(1 << g_iLog2NumClusters);
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1 / 2.3) * max(0.0, (0.8 / normDist) - 1), 4.0 / (C * 2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
float rangeFittedDistance = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1 / 2.3) * max(0.0, (0.8 / rangeFittedDistance) - 1), 4.0 / (C * 2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
return max(g_fClustBase, suggested_base);
}

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


return float4(vN, -dot(vN,p0));
}
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen, float sphRadiusIn)
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen_in, float sphRadiusIn, bool isOrthographic)
float3 V = dir; // ray direction down center of tile (does not need to be normalized).
float3 V = float3(isOrthographic ? 0.0 : dir.x, isOrthographic ? 0.0 : dir.y, dir.z); // ray direction down center of tile (does not need to be normalized).
float3 sphCen = float3(sphCen_in.x - (isOrthographic ? dir.x : 0.0), sphCen_in.y - (isOrthographic ? dir.y : 0.0), sphCen_in.z);
#if 1
float3 maxZdir = float3(-sphCen.z*sphCen.x, -sphCen.z*sphCen.y, sphCen.x*sphCen.x + sphCen.y*sphCen.y); // cross(sphCen,cross(Zaxis,sphCen))

// enlarge sphere so it overlaps the center of the tile assuming it overlaps the tile to begin with.
#if USE_LEFT_HAND_CAMERA_SPACE
float sphRadius = sphRadiusIn + (sphCen.z+offs)*halfTileSizeAtZDistOne;
float s = sphCen.z+offs;
float sphRadius = sphRadiusIn - (sphCen.z-offs)*halfTileSizeAtZDistOne;
float s = -(sphCen.z-offs);
float sphRadius = sphRadiusIn + (isOrthographic ? 1.0 : s)*halfTileSizeAtZDistOne;
float a = dot(V,V);
float CdotV = dot(sphCen,V);

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl


SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_DIR_SMP];
uint algo = SHADOW_DISPATCH_DIR_ALG;
return EvalShadow_CascadedDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_CascadedDepth_Blend( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )

// example of overriding punctual lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L )
{
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
// example for choosing different algos for point and spot lights

return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
#endif
}
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L, float2 unPositionSS )
{
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}

713
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
文件差异内容过多而无法显示
查看文件

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


//
#define LIGHTCATEGORY_PUNCTUAL (0)
#define LIGHTCATEGORY_AREA (1)
#define LIGHTCATEGORY_PROJECTOR (2)
#define LIGHTCATEGORY_ENV (3)
#define LIGHTCATEGORY_COUNT (4)
#define LIGHTCATEGORY_ENV (2)
#define LIGHTCATEGORY_COUNT (3)
#define LIGHTFEATUREFLAGS_PUNCTUAL (1)
#define LIGHTFEATUREFLAGS_AREA (2)
#define LIGHTFEATUREFLAGS_DIRECTIONAL (4)
#define LIGHTFEATUREFLAGS_PROJECTOR (8)
#define LIGHTFEATUREFLAGS_ENV (16)
#define LIGHTFEATUREFLAGS_SKY (32)
#define LIGHTFEATUREFLAGS_PUNCTUAL (256)
#define LIGHTFEATUREFLAGS_AREA (512)
#define LIGHTFEATUREFLAGS_DIRECTIONAL (1024)
#define LIGHTFEATUREFLAGS_ENV (2048)
#define LIGHTFEATUREFLAGS_SKY (4096)
//
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightDefinitions: static fields

#define USE_LEFT_HAND_CAMERA_SPACE (1)
#define TILE_SIZE_FPTL (16)
#define TILE_SIZE_CLUSTERED (32)
#define NUM_FEATURE_VARIANTS (16)
#define LIGHTFEATUREFLAGS_MASK (4095)
#define MATERIALFEATUREFLAGS_MASK (61440)
#define NUM_FEATURE_VARIANTS (31)
#define LIGHT_FEATURE_MASK_FLAGS (65280)
#define MATERIAL_FEATURE_MASK_FLAGS (255)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.TilePass.SFiniteLightBound
// PackingRules = Exact

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


#if defined (LIGHTLOOP_TILE_DIRECT) || defined(LIGHTLOOP_TILE_ALL)
#define PROCESS_DIRECTIONAL_LIGHT
#define PROCESS_PUNCTUAL_LIGHT
#define PROCESS_AREA_LIGHT
#define PROCESS_PROJECTOR_LIGHT
#endif
#if defined (LIGHTLOOP_TILE_INDIRECT) || defined(LIGHTLOOP_TILE_ALL)
#define PROCESS_ENV_LIGHT
#endif
#include "TilePass.cs.hlsl"
StructuredBuffer<uint> g_vLightListGlobal; // don't support Buffer yet in unity

StructuredBuffer<EnvLightData> _EnvLightDatas;
StructuredBuffer<ShadowData> _ShadowDatas;
// Use texture array for IES
//TEXTURE2D_ARRAY(_IESArray);
//SAMPLER2D(sampler_IESArray);
// Used by directional and spot lights
TEXTURE2D_ARRAY(_CookieTextures);
SAMPLER2D(sampler_CookieTextures);

TEXTURECUBE(_SkyTexture);
SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...
TEXTURE2D(_AmbientOcclusionTexture);
uint _ProjectorLightCount;
float _AmbientOcclusionDirectLightStrenght;
CBUFFER_END
struct LightLoopContext

}
//-----------------------------------------------------------------------------
// IES sampling function
// ----------------------------------------------------------------------------
// sphericalTexCoord is theta and phi spherical coordinate
//float4 SampleIES(LightLoopContext lightLoopContext, int index, float2 sphericalTexCoord, float lod)
//{
// return SAMPLE_TEXTURE2D_ARRAY_LOD(_IESArray, sampler_IESArray, sphericalTexCoord, index, 0);
//}
//-----------------------------------------------------------------------------
// Reflection proble / Sky sampling function
// ----------------------------------------------------------------------------

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

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


return (_UseTileLightList ? ((value >> ((lightIndexPlusOne & 1) * DWORD_PER_TILE)) & 0xffff) : value);
}
#endif
#endif // USE_FPTL_LIGHTLIST
#else
uint GetTileSize()
{
return 1;
}
#endif // LIGHTLOOP_TILE_PASS
void applyWeigthedIblLighting(float3 localDiffuseLighting, float3 localSpecularLighting, float2 weight, inout float3 iblDiffuseLighting, inout float3 iblSpecularLighting, inout float totalIblWeight)
{
// IBL weights should not exceed 1.
float accumulatedWeight = totalIblWeight + weight.y;
totalIblWeight = saturate(accumulatedWeight);
weight.y -= saturate(accumulatedWeight - totalIblWeight);
// TODO: We do'nt use ibl diffuse lighting currently, let here in case users want to use it.
// iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x);
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting, uint featureFlags,

uint i = 0; // Declare once to avoid the D3D11 compiler warning.
#ifdef PROCESS_DIRECTIONAL_LIGHT
if(featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
for(i = 0; i < _DirectionalLightCount; ++i)
for (i = 0; i < _DirectionalLightCount; ++i)
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Directional(context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
#endif
#ifdef PROCESS_PUNCTUAL_LIGHT
if(featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
if (featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
#ifdef LIGHTLOOP_TILE_PASS
for(i = 0; i < punctualLightCount; ++i)
for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;

diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
}
#endif
#else
#ifdef PROCESS_AREA_LIGHT
if(featureFlags & LIGHTFEATUREFLAGS_AREA)
{
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
for(i = 0; i < areaLightCount; ++i)
for (i = 0; i < _PunctualLightCount; ++i)
uint areaIndex = FetchIndex(areaLightStart, i);
if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
}
}
#endif
#ifdef PROCESS_PROJECTOR_LIGHT
if(featureFlags & LIGHTFEATUREFLAGS_PROJECTOR)
{
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint projectorLightStart;
uint projectorLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_PROJECTOR, projectorLightStart, projectorLightCount);
for(i = 0; i < projectorLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
uint projectorIndex = FetchIndex(projectorLightStart, i);
EvaluateBSDF_Projector(context, V, posInput, prelightData, _LightDatas[projectorIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#endif
#ifdef PROCESS_ENV_LIGHT
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
if(featureFlags & LIGHTFEATUREFLAGS_SKY)
{
if(_EnvLightSkyEnabled)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
}
if(featureFlags & LIGHTFEATUREFLAGS_ENV)
if (featureFlags & LIGHTFEATUREFLAGS_AREA)
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
for(i = 0; i < envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
#endif
// TODO: currently apply GI at the same time as reflection
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting * context.ambientOcclusion;
#endif
float3 localDiffuseLighting, localSpecularLighting;
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#ifdef LIGHTLOOP_TILE_PASS
#else // LIGHTLOOP_SINGLE_PASS
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
uint GetTileSize()
{
return 1;
}
// COMPILER BEHAVIOR WARNING!
// If rectangle lights are before line lights, the compiler will duplicate light matrices in VGPR because they are used differently between the two types of lights.
// By keeping line lights first we avoid this behavior and save substantial register pressure.
// TODO: This is based on the current Lit.shader and can be different for any other way of implementing area lights, how to be generic and ensure performance ?
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting, uint featureFlag,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
context.ambientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.unPositionSS).x;
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
i = 0;
if (areaLightCount > 0)
{
uint areaIndex = FetchIndex(areaLightStart, 0);
uint lightType = _LightDatas[areaIndex].lightType;
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
while (i < areaLightCount && lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_LINE,
localDiffuseLighting, localSpecularLighting);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
for (i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
i++;
areaIndex = i < areaLightCount ? FetchIndex(areaLightStart, i) : 0;
lightType = i < areaLightCount ? _LightDatas[areaIndex].lightType : 0xFF;
}
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
while (i < areaLightCount && lightType == GPULIGHTTYPE_RECTANGLE)
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_RECTANGLE,
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
for (i = 0; i < _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
i++;
areaIndex = i < areaLightCount ? FetchIndex(areaLightStart, i) : 0;
lightType = i < areaLightCount ? _LightDatas[areaIndex].lightType : 0xFF;
}
}
for (; i < _PunctualLightCount + _AreaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
#else
if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
for (i = _PunctualLightCount; i < _PunctualLightCount + _AreaLightCount; ++i)
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType,
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
#endif
for (; i < _PunctualLightCount + _AreaLightCount + _ProjectorLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Projector( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// TODO: Check the reflection hierarchy, for the current system (matching legacy unity) we must sort from bigger solid angle to lower (lower override bigger). So begging by sky
// TODO: Change the way it is done by reversing the order, from smaller solid angle to bigger, so we can early out when the weight is 1.
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float totalIblWeight = 0.0; // Max: 1
// Only apply sky IBL if the sky texture is available.
if (_EnvLightSkyEnabled)
// Reflection probes are sorted by volume (in the increasing order).
if (featureFlags & LIGHTFEATUREFLAGS_ENV)
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
#ifdef LIGHTLOOP_TILE_PASS
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
#else
uint envLightCount = _EnvLightCount;
#endif
// Note: In case of IBL we are sorted from smaller to bigger projected solid angle bounds. We are not sorted by type so we can't do a 'while' approach like for area light.
for (i = 0; i < envLightCount && totalIblWeight < 1.0; ++i)
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightIndex = FetchIndex(envLightStart, i);
#else
uint envLightIndex = i;
#endif
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[envLightIndex], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, iblDiffuseLighting, iblSpecularLighting, totalIblWeight);
}
for (i = 0; i < _EnvLightCount; ++i)
if (featureFlags & LIGHTFEATUREFLAGS_SKY)
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[i], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
// Only apply the sky IBL if the sky texture is available, and if we haven't yet accumulated enough IBL lighting.
if (_EnvLightSkyEnabled && totalIblWeight < 1.0)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, iblDiffuseLighting, iblSpecularLighting, totalIblWeight);
}
// Apply ambient occlusion on direct lighting based on strenght factor
diffuseLighting *= lerp(1.0, context.ambientOcclusion, _AmbientOcclusionDirectLightStrenght);
// Add indirect diffuse + emissive (if any)
// Apply GI at the same time as reflection
// Add indirect diffuse + emissive (if any) - Ambient occlusion is multiply by emissive which is wrong but not a big deal
#endif

14
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/builddispatchindirect.compute


#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../Material/Material.hlsl" // This includes Material.hlsl
#include "FeatureFlags.hlsl"
RWBuffer<uint> g_DispatchIndirectBuffer : register( u0 ); // Indirect arguments have to be in a _buffer_, not a structured buffer
RWStructuredBuffer<uint> g_TileList;
StructuredBuffer<uint> g_TileFeatureFlags;

uint tileY = (dispatchThreadId + 0.5f) / (float)g_NumTilesX; // Integer division is extremely expensive, so we better avoid it
uint tileX = dispatchThreadId - tileY * g_NumTilesX;
uint variant = FeatureFlagsToTileVariant(featureFlags);
uint offset;
InterlockedAdd(g_DispatchIndirectBuffer[variant * 3 + 0], 1, offset);
g_TileList[variant * g_NumTiles + offset] = (tileY << 16) | tileX;
// Check if there is no light or no material (mean we are sky/background pixel) / Both test as we can enable/disable light/material classification
if ((featureFlags & LIGHT_FEATURE_MASK_FLAGS) != 0 && (featureFlags & MATERIAL_FEATURE_MASK_FLAGS) != 0)
{
uint variant = FeatureFlagsToTileVariant(featureFlags);
uint offset;
InterlockedAdd(g_DispatchIndirectBuffer[variant * 3 + 0], 1, offset);
g_TileList[variant * g_NumTiles + offset] = (tileY << 16) | tileX;
}
}

43
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-bigtile.compute


uniform float4x4 g_mScrProjection;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
uniform uint g_isOrthographic;
uniform int _EnvLightIndexShift;
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );

groupshared unsigned int lightsListLDS[MAX_NR_BIG_TILE_LIGHTS_PLUS_ONE];
groupshared uint lightOffs;
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;
return (m22*zDptBufSpace+m23) / (m32*zDptBufSpace+m33);
//float3 vP = float3(0.0f,0.0f,zDptBufSpace);
//float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
//return v4Pres.z / v4Pres.w;
}
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[lightsListLDS[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
lightsListLDS[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection == 0 ? vP0 : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
#if USE_LEFT_HAND_CAMERA_SPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection == 0 ? edgeSectionZero : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
}
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR)

43
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-clustered.compute


int g_iNrVisibLights;
float4x4 g_mInvScrProjection;
float4x4 g_mScrProjection;
uint g_isOrthographic;
int _EnvLightIndexShift;
float g_fClustScale;

groupshared uint lightOffsSph;
#endif
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;
return (m22*zDptBufSpace+m23) / (m32*zDptBufSpace+m33);
//float3 vP = float3(0.0f,0.0f,zDptBufSpace);
//float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
//return v4Pres.z / v4Pres.w;
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
coarseList[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection==0 ? vP0 : (((iSwizzle&0x2)==0 ? 1.0f : (-1.0f))*((iSwizzle&0x1)==(iSwizzle>>1) ? float3(1,0,0) : float3(0,1,0)));
#if USE_LEFT_HAND_CAMERA_SPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection == 0 ? edgeSectionZero : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
}
int CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)

37
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild.compute


uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform uint g_isOrthographic;
uniform int _EnvLightIndexShift;
uniform uint g_BaseFeatureFlags;

// return v4Pres.z / v4Pres.w;
//}
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;
return (m22*zDptBufSpace+m23) / (m32*zDptBufSpace+m33);
//float3 vP = float3(0.0f,0.0f,zDptBufSpace);
//float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
//return v4Pres.z / v4Pres.w;
}
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

if(t == 0)
{
uint featureFlags = ldsFeatureFlags | g_BaseFeatureFlags;
// In case of back
featureFlags &= ~(LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_AREA | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | 0xFFFFF); // list of features that are not enabled on background
// There is no stencil usage with compute path, featureFlags set to 0 is use to have fast rejection of tile in this case. It will still execute but will do nothing
featureFlags = 0;
}
g_TileFeatureFlags[tileIDX.y * nrTilesX + tileIDX.x] = featureFlags;

{
SFiniteLightBound lightData = g_data[prunedList[l]];
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius, g_isOrthographic!=0) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/materialflags.compute


#pragma kernel MaterialFlagsGen_Write MATERIALFLAGSGEN=MaterialFlagsGen_Write
#pragma kernel MaterialFlagsGen_Or MATERIALFLAGSGEN=MaterialFlagsGen_Or USE_OR
//#pragma #pragma enable_d3d11_debug_symbols
// #pragma enable_d3d11_debug_symbols
#include "../../../ShaderLibrary/common.hlsl"
#include "ShaderBase.hlsl"

#include "../../Material/Material.hlsl" // This includes Material.hlsl
#include "FeatureFlags.hlsl"
#include "../../Lighting/LightDefinition.cs.hlsl"
#define USE_MATERIAL_FEATURE_FLAGS
#define NR_THREADS 64

uint g_BaseFeatureFlags;
CBUFFER_END
Texture2D g_depth_tex : register( t0 );
TEXTURE2D(_StencilTexture); // DXGI_FORMAT_R8_UINT is not supported by Unity
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
[numthreads(NR_THREADS, 1, 1)]

}
GroupMemoryBarrierWithGroupSync();
uint materialFeatureFlags = g_BaseFeatureFlags;
uint materialFeatureFlags = g_BaseFeatureFlags; // Contain all lightFeatures or 0 (depends if we enable light classification or not)
[unroll]
for(int i = 0; i < 4; i++)
{

if (FetchDepth(g_depth_tex, uCrd) < VIEWPORT_SCALE_Z)
if (UnpackByte(LOAD_TEXTURE2D(_StencilTexture, uCrd).r) != STENCILLIGHTINGUSAGE_NO_LIGHTING) // This test is we are the sky/background or not
{
PositionInputs posInput = GetPositionInput(uCrd, invScreenSize);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);

{
#ifdef USE_OR
g_TileFeatureFlags[tileIDX.y * nrTilesX + tileIDX.x] |= ldsFeatureFlags;
#else
#else // Use in case we have disabled light classification
g_TileFeatureFlags[tileIDX.y * nrTilesX + tileIDX.x] = ldsFeatureFlags;
#endif
}

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/scrbound.compute


#include "../../../ShaderLibrary/common.hlsl"
#include "TilePass.cs.hlsl"
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvProjection;
uniform float4x4 g_mProjection;

else
{
//if((center.z+radius)<0.0)
if( length(center)>radius)
if(g_isOrthographic==0 && length(center)>radius)
{
float2 vMi, vMa;
bool2 bMi, bMa;

vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy;
}
else if(g_isOrthographic!=0)
{
float2 vMi = mul(g_mProjection, float4(center.xyz-radius,1)).xy; // no division needed for ortho
float2 vMa = mul(g_mProjection, float4(center.xyz+radius,1)).xy; // no division needed for ortho
vMin.xy = max(vMin.xy, vMi);
vMax.xy = min(vMax.xy, vMa);
}
#if USE_LEFT_HAND_CAMERA_SPACE

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Builtin/BuiltinData.hlsl


result = (builtinData.emissiveColor / builtinData.emissiveIntensity); needLinearToSRGB = true;
break;
case DEBUGVIEW_BUILTIN_BUILTINDATA_DEPTH_OFFSET:
result = builtinData.depthOffset.xxx * 10.0; // * 10 assuming 1 unity unity is 1m
result = builtinData.depthOffset.xxx * 10.0; // * 10 assuming 1 unity is 1m
break;
}
}

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit.meta


fileFormatVersion: 2
guid: c526d3e6d7f3ce1408308bb431089d2d
guid: 5cdc30333a95a30468e571c7db2230c0
timeCreated: 1476653183
timeCreated: 1501248892
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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


public readonly GUIStyle[] layerLabelColors =
{
new GUIStyle(EditorStyles.label),
new GUIStyle(EditorStyles.label),
new GUIStyle(EditorStyles.label),
new GUIStyle(EditorStyles.label)
new GUIStyle(EditorStyles.foldout),
new GUIStyle(EditorStyles.foldout),
new GUIStyle(EditorStyles.foldout),
new GUIStyle(EditorStyles.foldout)
};
public readonly GUIContent materialLayerText = new GUIContent("Material");

public readonly GUIContent layerMapMaskText = new GUIContent("Layer Mask", "Layer mask");
public readonly GUIContent layerInfluenceMapMaskText = new GUIContent("Layer Influence Mask", "Layer mask");
public readonly GUIContent vertexColorModeText = new GUIContent("Vertex Color Mode", "Mode multiply: vertex color is multiply with the mask. Mode additive: vertex color values are remapped between -1 and 1 and added to the mask (neutral at 0.5 vertex color).");
public readonly GUIContent layerCountText = new GUIContent("Layer Count", "Number of layers.");
public readonly GUIContent layerTilingBlendMaskText = new GUIContent("Tiling", "Tiling for the blend mask.");

public readonly GUIContent layerTilingText = new GUIContent("Tiling", "Tiling factor applied to UVSet");
public readonly GUIContent UVBaseText = new GUIContent("Base UV Mapping", "Base UV Mapping mode of the layer.");
public readonly GUIContent UVDetailText = new GUIContent("Detail UV Mapping", "Detail UV Mapping mode of the layer.");
public readonly GUIContent mainLayerInfluenceText = new GUIContent("Main layer influence", "Main layer influence.");
public readonly GUIContent densityOpacityInfluenceText = new GUIContent("Density / Opacity", "Density / Opacity");
public readonly GUIContent layeringOptionText = new GUIContent("Layering Options");
public readonly GUIContent useDensityModeModeText = new GUIContent("Use Density Mode", "Enable density mode");
public readonly GUIContent heightFactorText = new GUIContent("Height Multiplier", "Scale applied to the height of the layer.");
public readonly GUIContent heightControlText = new GUIContent("Height control");
public readonly GUIContent heightCenterOffsetText = new GUIContent("Height Center Offset", "Offset applied to the center of the height of the layer.");
public readonly GUIContent blendUsingHeight = new GUIContent("Blend Using Height", "Blend Layers using height.");
public readonly GUIContent inheritBaseColorThresholdText = new GUIContent("Threshold", "Inherit the base color from the base layer.");
public readonly GUIContent minimumOpacityText = new GUIContent("Minimum Opacity", "Minimum Opacity.");
public readonly GUIContent heightOffset = new GUIContent("Height Offset", "Offset applied to the height before layering.");
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
public StylesLayer()
{
layerLabelColors[0].normal.textColor = Color.white;

const int kMaxLayerCount = 4;
const int kSyncButtonWidth = 58;
public LayeredLitGUI()
{
m_LayerCount = 4;
m_PropertySuffixes[0] = "0";
m_PropertySuffixes[1] = "1";
m_PropertySuffixes[2] = "2";
m_PropertySuffixes[3] = "3";
}
Material[] m_MaterialLayers = new Material[kMaxLayerCount];
// Layer options

const string kLayerMaskMap = "_LayerMaskMap";
MaterialProperty layerInfluenceMaskMap = null;
const string kLayerInfluenceMaskMap = "_LayerInfluenceMaskMap";
MaterialProperty vertexColorMode = null;
const string kVertexColorMode = "_VertexColorMode";
MaterialProperty objectScaleAffectTile = null;

MaterialProperty useHeightBasedBlend = null;
const string kUseHeightBasedBlend = "_UseHeightBasedBlend";
// Properties for multiple layers inherit from referenced lit materials
MaterialProperty[] layerTexWorldScale = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVBase = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVMappingMask = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVDetail = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
// This one is specific to layer lit
MaterialProperty[] layerTiling = new MaterialProperty[kMaxLayerCount];
const string kLayerTiling = "_LayerTiling";
MaterialProperty useDensityMode = null;
const string kUseDensityMode = "_UseDensityMode";
MaterialProperty[] minimumOpacity = new MaterialProperty[kMaxLayerCount];
const string kMinimumOpacity = "_MinimumOpacity";
// HeightmapMode control
MaterialProperty[] heightFactor = new MaterialProperty[kMaxLayerCount];
const string kHeightFactor = "_HeightFactor";
MaterialProperty[] heightCenterOffset = new MaterialProperty[kMaxLayerCount];
const string kHeightCenterOffset = "_HeightCenterOffset";
MaterialProperty[] layerHeightAmplitude = new MaterialProperty[kMaxLayerCount];
const string kLayerHeightAmplitude = "_LayerHeightAmplitude";
MaterialProperty[] layerCenterOffset = new MaterialProperty[kMaxLayerCount];
const string kLayerCenterOffset = "_LayerCenterOffset";
MaterialProperty[] blendUsingHeight = new MaterialProperty[kMaxLayerCount - 1]; // Only in case of influence mode
const string kBlendUsingHeight = "_BlendUsingHeight";
// Influence
MaterialProperty[] inheritBaseNormal = new MaterialProperty[kMaxLayerCount - 1];

MaterialProperty[] inheritBaseColor = new MaterialProperty[kMaxLayerCount - 1];
const string kInheritBaseColor = "_InheritBaseColor";
MaterialProperty[] inheritBaseColorThreshold = new MaterialProperty[kMaxLayerCount - 1];
const string kInheritBaseColorThreshold = "_InheritBaseColorThreshold";
// Height blend
MaterialProperty[] heightOffset = new MaterialProperty[kMaxLayerCount];
const string kHeightOffset = "_HeightOffset";
MaterialProperty heightTransition = null;
const string kHeightTransition = "_HeightTransition";
// UI
MaterialProperty[] showLayer = new MaterialProperty[kMaxLayerCount];
const string kShowLayer = "_ShowLayer";
// Inherit from LitUI
horizonFade = FindProperty(kHorizonFade, props);
base.FindMaterialLayerProperties(props);
base.FindMaterialEmissiveProperties(props);
layerInfluenceMaskMap = FindProperty(kLayerInfluenceMaskMap, props);
vertexColorMode = FindProperty(kVertexColorMode, props);
objectScaleAffectTile = FindProperty(kObjectScaleAffectTile, props);
UVBlendMask = FindProperty(kUVBlendMask, props);

useMainLayerInfluence = FindProperty(kkUseMainLayerInfluence, props);
useHeightBasedBlend = FindProperty(kUseHeightBasedBlend, props);
useDensityMode = FindProperty(kUseDensityMode, props);
heightTransition = FindProperty(kHeightTransition, props);
layerTexWorldScale[i] = FindProperty(string.Format("{0}{1}", kTexWorldScale, i), props);
layerUVBase[i] = FindProperty(string.Format("{0}{1}", kUVBase, i), props);
layerUVMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVMappingMask, i), props);
layerUVDetail[i] = FindProperty(string.Format("{0}{1}", kUVDetail, i), props);
layerUVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVDetailsMappingMask, i), props);
layerTiling[i] = FindProperty(string.Format("{0}{1}", kLayerTiling, i), props);
minimumOpacity[i] = FindProperty(string.Format("{0}{1}", kMinimumOpacity, i), props);
// HeightmapMode control
heightFactor[i] = FindProperty(string.Format("{0}{1}", kHeightFactor, i), props);
heightCenterOffset[i] = FindProperty(string.Format("{0}{1}", kHeightCenterOffset, i), props);
layerHeightAmplitude[i] = FindProperty(string.Format("{0}{1}", kLayerHeightAmplitude, i), props);
layerCenterOffset[i] = FindProperty(string.Format("{0}{1}", kLayerCenterOffset, i), props);
heightOffset[i] = FindProperty(string.Format("{0}{1}", kHeightOffset, i), props);
showLayer[i] = FindProperty(string.Format("{0}{1}", kShowLayer, i), props);
blendUsingHeight[i - 1] = FindProperty(string.Format("{0}{1}", kBlendUsingHeight, i), props);
inheritBaseColorThreshold[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseColorThreshold, i), props);
// Reuse property from LitUI.cs
emissiveColor = FindProperty(kEmissiveColor, props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);
}
int numLayer

// put the name in the exclusionList below
static void SynchronizeLayerProperties(Material material, Material[] layers, int layerIndex)
{
string[] exclusionList = { kTexWorldScale, kUVBase, kUVMappingMask, kUVDetail, kUVDetailsMappingMask };
Material layerMaterial = layers[layerIndex];
if (layerMaterial != null)

string propertyName = ShaderUtil.GetPropertyName(layerShader, i);
string layerPropertyName = propertyName + layerIndex;
if (!exclusionList.Contains(propertyName))
if (material.HasProperty(layerPropertyName))
if (material.HasProperty(layerPropertyName))
ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(layerShader, i);
switch (type)
ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(layerShader, i);
switch (type)
case ShaderUtil.ShaderPropertyType.Color:
{
material.SetColor(layerPropertyName, layerMaterial.GetColor(propertyName));
break;
}
case ShaderUtil.ShaderPropertyType.Float:
case ShaderUtil.ShaderPropertyType.Range:
{
material.SetFloat(layerPropertyName, layerMaterial.GetFloat(propertyName));
break;
}
case ShaderUtil.ShaderPropertyType.Vector:
case ShaderUtil.ShaderPropertyType.Color:
{
material.SetColor(layerPropertyName, layerMaterial.GetColor(propertyName));
break;
}
case ShaderUtil.ShaderPropertyType.Float:
case ShaderUtil.ShaderPropertyType.Range:
{
material.SetFloat(layerPropertyName, layerMaterial.GetFloat(propertyName));
break;
}
case ShaderUtil.ShaderPropertyType.Vector:
{
material.SetVector(layerPropertyName, layerMaterial.GetVector(propertyName));
break;
}
case ShaderUtil.ShaderPropertyType.TexEnv:
{
material.SetTexture(layerPropertyName, layerMaterial.GetTexture(propertyName));
material.SetTextureOffset(layerPropertyName, layerMaterial.GetTextureOffset(propertyName));
material.SetTextureScale(layerPropertyName, layerMaterial.GetTextureScale(propertyName));
break;
}
material.SetVector(layerPropertyName, layerMaterial.GetVector(propertyName));
break;
}
case ShaderUtil.ShaderPropertyType.TexEnv:
{
material.SetTexture(layerPropertyName, layerMaterial.GetTexture(propertyName));
material.SetTextureOffset(layerPropertyName, layerMaterial.GetTextureOffset(propertyName));
material.SetTextureScale(layerPropertyName, layerMaterial.GetTextureScale(propertyName));
break;
}
}
}

{
bool result = false;
showLayer[layerIndex].floatValue = EditorGUILayout.Foldout(showLayer[layerIndex].floatValue != 0.0f, styles.layerLabels[layerIndex], styles.layerLabelColors[layerIndex]) ? 1.0f : 0.0f;
if (showLayer[layerIndex].floatValue == 0.0f)
return false;
;
bool heightBasedBlend = useHeightBasedBlend.floatValue > 0.0f;
EditorGUILayout.LabelField(styles.layerLabels[layerIndex], styles.layerLabelColors[layerIndex]);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
m_MaterialLayers[layerIndex] = EditorGUILayout.ObjectField(styles.materialLayerText, m_MaterialLayers[layerIndex], typeof(Material), true) as Material;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(materialImporter, "Change layer material");
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex);
result = true;
}
EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(layerUVBase[layerIndex], styles.UVBaseText);
if (EditorGUI.EndChangeCheck())
{
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex);
result = true;
}
if (((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Planar) ||
((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Triplanar))
EditorGUILayout.LabelField(styles.layeringOptionText, EditorStyles.boldLabel);
m_MaterialEditor.ShaderProperty(layerTexWorldScale[layerIndex], styles.layerTexWorldScaleText);
EditorGUI.indentLevel--;
if (((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Planar))
GUILayout.Label(" " + styles.UVDetailText.text + ": Planar");
else
GUILayout.Label(" " + styles.UVDetailText.text + ": Triplanar");
}
else
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(layerTiling[layerIndex], styles.layerTilingText);
EditorGUI.indentLevel--;
m_MaterialEditor.ShaderProperty(layerUVDetail[layerIndex], styles.UVDetailText);
m_MaterialLayers[layerIndex] = EditorGUILayout.ObjectField(styles.materialLayerText, m_MaterialLayers[layerIndex], typeof(Material), true) as Material;
Undo.RecordObject(materialImporter, "Change layer material");
}
// We setup the masking map based on the enum for each layer.
// using mapping mask allow to reduce the number of generated combination for a very small increase in ALU
LayerUVBaseMapping layerUVBaseMapping = (LayerUVBaseMapping)layerUVBase[layerIndex].floatValue;
float X, Y, Z, W;
X = (layerUVBaseMapping == LayerUVBaseMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVBaseMapping == LayerUVBaseMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVBaseMapping == LayerUVBaseMapping.UV2) ? 1.0f : 0.0f;
W = (layerUVBaseMapping == LayerUVBaseMapping.UV3) ? 1.0f : 0.0f;
layerUVMappingMask[layerIndex].colorValue = (layerIndex == 0) ? new Color(1.0f, 0.0f, 0.0f, 0.0f) : new Color(X, Y, Z, W); // Special case for Main Layer and Blend Mask, only UV0. As Layer0 is share by both here, need to force X to 1.0 in all case
UVDetailMapping layerUVDetailMapping = (UVDetailMapping)layerUVDetail[layerIndex].floatValue;
X = (layerUVDetailMapping == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == UVDetailMapping.UV2) ? 1.0f : 0.0f;
W = (layerUVDetailMapping == UVDetailMapping.UV3) ? 1.0f : 0.0f;
layerUVDetailsMappingMask[layerIndex].colorValue = new Color(X, Y, Z, W);
bool useDensityModeEnable = useDensityMode.floatValue != 0.0f;
if (useDensityModeEnable)
{
EditorGUILayout.LabelField(styles.densityOpacityInfluenceText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
m_MaterialEditor.ShaderProperty(minimumOpacity[layerIndex], styles.minimumOpacityText);
EditorGUI.indentLevel--;
}
// Display height control if they have a meaning
if ((tessellationMode != null && ((TessellationMode)tessellationMode.floatValue == TessellationMode.Displacement || (TessellationMode)tessellationMode.floatValue == TessellationMode.DisplacementPhong))
|| (enablePerPixelDisplacement.floatValue > 0.0f)
|| (useHeightBasedBlend.floatValue > 0.0f)
)
{
EditorGUILayout.LabelField(styles.heightControlText, EditorStyles.boldLabel);
// influence
if (layerIndex > 0)
{
int paramIndex = layerIndex - 1;
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightFactor[layerIndex], styles.heightFactorText);
layerHeightAmplitude[layerIndex].floatValue = material.GetFloat(kHeightAmplitude + layerIndex) * heightFactor[layerIndex].floatValue;
m_MaterialEditor.ShaderProperty(heightCenterOffset[layerIndex], styles.heightCenterOffsetText);
layerCenterOffset[layerIndex].floatValue = material.GetFloat(kHeightCenter + layerIndex) + heightCenterOffset[layerIndex].floatValue;
EditorGUI.indentLevel--;
}
m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
// influence
if (layerIndex > 0)
{
int paramIndex = layerIndex - 1;
if (mainLayerInfluenceEnable)
{
m_MaterialEditor.ShaderProperty(inheritBaseColor[paramIndex], styles.inheritBaseColorText);
m_MaterialEditor.ShaderProperty(inheritBaseNormal[paramIndex], styles.inheritBaseNormalText);
// Main height influence is only available if the shader use the heightmap for displacement (per vertex or per level)
// We always display it as it can be tricky to know when per pixel displacement is enabled or not
m_MaterialEditor.ShaderProperty(inheritBaseHeight[paramIndex], styles.inheritBaseHeightText);
}
}
bool heightBasedBlendEnable = useHeightBasedBlend.floatValue > 0.0f;
if (heightBasedBlendEnable)
if(heightBasedBlend)
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(blendUsingHeight[paramIndex], styles.blendUsingHeight);
EditorGUI.indentLevel--;
m_MaterialEditor.ShaderProperty(heightOffset[layerIndex], styles.heightOffset);
if (mainLayerInfluenceEnable)
{
EditorGUILayout.LabelField(styles.mainLayerInfluenceText, EditorStyles.boldLabel);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(inheritBaseColor[paramIndex], styles.inheritBaseColorText);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(inheritBaseColorThreshold[paramIndex], styles.inheritBaseColorThresholdText);
EditorGUI.indentLevel--;
m_MaterialEditor.ShaderProperty(inheritBaseNormal[paramIndex], styles.inheritBaseNormalText);
// Main height influence is only available if the shader use the heightmap for displacement (per vertex or per level)
// We always display it as it can be tricky to know when per pixel displacement is enabled or not
m_MaterialEditor.ShaderProperty(inheritBaseHeight[paramIndex], styles.inheritBaseHeightText);
EditorGUI.indentLevel--;
}
}
EditorGUI.indentLevel--;
DoLayerGUI(material, false, layerIndex);
if (layerIndex == 0)
EditorGUILayout.Space();

{
Undo.RecordObject(material, "Change layer count");
layerCount.floatValue = (float)newLayerCount;
SynchronizeAllLayersProperties();
layerChanged = true;
}

{
useMainLayerInfluence.floatValue = mainLayerModeInfluenceEnable ? 1.0f : 0.0f;
}
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = useDensityMode.hasMixedValue;
bool useDensityModeEnable = EditorGUILayout.Toggle(styles.useDensityModeModeText, useDensityMode.floatValue > 0.0f);
if (EditorGUI.EndChangeCheck())
if (!useMainLayerInfluence.hasMixedValue && useMainLayerInfluence.floatValue != 0.0f)
useDensityMode.floatValue = useDensityModeEnable ? 1.0f : 0.0f;
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(styles.layerInfluenceMapMaskText, layerInfluenceMaskMap);
EditorGUI.indentLevel--;
}
EditorGUI.BeginChangeCheck();

useHeightBasedBlend.floatValue = enabled ? 1.0f : 0.0f;
}
m_MaterialEditor.ShaderProperty(objectScaleAffectTile, mainLayerModeInfluenceEnable ? styles.objectScaleAffectTileText2 : styles.objectScaleAffectTileText);
if (enabled)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);
EditorGUI.indentLevel--;
}
m_MaterialEditor.ShaderProperty(horizonFade, Styles.horizonFadeText);
m_MaterialEditor.ShaderProperty(objectScaleAffectTile, mainLayerModeInfluenceEnable ? styles.objectScaleAffectTileText2 : styles.objectScaleAffectTileText);
EditorGUILayout.Space();

bool useHeightBasedBlend = material.GetFloat(kUseHeightBasedBlend) != 0.0f;
SetKeyword(material, "_HEIGHT_BASED_BLEND", useHeightBasedBlend);
bool useDensityModeEnable = material.GetFloat(kUseDensityMode) != 0.0f;
bool useDensityModeEnable = false;
for (int i = 0; i < material.GetInt(kLayerCount); ++i )
{
useDensityModeEnable |= material.GetFloat(kOpacityAsDensity + i) != 0.0f;
}
SetKeyword(material, "_DENSITY_MODE", useDensityModeEnable);
}

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


_HeightAmplitude2("Height Scale2", Float) = 1
_HeightAmplitude3("Height Scale3", Float) = 1
_HeightCenter0("Height Bias0", Float) = 0
_HeightCenter1("Height Bias1", Float) = 0
_HeightCenter2("Height Bias2", Float) = 0
_HeightCenter3("Height Bias3", Float) = 0
_HeightCenter0("Height Bias0", Range(0.0, 1.0)) = 0.5
_HeightCenter1("Height Bias1", Range(0.0, 1.0)) = 0.5
_HeightCenter2("Height Bias2", Range(0.0, 1.0)) = 0.5
_HeightCenter3("Height Bias3", Range(0.0, 1.0)) = 0.5
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}

// Layer blending options
_LayerMaskMap("LayerMaskMap", 2D) = "white" {}
_LayerInfluenceMaskMap("LayerInfluenceMaskMap", 2D) = "white" {}
// Layer blending options V2
[ToggleOff] _UseDensityMode("Use Density mode", Float) = 0.0
[ToggleOff] _UseMainLayerInfluence("UseMainLayerInfluence", Float) = 0.0
_HeightFactor0("_HeightFactor0", Float) = 1
_HeightFactor1("_HeightFactor1", Float) = 1
_HeightFactor2("_HeightFactor2", Float) = 1
_HeightFactor3("_HeightFactor3", Float) = 1
_HeightOffset0("Height Offset0", Float) = 0
_HeightOffset1("Height Offset1", Float) = 0
_HeightOffset2("Height Offset2", Float) = 0
_HeightOffset3("Height Offset3", Float) = 0
// Store result of combination of _HeightFactor and _HeightAmplitude0
[HideInInspector] _LayerHeightAmplitude0("_LayerHeightAmplitude0", Float) = 1
[HideInInspector] _LayerHeightAmplitude1("_LayerHeightAmplitude1", Float) = 1
[HideInInspector] _LayerHeightAmplitude2("_LayerHeightAmplitude2", Float) = 1
[HideInInspector] _LayerHeightAmplitude3("_LayerHeightAmplitude3", Float) = 1
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
_HeightCenterOffset0("_HeightCenterOffset0", Float) = 0.0
_HeightCenterOffset1("_HeightCenterOffset1", Float) = 0.0
_HeightCenterOffset2("_HeightCenterOffset2", Float) = 0.0
_HeightCenterOffset3("_HeightCenterOffset3", Float) = 0.0
// Store result of combination of _HeightCenterOffset0 and _HeightCenter0
[HideInInspector] _LayerCenterOffset0("_LayerCenterOffset0", Float) = 0.0
[HideInInspector] _LayerCenterOffset1("_LayerCenterOffset1", Float) = 0.0
[HideInInspector] _LayerCenterOffset2("_LayerCenterOffset2", Float) = 0.0
[HideInInspector] _LayerCenterOffset3("_LayerCenterOffset3", Float) = 0.0
_BlendUsingHeight1("_BlendUsingHeight1", Float) = 0.0
_BlendUsingHeight2("_BlendUsingHeight2", Float) = 0.0
_BlendUsingHeight3("_BlendUsingHeight3", Float) = 0.0
[ToggleOff] _UseDensityMode("Use Density mode", Float) = 0.0
[ToggleOff] _UseMainLayerInfluence("UseMainLayerInfluence", Float) = 0.0
_InheritBaseNormal1("_InheritBaseNormal1", Range(0, 1.0)) = 0.0
_InheritBaseNormal2("_InheritBaseNormal2", Range(0, 1.0)) = 0.0

_InheritBaseColor2("_InheritBaseColor2", Range(0, 1.0)) = 0.0
_InheritBaseColor3("_InheritBaseColor3", Range(0, 1.0)) = 0.0
_InheritBaseColorThreshold1("_InheritBaseColorThreshold1", Range(0, 1.0)) = 1.0
_InheritBaseColorThreshold2("_InheritBaseColorThreshold2", Range(0, 1.0)) = 1.0
_InheritBaseColorThreshold3("_InheritBaseColorThreshold3", Range(0, 1.0)) = 1.0
_MinimumOpacity0("_MinimumOpacity0", Range(0, 1.0)) = 1.0
_MinimumOpacity1("_MinimumOpacity1", Range(0, 1.0)) = 1.0
_MinimumOpacity2("_MinimumOpacity2", Range(0, 1.0)) = 1.0
_MinimumOpacity3("_MinimumOpacity3", Range(0, 1.0)) = 1.0
_OpacityAsDensity0("_OpacityAsDensity0", Range(0, 1.0)) = 0.0
_OpacityAsDensity1("_OpacityAsDensity1", Range(0, 1.0)) = 0.0
_OpacityAsDensity2("_OpacityAsDensity2", Range(0, 1.0)) = 0.0

_LayerTiling0("_LayerTiling0", Float) = 1
_LayerTiling1("_LayerTiling1", Float) = 1
_LayerTiling2("_LayerTiling2", Float) = 1
_LayerTiling3("_LayerTiling3", Float) = 1
[HideInInspector] _LayerCount("_LayerCount", Float) = 2.0

// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
_EmissionColor("Color", Color) = (1, 1, 1)
// WARNING
// All the following properties that concern the UV mapping are the same as in the Lit shader.
// This means that they will get overridden when synchronizing the various layers.
// To avoid this, make sure that all properties here are in the exclusion list in LayeredLitUI.SynchronizeLayerProperties
_TexWorldScale0("Tiling", Float) = 1.0
_TexWorldScale1("Tiling", Float) = 1.0
_TexWorldScale2("Tiling", Float) = 1.0

[HideInInspector] _UVDetailsMappingMask1("_UVDetailsMappingMask1", Color) = (1, 0, 0, 0)
[HideInInspector] _UVDetailsMappingMask2("_UVDetailsMappingMask2", Color) = (1, 0, 0, 0)
[HideInInspector] _UVDetailsMappingMask3("_UVDetailsMappingMask3", Color) = (1, 0, 0, 0)
[HideInInspector] _ShowLayer0("_ShowLayer0", Float) = 0
[HideInInspector] _ShowLayer1("_ShowLayer1", Float) = 0
[HideInInspector] _ShowLayer2("_ShowLayer2", Float) = 0
[HideInInspector] _ShowLayer3("_ShowLayer3", Float) = 0
}
HLSLINCLUDE

#include "../../../ShaderLibrary/common.hlsl"
#include "../../../ShaderLibrary/Wind.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"

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


_HeightAmplitude2("Height Scale2", Float) = 1
_HeightAmplitude3("Height Scale3", Float) = 1
_HeightCenter0("Height Bias0", Float) = 0
_HeightCenter1("Height Bias1", Float) = 0
_HeightCenter2("Height Bias2", Float) = 0
_HeightCenter3("Height Bias3", Float) = 0
_HeightCenter0("Height Bias0", Range(0.0, 1.0)) = 0.5
_HeightCenter1("Height Bias1", Range(0.0, 1.0)) = 0.5
_HeightCenter2("Height Bias2", Range(0.0, 1.0)) = 0.5
_HeightCenter3("Height Bias3", Range(0.0, 1.0)) = 0.5
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}

// Layer blending options
_LayerMaskMap("LayerMaskMap", 2D) = "white" {}
_LayerInfluenceMaskMap("LayerInfluenceMaskMap", 2D) = "white" {}
// Layer blending options V2
[ToggleOff] _UseDensityMode("Use Density mode", Float) = 0.0
[ToggleOff] _UseMainLayerInfluence("UseMainLayerInfluence", Float) = 0.0
_HeightFactor0("_HeightFactor0", Float) = 1
_HeightFactor1("_HeightFactor1", Float) = 1
_HeightFactor2("_HeightFactor2", Float) = 1
_HeightFactor3("_HeightFactor3", Float) = 1
_HeightOffset0("Height Offset0", Float) = 0
_HeightOffset1("Height Offset1", Float) = 0
_HeightOffset2("Height Offset2", Float) = 0
_HeightOffset3("Height Offset3", Float) = 0
// Store result of combination of _HeightFactor and _HeightAmplitude0
[HideInInspector] _LayerHeightAmplitude0("_LayerHeightAmplitude0", Float) = 1
[HideInInspector] _LayerHeightAmplitude1("_LayerHeightAmplitude1", Float) = 1
[HideInInspector] _LayerHeightAmplitude2("_LayerHeightAmplitude2", Float) = 1
[HideInInspector] _LayerHeightAmplitude3("_LayerHeightAmplitude3", Float) = 1
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
_HeightCenterOffset0("_HeightCenterOffset0", Float) = 0.0
_HeightCenterOffset1("_HeightCenterOffset1", Float) = 0.0
_HeightCenterOffset2("_HeightCenterOffset2", Float) = 0.0
_HeightCenterOffset3("_HeightCenterOffset3", Float) = 0.0
// Store result of combination of _HeightCenterOffset0 and _HeightCenter0
[HideInInspector] _LayerCenterOffset0("_LayerCenterOffset0", Float) = 0.0
[HideInInspector] _LayerCenterOffset1("_LayerCenterOffset1", Float) = 0.0
[HideInInspector] _LayerCenterOffset2("_LayerCenterOffset2", Float) = 0.0
[HideInInspector] _LayerCenterOffset3("_LayerCenterOffset3", Float) = 0.0
_BlendUsingHeight1("_BlendUsingHeight1", Float) = 0.0
_BlendUsingHeight2("_BlendUsingHeight2", Float) = 0.0
_BlendUsingHeight3("_BlendUsingHeight3", Float) = 0.0
[ToggleOff] _UseDensityMode("Use Density mode", Float) = 0.0
[ToggleOff] _UseMainLayerInfluence("UseMainLayerInfluence", Float) = 0.0
_InheritBaseNormal1("_InheritBaseNormal1", Range(0, 1.0)) = 0.0
_InheritBaseNormal2("_InheritBaseNormal2", Range(0, 1.0)) = 0.0

_InheritBaseColor2("_InheritBaseColor2", Range(0, 1.0)) = 0.0
_InheritBaseColor3("_InheritBaseColor3", Range(0, 1.0)) = 0.0
_InheritBaseColorThreshold1("_InheritBaseColorThreshold1", Range(0, 1.0)) = 1.0
_InheritBaseColorThreshold2("_InheritBaseColorThreshold2", Range(0, 1.0)) = 1.0
_InheritBaseColorThreshold3("_InheritBaseColorThreshold3", Range(0, 1.0)) = 1.0
_MinimumOpacity0("_MinimumOpacity0", Range(0, 1.0)) = 1.0
_MinimumOpacity1("_MinimumOpacity1", Range(0, 1.0)) = 1.0
_MinimumOpacity2("_MinimumOpacity2", Range(0, 1.0)) = 1.0
_MinimumOpacity3("_MinimumOpacity3", Range(0, 1.0)) = 1.0
_OpacityAsDensity0("_OpacityAsDensity0", Range(0, 1.0)) = 0.0
_OpacityAsDensity1("_OpacityAsDensity1", Range(0, 1.0)) = 0.0
_OpacityAsDensity2("_OpacityAsDensity2", Range(0, 1.0)) = 0.0

_LayerTiling0("_LayerTiling0", Float) = 1
_LayerTiling1("_LayerTiling1", Float) = 1
_LayerTiling2("_LayerTiling2", Float) = 1
_LayerTiling3("_LayerTiling3", Float) = 1
[HideInInspector] _LayerCount("_LayerCount", Float) = 2.0

// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
_EmissionColor("Color", Color) = (1, 1, 1)
// WARNING
// All the following properties that concern the UV mapping are the same as in the Lit shader.
// This means that they will get overridden when synchronizing the various layers.
// To avoid this, make sure that all properties here are in the exclusion list in LayeredLitUI.SynchronizeLayerProperties
_TexWorldScale0("Tiling", Float) = 1.0
_TexWorldScale1("Tiling", Float) = 1.0
_TexWorldScale2("Tiling", Float) = 1.0

[ToggleOff] _TessellationObjectScale("Tessellation object scale", Float) = 0.0
[ToggleOff] _TessellationTilingScale("Tessellation tiling scale", Float) = 1.0
// TODO: Handle culling mode for backface culling
[HideInInspector] _ShowLayer0("_ShowLayer0", Float) = 0
[HideInInspector] _ShowLayer1("_ShowLayer1", Float) = 0
[HideInInspector] _ShowLayer2("_ShowLayer2", Float) = 0
[HideInInspector] _ShowLayer3("_ShowLayer3", Float) = 0
}
HLSLINCLUDE

#include "../../../ShaderLibrary/common.hlsl"
#include "../../../ShaderLibrary/Wind.hlsl"
#include "../../../ShaderLibrary/tessellation.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"

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


// Material ID
public static GUIContent materialIDText = new GUIContent("Material type", "Subsurface Scattering: enable for translucent materials such as skin, vegetation, fruit, marble, wax and milk.");
public static GUIContent horizonFadeText = new GUIContent("Horizon Fade (Spec occlusion)", "horizon fade is use to control specular occlusion");
// Per pixel displacement
public static GUIContent enablePerPixelDisplacementText = new GUIContent("Enable Per Pixel Displacement", "");
public static GUIContent ppdMinSamplesText = new GUIContent("Minimum samples", "Minimum samples to use with per pixel displacement mapping");

protected const string kStencilRef = "_StencilRef";
protected MaterialProperty horizonFade = null;
protected const string kHorizonFade = "_HorizonFade";
// Wind
protected MaterialProperty windEnable = null;
protected const string kWindEnabled = "_EnableWind";

// MaterialID
materialID = FindProperty(kMaterialID, props, false); // LayeredLit is force to be standard for now, so materialID could not exist
horizonFade = FindProperty(kHorizonFade, props);
// Per pixel displacement
enablePerPixelDisplacement = FindProperty(kEnablePerPixelDisplacement, props);
ppdMinSamples = FindProperty(kPpdMinSamples, props);

{
base.BaseMaterialPropertiesGUI();
EditorGUI.indentLevel++;
// This follow double sided option
if (doubleSidedEnable.floatValue > 0.0f)
{

EditorGUI.indentLevel--;
}
m_MaterialEditor.ShaderProperty(horizonFade, StylesBaseLit.horizonFadeText);
GUILayout.Label(StylesBaseLit.tessellationText, EditorStyles.boldLabel);
EditorGUILayout.Space();
EditorGUILayout.LabelField(StylesBaseLit.tessellationText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
TessellationModePopup();
m_MaterialEditor.ShaderProperty(tessellationFactor, StylesBaseLit.tessellationFactorText);

protected override void VertexAnimationPropertiesGUI()
{
GUILayout.Label(StylesBaseLit.vertexAnimation, EditorStyles.boldLabel);
EditorGUILayout.LabelField(StylesBaseLit.vertexAnimation, EditorStyles.boldLabel);
EditorGUI.indentLevel++;

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


using System;
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;

public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (BC7/BC5/DXT5(nm))");
public static GUIContent normalMapOSText = new GUIContent("Normal Map OS", "Normal Map (BC7/DXT1/RGB)");
public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent horizonFadeText = new GUIContent("Horizon Fade (Spec occlusion)", "horizon fade is use to control specular occlusion");
public static GUIContent heightMapText = new GUIContent("Height Map (R)", "Height Map");
public static GUIContent heightMapAmplitudeText = new GUIContent("Height Map Amplitude", "Height Map amplitude in world units.");

public static GUIContent texWorldScaleText = new GUIContent("World scale", "Tiling factor applied to Planar/Trilinear mapping");
// Details
public static string detailText = "Inputs Detail";
public static string detailText = "Detail Inputs";
public static GUIContent UVDetailMappingText = new GUIContent("Detail UV mapping", "");
public static GUIContent detailMapNormalText = new GUIContent("Detail Map A(R) Ny(G) S(B) Nx(A)", "Detail Map");
public static GUIContent detailMaskText = new GUIContent("Detail Mask (G)", "Mask for detailMap");

public static GUIContent thicknessText = new GUIContent("Thickness", "If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
public static GUIContent thicknessMapText = new GUIContent("Thickness map (R)", "If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
// Clear Coat
public static GUIContent coatCoverageText = new GUIContent("Coat Coverage", "Percentage of clear coat coverage");
public static GUIContent coatIORText = new GUIContent("Coat IOR", "IOR of clear coat, value is [0..1] + 1.0. i.e 0.5 is IOR 1.5");
public static string lightingText = "Inputs Lighting";
public static string lightingText = "Lighting Inputs";
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive");
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive");
public static GUIContent emissiveColorModeText = new GUIContent("Emissive Color Usage", "Use emissive color or emissive mask");

// Lit shader is not layered but some layered materials inherit from it. In order to share code we need LitUI to account for this.
protected const int kMaxLayerCount = 4;
protected int m_LayerCount = 1;
protected string[] m_PropertySuffixes = { "", "", "", "" };
Planar,
Triplanar
Planar = 4,
Triplanar = 5
}
public enum NormalMapSpace

UseEmissiveMask,
}
protected MaterialProperty UVBase = null;
protected MaterialProperty[] UVBase = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty TexWorldScale = null;
protected MaterialProperty[] TexWorldScale = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty UVMappingMask = null;
protected MaterialProperty[] UVMappingMask = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty baseColor = null;
protected MaterialProperty[] baseColor = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty baseColorMap = null;
protected MaterialProperty[] baseColorMap = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty metallic = null;
protected MaterialProperty[] metallic = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty smoothness = null;
protected MaterialProperty[] smoothness = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty maskMap = null;
protected MaterialProperty[] maskMap = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty specularOcclusionMap = null;
protected MaterialProperty[] specularOcclusionMap = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty horizonFade = null;
protected const string kHorizonFade = "_HorizonFade";
protected MaterialProperty normalMap = null;
protected MaterialProperty[] normalMap = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty normalMapOS = null;
protected MaterialProperty[] normalMapOS = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty normalScale = null;
protected MaterialProperty[] normalScale = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty normalMapSpace = null;
protected MaterialProperty[] normalMapSpace = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty heightMap = null;
protected MaterialProperty[] heightMap = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty heightAmplitude = null;
protected MaterialProperty[] heightAmplitude = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty heightCenter = null;
protected MaterialProperty[] heightCenter = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty tangentMap = null;
protected const string kTangentMap = "_TangentMap";
protected MaterialProperty tangentMapOS = null;
protected const string kTangentMapOS = "_TangentMapOS";
protected MaterialProperty anisotropy = null;
protected const string kAnisotropy = "_Anisotropy";
protected MaterialProperty anisotropyMap = null;
protected const string kAnisotropyMap = "_AnisotropyMap";
protected MaterialProperty specularColor = null;
protected const string kSpecularColor = "_SpecularColor";
protected MaterialProperty specularColorMap = null;
protected const string kSpecularColorMap = "_SpecularColorMap";
protected MaterialProperty UVDetail = null;
protected MaterialProperty[] UVDetail = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty UVDetailsMappingMask = null;
protected MaterialProperty[] UVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty detailMap = null;
protected MaterialProperty[] detailMap = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty detailMask = null;
protected MaterialProperty[] detailMask = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty detailAlbedoScale = null;
protected MaterialProperty[] detailAlbedoScale = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty detailNormalScale = null;
protected MaterialProperty[] detailNormalScale = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty detailSmoothnessScale = null;
protected MaterialProperty[] detailSmoothnessScale = new MaterialProperty[kMaxLayerCount];
protected MaterialProperty specularColor = null;
protected const string kSpecularColor = "_SpecularColor";
protected MaterialProperty specularColorMap = null;
protected const string kSpecularColorMap = "_SpecularColorMap";
protected MaterialProperty tangentMap = null;
protected const string kTangentMap = "_TangentMap";
protected MaterialProperty tangentMapOS = null;
protected const string kTangentMapOS = "_TangentMapOS";
protected MaterialProperty anisotropy = null;
protected const string kAnisotropy = "_Anisotropy";
protected MaterialProperty anisotropyMap = null;
protected const string kAnisotropyMap = "_AnisotropyMap";
protected SubsurfaceScatteringProfile subsurfaceProfile = null;
protected MaterialProperty subsurfaceProfileID = null;
protected const string kSubsurfaceProfileID = "_SubsurfaceProfile";

protected MaterialProperty thicknessMap = null;
protected const string kThicknessMap = "_ThicknessMap";
protected MaterialProperty coatCoverage = null;
protected const string kCoatCoverage = "_CoatCoverage";
protected MaterialProperty coatIOR = null;
protected const string kCoatIOR = "_CoatIOR";
protected MaterialProperty emissiveColorMode = null;
protected const string kEmissiveColorMode = "_EmissiveColorMode";
protected MaterialProperty emissiveColor = null;

protected MaterialProperty emissiveIntensity = null;
protected const string kEmissiveIntensity = "_EmissiveIntensity";
protected void FindMaterialLayerProperties(MaterialProperty[] props)
{
for (int i = 0; i < m_LayerCount; ++i)
{
UVBase[i] = FindProperty(string.Format("{0}{1}", kUVBase, m_PropertySuffixes[i]), props);
TexWorldScale[i] = FindProperty(string.Format("{0}{1}", kTexWorldScale, m_PropertySuffixes[i]), props);
UVMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVMappingMask, m_PropertySuffixes[i]), props);
baseColor[i] = FindProperty(string.Format("{0}{1}", kBaseColor, m_PropertySuffixes[i]), props);
baseColorMap[i] = FindProperty(string.Format("{0}{1}", kBaseColorMap, m_PropertySuffixes[i]), props);
metallic[i] = FindProperty(string.Format("{0}{1}", kMetallic, m_PropertySuffixes[i]), props);
smoothness[i] = FindProperty(string.Format("{0}{1}", kSmoothness, m_PropertySuffixes[i]), props);
maskMap[i] = FindProperty(string.Format("{0}{1}", kMaskMap, m_PropertySuffixes[i]), props);
specularOcclusionMap[i] = FindProperty(string.Format("{0}{1}", kSpecularOcclusionMap, m_PropertySuffixes[i]), props);
normalMap[i] = FindProperty(string.Format("{0}{1}", kNormalMap, m_PropertySuffixes[i]), props);
normalMapOS[i] = FindProperty(string.Format("{0}{1}", kNormalMapOS, m_PropertySuffixes[i]), props);
normalScale[i] = FindProperty(string.Format("{0}{1}", kNormalScale, m_PropertySuffixes[i]), props);
normalMapSpace[i] = FindProperty(string.Format("{0}{1}", kNormalMapSpace, m_PropertySuffixes[i]), props);
heightMap[i] = FindProperty(string.Format("{0}{1}", kHeightMap, m_PropertySuffixes[i]), props);
heightAmplitude[i] = FindProperty(string.Format("{0}{1}", kHeightAmplitude, m_PropertySuffixes[i]), props);
heightCenter[i] = FindProperty(string.Format("{0}{1}", kHeightCenter, m_PropertySuffixes[i]), props);
// Details
UVDetail[i] = FindProperty(string.Format("{0}{1}", kUVDetail, m_PropertySuffixes[i]), props);
UVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVDetailsMappingMask, m_PropertySuffixes[i]), props);
detailMap[i] = FindProperty(string.Format("{0}{1}", kDetailMap, m_PropertySuffixes[i]), props);
detailMask[i] = FindProperty(string.Format("{0}{1}", kDetailMask, m_PropertySuffixes[i]), props);
detailAlbedoScale[i] = FindProperty(string.Format("{0}{1}", kDetailAlbedoScale, m_PropertySuffixes[i]), props);
detailNormalScale[i] = FindProperty(string.Format("{0}{1}", kDetailNormalScale, m_PropertySuffixes[i]), props);
detailSmoothnessScale[i] = FindProperty(string.Format("{0}{1}", kDetailSmoothnessScale, m_PropertySuffixes[i]), props);
}
}
protected void FindMaterialEmissiveProperties(MaterialProperty[] props)
{
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
emissiveColor = FindProperty(kEmissiveColor, props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);
}
UVBase = FindProperty(kUVBase, props);
TexWorldScale = FindProperty(kTexWorldScale, props);
UVMappingMask = FindProperty(kUVMappingMask, props);
FindMaterialLayerProperties(props);
FindMaterialEmissiveProperties(props);
baseColor = FindProperty(kBaseColor, props);
baseColorMap = FindProperty(kBaseColorMap, props);
metallic = FindProperty(kMetallic, props);
smoothness = FindProperty(kSmoothness, props);
maskMap = FindProperty(kMaskMap, props);
specularOcclusionMap = FindProperty(kSpecularOcclusionMap, props);
horizonFade = FindProperty(kHorizonFade, props);
normalMap = FindProperty(kNormalMap, props);
normalMapOS = FindProperty(kNormalMapOS, props);
normalScale = FindProperty(kNormalScale, props);
normalMapSpace = FindProperty(kNormalMapSpace, props);
heightMap = FindProperty(kHeightMap, props);
heightAmplitude = FindProperty(kHeightAmplitude, props);
heightCenter = FindProperty(kHeightCenter, props);
// The next properties are only supported for regular Lit shader (not layered ones) because it's complicated to blend those parameters if they are different on a per layer basis.
// Specular Color
specularColor = FindProperty(kSpecularColor, props);
specularColorMap = FindProperty(kSpecularColorMap, props);
// Anisotropy
specularColor = FindProperty(kSpecularColor, props);
specularColorMap = FindProperty(kSpecularColorMap, props);
// Details
UVDetail = FindProperty(kUVDetail, props);
UVDetailsMappingMask = FindProperty(kUVDetailsMappingMask, props);
detailMap = FindProperty(kDetailMap, props);
detailMask = FindProperty(kDetailMask, props);
detailAlbedoScale = FindProperty(kDetailAlbedoScale, props);
detailNormalScale = FindProperty(kDetailNormalScale, props);
detailSmoothnessScale = FindProperty(kDetailSmoothnessScale, props);
// Sub surface
subsurfaceProfileID = FindProperty(kSubsurfaceProfileID, props);

thicknessMap = FindProperty(kThicknessMap, props);
// Emissive
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
emissiveColor = FindProperty(kEmissiveColor, props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);
// clear coat
coatCoverage = FindProperty(kCoatCoverage, props);
coatIOR = FindProperty(kCoatIOR, props);
}
protected void ShaderSSSInputGUI(Material material)

m_MaterialEditor.TexturePropertySingleLine(Styles.subsurfaceRadiusMapText, subsurfaceRadiusMap);
m_MaterialEditor.ShaderProperty(thickness, Styles.thicknessText);
m_MaterialEditor.TexturePropertySingleLine(Styles.thicknessMapText, thicknessMap);
}
protected void ShaderClearCoatInputGUI()
{
m_MaterialEditor.ShaderProperty(coatCoverage, Styles.coatCoverageText);
m_MaterialEditor.ShaderProperty(coatIOR, Styles.coatIORText);
if ((NormalMapSpace)normalMapSpace.floatValue == NormalMapSpace.TangentSpace)
if ((NormalMapSpace)normalMapSpace[0].floatValue == NormalMapSpace.TangentSpace)
{
m_MaterialEditor.TexturePropertySingleLine(Styles.tangentMapText, tangentMap);
}

m_MaterialEditor.TexturePropertySingleLine(Styles.anisotropyMapText, anisotropyMap);
}
protected override void MaterialPropertiesGUI(Material material)
protected void DoLayerGUI(Material material, bool useEmissiveMask, int layerIndex)
bool useEmissiveMask = (EmissiveColorMode)emissiveColorMode.floatValue == EmissiveColorMode.UseEmissiveMask;
GUILayout.Label(Styles.InputsText, EditorStyles.boldLabel);
EditorGUILayout.LabelField(Styles.InputsText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap, baseColor);
m_MaterialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap[layerIndex], baseColor[layerIndex]);
if ((Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitStandard || (Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitAniso)
if ( materialID == null || // Will be the case for Layered materials where we only support standard and the parameter does not exist
(Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitStandard || (Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitAniso)
m_MaterialEditor.ShaderProperty(metallic, Styles.metallicText);
m_MaterialEditor.ShaderProperty(metallic[layerIndex], Styles.metallicText);
m_MaterialEditor.ShaderProperty(smoothness, Styles.smoothnessText);
m_MaterialEditor.ShaderProperty(smoothness[layerIndex], Styles.smoothnessText);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapESText, maskMap);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapESText, maskMap[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapSText, maskMap);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapSText, maskMap[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.specularOcclusionMapText, specularOcclusionMap);
m_MaterialEditor.ShaderProperty(horizonFade, Styles.horizonFadeText);
m_MaterialEditor.TexturePropertySingleLine(Styles.specularOcclusionMapText, specularOcclusionMap[layerIndex]);
m_MaterialEditor.ShaderProperty(normalMapSpace, Styles.normalMapSpaceText);
m_MaterialEditor.ShaderProperty(normalMapSpace[layerIndex], Styles.normalMapSpaceText);
if ((NormalMapSpace)normalMapSpace.floatValue == NormalMapSpace.ObjectSpace && ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Triplanar))
if ((NormalMapSpace)normalMapSpace[layerIndex].floatValue == NormalMapSpace.ObjectSpace && ((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.Triplanar))
{
EditorGUILayout.HelpBox(Styles.normalMapSpaceWarning.text, MessageType.Error);
}

// 2. to avoid the warning that ask to fix the object normal map texture (normalOS are just linear RGB texture
if ((NormalMapSpace)normalMapSpace.floatValue == NormalMapSpace.TangentSpace)
if ((NormalMapSpace)normalMapSpace[layerIndex].floatValue == NormalMapSpace.TangentSpace)
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap[layerIndex], normalScale[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapOSText, normalMapOS);
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapOSText, normalMapOS[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap);
if (!heightMap.hasMixedValue && heightMap.textureValue != null)
m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap[layerIndex]);
if (!heightMap[layerIndex].hasMixedValue && heightMap[layerIndex].textureValue != null)
m_MaterialEditor.ShaderProperty(heightAmplitude, Styles.heightMapAmplitudeText);
heightAmplitude.floatValue = Math.Max(0.0f, heightAmplitude.floatValue); // Must be positive
m_MaterialEditor.ShaderProperty(heightCenter, Styles.heightMapCenterText);
m_MaterialEditor.ShaderProperty(heightAmplitude[layerIndex], Styles.heightMapAmplitudeText);
heightAmplitude[layerIndex].floatValue = Math.Max(0.0f, heightAmplitude[layerIndex].floatValue); // Must be positive
m_MaterialEditor.ShaderProperty(heightCenter[layerIndex], Styles.heightMapCenterText);
if(materialID != null)
{
switch ((Lit.MaterialId)materialID.floatValue)
{
case Lit.MaterialId.LitSSS:

case Lit.MaterialId.LitSpecular:
m_MaterialEditor.TexturePropertySingleLine(Styles.specularColorText, specularColorMap, specularColor);
break;
case Lit.MaterialId.LitClearCoat:
ShaderClearCoatInputGUI();
break;
}
GUILayout.Label(" " + Styles.textureControlText, EditorStyles.label);
m_MaterialEditor.ShaderProperty(UVBase, Styles.UVBaseMappingText);
EditorGUILayout.LabelField(Styles.textureControlText, EditorStyles.label);
m_MaterialEditor.ShaderProperty(UVBase[layerIndex], Styles.UVBaseMappingText);
UVMappingMask.colorValue = new Color(1.0f, 0.0f, 0.0f, 0.0f); // This is override in the shader anyway but just in case.
if (((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) || ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Triplanar))
UVMappingMask[layerIndex].colorValue = new Color(1.0f, 0.0f, 0.0f, 0.0f); // This is override in the shader anyway but just in case.
if (((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.Planar) || ((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.Triplanar))
m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText);
m_MaterialEditor.ShaderProperty(TexWorldScale[layerIndex], Styles.texWorldScaleText);
m_MaterialEditor.TextureScaleOffsetProperty(baseColorMap);
m_MaterialEditor.TextureScaleOffsetProperty(baseColorMap[layerIndex]);
EditorGUI.indentLevel--;
GUILayout.Label(Styles.detailText, EditorStyles.boldLabel);
EditorGUILayout.LabelField(Styles.detailText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMapNormalText, detailMap);
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMapNormalText, detailMap[layerIndex]);
EditorGUI.indentLevel++;
if ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0)
if ((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.UV0)
m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText);
m_MaterialEditor.ShaderProperty(UVDetail[layerIndex], Styles.UVDetailMappingText);
else if ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar)
else if ((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.Planar)
GUILayout.Label(" " + Styles.UVDetailMappingText.text + ": Planar");
EditorGUILayout.LabelField(Styles.UVDetailMappingText.text + ": Planar");
else if ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Triplanar)
else if ((UVBaseMapping)UVBase[layerIndex].floatValue == UVBaseMapping.Triplanar)
GUILayout.Label(" " + Styles.UVDetailMappingText.text + ": Triplanar");
EditorGUILayout.LabelField(Styles.UVDetailMappingText.text + ": Triplanar");
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV2) ? 1.0f : 0.0f;
W = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
UVDetailsMappingMask.colorValue = new Color(X, Y, Z, W);
X = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV2) ? 1.0f : 0.0f;
W = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
UVDetailsMappingMask[layerIndex].colorValue = new Color(X, Y, Z, W);
m_MaterialEditor.TextureScaleOffsetProperty(detailMap[layerIndex]);
m_MaterialEditor.ShaderProperty(detailAlbedoScale[layerIndex], Styles.detailAlbedoScaleText);
m_MaterialEditor.ShaderProperty(detailNormalScale[layerIndex], Styles.detailNormalScaleText);
m_MaterialEditor.ShaderProperty(detailSmoothnessScale[layerIndex], Styles.detailSmoothnessScaleText);
m_MaterialEditor.TextureScaleOffsetProperty(detailMap);
m_MaterialEditor.ShaderProperty(detailAlbedoScale, Styles.detailAlbedoScaleText);
m_MaterialEditor.ShaderProperty(detailNormalScale, Styles.detailNormalScaleText);
m_MaterialEditor.ShaderProperty(detailSmoothnessScale, Styles.detailSmoothnessScaleText);
}
protected override void MaterialPropertiesGUI(Material material)
{
bool useEmissiveMask = (EmissiveColorMode)emissiveColorMode.floatValue == EmissiveColorMode.UseEmissiveMask;
DoLayerGUI(material, useEmissiveMask, 0);
GUILayout.Label(Styles.lightingText, EditorStyles.boldLabel);
EditorGUILayout.LabelField(Styles.lightingText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText);
if (!useEmissiveMask)

m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
EditorGUI.indentLevel--;
// The parent Base.ShaderPropertiesGUI will call DoEmissionArea
}

//SetKeyword(material, "_MATID_STANDARD", materialId == Lit.MaterialId.LitStandard); // See comment in Lit.shader, it is the default, we don't define it
SetKeyword(material, "_MATID_ANISO", materialId == Lit.MaterialId.LitAniso);
SetKeyword(material, "_MATID_SPECULAR", materialId == Lit.MaterialId.LitSpecular);
SetKeyword(material, "_MATID_CLEARCOAT", materialId == Lit.MaterialId.LitClearCoat);
}
}
} // namespace UnityEditor

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


[GenerateHLSL(PackingRules.Exact)]
public enum MaterialId
{
LitSSS = 0,
LitStandard = 1,
LitUnused0 = 2,
LitUnused1 = 3,
LitAniso = 4, // Should be the last as it is not setup by the users but generated based on anisotropy property
LitSpecular = 5, // Should be the last as it is not setup by the users but generated based on anisotropy property and specular
LitSSS = 0,
LitStandard = 1,
LitClearCoat = 2,
LitUnused = 3,
// We don't store any materialId for aniso but instead deduce it from LitStandard + value of specular + anisotropy parameters
// Consequence is that when querying materialId alone, it will read 2 RT and not only one. This may be a performance hit when only materialId is desired (like in material classification pass)
// Alternative is to use a materialId slot, if any are available.
LitAniso = 4,
// LitSpecular (DiffuseColor/SpecularColor) is an alternate parametrization for LitStandard (BaseColor/Metal/Specular), but it is the same shading model
// We don't want any specific materialId for it, instead we use LitStandard as materialId. However for UI purpose we still define this value here.
// For material classification we will use LitStandard too
LitSpecular = 5,
// If change, be sure it match what is done in Lit.hlsl: MaterialFeatureFlagsFromGBuffer
// Material bit mask must match LightDefinitions.s_MaterialFeatureMaskFlags value
LitSSS = 1 << 12,
LitStandard = 1 << 13,
LitAniso = 1 << 14,
LitSpecular = 1 << 15
}
LitSSS = 1 << MaterialId.LitSSS,
LitStandard = 1 << MaterialId.LitStandard,
LitClearCoat = 1 << MaterialId.LitClearCoat,
LitUnused = 1 << MaterialId.LitUnused,
LitAniso = 1 << MaterialId.LitAniso,
};
public enum SpecularValue
public class StandardDefinitions
// Value are defined in the tab name convertSpecularToValue in lit.hlsl
Water = 0, // 0.02 Water or ice
Regular = 1, // 0.04 regular dieletric
Gemstone = 2, // 0.20
SpecularColor = 3 // Special case: use specular color
public static int s_GBufferLitStandardRegularId = 0;
public static int s_GBufferLitStandardSpecularColorId = 1;
public static int s_GBufferLitStandardAnisotropicId = 2;
public static float s_DefaultSpecularValue = 0.04f;
public static float s_SkinSpecularValue = 0.028f;
}
//-----------------------------------------------------------------------------

[SurfaceDataAttributes("Smoothness")]
public float perceptualSmoothness;
[SurfaceDataAttributes("Material ID")]
public MaterialId materialId;
public MaterialId materialId; // matId above 3 are store in standard material gbuffer (2bit reserved)
[SurfaceDataAttributes("Ambient Occlusion")]
public float ambientOcclusion;

public float anisotropy; // anisotropic ratio(0->no isotropic; 1->full anisotropy in tangent direction)
[SurfaceDataAttributes("Metallic")]
public float metallic;
[SurfaceDataAttributes("Specular")]
public SpecularValue specular;
// SSS
[SurfaceDataAttributes("Subsurface Radius")]

// SpecColor
[SurfaceDataAttributes("Specular Color", false, true)]
public Vector3 specularColor;
// ClearCoat
[SurfaceDataAttributes("Coat Normal", true)]
public Vector3 coatNormalWS;
[SurfaceDataAttributes("Coat coverage")]
public float coatCoverage;
[SurfaceDataAttributes("Coat IOR")]
public float coatIOR; // Value is [0..1] for artists but the UI will display the value between [1..2]
};
//-----------------------------------------------------------------------------

// SpecColor
// fold into fresnel0
// ClearCoat
public Vector3 coatNormalWS;
public float coatCoverage;
public float coatIOR; // CoatIOR is in range[1..2] it is surfaceData + 1
};
//-----------------------------------------------------------------------------

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


//
#define MATERIALID_LIT_SSS (0)
#define MATERIALID_LIT_STANDARD (1)
#define MATERIALID_LIT_UNUSED0 (2)
#define MATERIALID_LIT_UNUSED1 (3)
#define MATERIALID_LIT_CLEAR_COAT (2)
#define MATERIALID_LIT_UNUSED (3)
#define MATERIALID_LIT_ANISO (4)
#define MATERIALID_LIT_SPECULAR (5)

#define MATERIALFEATUREFLAGS_LIT_SSS (4096)
#define MATERIALFEATUREFLAGS_LIT_STANDARD (8192)
#define MATERIALFEATUREFLAGS_LIT_ANISO (16384)
#define MATERIALFEATUREFLAGS_LIT_SPECULAR (32768)
#define MATERIALFEATUREFLAGS_LIT_SSS (1)
#define MATERIALFEATUREFLAGS_LIT_STANDARD (2)
#define MATERIALFEATUREFLAGS_LIT_CLEAR_COAT (4)
#define MATERIALFEATUREFLAGS_LIT_UNUSED (8)
#define MATERIALFEATUREFLAGS_LIT_ANISO (16)
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+SpecularValue: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+StandardDefinitions: static fields
#define SPECULARVALUE_WATER (0)
#define SPECULARVALUE_REGULAR (1)
#define SPECULARVALUE_GEMSTONE (2)
#define SPECULARVALUE_SPECULAR_COLOR (3)
#define GBUFFER_LIT_STANDARD_REGULAR_ID (0)
#define GBUFFER_LIT_STANDARD_SPECULAR_COLOR_ID (1)
#define GBUFFER_LIT_STANDARD_ANISOTROPIC_ID (2)
#define DEFAULT_SPECULAR_VALUE (0.04)
#define SKIN_SPECULAR_VALUE (0.028)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+SurfaceData: static fields

#define DEBUGVIEW_LIT_SURFACEDATA_TANGENT_WS (1006)
#define DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY (1007)
#define DEBUGVIEW_LIT_SURFACEDATA_METALLIC (1008)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR (1009)
#define DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_RADIUS (1010)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS (1011)
#define DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_PROFILE (1012)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_COLOR (1013)
#define DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_RADIUS (1009)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS (1010)
#define DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_PROFILE (1011)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_COLOR (1012)
#define DEBUGVIEW_LIT_SURFACEDATA_COAT_NORMAL_WS (1013)
#define DEBUGVIEW_LIT_SURFACEDATA_COAT_COVERAGE (1014)
#define DEBUGVIEW_LIT_SURFACEDATA_COAT_IOR (1015)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+TransmissionType: static fields

#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION (1045)
#define DEBUGVIEW_LIT_BSDFDATA_USE_THIN_OBJECT_MODE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1047)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_NORMAL_WS (1048)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_COVERAGE (1049)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_IOR (1050)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+GBufferMaterial: static fields

float3 tangentWS;
float anisotropy;
float metallic;
int specular;
float3 coatNormalWS;
float coatCoverage;
float coatIOR;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Lit+BSDFData

bool enableTransmission;
bool useThinObjectMode;
float3 transmittance;
float3 coatNormalWS;
float coatCoverage;
float coatIOR;
};
//

case DEBUGVIEW_LIT_SURFACEDATA_METALLIC:
result = surfacedata.metallic.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_SPECULAR:
result = GetIndexColor(surfacedata.specular);
break;
case DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_RADIUS:
result = surfacedata.subsurfaceRadius.xxx;
break;

result = surfacedata.specularColor;
needLinearToSRGB = true;
break;
case DEBUGVIEW_LIT_SURFACEDATA_COAT_NORMAL_WS:
result = surfacedata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_LIT_SURFACEDATA_COAT_COVERAGE:
result = surfacedata.coatCoverage.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_COAT_IOR:
result = surfacedata.coatIOR.xxx;
break;
}
}

break;
case DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE:
result = bsdfdata.transmittance;
break;
case DEBUGVIEW_LIT_BSDFDATA_COAT_NORMAL_WS:
result = bsdfdata.coatNormalWS;
break;
case DEBUGVIEW_LIT_BSDFDATA_COAT_COVERAGE:
result = bsdfdata.coatCoverage.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_COAT_IOR:
result = bsdfdata.coatIOR.xxx;
break;
}
}

843
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
文件差异内容过多而无法显示
查看文件

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


_HeightMap("HeightMap", 2D) = "black" {}
_HeightAmplitude("Height Amplitude", Float) = 0.01 // In world units
_HeightCenter("Height Center", Float) = 0.5 // In texture space
_HeightCenter("Height Center", Range(0.0, 1.0)) = 0.5 // In texture space
_DetailMap("DetailMap", 2D) = "black" {}
_DetailMask("DetailMask", 2D) = "white" {}

_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.0, 1.0)) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_CoatCoverage("Coat Coverage", Range(0.0, 1.0)) = 1.0
_CoatIOR("Coat IOR", Range(0.0, 1.0)) = 0.5
_SpecularColor("SpecularColor", Color) = (1, 1, 1, 1)
_SpecularColorMap("SpecularColorMap", 2D) = "white" {}

[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _UVBase("UV Set for base", Float) = 0
[Enum(UV0, 0, Planar, 4, TriPlanar, 5)] _UVBase("UV Set for base", Float) = 0
[Enum(Subsurface Scattering, 0, Standard, 1, Anisotropy, 4, Specular Color, 5)] _MaterialID("MaterialId", Int) = 1 // MaterialId.RegularLighting
[Enum(Subsurface Scattering, 0, Standard, 1, ClearCoat, 2, Anisotropy, 4, Specular Color, 5)] _MaterialID("MaterialId", Int) = 1 // MaterialId.RegularLighting
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5

// MaterialId are used as shader feature to allow compiler to optimize properly
// Note _MATID_STANDARD is not define as there is always the default case "_". We assign default as _MATID_STANDARD, so we never test _MATID_STANDARD
#pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR
#pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR _MATID_CLEARCOAT
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED

#include "../../../ShaderLibrary/common.hlsl"
#include "../../../ShaderLibrary/Wind.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"

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


#include "ShaderLibrary/SampleUVMapping.hlsl"
#include "../MaterialUtilities.hlsl"
void GetBuiltinData(FragInputs input, SurfaceData surfaceData, float alpha, float depthOffset, out BuiltinData builtinData)
{
// Builtin Data

void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.y); // Note that we pass the quantized value of LOD fade
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.x);
#endif
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal

#endif
ComputeLayerTexCoord0( texCoord0, float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0),
positionWS, mappingType, _TexWorldScale0, layerTexCoord, _LayerTiling0
positionWS, mappingType, _TexWorldScale0, layerTexCoord, 1.0
#if !defined(_MAIN_LAYER_INFLUENCE_MODE)
* tileObjectScale // We only affect layer0 in case we are not in influence mode (i.e we should not change the base object)
#endif

mappingType = UV_MAPPING_TRIPLANAR;
#endif
ComputeLayerTexCoord1( texCoord0, texCoord1, texCoord2, texCoord3,
positionWS, mappingType, _TexWorldScale1, layerTexCoord, _LayerTiling1 * tileObjectScale);
positionWS, mappingType, _TexWorldScale1, layerTexCoord, tileObjectScale);
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR2)

#endif
ComputeLayerTexCoord2( texCoord0, texCoord1, texCoord2, texCoord3,
positionWS, mappingType, _TexWorldScale2, layerTexCoord, _LayerTiling2 * tileObjectScale);
positionWS, mappingType, _TexWorldScale2, layerTexCoord, tileObjectScale);
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR3)

#endif
ComputeLayerTexCoord3( texCoord0, texCoord1, texCoord2, texCoord3,
positionWS, mappingType, _TexWorldScale3, layerTexCoord, _LayerTiling3 * tileObjectScale);
positionWS, mappingType, _TexWorldScale3, layerTexCoord, tileObjectScale);
}
// This is call only in this file

tileObjectScale = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#endif
height0 /= _LayerTiling0 * max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y);
height0 /= max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y);
height1 /= tileObjectScale * _LayerTiling1 * max(_BaseColorMap1_ST.x, _BaseColorMap1_ST.y);
height2 /= tileObjectScale * _LayerTiling2 * max(_BaseColorMap2_ST.x, _BaseColorMap2_ST.y);
height3 /= tileObjectScale * _LayerTiling3 * max(_BaseColorMap3_ST.x, _BaseColorMap3_ST.y);
height1 /= tileObjectScale * max(_BaseColorMap1_ST.x, _BaseColorMap1_ST.y);
height2 /= tileObjectScale * max(_BaseColorMap2_ST.x, _BaseColorMap2_ST.y);
height3 /= tileObjectScale * max(_BaseColorMap3_ST.x, _BaseColorMap3_ST.y);
#endif
}

void ComputeMaskWeights(float4 inputMasks, out float outWeights[_MAX_LAYER])
{
float masks[_MAX_LAYER];
#if defined(_DENSITY_MODE)
#else
masks[0] = 1.0;
#endif
masks[1] = inputMasks.r;
#if _LAYER_COUNT > 2
masks[2] = inputMasks.g;

return blendMasks;
}
float GetInfluenceMask(LayerTexCoord layerTexCoord, bool useLodSampling = false, float lod = 0)
{
return useLodSampling ? SAMPLE_UVMAPPING_TEXTURE2D_LOD(_LayerInfluenceMaskMap, sampler_LayerMaskMap, layerTexCoord.blendMask, lod).r : SAMPLE_UVMAPPING_TEXTURE2D(_LayerInfluenceMaskMap, sampler_LayerMaskMap, layerTexCoord.blendMask).r;
}
// Return the maximun amplitude use by all enabled heightmap
// use for tessellation culling and per pixel displacement
// TODO: For vertex displacement this should take into account the modification in ApplyTessellationTileScale but it should be conservative here (as long as tiling is not negative)

#if defined(_HEIGHTMAP0)
maxDisplacement = max( _LayerHeightAmplitude0, maxDisplacement);
maxDisplacement = _HeightAmplitude0;
maxDisplacement = max( _LayerHeightAmplitude1
maxDisplacement = max( _HeightAmplitude1
+_LayerHeightAmplitude0 * _InheritBaseHeight1
+_HeightAmplitude0 * _InheritBaseHeight1
#endif
, maxDisplacement);
#endif

maxDisplacement = max( _LayerHeightAmplitude2
maxDisplacement = max( _HeightAmplitude2
+_LayerHeightAmplitude0 * _InheritBaseHeight2
+_HeightAmplitude0 * _InheritBaseHeight2
#endif
, maxDisplacement);
#endif

#if defined(_HEIGHTMAP3)
maxDisplacement = max( _LayerHeightAmplitude3
maxDisplacement = max( _HeightAmplitude3
+_LayerHeightAmplitude0 * _InheritBaseHeight3
+_HeightAmplitude0 * _InheritBaseHeight3
#endif
, maxDisplacement);
#endif

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

// For per pixel displacement we need to have normalized height scale to calculate the interesection (required by the algorithm we use)
// mean that we will normalize by the highest amplitude.
// We store this normalization factor with the weights as it will be multiply by the readed height.
ppdParam.weights[0] = weights[0] * (_LayerHeightAmplitude0) / maxHeight;
ppdParam.weights[1] = weights[1] * (_LayerHeightAmplitude1 + _LayerHeightAmplitude0 * _InheritBaseHeight1) / maxHeight;
ppdParam.weights[2] = weights[2] * (_LayerHeightAmplitude2 + _LayerHeightAmplitude0 * _InheritBaseHeight2) / maxHeight;
ppdParam.weights[3] = weights[3] * (_LayerHeightAmplitude3 + _LayerHeightAmplitude0 * _InheritBaseHeight3) / maxHeight;
ppdParam.weights[0] = weights[0] * (_HeightAmplitude0) / maxHeight;
ppdParam.weights[1] = weights[1] * (_HeightAmplitude1 + _HeightAmplitude0 * _InheritBaseHeight1) / maxHeight;
ppdParam.weights[2] = weights[2] * (_HeightAmplitude2 + _HeightAmplitude0 * _InheritBaseHeight2) / maxHeight;
ppdParam.weights[3] = weights[3] * (_HeightAmplitude3 + _HeightAmplitude0 * _InheritBaseHeight3) / maxHeight;
float mainHeightInfluence = BlendLayeredScalar(0.0, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights);
float mainHeightInfluence = BlendLayeredScalar(0.0, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights) * influenceMask;
ppdParam.mainHeightInfluence = mainHeightInfluence;
#else
[unroll]

float height; // final height processed
float NdotV;
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)

// Note: The TBN is not normalize as it is based on mikkt. We should normalize it, but POM is always use on simple enough surfarce that mean it is not required (save 2 normalize). Tag: SURFACE_GRADIENT
// For planar the view vector is the world view vector (unless we want to support object triplanar ? and in this case used TransformWorldToObject)
// TODO: do we support object triplanar ? See ComputeLayerTexCoord
float3 viewDirTS = isPlanar ? float3(-V.xz, V.y) : TransformWorldToTangent(V, worldToTangent);
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, worldToTangent);
NdotV = viewDirTS.z;
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);

return 0.0;
}
float GetMaxHeight(float4 heights)
{
float maxHeight = max(heights.r, heights.g);
#ifdef _LAYEREDLIT_4_LAYERS
maxHeight = max(Max3(heights.r, heights.g, heights.b), heights.a);
#endif
#ifdef _LAYEREDLIT_3_LAYERS
maxHeight = Max3(heights.r, heights.g, heights.b);
#endif
return maxHeight;
}
// Returns layering blend mask after application of height based blend.
float4 ApplyHeightBlend(float4 heights, float4 blendMask)
{
// Add offsets for all the layers.
heights = heights + float4(_HeightOffset0, _HeightOffset1, _HeightOffset2, _HeightOffset3);
// We need to mask out inactive layers so that their height does not impact the result.
float4 maskedHeights = heights * blendMask.argb;
float maxHeight = GetMaxHeight(maskedHeights);
// Make sure that transition is not zero otherwise the next computation will be wrong.
// The epsilon here also has to be bigger than the epsilon in the next computation.
float transition = max(_HeightTransition, 1e-5);
// The goal here is to have all but the heighest layer at negative heights, then we add the transition so that if the next heighest layer is near transition it will have a positive value.
// Then we clamp this to zero and normalize everything so that heighest layer has a value of 1.
maskedHeights = maskedHeights - maxHeight.xxxx;
// We need to add an epsilon here for active layers (hence the blendMask again) so that at least a layer shows up if everything's too low.
maskedHeights = (max(0, maskedHeights + transition) + 1e-6) * blendMask.argb;
// Normalize
maxHeight = GetMaxHeight(maskedHeights);
maskedHeights = maskedHeights / maxHeight.xxxx;
return maskedHeights.yzwx;
}
float4 blendMasks = GetBlendMask(layerTexCoord, vertexColor, true, lod);
float4 inputBlendMasks = GetBlendMask(layerTexCoord, vertexColor, true, lod);
ComputeMaskWeights(blendMasks, weights);
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0, lod).r - _LayerCenterOffset0) * _LayerHeightAmplitude0;
float height1 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1, lod).r - _LayerCenterOffset1) * _LayerHeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2, lod).r - _LayerCenterOffset2) * _LayerHeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3, lod).r - _LayerCenterOffset3) * _LayerHeightAmplitude3;
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0, lod).r - _HeightCenter0) * _HeightAmplitude0;
float height1 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1, lod).r - _HeightCenter1) * _HeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2, lod).r - _HeightCenter2) * _HeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3, lod).r - _HeightCenter3) * _HeightAmplitude3;
float4 resultBlendMasks = inputBlendMasks;
#if defined(_HEIGHT_BASED_BLEND)
resultBlendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), inputBlendMasks);
#endif
ComputeMaskWeights(resultBlendMasks, weights);
float influenceMask = GetInfluenceMask(layerTexCoord, true, lod);
return heightResult + height0 * inheritBaseHeight;
return heightResult + height0 * inheritBaseHeight * inputBlendMasks.a * influenceMask; // We multiply by the input mask for the first layer because if the mask here is black it means that the layer is not actually underneath any visible layer so we don't want to inherit its height.
#else
float heightResult = 0.0;

float3 ApplyHeightBasedBlend(float3 inputMask, float3 inputHeight, float3 blendUsingHeight)
{
return saturate(lerp(inputMask * inputHeight * blendUsingHeight * 100, 1, inputMask * inputMask)); // 100 arbitrary scale to limit blendUsingHeight values.
}
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, out float outWeights[_MAX_LAYER])
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, float4 blendMasks, out float outWeights[_MAX_LAYER])
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
#if defined(_DENSITY_MODE)
// Note: blendMasks.argb because a is main layer
float4 minOpaParam = float4(_MinimumOpacity0, _MinimumOpacity1, _MinimumOpacity2, _MinimumOpacity3);
float4 remapedOpacity = lerp(minOpaParam, float4(1.0, 1.0, 1.0, 1.0), inputAlphaMask); // Remap opacity mask from [0..1] to [minOpa..1]
float4 opacityAsDensity = saturate((inputAlphaMask - (float4(1.0, 1.0, 1.0, 1.0) - blendMasks.argb)) * 20.0);
float4 useOpacityAsDensityParam = float4(_OpacityAsDensity0, _OpacityAsDensity1, _OpacityAsDensity2, _OpacityAsDensity3);
blendMasks.argb = lerp(blendMasks.argb * remapedOpacity, opacityAsDensity, useOpacityAsDensityParam);
#endif
for (int i = 0; i < _MAX_LAYER; ++i)
{
outWeights[i] = 0.0f;
}
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0).r - _LayerCenterOffset0) * _LayerHeightAmplitude0;
float height1 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1).r - _LayerCenterOffset1) * _LayerHeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2).r - _LayerCenterOffset2) * _LayerHeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3).r - _LayerCenterOffset3) * _LayerHeightAmplitude3;
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0).r - _HeightCenter0) * _HeightAmplitude0;
float height1 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1).r - _HeightCenter1) * _HeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2).r - _HeightCenter2) * _HeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3).r - _HeightCenter3) * _HeightAmplitude3;
SetEnabledHeightByLayer(height0, height1, height2, height3);
float4 heights = float4(height0, height1, height2, height3);

heights.y += (heights.x * 0.0001);
#endif
#else
float4 heights = float4(0.0, 0.0, 0.0, 0.0);
blendMasks = ApplyHeightBlend(heights, blendMasks);
#endif
// If no heightmap is set on any layer, we don't need to try and blend them based on height...
// don't apply on main layer
blendMasks.rgb = ApplyHeightBasedBlend(blendMasks.rgb, heights.yzw, float3(_BlendUsingHeight1, _BlendUsingHeight2, _BlendUsingHeight3));
#if defined(_DENSITY_MODE)
// Note: blendMasks.argb because a is main layer
float4 opacityAsDensity = saturate((inputAlphaMask - (float4(1.0, 1.0, 1.0, 1.0) - blendMasks.argb)) * 20.0);
float4 useOpacityAsDensityParam = float4(_OpacityAsDensity0, _OpacityAsDensity1, _OpacityAsDensity2, _OpacityAsDensity3);
blendMasks.argb = lerp(blendMasks.argb, opacityAsDensity, useOpacityAsDensityParam);
float3 ComputeMainNormalInfluence(FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
float3 ComputeMainNormalInfluence(float influenceMask, FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float inputMainLayerMask, float weights[_MAX_LAYER])
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights);
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights) * influenceMask;
// We will add smoothly the contribution of the normal map by using lower mips with help of bias sampling. InfluenceFactor must be [0..numMips] // Caution it cause banding...
// Note: that we don't take details map into account here.
float maxMipBias = log2(max(_NormalMap0_TexelSize.z, _NormalMap0_TexelSize.w)); // don't do + 1 as it is for bias, not lod

#ifdef SURFACE_GRADIENT
return normalTS + influenceFactor * mainNormalTS;
return normalTS + influenceFactor * mainNormalTS * inputMainLayerMask;
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor);
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor * inputMainLayerMask);
float3 ComputeMainBaseColorInfluence(float3 baseColor0, float3 baseColor1, float3 baseColor2, float3 baseColor3, float compoMask, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
float3 ComputeMainBaseColorInfluence(float influenceMask, float3 baseColor0, float3 baseColor1, float3 baseColor2, float3 baseColor3, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseColor1, _InheritBaseColor2, _InheritBaseColor3, weights);
float influenceThreshold = BlendLayeredScalar(1.0, _InheritBaseColorThreshold1, _InheritBaseColorThreshold2, _InheritBaseColorThreshold3, weights);
influenceFactor = influenceFactor * (1.0 - saturate(compoMask / influenceThreshold));
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseColor1, _InheritBaseColor2, _InheritBaseColor3, weights) * influenceMask;
// We want to calculate the mean color of the texture. For this we will sample a low mipmap
float textureBias = 15.0; // Use maximum bias

void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.y); // Note that we pass the quantized value of LOD fade
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.x);
#endif
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal

GetLayerTexCoord(input, layerTexCoord);
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord);
float influenceMask = 0.0f;
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
influenceMask = GetInfluenceMask(layerTexCoord);
#endif
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord, influenceMask);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);

float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3, normalTS3);
// Note: If per pixel displacement is enabled it mean we will fetch again the various heightmaps at the intersection location. Not sure the compiler can optimize.
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), weights);
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), blendMasks, weights);
// For layered shader, alpha of base color is used as either an opacity mask, a composition mask for inheritance parameters or a density mask.
float alpha = PROP_BLEND_SCALAR(alpha, weights);

#endif
float3 normalTS = float3(0.0, 0.0, 0.0);
surfaceData.baseColor = ComputeMainBaseColorInfluence(surfaceData0.baseColor, surfaceData1.baseColor, surfaceData2.baseColor, surfaceData3.baseColor, alpha0, layerTexCoord, weights);
float3 normalTS = ComputeMainNormalInfluence(input, normalTS0, normalTS1, normalTS2, normalTS3, layerTexCoord, weights);
#else
surfaceData.baseColor = SURFACEDATA_BLEND_VECTOR3(surfaceData, baseColor, weights);
float3 normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
if (influenceMask > 0.0f)
{
surfaceData.baseColor = ComputeMainBaseColorInfluence(influenceMask, surfaceData0.baseColor, surfaceData1.baseColor, surfaceData2.baseColor, surfaceData3.baseColor, layerTexCoord, weights);
normalTS = ComputeMainNormalInfluence(influenceMask, input, normalTS0, normalTS1, normalTS2, normalTS3, layerTexCoord, blendMasks.a, weights);
}
else
{
surfaceData.baseColor = SURFACEDATA_BLEND_VECTOR3(surfaceData, baseColor, weights);
normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
}
surfaceData.perceptualSmoothness = SURFACEDATA_BLEND_SCALAR(surfaceData, perceptualSmoothness, weights);
surfaceData.ambientOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, ambientOcclusion, weights);

surfaceData.materialId = 1; // MaterialId.LitStandard
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;
surfaceData.coatNormalWS = float3(0.0, 0.0, 0.0);
surfaceData.coatCoverage = 0.0f;
surfaceData.coatIOR = 0.5;
GetNormalAndTangentWS(input, V, normalTS, surfaceData.normalWS, surfaceData.tangentWS);
// Done one time for all layered - cumulate with spec occ alpha for now

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


#ifdef _DETAIL_MAP_IDX
#ifdef SURFACE_GRADIENT
normalTS += detailNormalTS;
normalTS += detailNormalTS * detailMask;
#else
normalTS = lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask);
#endif

surfaceData.materialId = MATERIALID_LIT_ANISO;
#elif defined(_MATID_SPECULAR)
surfaceData.materialId = MATERIALID_LIT_SPECULAR;
#elif defined(_MATID_CLEARCOAT)
surfaceData.materialId = MATERIALID_LIT_CLEAR_COAT;
#else // Default
surfaceData.materialId = MATERIALID_LIT_STANDARD;
#endif

#endif
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
#ifdef _MATID_SPECULAR
// To save 1bit space in GBuffer we don't store specular as materialID but in the enum of the specular value
surfaceData.specular = SPECULARVALUE_SPECULAR_COLOR;
#else
surfaceData.specular = SPECULARVALUE_REGULAR;
#endif
surfaceData.subsurfaceProfile = _SubsurfaceProfile;
surfaceData.subsurfaceRadius = _SubsurfaceRadius;
surfaceData.thickness = _Thickness;

surfaceData.specularColor *= SAMPLE_UVMAPPING_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, layerTexCoord.base).rgb;
#endif
surfaceData.coatNormalWS = input.worldToTangent[2].xyz; // Assign vertex normal
surfaceData.coatCoverage = _CoatCoverage;
surfaceData.coatIOR = _CoatIOR;
surfaceData.materialId = 1; // MaterialId.LitStandard
surfaceData.materialId = MATERIALID_LIT_STANDARD;
// Note: any parameters set here must also be set in GetSurfaceAndBuiltinData() layer version
surfaceData.specular = 0.0;
surfaceData.coatNormalWS = float3(0.0, 0.0, 0.0);
surfaceData.coatCoverage = 0.0f;
surfaceData.coatIOR = 0.5;
#endif // #if !defined(LAYERED_LIT_SHADER)

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


PROP_DECL_TEX2D(_DetailMap);
TEXTURE2D(_LayerMaskMap);
TEXTURE2D(_LayerInfluenceMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
#endif

float _SubsurfaceRadius;
float _Thickness;
float _CoatCoverage;
float _CoatIOR;
float4 _SpecularColor;
float _TexWorldScale;

PROP_DECL(float, _HeightAmplitude);
PROP_DECL(float, _HeightCenter);
float _BlendUsingHeight1;
float _BlendUsingHeight2;
float _BlendUsingHeight3;
PROP_DECL(float, _LayerHeightAmplitude);
PROP_DECL(float, _LayerCenterOffset);
PROP_DECL(float, _MinimumOpacity);
PROP_DECL(float, _OpacityAsDensity);
float _InheritBaseNormal1;
float _InheritBaseNormal2;

float _InheritBaseColor1;
float _InheritBaseColor2;
float _InheritBaseColor3;
float _InheritBaseColorThreshold1;
float _InheritBaseColorThreshold2;
float _InheritBaseColorThreshold3;
PROP_DECL(float, _LayerTiling);
PROP_DECL(float, _HeightOffset);
float _HeightTransition;
float _TexWorldScaleBlendMask;
PROP_DECL(float, _TexWorldScale);

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


// Thus the following code play with both.
#if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS)
bool frustumCulled = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])_FrustumPlanes); // _FrustumPlanes are primary camera planes
bool frustumCulledCurrentView = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])_FrustumPlanes); // _FrustumPlanes are primary camera planes
bool frustumCulledMainView = false;
bool frustumCulled = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])unity_CameraWorldClipPlanes); // unity_CameraWorldClipPlanes is set by legacy Unity in case of shadow and contain shadow view plan
bool frustumCulledCurrentView = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])unity_CameraWorldClipPlanes); // unity_CameraWorldClipPlanes is set by legacy Unity in case of shadow and contain shadow view plan
// In the case of shadow, we don't want to tessellate anything that is not seen by the main view frustum. It can result in minor popping of tessellation into a shadow but we can't afford it anyway.
bool frustumCulledMainView = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])_FrustumPlanes);
#endif
bool faceCull = false;

}
#endif
if (frustumCulled || faceCull)
if (frustumCulledCurrentView || faceCull)
}
// See comment above:
// During shadow passes, we decide that anything outside the main view frustum should not be tessellated.
if (frustumCulledMainView)
{
return float4(1.0, 1.0, 1.0, 1.0);
}
// We use the parameters of the primary (scene view) camera in order

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


_HeightMap("HeightMap", 2D) = "black" {}
_HeightAmplitude("Height Amplitude", Float) = 0.01 // In world units
_HeightCenter("Height Center", Float) = 0.5 // In texture space
_HeightCenter("Height Center", Range(0.0, 1.0)) = 0.5 // In texture space
_DetailMap("DetailMap", 2D) = "black" {}
_DetailMask("DetailMask", 2D) = "white" {}

_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.0, 1.0)) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_CoatCoverage("Coat Coverage", Range(0.0, 1.0)) = 1.0
_CoatIOR("Coat IOR", Range(0.0, 1.0)) = 0.5
_SpecularColor("SpecularColor", Color) = (1, 1, 1, 1)
_SpecularColorMap("SpecularColorMap", 2D) = "white" {}

[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _UVBase("UV Set for base", Float) = 0
[Enum(UV0, 0, Planar, 4, TriPlanar, 5)] _UVBase("UV Set for base", Float) = 0
[Enum(Subsurface Scattering, 0, Standard, 1, Anisotropy, 4, Specular Color, 5)] _MaterialID("MaterialId", Int) = 1 // MaterialId.RegularLighting
[Enum(Subsurface Scattering, 0, Standard, 1, ClearCoat, 2, Anisotropy, 4, Specular Color, 5)] _MaterialID("MaterialId", Int) = 1 // MaterialId.RegularLighting
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5

// MaterialId are used as shader feature to allow compiler to optimize properly
// Note _MATID_STANDARD is not define as there is always the default case "_". We assign default as _MATID_STANDARD, so we never test _MATID_STANDARD
#pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR
#pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR _MATID_CLEARCOAT
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED

#include "../../../ShaderLibrary/common.hlsl"
#include "../../../ShaderLibrary/Wind.hlsl"
#include "../../../ShaderLibrary/tessellation.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"

225
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader


Shader "Hidden/HDRenderPipeline/CombineSubsurfaceScattering"
Shader "Hidden/HDRenderPipeline/SubsurfaceScattering"
// Old SSS Model >>>
// <<< Old SSS Model
SubShader
{

{
Ref 1 // StencilBits.SSS
Ref 1 // StencilLightingUsage.SplitLighting
Comp Equal
Pass Keep
}

ZWrite Off
// Old SSS Model >>>
// <<< Old SSS Model
HLSLPROGRAM
#pragma target 4.5

#pragma vertex Vert
#pragma fragment Frag
// Old SSS Model >>>
#pragma multi_compile SSS_MODEL_BASIC SSS_MODEL_DISNEY
// <<< Old SSS Model
// Tweak parameters for the Disney SSS below.
#define SSS_BILATERAL_FILTER 1
#define SSS_USE_TANGENT_PLANE 0
#define SSS_CLAMP_ARTIFACT 0
#define SSS_DEBUG_LOD 0
#define SSS_DEBUG_NORMAL_VS 0
// Do not modify these.
#define SSS_PASS 1

//-------------------------------------------------------------------------------------
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#define UNITY_MATERIAL_LIT // Needs to be defined before including Material.hlsl
#include "../../../Material/Material.hlsl"

//-------------------------------------------------------------------------------------
float _WorldScales[SSS_N_PROFILES]; // Size of the world unit in meters
#ifdef SSS_MODEL_DISNEY
float _FilterKernelsNearField[SSS_N_PROFILES][SSS_N_SAMPLES_NEAR_FIELD][2]; // 0 = radius, 1 = reciprocal of the PDF
float _FilterKernelsFarField[SSS_N_PROFILES][SSS_N_SAMPLES_FAR_FIELD][2]; // 0 = radius, 1 = reciprocal of the PDF
#else
float4 _FilterKernelsBasic[SSS_N_PROFILES][SSS_BASIC_N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[SSS_BASIC_N_SAMPLES]; // RGB for chromatic, A for achromatic
#endif
float4 _WorldScales[SSS_N_PROFILES]; // Size of the world unit in meters (only the X component is used)
float4 _FilterKernelsBasic[SSS_N_PROFILES][SSS_BASIC_N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[SSS_BASIC_N_SAMPLES]; // RGB for chromatic, A for achromatic
TEXTURE2D(_IrradianceSource); // Includes transmitted light
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters

//-------------------------------------------------------------------------------------
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal().
// N.b.: the returned value is multiplied by 4. It is irrelevant due to weight renormalization.
float3 KernelValCircle(float r, float3 S)
{
float3 expOneThird = exp(((-1.0 / 3.0) * r) * S);
return /* 0.25 * */ S * (expOneThird + expOneThird * expOneThird * expOneThird);
}
// Computes F(r)/P(r), s.t. r = sqrt(a^2 + b^2).
// Rescaling of the PDF is handled by 'totalWeight'.
float3 ComputeBilateralWeight(float a2, float b, float mmPerUnit, float3 S, float rcpPdf)
{
#if (SSS_BILATERAL_FILTER == 0)
b = 0;
#endif
#if SSS_USE_TANGENT_PLANE
// Both 'a2' and 'b2' require unit conversion.
float r = sqrt(a2 + b * b) * mmPerUnit;
#else
// Only 'b2' requires unit conversion.
float r = sqrt(a2 + (b * mmPerUnit) * (b * mmPerUnit));
#endif
#if SSS_CLAMP_ARTIFACT
return saturate(KernelValCircle(r, S) * rcpPdf);
#else
return KernelValCircle(r, S) * rcpPdf;
#endif
}
#define SSS_ITER(i, n, kernel, profileID, shapeParam, centerPosUnSS, centerPosVS, \
useTangentPlane, tangentX, tangentY, mmPerUnit, pixelsPerMm, \
totalIrradiance, totalWeight) \
{ \
float r = kernel[profileID][i][0]; \
/* The relative sample position is known at compile time. */ \
float phi = SampleDiskFibonacci(i, n).y; \
float2 vec = r * float2(cos(phi), sin(phi)); \
\
/* Compute the screen-space position and the associated irradiance. */ \
float2 position; float3 irradiance; \
/* Compute the squared distance (in mm) in the screen-aligned plane. */ \
float dXY2; \
\
if (useTangentPlane) \
{ \
/* 'vec' is given relative to the tangent frame. */ \
float3 relPosVS = vec.x * tangentX + vec.y * tangentY; \
float3 positionVS = centerPosVS + relPosVS; \
float4 positionCS = mul(projMatrix, float4(positionVS, 1)); \
float2 positionSS = ComputeScreenSpacePosition(positionCS); \
\
position = positionSS * _ScreenSize.xy; \
irradiance = LOAD_TEXTURE2D(_IrradianceSource, position).rgb; \
dXY2 = dot(relPosVS.xy, relPosVS.xy); \
} \
else \
{ \
/* 'vec' is given directly in screen-space. */ \
position = centerPosUnSS + vec * pixelsPerMm; \
irradiance = LOAD_TEXTURE2D(_IrradianceSource, position).rgb; \
dXY2 = r * r; \
} \
\
/* TODO: see if making this a [branch] improves performance. */ \
[flatten] \
if (any(irradiance)) \
{ \
/* Apply bilateral weighting. */ \
float z = LOAD_TEXTURE2D(_MainDepthTexture, position).r; \
float d = LinearEyeDepth(z, _ZBufferParams); \
float t = d - centerPosVS.z; \
float p = kernel[profileID][i][1]; \
float3 w = ComputeBilateralWeight(dXY2, t, mmPerUnit, shapeParam, p); \
\
totalIrradiance += w * irradiance; \
totalWeight += w; \
} \
else \
{ \
/*************************************************************************/ \
/* The irradiance is 0. This could happen for 3 reasons. */ \
/* Most likely, the surface fragment does not have an SSS material. */ \
/* Alternatively, our sample comes from a region without any geometry. */ \
/* Finally, the surface fragment could be completely shadowed. */ \
/* Our blur is energy-preserving, so 'centerWeight' should be set to 0. */ \
/* We do not terminate the loop since we want to gather the contribution */ \
/* of the remaining samples (e.g. in case of hair covering skin). */ \
/* Note: See comment in the output of deferred.shader */ \
/*************************************************************************/ \
} \
}
#define SSS_LOOP(n, kernel, profileID, shapeParam, centerPosUnSS, centerPosVS, \
useTangentPlane, tangentX, tangentY, mmPerUnit, pixelsPerMm, \
totalIrradiance, totalWeight) \
{ \
float centerRadius = kernel[profileID][0][0]; \
float centerRcpPdf = kernel[profileID][0][1]; \
float3 centerWeight = KernelValCircle(centerRadius, shapeParam) * centerRcpPdf; \
\
totalIrradiance = centerWeight * centerIrradiance; \
totalWeight = centerWeight; \
\
/* Integrate over the screen-aligned or tangent plane in the view space. */ \
[unroll] \
for (uint i = 1; i < n; i++) \
{ \
SSS_ITER(i, n, kernel, profileID, shapeParam, centerPosUnSS, centerPosVS, \
useTangentPlane, tangentX, tangentY, mmPerUnit, pixelsPerMm, \
totalIrradiance, totalWeight) \
} \
}
struct Attributes
{
uint vertexID : SV_VertexID;

int profileID = bsdfData.subsurfaceProfile;
float distScale = bsdfData.subsurfaceRadius;
#ifdef SSS_MODEL_DISNEY
float3 shapeParam = _ShapeParams[profileID].rgb;
float maxDistance = _ShapeParams[profileID].a;
#else
#endif
// Take the first (central) sample.
// TODO: copy its neighborhood into LDS.

float3 centerPosVS = ComputeViewSpacePosition(centerPosSS, centerDepth, _InvProjMatrix);
float3 cornerPosVS = ComputeViewSpacePosition(cornerPosSS, centerDepth, _InvProjMatrix);
#ifdef SSS_MODEL_DISNEY
float mmPerUnit = MILLIMETERS_PER_METER * (_WorldScales[profileID] / distScale);
float unitsPerMm = rcp(mmPerUnit);
// Compute the view-space dimensions of the pixel as a quad projected onto geometry.
float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy);
float2 pixelsPerMm = rcp(unitsPerPixel) * unitsPerMm;
// We perform point sampling. Therefore, we can avoid the cost
// of filtering if we stay within the bounds of the current pixel.
// We use the value of 1 instead of 0.5 as an optimization.
// N.b.: our LoD selection algorithm is the same regardless of
// whether we integrate over the tangent plane or not, since we
// don't want the orientation of the tangent plane to create
// divergence of execution across the warp.
float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y);
[branch]
if (distScale == 0 || maxDistInPixels < 1)
{
#if SSS_DEBUG_LOD
return float4(0, 0, 1, 1);
#else
return float4(bsdfData.diffuseColor * centerIrradiance, 1);
#endif
}
const bool useTangentPlane = SSS_USE_TANGENT_PLANE != 0;
float4x4 viewMatrix, projMatrix;
GetLeftHandedViewSpaceMatrices(viewMatrix, projMatrix);
// Compute the tangent frame in view space.
float3 normalVS = mul((float3x3)viewMatrix, bsdfData.normalWS);
float3 tangentX = GetLocalFrame(normalVS)[0] * unitsPerMm;
float3 tangentY = GetLocalFrame(normalVS)[1] * unitsPerMm;
#if SSS_DEBUG_NORMAL_VS
// We expect the view-space normal to be front-facing.
if (normalVS.z >= 0) return float4(1, 0, 0, 1);
#endif
// Accumulate filtered irradiance and bilateral weights (for renormalization).
float3 totalIrradiance, totalWeight;
// Use fewer samples for SS regions smaller than 5x5 pixels (rotated by 45 degrees).
[branch]
if (maxDistInPixels < SSS_LOD_THRESHOLD)
{
#if SSS_DEBUG_LOD
return float4(0.5, 0.5, 0, 1);
#else
SSS_LOOP(SSS_N_SAMPLES_FAR_FIELD, _FilterKernelsFarField,
profileID, shapeParam, centerPosition, centerPosVS,
useTangentPlane, tangentX, tangentY, mmPerUnit, pixelsPerMm,
totalIrradiance, totalWeight)
#endif
}
else
{
#if SSS_DEBUG_LOD
return float4(1, 0, 0, 1);
#else
SSS_LOOP(SSS_N_SAMPLES_NEAR_FIELD, _FilterKernelsNearField,
profileID, shapeParam, centerPosition, centerPosVS,
useTangentPlane, tangentX, tangentY, mmPerUnit, pixelsPerMm,
totalIrradiance, totalWeight)
#endif
}
#else
// Rescaling the filter is equivalent to inversely scaling the world.
float metersPerUnit = _WorldScales[profileID] / distScale * SSS_BASIC_DISTANCE_SCALE;
float metersPerUnit = _WorldScales[profileID].x / distScale * SSS_BASIC_DISTANCE_SCALE;
float centimPerUnit = CENTIMETERS_PER_METER * metersPerUnit;
// Compute the view-space dimensions of the pixel as a quad projected onto geometry.
float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy);

// of the remaining samples (e.g. in case of hair covering skin).
}
}
#endif
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
}

122
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/FoliageSSSProfile.asset


m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: FoliageSSSProfile
m_EditorClassIdentifier:
scatteringDistance: {r: 0.75735295, g: 0.7008203, b: 0.24502596, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 1
thicknessRemap: {x: 0, y: 0.2873168}
worldScale: 1
settingsIndex: 1
m_ShapeParam: {x: 1.3203883, y: 1.4268992, z: 4.0812}
m_MaxRadius: 7.839332
m_FilterKernelNearField:
- {x: 0.013854082, y: 1.5332626}
- {x: 0.04207757, y: 1.5715919}
- {x: 0.07101321, y: 1.611625}
- {x: 0.10069309, y: 1.653469}
- {x: 0.13115102, y: 1.6972395}
- {x: 0.16242325, y: 1.743061}
- {x: 0.19454831, y: 1.791069}
- {x: 0.22756726, y: 1.8414105}
- {x: 0.2615238, y: 1.8942443}
- {x: 0.29646498, y: 1.9497447}
- {x: 0.33244094, y: 2.0081}
- {x: 0.36950532, y: 2.069517}
- {x: 0.40771604, y: 2.1342213}
- {x: 0.44713485, y: 2.2024598}
- {x: 0.48782852, y: 2.274504}
- {x: 0.5298689, y: 2.3506513}
- {x: 0.5733336, y: 2.4312308}
- {x: 0.6183063, y: 2.5166042}
- {x: 0.66487795, y: 2.6071734}
- {x: 0.71314675, y: 2.703383}
- {x: 0.76321995, y: 2.805728}
- {x: 0.81521386, y: 2.9147599}
- {x: 0.86925554, y: 3.031096}
- {x: 0.92548406, y: 3.1554284}
- {x: 0.9840515, y: 3.288537}
- {x: 1.0451256, y: 3.431302}
- {x: 1.1088905, y: 3.5847225}
- {x: 1.1755506, y: 3.749937}
- {x: 1.2453312, y: 3.9282467}
- {x: 1.3184844, y: 4.1211514}
- {x: 1.3952904, y: 4.3303804}
- {x: 1.4760638, y: 4.5579505}
- {x: 1.5611593, y: 4.8062224}
- {x: 1.650978, y: 5.0779796}
- {x: 1.7459753, y: 5.3765287}
- {x: 1.8466738, y: 5.7058387}
- {x: 1.9536757, y: 6.070716}
- {x: 2.0676782, y: 6.4770336}
- {x: 2.189499, y: 6.9320674}
- {x: 2.3201032, y: 7.4449396}
- {x: 2.4606442, y: 8.027264}
- {x: 2.612515, y: 8.694056}
- {x: 2.777422, y: 9.465107}
- {x: 2.9574924, y: 10.367077}
- {x: 3.1554203, y: 11.436736}
- {x: 3.3747015, y: 12.726331}
- {x: 3.6199868, y: 14.312694}
- {x: 3.897662, y: 16.313623}
- {x: 4.2168484, y: 18.919455}
- {x: 4.5912457, y: 22.459015}
- {x: 5.042839, y: 27.553566}
- {x: 5.610336, y: 35.534466}
- {x: 6.3721733, y: 49.863647}
- {x: 7.53103, y: 83.235695}
- {x: 10.026244, y: 249.90146}
m_FilterKernelFarField:
- {x: 0.036647703, y: 1.5641627}
- {x: 0.113649175, y: 1.671985}
- {x: 0.19610003, y: 1.7934121}
- {x: 0.28470552, y: 1.9309369}
- {x: 0.38030306, y: 2.0876582}
- {x: 0.48389605, y: 2.2674706}
- {x: 0.5966971, y: 2.4753277}
- {x: 0.72018707, y: 2.717616}
- {x: 0.85619545, y: 3.0026984}
- {x: 1.0070126, y: 3.3417335}
- {x: 1.1755506, y: 3.749937}
- {x: 1.3655809, y: 4.248627}
- {x: 1.5821002, y: 4.868682}
- {x: 1.8319175, y: 5.6567397}
- {x: 2.1246579, y: 6.6871305}
- {x: 2.4745958, y: 8.086858}
- {x: 2.9043517, y: 10.094101}
- {x: 3.4533012, y: 13.217383}
- {x: 4.20053, y: 18.777578}
- {x: 5.349281, y: 31.61934}
- {x: 7.839332, y: 95.36225}
texturingMode: 0
enableTransmission: 1
enableThinObject: 1
tintColor: {r: 1, g: 1, b: 1, a: 1}
thicknessRemap: {x: 0, y: 0.2873168}
settingsIndex: 0
m_FilterKernel:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.00000001629312}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.034422863}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.07085508}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.112142384}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.16452742}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.25364923}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.03442289}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.07085508}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.11214242}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.16452742}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.2536493}
m_HalfRcpVariances:
- {x: 49.999992, y: 49.999992, z: 49.999992}
- {x: 12.499998, y: 12.499998, z: 12.499998}
m_HalfRcpWeightedVariances: {x: 22.222221, y: 22.222221, z: 22.222221, w: 22.222221}
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
m_FilterKernelBasic:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.11381993}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -1.3907351}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.11382001}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 1.3907368}

156
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset


m_EditorClassIdentifier:
scatteringDistance: {r: 0.758, g: 0.321, b: 0.201, a: 1}
transmissionTint: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1}
texturingMode: 0
texturingMode: 1
m_MaxRadius: 8.458925
m_MaxRadius: 7.84603
- {x: 0, y: 1.516}
- {x: 0.027902514, y: 1.5535468}
- {x: 0.056502663, y: 1.5927485}
- {x: 0.0858313, y: 1.6337082}
- {x: 0.1159215, y: 1.6765369}
- {x: 0.14680836, y: 1.7213551}
- {x: 0.17852913, y: 1.7682924}
- {x: 0.21112362, y: 1.81749}
- {x: 0.24463426, y: 1.8691009}
- {x: 0.27910653, y: 1.9232914}
- {x: 0.31458887, y: 1.9802433}
- {x: 0.35113326, y: 2.0401537}
- {x: 0.3887955, y: 2.1032388}
- {x: 0.42763543, y: 2.1697347}
- {x: 0.46771717, y: 2.2399004}
- {x: 0.5091102, y: 2.3140202}
- {x: 0.55188924, y: 2.3924074}
- {x: 0.59613484, y: 2.4754071}
- {x: 0.6419343, y: 2.563401}
- {x: 0.68938226, y: 2.6568115}
- {x: 0.7385812, y: 2.756108}
- {x: 0.78964317, y: 2.8618138}
- {x: 0.8426895, y: 2.9745123}
- {x: 0.89785355, y: 3.0948577}
- {x: 0.95528066, y: 3.2235847}
- {x: 1.0151305, y: 3.3615222}
- {x: 1.0775794, y: 3.5096087}
- {x: 1.1428206, y: 3.66891}
- {x: 1.2110695, y: 3.8406446}
- {x: 1.282564, y: 4.026209}
- {x: 1.3575704, y: 4.227214}
- {x: 1.4363859, y: 4.4455285}
- {x: 1.5193442, y: 4.6833334}
- {x: 1.6068225, y: 4.943191}
- {x: 1.6992486, y: 5.228136}
- {x: 1.7971107, y: 5.541792}
- {x: 1.9009686, y: 5.88852}
- {x: 2.0114706, y: 6.273631}
- {x: 2.1293726, y: 6.7036633}
- {x: 2.2555614, y: 7.18675}
- {x: 2.3910918, y: 7.7331758}
- {x: 2.537231, y: 8.35613}
- {x: 2.6955185, y: 9.072821}
- {x: 2.8678567, y: 9.906171}
- {x: 3.056636, y: 10.887414}
- {x: 3.2649205, y: 12.060253}
- {x: 3.496729, y: 13.487793}
- {x: 3.7574923, y: 15.264698}
- {x: 4.054809, y: 17.539753}
- {x: 4.3997865, y: 20.560957}
- {x: 4.8096266, y: 24.774817}
- {x: 5.3131247, y: 31.074501}
- {x: 5.9642344, y: 41.544285}
- {x: 6.884045, y: 62.43729}
- {x: 8.458925, y: 125.02069}
- {x: 0.013865918, y: 1.5345725}
- {x: 0.04211352, y: 1.5729346}
- {x: 0.07107388, y: 1.6130018}
- {x: 0.100779116, y: 1.6548817}
- {x: 0.13126306, y: 1.6986896}
- {x: 0.16256203, y: 1.7445502}
- {x: 0.1947145, y: 1.7925992}
- {x: 0.22776169, y: 1.8429838}
- {x: 0.26174724, y: 1.8958628}
- {x: 0.29671827, y: 1.9514104}
- {x: 0.33272493, y: 2.0098157}
- {x: 0.369821, y: 2.0712852}
- {x: 0.40806437, y: 2.1360447}
- {x: 0.44751683, y: 2.2043417}
- {x: 0.48824534, y: 2.276447}
- {x: 0.5303216, y: 2.3526597}
- {x: 0.5738235, y: 2.433308}
- {x: 0.61883456, y: 2.5187542}
- {x: 0.665446, y: 2.609401}
- {x: 0.713756, y: 2.7056925}
- {x: 0.763872, y: 2.808125}
- {x: 0.8159103, y: 2.91725}
- {x: 0.8699981, y: 3.0336854}
- {x: 0.9262747, y: 3.1581244}
- {x: 0.98489225, y: 3.2913465}
- {x: 1.0460185, y: 3.434234}
- {x: 1.1098381, y: 3.5877857}
- {x: 1.1765549, y: 3.7531407}
- {x: 1.2463952, y: 3.9316032}
- {x: 1.319611, y: 4.124672}
- {x: 1.3964823, y: 4.3340797}
- {x: 1.4773248, y: 4.561845}
- {x: 1.5624928, y: 4.810328}
- {x: 1.6523882, y: 5.082317}
- {x: 1.747467, y: 5.381122}
- {x: 1.8482518, y: 5.710715}
- {x: 1.9553448, y: 6.0759025}
- {x: 2.069445, y: 6.482568}
- {x: 2.1913698, y: 6.9379897}
- {x: 2.3220856, y: 7.4513016}
- {x: 2.4627466, y: 8.0341215}
- {x: 2.614747, y: 8.701484}
- {x: 2.7797952, y: 9.473195}
- {x: 2.9600194, y: 10.375936}
- {x: 3.1581159, y: 11.446505}
- {x: 3.3775842, y: 12.737201}
- {x: 3.6230793, y: 14.324919}
- {x: 3.9009922, y: 16.327562}
- {x: 4.220452, y: 18.935623}
- {x: 4.5951686, y: 22.478209}
- {x: 5.047148, y: 27.57712}
- {x: 5.615129, y: 35.564823}
- {x: 6.3776174, y: 49.90625}
- {x: 7.5374603, y: 83.30668}
- {x: 10.03481, y: 250.11497}
- {x: 0, y: 1.516}
- {x: 0.07457052, y: 1.6178904}
- {x: 0.15428384, y: 1.7323332}
- {x: 0.23978925, y: 1.861574}
- {x: 0.33185518, y: 2.0083904}
- {x: 0.43139812, y: 2.1762547}
- {x: 0.53952074, y: 2.3695562}
- {x: 0.6575622, y: 2.5939138}
- {x: 0.7871677, y: 2.8566267}
- {x: 0.93038195, y: 3.1673388}
- {x: 1.0897847, y: 3.5390525}
- {x: 1.2686841, y: 3.9897263}
- {x: 1.4714115, y: 4.544919}
- {x: 1.7037815, y: 5.2423906}
- {x: 1.9738544, y: 6.140622}
- {x: 2.2932806, y: 7.335897}
- {x: 2.679871, y: 8.999949}
- {x: 3.1630776, y: 11.474433}
- {x: 3.797516, y: 15.554795}
- {x: 4.7049003, y: 23.627026}
- {x: 6.2721014, y: 47.62654}
- {x: 0.03667902, y: 1.5654991}
- {x: 0.11374626, y: 1.6734134}
- {x: 0.19626758, y: 1.7949444}
- {x: 0.28494877, y: 1.9325867}
- {x: 0.38062802, y: 2.0894418}
- {x: 0.48430943, y: 2.2694077}
- {x: 0.59720695, y: 2.4774427}
- {x: 0.72080237, y: 2.7199378}
- {x: 0.8569269, y: 3.005264}
- {x: 1.007873, y: 3.3445888}
- {x: 1.1765549, y: 3.7531407}
- {x: 1.3667475, y: 4.252257}
- {x: 1.5834517, y: 4.872841}
- {x: 1.8334827, y: 5.6615734}
- {x: 2.126473, y: 6.692844}
- {x: 2.4767098, y: 8.093767}
- {x: 2.9068332, y: 10.102725}
- {x: 3.4562516, y: 13.228675}
- {x: 4.2041187, y: 18.793621}
- {x: 5.3538504, y: 31.646347}
- {x: 7.84603, y: 95.44374}
scatterDistance1: {r: 0.3, g: 0.2, b: 0.2, a: 0}
scatterDistance2: {r: 0.6, g: 0.2, b: 0.2, a: 0}
lerpWeight: 0.5

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


// PDF(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / 4
// CDF(r, s) = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]
// ------------------------------------------------------------------------------------
// N.b.: computation of normalized weights, and multiplication by the surface albedo
// of the actual geometry is performed at runtime (in the shader).
m_FilterKernelNearField[i].x = r;

m_MaxRadius = m_FilterKernelNearField[SssConstants.SSS_N_SAMPLES_NEAR_FIELD - 1].x;
// Importance sample the far field kernel.
for (int i = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; i < n; i++)
{

m_FilterKernelFarField[i].y = 1.0f / KernelPdf(r, s);
}
m_MaxRadius = m_FilterKernelFarField[SssConstants.SSS_N_SAMPLES_FAR_FIELD - 1].x;
// Old SSS Model >>>
UpdateKernelAndVarianceData();
// <<< Old SSS Model

// Set in BuildKernel().
get { return m_FilterKernelNearField; }
}
public Vector2[] filterKernelFarField
{
// Set in BuildKernel().

{
public int numProfiles; // Excluding the neutral profile
public SubsurfaceScatteringProfile[] profiles;
// Below are the cached values.
[NonSerialized] public uint texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
[NonSerialized] public uint transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
[NonSerialized] public float[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
[NonSerialized] public float[] worldScales; // Size of the world unit in meters
[NonSerialized] public Vector4[] shapeParams; // RGB = S = 1 / D, A = filter radius
[NonSerialized] public Vector4[] transmissionTints; // RGB = color, A = unused
[NonSerialized] public float[] filterKernelsNearField; // 0 = radius, 1 = reciprocal of the PDF
[NonSerialized] public float[] filterKernelsFarField; // 0 = radius, 1 = reciprocal of the PDF
// Below are the cached values. TODO: uncomment when SSS profile asset serialization is fixed.
/*[NonSerialized]*/ public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
/*[NonSerialized]*/ public int transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
/*[NonSerialized]*/ public Vector4[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
/*[NonSerialized]*/ public Vector4[] worldScales; // Size of the world unit in meters (only the X component is used)
/*[NonSerialized]*/ public Vector4[] shapeParams; // RGB = S = 1 / D, A = filter radius
/*[NonSerialized]*/ public Vector4[] transmissionTints; // RGB = color, A = unused
/*[NonSerialized]*/ public Vector4[] filterKernels; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
[NonSerialized] public Vector4[] halfRcpWeightedVariances;
[NonSerialized] public Vector4[] filterKernelsBasic;
/*[NonSerialized]*/ public Vector4[] halfRcpWeightedVariances;
/*[NonSerialized]*/ public Vector4[] halfRcpVariancesAndWeights;
/*[NonSerialized]*/ public Vector4[] filterKernelsBasic;
// <<< Old SSS Model
// --- Public Methods ---

numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
worldScales = null;
shapeParams = null;
transmissionTints = null;
filterKernelsNearField = null;
filterKernelsFarField = null;
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
worldScales = null;
shapeParams = null;
transmissionTints = null;
filterKernels = null;
useDisneySSS = true;
halfRcpWeightedVariances = null;
filterKernelsBasic = null;
useDisneySSS = true;
halfRcpWeightedVariances = null;
halfRcpVariancesAndWeights = null;
filterKernelsBasic = null;
// <<< Old SSS Model
UpdateCache();

{
texturingModeFlags = transmissionFlags = 0;
const int thicknessRemapsLen = SssConstants.SSS_N_PROFILES * 2;
if (thicknessRemaps == null || thicknessRemaps.Length != thicknessRemapsLen)
if (thicknessRemaps == null || thicknessRemaps.Length != SssConstants.SSS_N_PROFILES)
thicknessRemaps = new float[thicknessRemapsLen];
thicknessRemaps = new Vector4[SssConstants.SSS_N_PROFILES];
worldScales = new float[SssConstants.SSS_N_PROFILES];
worldScales = new Vector4[SssConstants.SSS_N_PROFILES];
}
if (shapeParams == null || shapeParams.Length != SssConstants.SSS_N_PROFILES)

transmissionTints = new Vector4[SssConstants.SSS_N_PROFILES];
}
const int filterKernelsNearFieldLen = 2 * SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_NEAR_FIELD;
if (filterKernelsNearField == null || filterKernelsNearField.Length != filterKernelsNearFieldLen)
const int filterKernelsNearFieldLen = SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_NEAR_FIELD;
if (filterKernels == null || filterKernels.Length != filterKernelsNearFieldLen)
filterKernelsNearField = new float[filterKernelsNearFieldLen];
filterKernels = new Vector4[filterKernelsNearFieldLen];
const int filterKernelsFarFieldLen = 2 * SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_FAR_FIELD;
if (filterKernelsFarField == null || filterKernelsFarField.Length != filterKernelsFarFieldLen)
// Old SSS Model >>>
if (halfRcpWeightedVariances == null || halfRcpWeightedVariances.Length != SssConstants.SSS_N_PROFILES)
filterKernelsFarField = new float[filterKernelsFarFieldLen];
halfRcpWeightedVariances = new Vector4[SssConstants.SSS_N_PROFILES];
// Old SSS Model >>>
if (halfRcpWeightedVariances == null || halfRcpWeightedVariances.Length != SssConstants.SSS_N_PROFILES)
if (halfRcpVariancesAndWeights == null || halfRcpVariancesAndWeights.Length != 2 * SssConstants.SSS_N_PROFILES)
halfRcpWeightedVariances = new Vector4[SssConstants.SSS_N_PROFILES];
halfRcpVariancesAndWeights = new Vector4[2 * SssConstants.SSS_N_PROFILES];
}
const int filterKernelsLen = SssConstants.SSS_N_PROFILES * SssConstants.SSS_BASIC_N_SAMPLES;

if (i >= numProfiles || profiles[i] == null)
{
// Pink transmission
transmissionFlags |= (uint)1 << i * 2;
transmissionFlags |= 1 << i * 2;
worldScales[i] = 1.0f;
worldScales[i] = Vector4.one;
filterKernelsNearField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsNearField[2 * (n * i + j) + 1] = 1.0f;
}
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
{
filterKernelsFarField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsFarField[2 * (n * i + j) + 1] = 1.0f;
filterKernels[n * i + j].x = 0.0f;
filterKernels[n * i + j].y = 1.0f;
filterKernels[n * i + j].z = 0.0f;
filterKernels[n * i + j].w = 1.0f;
halfRcpWeightedVariances[i] = Vector4.one;
halfRcpWeightedVariances[i] = Vector4.one;
halfRcpVariancesAndWeights[2 * i + 0] = Vector4.one;
halfRcpVariancesAndWeights[2 * i + 1] = Vector4.one;
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{

Debug.Assert(numProfiles < 16, "Transmission flags (32-bit integer) cannot support more than 16 profiles.");
texturingModeFlags |= (uint)profiles[i].texturingMode << i;
transmissionFlags |= (uint)profiles[i].transmissionMode << i * 2;
texturingModeFlags |= (int)profiles[i].texturingMode << i;
transmissionFlags |= (int)profiles[i].transmissionMode << i * 2;
thicknessRemaps[2 * i] = profiles[i].thicknessRemap.x;
thicknessRemaps[2 * i + 1] = profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x;
worldScales[i] = profiles[i].worldScale;
shapeParams[i] = profiles[i].shapeParameter;
shapeParams[i].w = profiles[i].maxRadius;
transmissionTints[i] = profiles[i].transmissionTint;
thicknessRemaps[i] = new Vector4(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x, 0.0f, 0.0f);
worldScales[i] = new Vector4(profiles[i].worldScale, 0, 0, 0);
shapeParams[i] = profiles[i].shapeParameter;
shapeParams[i].w = profiles[i].maxRadius;
transmissionTints[i] = profiles[i].transmissionTint * 0.25f; // Premultiplied
filterKernelsNearField[2 * (n * i + j) + 0] = profiles[i].filterKernelNearField[j].x;
filterKernelsNearField[2 * (n * i + j) + 1] = profiles[i].filterKernelNearField[j].y;
}
filterKernels[n * i + j].x = profiles[i].filterKernelNearField[j].x;
filterKernels[n * i + j].y = profiles[i].filterKernelNearField[j].y;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
{
filterKernelsFarField[2 * (n * i + j) + 0] = profiles[i].filterKernelFarField[j].x;
filterKernelsFarField[2 * (n * i + j) + 1] = profiles[i].filterKernelFarField[j].y;
if (j < SssConstants.SSS_N_SAMPLES_FAR_FIELD)
{
filterKernels[n * i + j].z = profiles[i].filterKernelFarField[j].x;
filterKernels[n * i + j].w = profiles[i].filterKernelFarField[j].y;
}
Vector4 stdDev1 = ((1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * profiles[i].scatterDistance1;
Vector4 stdDev2 = ((1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * profiles[i].scatterDistance2;
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
// Rescale by 4 to counter rescaling of transmission tints.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
halfRcpVariancesAndWeights[2 * i + 0] = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4 * (1.0f - profiles[i].lerpWeight));
halfRcpVariancesAndWeights[2 * i + 1] = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4 * profiles[i].lerpWeight);
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{
filterKernelsBasic[n * i + j] = profiles[i].filterKernelBasic[j];

{
int i = SssConstants.SSS_NEUTRAL_PROFILE_ID;
worldScales[i] = 1.0f;
worldScales[i] = Vector4.one;
filterKernelsNearField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsNearField[2 * (n * i + j) + 1] = 1.0f;
}
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; j < n; j++)
{
filterKernelsFarField[2 * (n * i + j) + 0] = 0.0f;
filterKernelsFarField[2 * (n * i + j) + 1] = 1.0f;
filterKernels[n * i + j].x = 0.0f;
filterKernels[n * i + j].y = 1.0f;
filterKernels[n * i + j].z = 0.0f;
filterKernels[n * i + j].w = 1.0f;
}
// Old SSS Model >>>

public void OnAfterDeserialize()
{
UpdateCache();
// TODO: uncomment when SSS profile asset serialization is fixed.
// UpdateCache();
}
}

if (useDisneySSS)
{
EditorGUILayout.PropertyField(m_ScatteringDistance, styles.sssProfileScatteringDistance);
GUI.enabled = false;
EditorGUILayout.PropertyField(m_MaxRadius, styles.sssProfileMaxRadius);
GUI.enabled = true;

Vector2 R = m_ThicknessRemap.vector2Value;
bool transmissionEnabled = m_TransmissionMode.intValue != (int)SubsurfaceScatteringProfile.TransmissionMode.None;
// Draw the profile.
m_ProfileMaterial.SetFloat( "_MaxRadius", r);
m_ProfileMaterial.SetVector("_ShapeParam", S);
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);
// Apply the three-sigma rule, and rescale.

Vector4 stdDev1 = new Vector4(s * m_ScatterDistance1.colorValue.r, s * m_ScatterDistance1.colorValue.g, s * m_ScatterDistance1.colorValue.b);
Vector4 stdDev2 = new Vector4(s * m_ScatterDistance2.colorValue.r, s * m_ScatterDistance2.colorValue.g, s * m_ScatterDistance2.colorValue.b);
m_ProfileMaterial.SetVector("_StdDev1", stdDev1);
m_ProfileMaterial.SetVector("_StdDev2", stdDev2);
m_ProfileMaterial.SetFloat("_LerpWeight", m_LerpWeight.floatValue);
m_ProfileMaterial.SetFloat("_MaxRadius", rMax);
Vector4 stdDev1 = s * m_ScatterDistance1.colorValue;
Vector4 stdDev2 = s * m_ScatterDistance2.colorValue;
m_ProfileMaterial.SetVector(HDShaderIDs._StdDev1, stdDev1);
m_ProfileMaterial.SetVector(HDShaderIDs._StdDev2, stdDev2);
m_ProfileMaterial.SetFloat(HDShaderIDs._LerpWeight, m_LerpWeight.floatValue);
m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, rMax);
// Draw the profile.
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);

// Old SSS Model >>>
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
Vector4 halfRcpVarianceAndWeight1 = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4 * (1.0f - m_LerpWeight.floatValue));
Vector4 halfRcpVarianceAndWeight2 = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4 * m_LerpWeight.floatValue);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight1, halfRcpVarianceAndWeight1);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight2, halfRcpVarianceAndWeight2);
// <<< Old SSS Model
m_TransmittanceMaterial.SetVector(HDShaderIDs._ShapeParam, S);
m_TransmittanceMaterial.SetVector(HDShaderIDs._TransmissionTint, transmissionEnabled ? T : Vector4.zero);
m_TransmittanceMaterial.SetVector(HDShaderIDs._ThicknessRemap, R);
m_TransmittanceMaterial.SetVector("_ShapeParam", S);
m_TransmittanceMaterial.SetVector("_TransmissionTint", transmissionEnabled ? T : Vector4.zero);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", R);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
serializedObject.ApplyModifiedProperties();

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


protected virtual void BaseMaterialPropertiesGUI()
{
EditorGUILayout.LabelField(StylesBaseUnlit.optionText, EditorStyles.boldLabel);
GUILayout.Label(StylesBaseUnlit.optionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{

}
// This function must finish with double sided option (see LitUI.cs)
m_MaterialEditor.ShaderProperty(doubleSidedEnable, StylesBaseUnlit.doubleSidedEnableText);
EditorGUI.indentLevel--;
}
static public void SetKeyword(Material m, string keyword, bool state)

// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
//EditorGUI.indentLevel++;
BaseMaterialPropertiesGUI();
EditorGUILayout.Space();

DoEmissionArea(material);
GUILayout.Label(StylesBaseUnlit.advancedText, EditorStyles.boldLabel);
EditorGUILayout.Space();
EditorGUILayout.LabelField(StylesBaseUnlit.advancedText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUI.indentLevel--;
}
if (EditorGUI.EndChangeCheck())

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs


protected override void MaterialPropertiesGUI(Material material)
{
GUILayout.Label(Styles.InputsText, EditorStyles.boldLabel);
EditorGUILayout.LabelField(Styles.InputsText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(Styles.colorText, colorMap, color);

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader


//-------------------------------------------------------------------------------------
#include "../../../ShaderLibrary/common.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"

42
Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/CameraMotionVectors.shader


#include "../ShaderPass/VaryingMesh.hlsl"
#include "../ShaderPass/VertMesh.hlsl"
PackedVaryingsType Vert(AttributesMesh inputMesh)
float4 _CameraPosDiff;
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
};
Varyings Vert(Attributes input)
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return PackVaryingsType(varyingsType);
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
return output;
float4 Frag(PackedVaryingsToPS packedInput) : SV_Target
float4 Frag(Varyings input) : SV_Target
PositionInputs posInput = GetPositionInput(packedInput.vmesh.positionCS.xy, _ScreenSize.zw);
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float3 vPos = ComputeViewSpacePosition(posInput.positionSS, depth, _InvProjMatrix);
float4 worldPos = mul(unity_CameraToWorld, float4(vPos, 1.0));
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float4 worldPos = float4(posInput.positionWS, 1.0);
float4 prevPos = worldPos;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
prevPos -= _CameraPosDiff;
#endif
float4 prevClipPos = mul(_PrevViewProjMatrix, worldPos);
float4 curClipPos = mul(_ViewProjMatrix, worldPos);
float4 prevClipPos = mul(_PrevViewProjMatrix, prevPos);
float4 curClipPos = mul(_NonJitteredViewProjMatrix, worldPos);
#if UNITY_UV_STARTS_AT_TOP
previousPositionCS.y = 1.0 - previousPositionCS.y;
positionCS.y = 1.0 - positionCS.y;
#endif
return float4(positionCS - previousPositionCS, 0.0, 1.0);
}

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/HDRenderPipelineResources.asset


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

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

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs


instance.deferredShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.Shader");
instance.screenSpaceAmbientOcclusionShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.Shader");
instance.subsurfaceScatteringCS = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute");
instance.clearDispatchIndirectShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/cleardispatchindirect.compute");
instance.buildDispatchIndirectShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/builddispatchindirect.compute");

instance.buildPerVoxelLightListShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-clustered.compute");
instance.buildMaterialFlagsShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/materialflags.compute");
instance.shadeOpaqueShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/shadeopaque.compute");
instance.deferredComputeShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Deferred.compute");
// SceneSettings
// These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime (only to draw in editor)

// Lighting resources
public Shader deferredShader;
public Shader screenSpaceAmbientOcclusionShader;
public ComputeShader subsurfaceScatteringCS;
// Lighting tile pass resources
public ComputeShader clearDispatchIndirectShader;

public ComputeShader buildPerBigTileLightListShader;
public ComputeShader buildPerVoxelLightListShader; // clustered
public ComputeShader buildMaterialFlagsShader;
public ComputeShader shadeOpaqueShader;
public ComputeShader deferredComputeShader;
// SceneSettings
// These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime (only to draw in editor)

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


// N.b.: we multiply by the surface albedo of the actual geometry during shading.
// Apply gamma for visualization only. Do not apply gamma to the color.
return float4(pow(M, 1.0 / 3.0) * A, 1);
return float4(sqrt(M) * A, 1);
#else
float r = (2 * length(input.texcoord - 0.5)) * _MaxRadius * SSS_BASIC_DISTANCE_SCALE;
float3 var1 = _StdDev1.rgb * _StdDev1.rgb;

float3 magnitude = lerp(exp(-r * r / (2 * var1)) / (TWO_PI * var1),
exp(-r * r / (2 * var2)) / (TWO_PI * var2), _LerpWeight);
return float4(magnitude, 1);
// N.b.: we multiply by the surface albedo of the actual geometry during shading.
// Apply gamma for visualization only.
return float4(sqrt(magnitude), 1);
#endif
}
ENDHLSL

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


// Inputs & outputs
//-------------------------------------------------------------------------------------
uint _UseDisneySSS;
float4 _HalfRcpVarianceAndWeight1, _HalfRcpVarianceAndWeight2;
float4 _ShapeParam, _TransmissionTint, _ThicknessRemap;
//-------------------------------------------------------------------------------------

float4 Frag(Varyings input) : SV_Target
{
float d = (_ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x));
float3 T = ComputeTransmittance(_ShapeParam.rgb, float3(1, 1, 1), d, 1);
float3 T;
if (_UseDisneySSS)
{
T = ComputeTransmittance(_ShapeParam.rgb, float3(0.25, 0.25, 0.25), d, 1);
}
else
{
T = ComputeTransmittanceJimenez(_HalfRcpVarianceAndWeight1.rgb,
_HalfRcpVarianceAndWeight1.a,
_HalfRcpVarianceAndWeight2.rgb,
_HalfRcpVarianceAndWeight2.a,
float3(0.25, 0.25, 0.25), d, 1);
}
return float4(pow(T, 1.0 / 3) * _TransmissionTint.rgb, 1);
return float4(sqrt(T) * _TransmissionTint.rgb, 1);
}
ENDHLSL
}

3
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettings.cs


{
public CommonSettings commonSettings
{
set { m_CommonSettings = value; }
set { m_SkySettings = value; }
set { m_SsaoSettings = value; }
get { return m_SsaoSettings; }
}

11
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


#if SHADERPASS != SHADERPASS_FORWARD
#if SHADERPASS != SHADERPASS_FORWARD
#error SHADERPASS_is_not_correctly_define
#endif

PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
outColor = float4(0.0, 0.0, 0.0, 0.0);
// We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode != DEBUGLIGHTINGMODE_NONE)
#endif
{
uint featureFlags = 0xFFFFFFFF;
float3 diffuseLighting;
float3 specularLighting;

outColor = float4(diffuseLighting + specularLighting, builtinData.opacity);
}
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.depthRaw;

float3 result = float3(1.0, 0.0, 1.0);
bool needLinearToSRGB = false;
GetPropertiesDataDebug(_DebugViewMaterial, result, needLinearToSRGB);
GetVaryingsDataDebug(_DebugViewMaterial, input, result, needLinearToSRGB);
GetBuiltinDataDebug(_DebugViewMaterial, builtinData, result, needLinearToSRGB);
GetSurfaceDataDebug(_DebugViewMaterial, surfaceData, result, needLinearToSRGB);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassVelocity.hlsl


// It is not possible to correctly generate the motion vector for tesselated geometry as tessellation parameters can change
// from one frame to another (adaptative, lod) + in Unity we only receive information for one non tesselated vertex.
// So motion vetor will be based on interpolate previous position at vertex level instead.
varyingsType.vpass.positionCS = mul(_ViewProjMatrix, mul(unity_ObjectToWorld, float4(inputMesh.positionOS, 1.0)));
varyingsType.vpass.positionCS = mul(_NonJitteredViewProjMatrix, mul(unity_ObjectToWorld, float4(inputMesh.positionOS, 1.0)));
varyingsType.vpass.previousPositionCS = mul(_PrevViewProjMatrix, mul(unity_MatrixPreviousM, unity_MotionVectorsParams.x ? float4(inputPass.previousPositionOS, 1.0) : float4(inputMesh.positionOS, 1.0)));
return PackVaryingsType(varyingsType);

3
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


#ifndef UNITY_SHADER_VARIABLES_INCLUDED
#define UNITY_SHADER_VARIABLES_INCLUDED
#include "ShaderConfig.cs.hlsl"
// CAUTION:
// Currently the shaders compiler always include regualr Unity shaderVariables, so I get a conflict here were UNITY_SHADER_VARIABLES_INCLUDED is already define, this need to be fixed.
// As I haven't change the variables name yet, I simply don't define anything, and I put the transform function at the end of the file outside the guard header.

CBUFFER_START(UnityPerPass)
float4x4 _PrevViewProjMatrix;
float4x4 _ViewProjMatrix;
float4x4 _NonJitteredViewProjMatrix;
float4x4 _ViewMatrix;
float4x4 _ProjMatrix;
float4x4 _InvViewProjMatrix;

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs


public override void RenderSky(BuiltinSkyParameters builtinParams, SkySettings skyParameters, bool renderForCubemap)
{
m_SkyHDRIMaterial.SetTexture("_Cubemap", m_HdriSkyParams.skyHDRI);
m_SkyHDRIMaterial.SetVector("_SkyParam", new Vector4(m_HdriSkyParams.exposure, m_HdriSkyParams.multiplier, m_HdriSkyParams.rotation, 0.0f));
m_SkyHDRIMaterial.SetTexture(HDShaderIDs._Cubemap, m_HdriSkyParams.skyHDRI);
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_HdriSkyParams.exposure, m_HdriSkyParams.multiplier, m_HdriSkyParams.rotation, 0.0f));
builtinParams.commandBuffer.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, renderForCubemap ? 0 : 1);
}

191
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
//[CanEditMultipleObjects]
//[CustomEditor(typeof(ProceduralSkyParameters))]
//public class ProceduralSkyParametersEditor
// : Editor
//{
// private class Styles
// {
// public readonly GUIContent skyHDRI = new GUIContent("HDRI");
// public readonly GUIContent skyResolution = new GUIContent("Resolution");
// public readonly GUIContent skyExposure = new GUIContent("Exposure");
// public readonly GUIContent skyRotation = new GUIContent("Rotation");
// public readonly GUIContent skyMultiplier = new GUIContent("Multiplier");
// }
[CanEditMultipleObjects]
[CustomEditor(typeof(ProceduralSkySettings))]
public class ProceduralSkySettingsEditor : Editor
{
private float heightFogFalloff = 1.0f;
private float heightFogHeight = 0.0f;
private class Styles
{
public readonly GUIContent skyHDRI = new GUIContent("HDRI");
public readonly GUIContent skyResolution = new GUIContent("Resolution");
public readonly GUIContent skyExposure = new GUIContent("Exposure");
public readonly GUIContent skyRotation = new GUIContent("Rotation");
public readonly GUIContent skyMultiplier = new GUIContent("Multiplier");
public readonly GUIContent lightingOverride = new GUIContent("Lighting Override", "If a lighting override cubemap is provided, this cubemap will be used to compute lighting instead of the result from the visible sky.");
}
private static Styles s_Styles = null;
private static Styles styles
{
get
{
if (s_Styles == null)
s_Styles = new Styles();
return s_Styles;
}
}
private SerializedProperty m_SkyHDRI;
private SerializedProperty m_SkyResolution;
private SerializedProperty m_SkyExposure;
private SerializedProperty m_SkyMultiplier;
private SerializedProperty m_SkyRotation;
private SerializedProperty m_LightingOverride;
private SerializedProperty m_updateMode;
private SerializedProperty m_updatePeriod;
private SerializedProperty m_worldScaleExponent;
private SerializedProperty m_maxSkyDistance;
private SerializedProperty m_worldMieColorIntensity;
private SerializedProperty m_worldMieColorRamp;
private SerializedProperty m_worldMieDensity;
private SerializedProperty m_worldMieNearScatterPush;
private SerializedProperty m_worldMiePhaseAnisotropy;
private SerializedProperty m_worldRayleighColorIntensity;
private SerializedProperty m_worldRayleighColorRamp;
private SerializedProperty m_worldRayleighDensity;
private SerializedProperty m_worldRayleighNearScatterPush;
private SerializedProperty m_heightSeaLevel;
private SerializedProperty m_heightDistance;
private SerializedProperty m_heightMieDensity;
private SerializedProperty m_heightMieNearScatterPush;
private SerializedProperty m_heightRayleighColor;
private SerializedProperty m_heightRayleighDensity;
private SerializedProperty m_heightRayleighIntensity;
private SerializedProperty m_heightRayleighNearScatterPush;
void OnEnable()
{
m_SkyHDRI = serializedObject.FindProperty("skyHDRI");
m_SkyResolution = serializedObject.FindProperty("resolution");
m_SkyExposure = serializedObject.FindProperty("exposure");
m_SkyMultiplier = serializedObject.FindProperty("multiplier");
m_SkyRotation = serializedObject.FindProperty("rotation");
m_updateMode = serializedObject.FindProperty("updateMode");
m_updatePeriod = serializedObject.FindProperty("updatePeriod");
m_LightingOverride = serializedObject.FindProperty("lightingOverride");
m_maxSkyDistance = serializedObject.FindProperty("maxSkyDistance");
m_worldScaleExponent = serializedObject.FindProperty("worldScaleExponent");
m_worldMieColorIntensity = serializedObject.FindProperty("worldMieColorIntensity");
m_worldMieColorRamp = serializedObject.FindProperty("worldMieColorRamp");
m_worldMieDensity = serializedObject.FindProperty("worldMieDensity");
m_worldMieNearScatterPush = serializedObject.FindProperty("worldMieNearScatterPush");
m_worldMiePhaseAnisotropy = serializedObject.FindProperty("worldMiePhaseAnisotropy");
m_worldRayleighColorIntensity = serializedObject.FindProperty("worldRayleighColorIntensity");
m_worldRayleighColorRamp = serializedObject.FindProperty("worldRayleighColorRamp");
m_worldRayleighDensity = serializedObject.FindProperty("worldRayleighDensity");
m_worldRayleighNearScatterPush = serializedObject.FindProperty("worldRayleighNearScatterPush");
m_heightSeaLevel = serializedObject.FindProperty("heightSeaLevel");
m_heightDistance = serializedObject.FindProperty("heightDistance");
m_heightMieDensity = serializedObject.FindProperty("heightMieDensity");
m_heightMieNearScatterPush = serializedObject.FindProperty("heightMieNearScatterPush");
m_heightRayleighColor = serializedObject.FindProperty("heightRayleighColor");
m_heightRayleighDensity = serializedObject.FindProperty("heightRayleighDensity");
m_heightRayleighIntensity = serializedObject.FindProperty("heightRayleighIntensity");
m_heightRayleighNearScatterPush = serializedObject.FindProperty("heightRayleighNearScatterPush");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// private static Styles s_Styles = null;
// private static Styles styles
// {
// get
// {
// if (s_Styles == null)
// s_Styles = new Styles();
// return s_Styles;
// }
// }
EditorGUILayout.LabelField(new GUIContent("Skydome"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_SkyHDRI, styles.skyHDRI);
EditorGUILayout.PropertyField(m_SkyResolution, styles.skyResolution);
EditorGUILayout.PropertyField(m_SkyExposure, styles.skyExposure);
EditorGUILayout.PropertyField(m_SkyMultiplier, styles.skyMultiplier);
EditorGUILayout.PropertyField(m_SkyRotation, styles.skyRotation);
EditorGUILayout.PropertyField(m_updateMode);
EditorGUILayout.PropertyField(m_updatePeriod);
EditorGUILayout.PropertyField(m_LightingOverride, styles.lightingOverride);
EditorGUILayout.Space();
EditorGUILayout.LabelField(new GUIContent("Atmosphere"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_worldMieDensity, new GUIContent("Density"));
m_worldRayleighDensity.floatValue = m_worldMieDensity.floatValue;
EditorGUILayout.PropertyField(m_worldScaleExponent, new GUIContent("Global scale"));
EditorGUILayout.PropertyField(m_maxSkyDistance, new GUIContent("Sky distance"));
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_worldMieColorRamp);
EditorGUILayout.PropertyField(m_worldMieColorIntensity);
EditorGUILayout.PropertyField(m_worldMieNearScatterPush);
EditorGUILayout.PropertyField(m_worldMiePhaseAnisotropy);
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_worldRayleighColorRamp);
EditorGUILayout.PropertyField(m_worldRayleighColorIntensity);
//EditorGUILayout.PropertyField(m_worldRayleighDensity);
EditorGUILayout.PropertyField(m_worldRayleighNearScatterPush);
EditorGUILayout.Space();
EditorGUILayout.LabelField(new GUIContent("Height fog"), EditorStyles.boldLabel);
// private SerializedProperty m_SkyHDRI;
// private SerializedProperty m_SkyResolution;
// private SerializedProperty m_SkyExposure;
// private SerializedProperty m_SkyMultiplier;
// private SerializedProperty m_SkyRotation;
heightFogHeight = EditorGUILayout.FloatField(new GUIContent("Height"), heightFogHeight);
EditorGUILayout.PropertyField(m_heightDistance, new GUIContent("Falloff"));
// void OnEnable()
// {
// m_SkyHDRI = serializedObject.FindProperty("skyHDRI");
// m_SkyResolution = serializedObject.FindProperty("resolution");
// m_SkyExposure = serializedObject.FindProperty("exposure");
// m_SkyMultiplier = serializedObject.FindProperty("multiplier");
// m_SkyRotation = serializedObject.FindProperty("rotation");
// }
m_heightSeaLevel.floatValue = heightFogHeight + m_heightDistance.floatValue * 2.0f - 2.0f;
EditorGUILayout.PropertyField(m_heightMieDensity, new GUIContent("Density"));
m_heightRayleighDensity.floatValue = m_heightMieDensity.floatValue;
// public override void OnInspectorGUI()
// {
// serializedObject.Update();
EditorGUILayout.PropertyField(m_heightMieNearScatterPush);
EditorGUILayout.PropertyField(m_heightRayleighColor);
//EditorGUILayout.PropertyField(m_heightRayleighDensity);
EditorGUILayout.PropertyField(m_heightRayleighIntensity);
EditorGUILayout.PropertyField(m_heightRayleighNearScatterPush);
// EditorGUILayout.PropertyField(m_SkyHDRI, styles.skyHDRI);
// EditorGUILayout.PropertyField(m_SkyResolution, styles.skyResolution);
// EditorGUILayout.PropertyField(m_SkyExposure, styles.skyExposure);
// EditorGUILayout.PropertyField(m_SkyMultiplier, styles.skyMultiplier);
// EditorGUILayout.PropertyField(m_SkyRotation, styles.skyRotation);
//base.DrawDefaultInspector();
// serializedObject.ApplyModifiedProperties();
// }
//}
serializedObject.ApplyModifiedProperties();
}
}
}

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


m_SkyboxCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true; // Generate regular mipmap for filtered importance sampling
m_SkyboxCubemapRT.autoGenerateMips = false; // We will generate regular mipmap for filtered importance sampling manually
m_SkyboxCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxCubemapRT.Create();

Utilities.SetRenderTarget(builtinParams.commandBuffer, target, ClearFlag.ClearNone, 0, (CubemapFace)i);
m_Renderer.RenderSky(builtinParams, skySettings, true);
}
// Generate mipmap for our cubemap
Debug.Assert(target.autoGenerateMips == false);
builtinParams.commandBuffer.GenerateMips(target);
}
private void BlitCubemap(CommandBuffer cmd, Cubemap source, RenderTexture dest)

cmd.DrawProcedural(Matrix4x4.identity, m_BlitCubemapMaterial, 0, MeshTopology.Triangles, 3, 1, propertyBlock);
}
// Generate mipmap for our cubemap
Debug.Assert(dest.autoGenerateMips == false);
cmd.GenerateMips(dest);
}
private void RenderCubemapGGXConvolution(CommandBuffer cmd, BuiltinSkyParameters builtinParams, SkySettings skyParams, Texture input, RenderTexture target)

public void UpdateEnvironment(HDCamera camera, Light sunLight, CommandBuffer cmd)
{
// We need one frame delay for this update to work since DynamicGI.UpdateEnvironment is executed direclty but the renderloop is not (so we need to wait for the sky texture to be rendered first)
// 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))

m_UpdatedFramesRequired--;
m_SkyParametersHash = skySettings.GetHash();
m_CurrentUpdateTime = 0.0f;
#if UNITY_EDITOR
// In the editor when we change the sky we want to make the GI dirty so when baking again the new sky is taken into account.
// Changing the hash of the rendertarget allow to say that GI is dirty
m_SkyboxCubemapRT.imageContentsHash = new Hash128((uint)skySettings.GetHash(), 0, 0, 0);
#endif
if(m_SkyParametersHash != 0)
if (m_SkyParametersHash != 0)
{
using (new Utilities.ProfilingSample("Reset Sky Environment", cmd))
{

// Flip texture.
// Temporarily disabled until proper API reaches trunk
//Graphics.Blit(temp, tempRT, new Vector2(1.0f, -1.0f), new Vector2(0.0f, 0.0f));
Graphics.Blit(temp, tempRT);
Graphics.Blit(temp, tempRT, new Vector2(1.0f, -1.0f), new Vector2(0.0f, 0.0f));
result.ReadPixels(new Rect(0, 0, resolution * 6, resolution), 0, 0);
result.Apply();

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


public abstract class SkySettings : ScriptableObject
{
protected class Unhashed : System.Attribute {}
[Range(0,360)]
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;

15
Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs


using UnityEngine.Rendering;
using UnityObject = UnityEngine.Object;
using System.Reflection;
using UnityEngine.Rendering.PostProcessing;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

{
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

96
Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


using System;
using UnityEngine.Rendering;
using UnityEngine.XR;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
{

private RenderTargetIdentifier m_CameraRTID;
private bool m_RenderToIntermediateTarget = false;
private bool m_IntermediateTextureArray = false;
private const int kShadowDepthBufferBits = 16;
private const int kCameraDepthBufferBits = 32;

{
base.Render(context, cameras);
bool stereoEnabled = XRSettings.isDeviceActive;
if (!CullResults.GetCullingParameters(camera, out cullingParameters))
if (!CullResults.GetCullingParameters(camera, stereoEnabled, out cullingParameters))
continue;
cullingParameters.shadowDistance = Mathf.Min(m_ShadowSettings.maxShadowDistance, camera.farClipPlane);

lightData.shadowsRendered = RenderShadows(ref m_CullResults, ref visibleLights[lightData.shadowLightIndex], lightData.shadowLightIndex, ref context);
// Setup camera matrices and RT
context.SetupCameraProperties(camera);
context.SetupCameraProperties(camera, stereoEnabled);
// Setup light and shadow shader constants
SetupShaderLightConstants(visibleLights, ref lightData, ref m_CullResults, ref context);

if (!lightData.isSingleDirectionalLight)
configuration |= RendererConfiguration.PerObjectLightIndices8;
BeginForwardRendering(camera, ref context);
BeginForwardRendering(camera, ref context, stereoEnabled);
// Render Opaques
var litSettings = new DrawRendererSettings(m_CullResults, camera, m_LitPassName);

context.DrawRenderers(ref litSettings);
// Release temporary RT
var discardRT = CommandBufferPool.Get();
discardRT.ReleaseTemporaryRT(m_ShadowMapProperty);
discardRT.ReleaseTemporaryRT(m_CameraRTProperty);
context.ExecuteCommandBuffer(discardRT);
CommandBufferPool.Release(discardRT);
// TODO: Check skybox shader
context.DrawSkybox(camera);

context.DrawRenderers(ref litSettings);
context.DrawRenderers(ref unlitSettings);
EndForwardRendering(camera, ref context);
EndForwardRendering(camera, ref context, stereoEnabled);
// Release temporary RT
var discardRT = CommandBufferPool.Get();
discardRT.ReleaseTemporaryRT(m_ShadowMapProperty);
discardRT.ReleaseTemporaryRT(m_CameraRTProperty);
context.ExecuteCommandBuffer(discardRT);
CommandBufferPool.Release(discardRT);
}
context.Submit();

return (type == LightType.Directional || type == LightType.Spot);
}
private void BeginForwardRendering(Camera camera, ref ScriptableRenderContext context)
private void BeginForwardRendering(Camera camera, ref ScriptableRenderContext context, bool stereoEnabled)
if (stereoEnabled)
context.StartMultiEye(camera);
m_RenderToIntermediateTarget = GetRenderToIntermediateTarget(camera);
var cmd = CommandBufferPool.Get("SetCameraRenderTarget");

{
cmd.GetTemporaryRT(m_CameraRTProperty, Screen.width, Screen.height, kCameraDepthBufferBits,
FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, m_Asset.MSAASampleCount);
cmd.SetRenderTarget(m_CameraRTID);
m_IntermediateTextureArray = false;
if (stereoEnabled)
{
RenderTextureDescriptor xrDesc = XRSettings.eyeTextureDesc;
xrDesc.depthBufferBits = kCameraDepthBufferBits;
xrDesc.colorFormat = RenderTextureFormat.ARGB32;
xrDesc.msaaSamples = m_Asset.MSAASampleCount;
m_IntermediateTextureArray = (xrDesc.dimension == TextureDimension.Tex2DArray);
cmd.GetTemporaryRT(m_CameraRTProperty, xrDesc, FilterMode.Bilinear);
}
else
{
cmd.GetTemporaryRT(m_CameraRTProperty, Screen.width, Screen.height, kCameraDepthBufferBits,
FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, m_Asset.MSAASampleCount);
}
if (m_IntermediateTextureArray)
cmd.SetRenderTarget(m_CameraRTID, 0, CubemapFace.Unknown, -1);
else
cmd.SetRenderTarget(m_CameraRTID);
}
else
{

else
{
cmd.SetRenderTarget(BuiltinRenderTextureType.None);
cmd.SetRenderTarget(BuiltinRenderTextureType.CurrentActive);
cmd.ClearRenderTarget(camera.clearFlags == CameraClearFlags.Color, camera.clearFlags == CameraClearFlags.Color || camera.clearFlags == CameraClearFlags.Depth, camera.backgroundColor);
{
bool clearDepth = (camera.clearFlags != CameraClearFlags.Nothing);
bool clearColor = (camera.clearFlags == CameraClearFlags.Color);
cmd.ClearRenderTarget(clearDepth, clearColor, camera.backgroundColor);
}
private void EndForwardRendering(Camera camera, ref ScriptableRenderContext context)
private void EndForwardRendering(Camera camera, ref ScriptableRenderContext context, bool stereoEnabled)
if (!m_RenderToIntermediateTarget)
return;
if (m_RenderToIntermediateTarget)
{
var cmd = CommandBufferPool.Get("Blit");
if (m_IntermediateTextureArray)
{
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, 0, CubemapFace.Unknown, -1);
cmd.Blit(m_CameraRTID, BuiltinRenderTextureType.CurrentActive);
}
else
cmd.Blit(BuiltinRenderTextureType.CurrentActive, BuiltinRenderTextureType.CameraTarget);
if (camera.cameraType == CameraType.SceneView)
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
var cmd = CommandBufferPool.Get("Blit");
cmd.Blit(BuiltinRenderTextureType.CurrentActive, BuiltinRenderTextureType.CameraTarget);
if (camera.cameraType == CameraType.SceneView)
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
if (stereoEnabled)
{
context.StopMultiEye(camera);
context.StereoEndRender(camera);
}
}
private bool GetRenderToIntermediateTarget(Camera camera)

7
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader


// Shader targeted for low end devices. Single Pass Forward Rendering. Shader Model 2
// Shader targeted for low end devices. Single Pass Forward Rendering. Shader Model 2
Shader "ScriptableRenderPipeline/LightweightPipeline/NonPBR"
{

#pragma shader_feature _EMISSION
#pragma shader_feature _ _REFLECTION_CUBEMAP _REFLECTION_PROBE
#pragma multi_compile _ LIGHTWEIGHT_LINEAR
#pragma multi_compile _ LIGHTWEIGHT_LINEAR
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ _LIGHT_PROBES_ON

v2f vert(LightweightVertexInput v)
{
v2f o = (v2f)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.uv01.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv01.zw = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;

2
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc


float4 tangent : TANGENT;
float3 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f

half4 viewDir : TEXCOORD5; // xyz: viewDir
UNITY_FOG_COORDS_PACKED(6, half4) // x: fogCoord, yzw: vertexColor
float4 hpos : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
// Per object light list data

7
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightUnlit.shader


CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma multi_compile_fog
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON

{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f

float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;

v2f vert(appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);

1
Assets/ScriptableRenderPipeline/ShaderLibrary/API/D3D11.hlsl


#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define SAMPLER2D(samplerName) SamplerState samplerName
#define SAMPLERCUBE(samplerName) SamplerState samplerName

1
Assets/ScriptableRenderPipeline/ShaderLibrary/API/Metal.hlsl


#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define SAMPLER2D(samplerName) SamplerState samplerName
#define SAMPLERCUBE(samplerName) SamplerState samplerName

1
Assets/ScriptableRenderPipeline/ShaderLibrary/API/PSSL.hlsl


#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName
#define SAMPLER2D(samplerName) SamplerState samplerName
#define SAMPLERCUBE(samplerName) SamplerState samplerName

21
Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl


float a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
float b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
// Replacing max() with saturate() results in a 12 cycle SGPR forwarding stall on PS4.
return max(INV_PI * (a * sinSqSigma + b), 0); // (a/Pi)*x+(b/Pi)
return saturate(INV_PI * (a * sinSqSigma + b));
}
#endif
#endif

return isfinite(sum) ? sum : 0.0;
#endif
}
// For polygonal lights.
float LTCEvaluate(float4x3 L, float3 V, float3 N, float NdotV, float3x3 invM)
{
// Construct a view-dependent orthonormal basis around N.
// TODO: it could be stored in PreLightData, since all LTC lights compute it more than once.
float3x3 basis;
basis[0] = normalize(V - N * NdotV);
basis[1] = normalize(cross(N, basis[0]));
basis[2] = N;
// rotate area light in local basis
invM = mul(transpose(basis), invM);
L = mul(L, invM);
// Polygon irradiance in the transformed configuration
return PolygonIrradiance(L);
}
float LineFpo(float tLDDL, float lrcpD, float rcpD)

33
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


// headers from ShaderLibrary do not include "common.hlsl", this should be included in the .shader using it (or Material.hlsl)
// Rules: When doing an array for constant buffer variables, we always use float4 to avoid any packing issue, particularly between compute shader and pixel shaders
// i.e don't use SetGlobalFloatArray or SetComputeFloatParams
// The array can be alias in hlsl. Exemple:
// uniform float4 packedArray[3];
// static float unpackedArray[12] = (float[12]packedArray;
// Include language header
#if defined(SHADER_API_D3D11)

#error unsupported shader api
#endif
#include "API/Validate.hlsl"
#include "Noise.hlsl"
// Some shader compiler don't support to do multiple ## for concatenation inside the same macro, it require an indirection.
// This is the purpose of this macro

#define INV_FOUR_PI 0.07957747155
#define HALF_PI 1.57079632679
#define INV_HALF_PI 0.636619772367
#define INFINITY asfloat(0x7F800000)
#define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0
#define FLT_MIN 1.175494351e-38 // Minimum representable positive floating-point number

return rad * 180.0 / PI;
}
// Square functions for cleaner code
float Sqr(float x)
{
return x * x;
}
float3 Sqr(float3 x)
{
return x * x;
}
// Acos in 14 cycles.
// Ref: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
float FastACos(float inX)

}
// Same as smoothstep except it assume 0, 1 interval for x
float smoothstep01(float x)
float Smoothstep01(float x)
{
return x * x * (3.0 - (2.0 * x));
}

}
// LOD dithering transition helper
// ditherFactor should be a quantized value between 0..15/16, i.e the one provide by Unity
// LOD1 must use this functoin with ditherFactor 0..1
// LOD1 must use this function with ditherFactor 0..1
// Generate a fixed pattern
float p = cos(dot(unPositionSS, float2(443.8975, 397.2973)));
p = frac(p * 491.1871);
// Generate a spatially varying pattern.
// Unfortunately, varying the pattern with time confuses the TAA, increasing the amount of noise.
float p = GenerateHashedRandomFloat(unPositionSS);
p = (ditherFactor >= 0.5) ? (15.0 / 16.0) - p : p;
p = (ditherFactor >= 0.5) ? p : 1 - p;
clip(ditherFactor - p);
}

28
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl


float PerceptualSmoothnessToRoughness(float perceptualSmoothness)
{
return (1 - perceptualSmoothness) * (1 - perceptualSmoothness);
return (1.0 - perceptualSmoothness) * (1.0 - perceptualSmoothness);
return (1 - perceptualSmoothness);
return (1.0 - perceptualSmoothness);
}
// ----------------------------------------------------------------------------

// Computes the fraction of light passing through the object.
// Evaluate Int{0, inf}{2 * Pi * r * R(sqrt(r^2 + d^2))}, where R is the diffusion profile.
// Note: 'volumeAlbedo' should be premultiplied by 0.25.
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar (BSSRDF only).
float3 ComputeTransmittance(float3 S, float3 volumeAlbedo, float thickness, float radiusScale)
{

float3 expOneThird = exp(((-1.0 / 3.0) * thickness) * S);
return 0.25 * (expOneThird + 3 * expOneThird * expOneThird * expOneThird) * volumeAlbedo;
// Premultiply & optimize: T = (1/4 * A) * (e^(-t * S) + 3 * e^(-1/3 * t * S))
return volumeAlbedo * (expOneThird * expOneThird * expOneThird + 3 * expOneThird);
}
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians.
// Ref: Real-Time Realistic Skin Translucency (2010), equation 9 (modified).
// Note: 'volumeAlbedo' should be premultiplied by 0.25, correspondingly 'lerpWeight' by 4,
// and 'halfRcpVariance1' should be prescaled by (0.1 * SssConstants.SSS_BASIC_DISTANCE_SCALE)^2.
float3 ComputeTransmittanceJimenez(float3 halfRcpVariance1, float lerpWeight1,
float3 halfRcpVariance2, float lerpWeight2,
float3 volumeAlbedo, float thickness, float radiusScale)
{
// Thickness and SSS radius are decoupled for artists.
// In theory, we should modify the thickness by the inverse of the radius scale of the profile.
// thickness /= radiusScale;
float t2 = thickness * thickness;
// T = A * lerp(exp(-t2 * halfRcpVariance1), exp(-t2 * halfRcpVariance2), lerpWeight2)
return volumeAlbedo * (exp(-t2 * halfRcpVariance1) * lerpWeight1 + exp(-t2 * halfRcpVariance2) * lerpWeight2);
return saturate((-NdotL + w) / ((1 + w) * (1 + w)));
return saturate((NdotL + w) / ((1 + w) * (1 + w)));
}
// MACRO from Legacy Untiy

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

正在加载...
取消
保存