Evgenii Golubev 7 年前
当前提交
5bf0af64
共有 29 个文件被更改,包括 598 次插入589 次删除
  1. 20
      Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  2. 2
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs
  3. 42
      Assets/ScriptableRenderPipeline/Fptl/ClusteredUtils.h
  4. 41
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  5. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  6. 14
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  7. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  8. 42
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ClusteredUtils.hlsl
  9. 18
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  10. 287
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  11. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  12. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  13. 199
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  14. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  15. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  16. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  17. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  18. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs
  19. 68
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  20. 70
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  21. 327
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  22. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit
  23. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader.meta
  24. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  25. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader.meta
  26. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  27. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs.meta
  28. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  29. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit.meta

20
Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs


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

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)

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


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

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

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


public float debugOverlayRatio = 0.33f;
public FullScreenDebugMode fullScreenDebugMode = FullScreenDebugMode.None;
public MaterialDebugSettings materialDebugSettings = new MaterialDebugSettings();
public LightingDebugSettings lightingDebugSettings = new LightingDebugSettings();

public static int[] debugViewMaterialPropertiesValues = null;
public static GUIContent[] debugViewMaterialGBufferStrings = null;
public static int[] debugViewMaterialGBufferValues = null;
public static GUIContent[] lightingFullScreenDebugStrings = null;
public static int[] lightingFullScreenDebugValues = null;
public static GUIContent[] renderingFullScreenDebugStrings = null;
public static int[] renderingFullScreenDebugValues = null;
public DebugDisplaySettings()
{

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<bool>("Rendering", "Display Transparency",() => renderingDebugSettings.displayTransparentObjects, (value) => renderingDebugSettings.displayTransparentObjects = (bool)value);
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Enable Distortion",() => renderingDebugSettings.enableDistortion, (value) => renderingDebugSettings.enableDistortion = (bool)value);
DebugMenuManager.instance.AddDebugItem<bool>("Rendering", "Enable Subsurface Scattering",() => renderingDebugSettings.enableSSSAndTransmission, (value) => renderingDebugSettings.enableSSSAndTransmission = (bool)value);
DebugMenuManager.instance.AddDebugItem<int>("Rendering", kFullScreenDebugMode, () => (int)fullScreenDebugMode, (value) => fullScreenDebugMode = (FullScreenDebugMode)value, DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.renderingFullScreenDebugStrings, DebugDisplaySettings.renderingFullScreenDebugValues));
}
public void OnValidate()

FillWithPropertiesEnum(typeof(Attributes.DebugViewGbuffer), debugViewMaterialGBufferStrings, debugViewMaterialGBufferValues, "", ref index);
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
{

public enum FullScreenDebugMode
{
None,
// Lighting
MinLightingFullScreenDebug,
MaxLightingFullScreenDebug,
// Rendering
MinRenderingFullScreenDebug,
NanTracker
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;

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


// UnityEngine.Experimental.Rendering.HDPipeline.FullScreenDebugMode: static fields
//
#define FULLSCREENDEBUGMODE_NONE (0)
#define FULLSCREENDEBUGMODE_SSAO (1)
#define FULLSCREENDEBUGMODE_SSAOBEFORE_FILTERING (2)
#define FULLSCREENDEBUGMODE_MOTION_VECTORS (3)
#define FULLSCREENDEBUGMODE_NAN_TRACKER (4)
#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

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


foreach (Object obj in materials)
{
Material mat = obj as Material;
if (mat.shader.name == "HDRenderPipeline/InfluenceLayeredLit" || mat.shader.name == "HDRenderPipeline/InfluenceLayeredLitTessellation")
if (mat.shader.name == "HDRenderPipeline/LayeredLit" || mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
InfluenceLayeredLitGUI.SynchronizeAllLayers(mat);
LayeredLitGUI.SynchronizeAllLayers(mat);
EditorUtility.SetDirty(mat);
}
}

string.Format("{0} / {1} materials cleaned.", i, length),
i / (float)(length - 1));
if (mat.shader.name == "HDRenderPipeline/InfluenceLayeredLit" || mat.shader.name == "HDRenderPipeline/InfluenceLayeredLitTessellation")
if (mat.shader.name == "HDRenderPipeline/LayeredLit" || mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
InfluenceLayeredLitGUI.SetupMaterialKeywordsAndPass(mat);
LayeredLitGUI.SetupMaterialKeywordsAndPass(mat);
EditorUtility.SetDirty(mat);
}
else if (mat.shader.name == "HDRenderPipeline/Lit" || mat.shader.name == "HDRenderPipeline/LitTessellation")

Object[] materials = Resources.FindObjectsOfTypeAll<Material>();
Shader litShader = Shader.Find("HDRenderPipeline/Lit");
Shader layeredLitShader = Shader.Find("HDRenderPipeline/InfluenceLayeredLit");
Shader layeredLitShader = Shader.Find("HDRenderPipeline/LayeredLit");
foreach (Object obj in materials)
{

LitGUI.SetupMaterialKeywordsAndPass(mat);
EditorUtility.SetDirty(mat);
}
else if (mat.shader.name == "HDRenderPipeline/InfluenceLayeredLitTessellation")
else if (mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
InfluenceLayeredLitGUI.SetupMaterialKeywordsAndPass(mat);
LayeredLitGUI.SetupMaterialKeywordsAndPass(mat);
EditorUtility.SetDirty(mat);
}
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


public void PushFullScreenDebugTexture(CommandBuffer cb, int textureID, Camera camera, ScriptableRenderContext renderContext, FullScreenDebugMode debugMode)
{
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);

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)
m_DebugFullScreen.SetFloat(HDShaderIDs._FullScreenDebugMode, (float)m_DebugDisplaySettings.lightingDebugSettings.fullScreenDebugMode);
m_DebugFullScreen.SetFloat(HDShaderIDs._FullScreenDebugMode, (float)m_DebugDisplaySettings.fullScreenDebugMode);
Utilities.DrawFullScreen(cmd, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
}

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

18
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 kMaterialID = "_MaterialID";
protected const string kStencilRef = "_StencilRef";
protected MaterialProperty horizonFade = null;
protected const string kHorizonFade = "_HorizonFade";
// Wind
protected MaterialProperty windEnable = null;

depthOffsetEnable = FindProperty(kDepthOffsetEnable, props);
// MaterialID
materialID = FindProperty(kMaterialID, props, false); // InfluenceLayeredLit is force to be standard for now, so materialID could not exist
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);

{
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++;

287
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 specularColorText = new GUIContent("Specular Color", "Specular color (RGB)");
// Emissive
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 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);
// 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);
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);
// 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);

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

protected void ShaderAnisoInputGUI()
{
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:

Debug.Assert(false, "Encountered an unsupported MaterialID.");
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);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMapNormalText, detailMap);
EditorGUILayout.LabelField(Styles.detailText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMapNormalText, detailMap[layerIndex]);
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
}

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


float3 specularFGD; // Store preconvoled BRDF for both specular and diffuse
float diffuseFGD;
// Area lights (17 VGPRs). Scalarize?
// Area lights (17 VGPRs)
float3x3 orthoBasisViewNormal; // Right-handed view-dependent orthogonal basis around the normal (6x VGPRs)
float3x3 ltcTransformDiffuse; // Inverse transformation for Lambertian or Disney Diffuse (4x VGPRs)
float3x3 ltcTransformSpecular; // Inverse transformation for GGX (4x VGPRs)

4
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" {}

[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
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0

199
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

#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]

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

ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
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);

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


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

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

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


// w - inside tessellation factor
float3 GetTessellationDisplacement(VaryingsMeshToDS input)
{
// This call will work for both InfluenceLayeredLit and Lit shader
// This call will work for both LayeredLit and Lit shader
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(

4
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" {}

[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
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0

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

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


Shader "HDRenderPipeline/InfluenceLayeredLitTessellation"
Shader "HDRenderPipeline/LayeredLitTessellation"
{
Properties
{

_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
// 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
_HeightCenterOffset0("_HeightCenterOffset0", Float) = 0.0
_HeightCenterOffset1("_HeightCenterOffset1", Float) = 0.0
_HeightCenterOffset2("_HeightCenterOffset2", Float) = 0.0
_HeightCenterOffset3("_HeightCenterOffset3", Float) = 0.0
_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 _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
_HeightTransition("Height Transition", Range(0, 1.0)) = 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 InfluenceLayeredLitUI.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

}
}
CustomEditor "Experimental.Rendering.HDPipeline.InfluenceLayeredLitGUI"
CustomEditor "Experimental.Rendering.HDPipeline.LayeredLitGUI"
}

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


Shader "HDRenderPipeline/InfluenceLayeredLit"
Shader "HDRenderPipeline/LayeredLit"
{
Properties
{

_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
// 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
_HeightCenterOffset0("_HeightCenterOffset0", Float) = 0.0
_HeightCenterOffset1("_HeightCenterOffset1", Float) = 0.0
_HeightCenterOffset2("_HeightCenterOffset2", Float) = 0.0
_HeightCenterOffset3("_HeightCenterOffset3", Float) = 0.0
_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 _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
_HeightTransition("Height Transition", Range(0, 1.0)) = 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 InfluenceLayeredLitUI.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

}
}
CustomEditor "Experimental.Rendering.HDPipeline.InfluenceLayeredLitGUI"
CustomEditor "Experimental.Rendering.HDPipeline.LayeredLitGUI"
}

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


namespace UnityEditor.Experimental.Rendering.HDPipeline
{
internal class InfluenceLayeredLitGUI : LitGUI
internal class LayeredLitGUI : LitGUI
{
public enum LayerUVBaseMapping
{

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

{
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;
// influence
if (layerIndex > 0)
{
int paramIndex = layerIndex - 1;
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
m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
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);
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 useDensityModeEnable = useDensityMode.floatValue != 0.0f;
if (useDensityModeEnable)
{
EditorGUILayout.LabelField(styles.densityOpacityInfluenceText, EditorStyles.boldLabel);
if(heightBasedBlend)
{
m_MaterialEditor.ShaderProperty(heightOffset[layerIndex], styles.heightOffset);
}
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
m_MaterialEditor.ShaderProperty(minimumOpacity[layerIndex], styles.minimumOpacityText);
}
// 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);
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--;
EditorGUILayout.Space();
// influence
if (layerIndex > 0)
{
int paramIndex = layerIndex - 1;
bool heightBasedBlendEnable = useHeightBasedBlend.floatValue > 0.0f;
if (heightBasedBlendEnable)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(blendUsingHeight[paramIndex], styles.blendUsingHeight);
EditorGUI.indentLevel--;
}
if (mainLayerInfluenceEnable)
{
EditorGUILayout.LabelField(styles.mainLayerInfluenceText, EditorStyles.boldLabel);
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);
}

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/InfluenceLayeredLitTessellation.shader.meta → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader.meta

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/InfluenceLayeredLitTessellation.shader → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/InfluenceLayeredLit.shader.meta → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader.meta

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/InfluenceLayeredLit.shader → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/InfluenceLayeredLitUI.cs.meta → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs.meta

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/InfluenceLayeredLitUI.cs → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit.meta → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit.meta

正在加载...
取消
保存