浏览代码

HDRenderLoop: Large refactor to add Triplanar and detail map on LayeredLit

/main
Sebastien Lagarde 8 年前
当前提交
87a19817
共有 8 个文件被更改,包括 654 次插入429 次删除
  1. 235
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
  2. 112
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  3. 263
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs
  4. 50
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader
  5. 250
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl
  6. 24
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl
  7. 139
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl
  8. 10
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl

235
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs


{
internal class LayeredLitGUI : LitGUI
{
public enum LayerMapping
public enum LayerUVBaseMapping
UV3,
//Triplanar,
Triplanar,
}
public enum LayerUVDetailMapping
{
UV0,
UV1,
UV3
private class Styles
private class StylesLayer
{
public readonly GUIContent[] layerLabels =
{

new GUIContent("Layer 3"),
};
public readonly GUIContent materialLayer = new GUIContent("Material");
public readonly GUIContent syncButton = new GUIContent("Re-Synchronize Layers", "Re-synchronize all layers's properties with the referenced Material");
public readonly GUIContent layers = new GUIContent("Layers");
public readonly GUIContent emission = new GUIContent("Emissive");
public readonly GUIContent layerMapMask = new GUIContent("Layer Mask", "Layer mask (multiplied by vertex color if enabled)");
public readonly GUIContent layerMapVertexColor = new GUIContent("Use Vertex Color", "Layer mask (multiplied by layer mask if enabled)");
public readonly GUIContent layerCount = new GUIContent("Layer Count", "Number of layers.");
public readonly GUIContent layerSize = new GUIContent("Size", "Size of the layer mapping in world units.");
public readonly GUIContent layerMapping = new GUIContent("Mapping", "Mapping mode of the layer.");
public readonly GUIContent materialLayerText = new GUIContent("Material");
public readonly GUIContent syncButtonText = new GUIContent("Re-Synchronize Layers", "Re-synchronize all layers's properties with the referenced Material");
public readonly GUIContent layersText = new GUIContent("Layers");
public readonly GUIContent emissiveText = new GUIContent("Emissive");
public readonly GUIContent layerMapMaskText = new GUIContent("Layer Mask", "Layer mask (multiplied by vertex color if enabled)");
public readonly GUIContent layerMapVertexColorText = new GUIContent("Use Vertex Color", "Layer mask (multiplied by layer mask if enabled)");
public readonly GUIContent layerCountText = new GUIContent("Layer Count", "Number of layers.");
public readonly GUIContent layerTexWorldScaleText = new GUIContent("Tex world scale", "Scale to apply to world position for Planar/Trilinear");
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.");
static Styles s_Styles = null;
private static Styles styles { get { if (s_Styles == null) s_Styles = new Styles(); return s_Styles; } }
static StylesLayer s_Styles = null;
private static StylesLayer styles { get { if (s_Styles == null) s_Styles = new StylesLayer(); return s_Styles; } }
// Needed for json serialization to work
[Serializable]

}
private const int kMaxLayerCount = 4;
private const int kSyncButtonWidth = 58;
private const string kLayerMaskMap = "_LayerMaskMap";
private const string kLayerMaskVertexColor = "_LayerMaskVertexColor";
private const string kLayerCount = "_LayerCount";
private const string kLayerMapping = "_LayerMapping";
private const string kLayerSize = "_LayerSize";
const int kMaxLayerCount = 4;
const int kSyncButtonWidth = 58;
private Material[] m_MaterialLayers = new Material[kMaxLayerCount];
Material[] m_MaterialLayers = new Material[kMaxLayerCount];
MaterialProperty layerCountProperty = null;
MaterialProperty layerMaskMapProperty = null;
MaterialProperty layerMaskVertexColorProperty = null;
MaterialProperty[] layerMappingProperty = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerSizeProperty = new MaterialProperty[kMaxLayerCount];
MaterialProperty layerMaskMap = null;
const string kLayerMaskMap = "_LayerMaskMap";
MaterialProperty layerMaskVertexColor = null;
const string kLayerMaskVertexColor = "_LayerMaskVertexColor";
MaterialProperty layerCount = null;
const string kLayerCount = "_LayerCount";
MaterialProperty[] layerTexWorldScale = new MaterialProperty[kMaxLayerCount];
const string kLayerTexWorldScale = "_TexWorldScale";
MaterialProperty[] layerUVBase = new MaterialProperty[kMaxLayerCount];
const string kLayerUVBase = "_UVBase";
MaterialProperty[] layerUVMappingMask = new MaterialProperty[kMaxLayerCount];
const string kLayerUVMappingMask = "_UVMappingMask";
MaterialProperty[] layerUVDetail = new MaterialProperty[kMaxLayerCount];
const string kLayerUVDetail = "_UVDetail";
MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
const string kLayerUVDetailsMappingMask = "_UVDetailsMappingMask";
int layerCount
private void FindLayerProperties(MaterialProperty[] props)
set { layerCountProperty.floatValue = (float)value; }
get { return (int)layerCountProperty.floatValue; }
layerMaskMap = FindProperty(kLayerMaskMap, props);
layerMaskVertexColor = FindProperty(kLayerMaskVertexColor, props);
layerCount = FindProperty(kLayerCount, props);
for (int i = 0; i < numLayer; ++i)
{
layerTexWorldScale[i] = FindProperty(string.Format("{0}{1}", kLayerTexWorldScale, i), props);
layerUVBase[i] = FindProperty(string.Format("{0}{1}", kLayerUVBase, i), props);
layerUVMappingMask[i] = FindProperty(string.Format("{0}{1}", kLayerUVMappingMask, i), props);
layerUVDetail[i] = FindProperty(string.Format("{0}{1}", kLayerUVDetail, i), props);
layerUVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kLayerUVDetailsMappingMask, i), props);
}
}
int numLayer
{
set { layerCount.floatValue = (float)value; }
get { return (int)layerCount.floatValue; }
for (int i = 0; i < layerCount; ++i)
for (int i = 0; i < numLayer; ++i)
{
SynchronizeLayerProperties(i);
}

{
bool result = true;
outValueNames = "";
for (int i = 0; i < layerCount; ++i)
for (int i = 0; i < numLayer; ++i)
{
Material layer = m_MaterialLayers[i];
if (layer != null)

outValueNames += shortNames[currentValue] + " ";
for (int j = i + 1; j < layerCount; ++j)
for (int j = i + 1; j < numLayer; ++j)
{
Material otherLayer = m_MaterialLayers[j];
if (otherLayer != null)

{
bool result = true;
outValueNames = "";
for (int i = 0; i < layerCount; ++i)
for (int i = 0; i < numLayer; ++i)
{
Material layer = m_MaterialLayers[i];
if (layer != null)

for (int j = i + 1; j < layerCount; ++j)
for (int j = i + 1; j < numLayer; ++j)
{
Material otherLayer = m_MaterialLayers[j];
if (otherLayer != null)

{
string optionValueNames = "";
// We need to check consistency between all layers.
// Each input options and each input maps might can result in different #defines in the shader so all of them need to be consistent
// Each input options and each input maps can result in different #defines in the shader so all of them need to be consistent
string[] emissiveModeShortNames = { "Color", "Mask" };
string[] detailModeShortNames = { "DNormal", "DAOHeight" };
if (!CheckInputOptionConsistency(kSmoothnessTextureChannelProp, smoothnessSourceShortNames, ref optionValueNames))
if (!CheckInputOptionConsistency(kSmoothnessTextureChannel, smoothnessSourceShortNames, ref optionValueNames))
}
if (!CheckInputOptionConsistency(kEmissiveColorMode, emissiveModeShortNames, ref optionValueNames))
{
warningInputOptions += "Emissive Mode: " + optionValueNames + "\n";
}
if (!CheckInputOptionConsistency(kNormalMapSpace, normalMapShortNames, ref optionValueNames))
{

{
warningInputOptions += "Height Map Mode: " + optionValueNames + "\n";
}
if (!CheckInputOptionConsistency(kDetailMapMode, detailModeShortNames, ref optionValueNames))
{
warningInputOptions += "Detail Map Mode: " + optionValueNames + "\n";
}
if (warningInputOptions != string.Empty)
{

if (!CheckInputMapConsistency(kNormalMap, ref optionValueNames))
{
warningInputMaps += "Normal Map: " + optionValueNames + "\n";
}
if (!CheckInputMapConsistency(kDetailMap, ref optionValueNames))
{
warningInputMaps += "Detail Map: " + optionValueNames + "\n";
if (!CheckInputMapConsistency(kspecularOcclusionMap, ref optionValueNames))
if (!CheckInputMapConsistency(kSpecularOcclusionMap, ref optionValueNames))
}
if (!CheckInputMapConsistency(kEmissiveColorMap, ref optionValueNames))
{
warningInputMaps += "Emissive Color Map: " + optionValueNames + "\n";
}
if (!CheckInputMapConsistency(kHeightMap, ref optionValueNames))
{

// We synchronize input options with the firsts non null Layer (all layers should have consistent options)
Material firstLayer = null;
int i = 0;
while (i < layerCount && !(firstLayer = m_MaterialLayers[i])) ++i;
while (i < numLayer && !(firstLayer = m_MaterialLayers[i])) ++i;
material.SetFloat(kSmoothnessTextureChannelProp, firstLayer.GetFloat(kSmoothnessTextureChannelProp));
material.SetFloat(kEmissiveColorMode, firstLayer.GetFloat(kEmissiveColorMode));
material.SetFloat(kSmoothnessTextureChannel, firstLayer.GetFloat(kSmoothnessTextureChannel));
// Force emissive to be emissive color
material.SetFloat(kEmissiveColorMode, (float)EmissiveColorMode.UseEmissiveColor);
}
}

EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
m_MaterialLayers[layerIndex] = EditorGUILayout.ObjectField(styles.materialLayer, m_MaterialLayers[layerIndex], typeof(Material), true) as Material;
m_MaterialLayers[layerIndex] = EditorGUILayout.ObjectField(styles.materialLayerText, m_MaterialLayers[layerIndex], typeof(Material), true) as Material;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(materialImporter, "Change layer material");

EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(layerMappingProperty[layerIndex], styles.layerMapping);
m_MaterialEditor.ShaderProperty(layerUVBase[layerIndex], styles.UVBaseText);
if ((LayerMapping)layerMappingProperty[layerIndex].floatValue == LayerMapping.Planar)
if (((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Planar) ||
((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Triplanar))
m_MaterialEditor.ShaderProperty(layerSizeProperty[layerIndex], styles.layerSize);
m_MaterialEditor.ShaderProperty(layerTexWorldScale[layerIndex], styles.layerTexWorldScaleText);
else
{
EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(layerUVDetail[layerIndex], styles.UVDetailText);
if (EditorGUI.EndChangeCheck())
{
result = true;
}
}
EditorGUI.indentLevel--;

GUI.changed = false;
EditorGUI.indentLevel++;
GUILayout.Label(styles.layers, EditorStyles.boldLabel);
GUILayout.Label(styles.layersText, EditorStyles.boldLabel);
int newLayerCount = EditorGUILayout.IntSlider(styles.layerCount, (int)layerCountProperty.floatValue, 2, 4);
int newLayerCount = EditorGUILayout.IntSlider(styles.layerCountText, (int)layerCount.floatValue, 2, 4);
layerCountProperty.floatValue = (float)newLayerCount;
layerCount.floatValue = (float)newLayerCount;
m_MaterialEditor.ShaderProperty(layerMaskVertexColorProperty, styles.layerMapVertexColor);
m_MaterialEditor.TexturePropertySingleLine(styles.layerMapMask, layerMaskMapProperty);
m_MaterialEditor.ShaderProperty(layerMaskVertexColor, styles.layerMapVertexColorText);
m_MaterialEditor.TexturePropertySingleLine(styles.layerMapMaskText, layerMaskMap);
for (int i = 0; i < layerCount; i++)
for (int i = 0; i < numLayer; i++)
{
layerChanged |= DoLayerGUI(materialImporter, i);
}

{
GUILayout.FlexibleSpace();
if (GUILayout.Button(styles.syncButton))
if (GUILayout.Button(styles.syncButtonText))
{
SynchronizeAllLayersProperties();
layerChanged = true;

{
// Find first non null layer
int i = 0;
while (i < layerCount && (m_MaterialLayers[i] == null)) ++i;
while (i < numLayer && (m_MaterialLayers[i] == null)) ++i;
if (i < layerCount)
if (i < numLayer)
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kspecularOcclusionMap + i));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kSpecularOcclusionMap + i));
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap + i));
SetKeyword(material, "_HEIGHTMAP", material.GetTexture(kHeightMap + i));
}

{
// Setup lightmap emissive flags
bool nonNullEmissive = false;
for(int i = 0 ; i < layerCount ; ++i)
for(int i = 0 ; i < numLayer; ++i)
{
string paramName = string.Format("_EmissiveIntensity{0}", i);
if (material.GetFloat(paramName) > 0.0f)

}
var realtimeEmission = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
bool shouldEmissionBeEnabled = nonNullEmissive || realtimeEmission;
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)

void SetupMaterialForLayers(Material material)
{
if (layerCount == 4)
if (numLayer == 4)
else if (layerCount == 3)
else if (numLayer == 3)
{
SetKeyword(material, "_LAYEREDLIT_4_LAYERS", false);
SetKeyword(material, "_LAYEREDLIT_3_LAYERS", true);

SetKeyword(material, "_LAYEREDLIT_3_LAYERS", false);
}
const string kLayerMappingUV1 = "_LAYER_MAPPING_UV1_";
const string kLayerMappingPlanar = "_LAYER_MAPPING_PLANAR_";
for (int i = 0 ; i <layerCount ; ++i)
for (int i = 0 ; i < numLayer; ++i)
string layerMappingParam = string.Format("{0}{1}", kLayerMapping, i);
LayerMapping layerMapping = (LayerMapping)material.GetFloat(layerMappingParam);
// 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
string layerUVBaseParam = string.Format("{0}{1}", kLayerUVBase, i);
LayerUVBaseMapping layerUVBaseMapping = (LayerUVBaseMapping)material.GetFloat(layerUVBaseParam);
string layerUVDetailParam = string.Format("{0}{1}", kLayerUVDetail, i);
LayerUVDetailMapping layerUVDetailMapping = (LayerUVDetailMapping)material.GetFloat(layerUVDetailParam);
string currentLayerMappingTriplanar = string.Format("{0}{1}", kLayerMappingTriplanar, i);
string currentLayerMappingUV1 = string.Format("{0}{1}", kLayerMappingUV1, i);
string currentLayerMappingPlanar = string.Format("{0}{1}", kLayerMappingPlanar, i);
string currentLayerMappingTriplanar = string.Format("{0}{1}", kLayerMappingTriplanar, i);
float X, Y, Z, W;
X = (layerUVBaseMapping == LayerUVBaseMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVBaseMapping == LayerUVBaseMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVBaseMapping == LayerUVBaseMapping.UV3) ? 1.0f : 0.0f;
W = (layerUVBaseMapping == LayerUVBaseMapping.Planar) ? 1.0f : 0.0f;
layerUVMappingMask[i].colorValue = new Color(X, Y, Z, W);
if(layerMapping == LayerMapping.UV1)
{
SetKeyword(material, currentLayerMappingUV1, true);
SetKeyword(material, currentLayerMappingPlanar, false);
SetKeyword(material, currentLayerMappingTriplanar, false);
}
else if(layerMapping == LayerMapping.Planar)
if (layerUVBaseMapping == LayerUVBaseMapping.Triplanar)
SetKeyword(material, currentLayerMappingUV1, false);
SetKeyword(material, currentLayerMappingPlanar, true);
SetKeyword(material, currentLayerMappingTriplanar, false);
SetKeyword(material, currentLayerMappingTriplanar, true);
//else if(layerMapping == LayerMapping.Triplanar)
//{
// SetKeyword(material, currentLayerMappingUV1, false);
// SetKeyword(material, currentLayerMappingPlanar, false);
// SetKeyword(material, currentLayerMappingTriplanar, true);
//}
}
}
private void FindLayerProperties(MaterialProperty[] props)
{
layerMaskMapProperty = FindProperty(kLayerMaskMap, props);
layerMaskVertexColorProperty = FindProperty(kLayerMaskVertexColor, props);
layerCountProperty = FindProperty(kLayerCount, props);
for (int i = 0; i < layerCount; ++i)
{
layerMappingProperty[i] = FindProperty(string.Format("{0}{1}", kLayerMapping, i), props);
layerSizeProperty[i] = FindProperty(string.Format("{0}{1}", kLayerSize, i), props);
X = (layerUVDetailMapping == LayerUVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == LayerUVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == LayerUVDetailMapping.UV3) ? 1.0f : 0.0f;
layerUVDetailsMappingMask[i].colorValue = new Color(X, Y, Z, 0.0f);
}
}

{
ShaderOptionsGUI();
EditorGUI.indentLevel++;
EditorGUILayout.LabelField(styles.emission);
EditorGUILayout.LabelField(styles.emissiveText);
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.LightmapEmissionProperty(1);
EditorGUI.indentLevel--;
EditorGUILayout.Space();

112
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader


_NormalMap2("NormalMap2", 2D) = "bump" {}
_NormalMap3("NormalMap3", 2D) = "bump" {}
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
_HeightMap0("HeightMap0", 2D) = "black" {}
_HeightMap1("HeightMap1", 2D) = "black" {}
_HeightMap2("HeightMap2", 2D) = "black" {}

_HeightBias1("Height Bias1", Float) = 0
_HeightBias2("Height Bias2", Float) = 0
_HeightBias3("Height Bias3", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}

_DetailAOScale2("_DetailAOScale2", Range(-2.0, 2.0)) = 1
_DetailAOScale3("_DetailAOScale3", Range(-2.0, 2.0)) = 1
[Enum(UV0, 0, UV1, 1)] _UVDetail("UV Set for detailMap", Float) = 0
// Specific to planar mapping
_TexWorldScale0("TexWorldScale0", Float) = 1.0
_TexWorldScale1("TexWorldScale1", Float) = 1.0

[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
// Material Id
[HideInInspector] _MaterialId("_MaterialId", FLoat) = 0
[HideInInspector] _LayerCount("__layerCount", Float) = 2.0
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping0("Layer 0 Mapping", Float) = 0
[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping1("Layer 1 Mapping", Float) = 0
[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping2("Layer 2 Mapping", Float) = 0
[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping3("Layer 3 Mapping", Float) = 0
// Following store the result of the enum above
_CoordWeight0("CoordWeight0", Color) = (1, 0, 0, 0)
_CoordWeight1("CoordWeight1", Color) = (1, 0, 0, 0)
_CoordWeight2("CoordWeight2", Color) = (1, 0, 0, 0)
_CoordWeight3("CoordWeight3", Color) = (1, 0, 0, 0)
[HideInInspector] _LayerCount("_LayerCount", Float) = 2.0
_TexWorldScale0("Scale to apply on world coordinate", Float) = 1.0
_TexWorldScale1("Scale to apply on world coordinate", Float) = 1.0
_TexWorldScale2("Scale to apply on world coordinate", Float) = 1.0
_TexWorldScale3("Scale to apply on world coordinate", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase3("UV Set for base3", Float) = 0
[HideInInspector] _UVMappingMask0("_UVMappingMask0", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask1("_UVMappingMask1", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask2("_UVMappingMask2", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask3("_UVMappingMask3", Color) = (1, 0, 0, 0)
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail0("UV Set for detail0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail1("UV Set for detail1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail2("UV Set for detail2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail3("UV Set for detail3", Float) = 0
[HideInInspector] _UVDetailsMappingMask0("_UVDetailsMappingMask0", Float) = 0
[HideInInspector] _UVDetailsMappingMask1("_UVDetailsMappingMask1", Float) = 0
[HideInInspector] _UVDetailsMappingMask2("_UVDetailsMappingMask2", Float) = 0
[HideInInspector] _UVDetailsMappingMask3("_UVDetailsMappingMask3", Float) = 0
}
HLSLINCLUDE

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_0
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_1
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_2
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_3
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _EMISSIVE_COLOR
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _EMISSIVE_COLOR
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _LAYER_MASK_MAP _LAYER_VERTEX_COLOR _LAYER_MASK_MAP_VERTEX_COLOR
#pragma shader_feature _LAYEREDLIT_2_LAYERS _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS
#pragma shader_feature _ _LAYER_MAPPING_TRIPLANAR_0
#pragma shader_feature _ _LAYER_MAPPING_TRIPLANAR_1
#pragma shader_feature _ _LAYER_MAPPING_TRIPLANAR_2
#pragma shader_feature _ _LAYER_MAPPING_TRIPLANAR_3
#pragma shader_feature _LAYER_MASK_MAP
#pragma shader_feature _LAYER_VERTEX_COLOR
#pragma shader_feature _ _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON
//-------------------------------------------------------------------------------------
// Define

# define _LAYER_COUNT 2
#endif
// Set of users variables
#define PROP_DECL(type, name) type name, name##0, name##1, name##2, name##3;
#define PROP_DECL_TEX2D(name)\

TEXTURE2D(name##2); \
TEXTURE2D(name##3);
#define PROP_SAMPLE(name, textureName, layerCoord, swizzle)\
name##0 = SampleLayer(TEXTURE2D_PARAM(textureName##0, sampler##textureName##0), layerCoord, 0).##swizzle; \
name##1 = SampleLayer(TEXTURE2D_PARAM(textureName##1, sampler##textureName##0), layerCoord, 1).##swizzle; \
name##2 = SampleLayer(TEXTURE2D_PARAM(textureName##2, sampler##textureName##0), layerCoord, 2).##swizzle; \
name##3 = SampleLayer(TEXTURE2D_PARAM(textureName##3, sampler##textureName##0), layerCoord, 3).##swizzle;
#define PROP_MUL(name, multiplier, swizzle)\
name##0 *= multiplier##0.##swizzle; \
name##1 *= multiplier##1.##swizzle; \
name##2 *= multiplier##2.##swizzle; \
name##3 *= multiplier##3.##swizzle;
#define PROP_ASSIGN(name, input, swizzle)\
name##0 = input##0.##swizzle; \
name##1 = input##1.##swizzle; \
name##2 = input##2.##swizzle; \
name##3 = input##3.##swizzle;
#define PROP_ASSIGN_VALUE(name, input)\
name##0 = input; \
name##1 = input; \
name##2 = input; \
name##3 = input;
#define PROP_BLEND_COLOR(name, mask) name = BlendLayeredColor(name##0, name##1, name##2, name##3, mask);
#define PROP_BLEND_SCALAR(name, mask) name = BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
//-------------------------------------------------------------------------------------
// variable declaration

TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
TEXTURE2D(_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
PROP_DECL(float, _CoordWeight);
TEXTURE2D(_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailMappingMask);
float _AlphaCutoff;

263
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs


{
protected static class Styles
{
public enum DetailMapMode
{
DetailWithNormal,
DetailWithAOHeight,
}
public static GUIContent uvSetLabel = new GUIContent("UV Set");
public static string detailText = "Inputs Detail";
public static string lightingText = "Inputs Lighting";

public static string InputsOptionsText = "Inputs options";
public static GUIContent smoothnessMapChannelText = new GUIContent("Smoothness Source", "Smoothness texture and channel");
public static GUIContent UVBaseMappingText = new GUIContent("UV set for Base", "");
public static GUIContent texWorldScaleText = new GUIContent("Scale to apply on world coordinate in case of Planar/Triplanar", "");
public static GUIContent UVBaseDetailMappingText = new GUIContent("UV set for Base and Detail", "");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", "");
public static GUIContent detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height");
public static GUIContent UVDetailMappingText = new GUIContent("UV set for Detail", "");
public static GUIContent detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height");
public static string InputsText = "Inputs";

public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (BC5) - DXT5 for test");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5");
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", "");
public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC5) - DXT5 for test");
public static GUIContent anisotropyText = new GUIContent("Anisotropy", "Anisotropy scale factor");

public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive.");
public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect.");
}
public enum SurfaceType

protected MaterialEditor m_MaterialEditor;
private MaterialProperty surfaceType = null;
private MaterialProperty alphaCutoffEnable = null;
private MaterialProperty blendMode = null;
private MaterialProperty alphaCutoff = null;
private MaterialProperty doubleSidedMode = null;
MaterialProperty surfaceType = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty doubleSidedMode = null;
private const string kSurfaceType = "_SurfaceType";
private const string kBlendMode = "_BlendMode";
private const string kAlphaCutoff = "_AlphaCutoff";
private const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
private const string kDoubleSidedMode = "_DoubleSidedMode";
const string kSurfaceType = "_SurfaceType";
const string kBlendMode = "_BlendMode";
const string kAlphaCutoff = "_AlphaCutoff";
const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
const string kDoubleSidedMode = "_DoubleSidedMode";
protected static string[] reservedProperties = new string[] { kSurfaceType, kBlendMode, kAlphaCutoff, kAlphaCutoffEnabled, kDoubleSidedMode };
protected abstract void FindInputProperties(MaterialProperty[] props);

MaskAlpha,
AlbedoAlpha,
}
public enum EmissiveColorMode
public enum UVBaseMapping
UseEmissiveColor,
UseEmissiveMask,
UV0,
Planar,
Triplanar
public enum NormalMapSpace
{
TangentSpace,

Parallax,
Displacement,
}
public enum DetailMapMode
{
DetailWithNormal,

MaterialProperty UVDetail = null;
MaterialProperty smoothnessMapChannel = null;
MaterialProperty emissiveColorMode = null;
MaterialProperty detailMapMode = null;
public enum UVDetailMapping
{
UV0,
UV1,
UV3
}
MaterialProperty baseColor = null;
MaterialProperty baseColorMap = null;
MaterialProperty metallic = null;
MaterialProperty smoothness = null;
MaterialProperty maskMap = null;
MaterialProperty specularOcclusionMap = null;
MaterialProperty normalMap = null;
MaterialProperty normalMapSpace = null;
MaterialProperty heightMap = null;
MaterialProperty heightScale = null;
MaterialProperty heightBias = null;
MaterialProperty tangentMap = null;
MaterialProperty anisotropy = null;
MaterialProperty anisotropyMap = null;
MaterialProperty heightMapMode = null;
MaterialProperty detailMap = null;
MaterialProperty detailMask = null;
MaterialProperty detailAlbedoScale = null;
MaterialProperty detailNormalScale = null;
MaterialProperty detailSmoothnessScale = null;
MaterialProperty detailHeightScale = null;
MaterialProperty detailAOScale = null;
MaterialProperty emissiveColor = null;
MaterialProperty emissiveColorMap = null;
MaterialProperty emissiveIntensity = null;
// MaterialProperty subSurfaceRadius = null;
// MaterialProperty subSurfaceRadiusMap = null;
public enum EmissiveColorMode
{
UseEmissiveColor,
UseEmissiveMask,
}
protected const string kUVDetail = "_UVDetail";
protected const string kSmoothnessTextureChannelProp = "_SmoothnessTextureChannel";
protected const string kEmissiveColorMode = "_EmissiveColorMode";
protected MaterialProperty smoothnessMapChannel = null;
protected const string kSmoothnessTextureChannel = "_SmoothnessTextureChannel";
protected MaterialProperty UVBase = null;
protected const string kUVBase = "_UVBase";
protected MaterialProperty TexWorldScale = null;
protected const string kTexWorldScale = "_TexWorldScale";
protected MaterialProperty UVMappingMask = null;
protected const string kUVMappingMask = "_UVMappingMask";
protected MaterialProperty normalMapSpace = null;
protected MaterialProperty heightMapMode = null;
protected MaterialProperty detailMapMode = null;
protected MaterialProperty UVDetail = null;
protected const string kUVDetail = "_UVDetail";
protected MaterialProperty UVDetailsMappingMask = null;
protected const string kUVDetailsMappingMask = "_UVDetailsMappingMask";
protected MaterialProperty emissiveColorMode = null;
protected const string kEmissiveColorMode = "_EmissiveColorMode";
protected MaterialProperty baseColor = null;
protected const string kBaseColor = "_BaseColor";
protected MaterialProperty baseColorMap = null;
protected const string kBaseColorMap = "_BaseColorMap";
protected MaterialProperty metallic = null;
protected const string kMettalic = "_Mettalic";
protected MaterialProperty smoothness = null;
protected const string kSmoothness = "_Smoothness";
protected MaterialProperty maskMap = null;
protected const string kMaskMap = "_MaskMap";
protected MaterialProperty specularOcclusionMap = null;
protected const string kSpecularOcclusionMap = "_SpecularOcclusionMap";
protected MaterialProperty normalMap = null;
protected const string kMaskMap = "_MaskMap";
protected const string kspecularOcclusionMap = "_SpecularOcclusionMap";
protected const string kEmissiveColorMap = "_EmissiveColorMap";
protected MaterialProperty heightMap = null;
protected MaterialProperty heightScale = null;
protected const string kHeightScale = "_HeightScale";
protected MaterialProperty heightBias = null;
protected const string kHeightBias= "_HeightBias";
protected MaterialProperty tangentMap = null;
protected MaterialProperty anisotropy = null;
protected const string kAnisotropy = "_Anisotropy";
protected MaterialProperty anisotropyMap = null;
protected MaterialProperty detailMap = null;
protected MaterialProperty detailMask = null;
protected MaterialProperty detailAlbedoScale = null;
protected MaterialProperty detailNormalScale = null;
protected MaterialProperty detailSmoothnessScale = null;
protected MaterialProperty detailHeightScale = null;
protected MaterialProperty detailAOScale = null;
// MaterialProperty subSurfaceRadius = null;
// MaterialProperty subSurfaceRadiusMap = null;
protected MaterialProperty emissiveColor = null;
protected const string kEmissiveColor = "_EmissiveColor";
protected MaterialProperty emissiveColorMap = null;
protected const string kEmissiveColorMap = "_EmissiveColorMap";
protected MaterialProperty emissiveIntensity = null;
protected const string kEmissiveIntensity = "_EmissiveIntensity";
{
UVDetail = FindProperty(kUVDetail, props);
smoothnessMapChannel = FindProperty(kSmoothnessTextureChannelProp, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
{
smoothnessMapChannel = FindProperty(kSmoothnessTextureChannel, props);
UVBase = FindProperty(kUVBase, props);
TexWorldScale = FindProperty(kTexWorldScale, props);
UVMappingMask = FindProperty(kUVMappingMask, props);
UVDetail = FindProperty(kUVDetail, props);
UVDetailsMappingMask = FindProperty(kUVDetailsMappingMask, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
baseColor = FindProperty("_BaseColor", props);
baseColorMap = FindProperty("_BaseColorMap", props);
metallic = FindProperty("_Metallic", props);
smoothness = FindProperty("_Smoothness", props);
baseColor = FindProperty(kBaseColor, props);
baseColorMap = FindProperty(kBaseColorMap, props);
metallic = FindProperty(kMetallic, props);
smoothness = FindProperty(kSmoothness, props);
specularOcclusionMap = FindProperty(kspecularOcclusionMap, props);
specularOcclusionMap = FindProperty(kSpecularOcclusionMap, props);
heightScale = FindProperty("_HeightScale", props);
heightBias = FindProperty("_HeightBias", props);
tangentMap = FindProperty("_TangentMap", props);
anisotropy = FindProperty("_Anisotropy", props);
anisotropyMap = FindProperty("_AnisotropyMap", props);
emissiveColor = FindProperty("_EmissiveColor", props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty("_EmissiveIntensity", props);
heightScale = FindProperty(kHeightScale, props);
heightBias = FindProperty(kHeightBias, props);
tangentMap = FindProperty(kTangentMap, props);
anisotropy = FindProperty(kAnisotropy, props);
anisotropyMap = FindProperty(kAnisotropyMap, props);
detailMap = FindProperty(kDetailMap, props);
detailMask = FindProperty(kDetailMask, props);
detailAlbedoScale = FindProperty(kDetailAlbedoScale, props);

detailAOScale = FindProperty(kDetailAOScale, props);
emissiveColor = FindProperty(kEmissiveColor, props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);
// When Planar or Triplanar is enable the UVDetail use the same mode, so we disable the choice on UVDetail
bool enableUVDetail = (UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0;
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText.text);
m_MaterialEditor.ShaderProperty(UVBase, enableUVDetail ? Styles.UVBaseDetailMappingText.text : Styles.UVBaseMappingText.text);
float X, Y, Z, W;
X = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0) ? 1.0f : 0.0f;
W = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) ? 1.0f : 0.0f;
UVMappingMask.colorValue = new Color(X, 0.0f, 0.0f, W);
if (((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) || ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Triplanar))
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText.text);
EditorGUI.indentLevel--;
}
if (enableUVDetail)
{
m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText.text);
}
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.UV3) ? 1.0f : 0.0f;
UVDetailsMappingMask.colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText.text);
EditorGUI.indentLevel--;
}

bool smoothnessInAlbedoAlpha = (SmoothnessMapChannel)smoothnessMapChannel.floatValue == SmoothnessMapChannel.AlbedoAlpha;
bool smoothnessInAlbedoAlpha = (SmoothnessMapChannel)smoothnessMapChannel.floatValue == SmoothnessMapChannel.AlbedoAlpha;
bool useDetailMapWithNormal = (DetailMapMode)detailMapMode.floatValue == DetailMapMode.DetailWithNormal;
bool useDetailMapWithNormal = (DetailMapMode)detailMapMode.floatValue == DetailMapMode.DetailWithNormal;
GUILayout.Label(Styles.InputsText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(smoothnessInAlbedoAlpha ? Styles.baseColorSmoothnessText : Styles.baseColorText, baseColorMap, baseColor);

EditorGUILayout.Space();
GUILayout.Label(Styles.detailText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
m_MaterialEditor.ShaderProperty(UVDetail, Styles.uvSetLabel.text);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
if (useDetailMapWithNormal)
{

EditorGUI.indentLevel--;
}
// TODO: try to setup minimun value to fall back to standard shaders and reverse
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
base.AssignNewShaderToMaterial(material, oldShader, newShader);

{
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap) || material.GetTexture(kDetailMap)); // With details map, we always use a normal map and Unity provide a default (0, 0, 1) normal map for ir
SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kspecularOcclusionMap));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kSpecularOcclusionMap));
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_HEIGHTMAP", material.GetTexture(kHeightMap));
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMap));

public static bool ShouldEmissionBeEnabled(Material mat)
{
float emissiveIntensity = mat.GetFloat(kEmissiveIntensity);
var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
return emissiveIntensity > 0.0f || realtimeEmission;
}
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{

{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", (NormalMapSpace)material.GetFloat(kNormalMapSpace) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannelProp)) == SmoothnessMapChannel.AlbedoAlpha);
SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannel)) == SmoothnessMapChannel.AlbedoAlpha);
SetKeyword(material, "_MAPPING_TRIPLANAR", ((UVBaseMapping)material.GetFloat(kUVBase)) == UVBaseMapping.Triplanar);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", ((NormalMapSpace)material.GetFloat(kNormalMapSpace)) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_HEIGHTMAP_AS_DISPLACEMENT", ((HeightmapMode)material.GetFloat(kHeightMapMode)) == HeightmapMode.Displacement);
SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", ((DetailMapMode)material.GetFloat(kDetailMapMode)) == DetailMapMode.DetailWithNormal);
SetKeyword(material, "_REQUIRE_UV3", ((UVDetailMapping)material.GetFloat(kUVDetail)) == UVDetailMapping.UV3 && (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV0);
SetKeyword(material, "_HEIGHTMAP_AS_DISPLACEMENT", (HeightmapMode)material.GetFloat(kHeightMapMode) == HeightmapMode.Displacement);
SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", (DetailMapMode)material.GetFloat(kDetailMapMode) == DetailMapMode.DetailWithNormal);
public static bool ShouldEmissionBeEnabled(Material mat)
{
float emissiveIntensity = mat.GetFloat("_EmissiveIntensity");
var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
return emissiveIntensity > 0.0f || realtimeEmission;
}
// TODO: ? or remove
bool HasValidEmissiveKeyword(Material material)
{
/*

50
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader


_SpecularOcclusionMap("SpecularOcclusion", 2D) = "white" {}
_NormalMap("NormalMap", 2D) = "bump" {}
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
_TangentMap("TangentMap", 2D) = "bump" {}
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0

_DetailNormalScale("_DetailNormalScale", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(-2.0, 2.0)) = 1
_DetailHeightScale("_DetailHeightScale", Range(-2.0, 2.0)) = 1
_DetailAOScale("_DetailAOScale", Range(-2.0, 2.0)) = 1
[Enum(UV0, 0, UV1, 1)] _UVDetail("UV Set for detailMap", Float) = 0
_DetailAOScale("_DetailAOScale", Range(-2.0, 2.0)) = 1
_SubSurfaceRadius("SubSurfaceRadius", Range(0.0, 1.0)) = 0
_SubSurfaceRadiusMap("SubSurfaceRadiusMap", 2D) = "white" {}

[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _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
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1,0,0,0)
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
}
HLSLINCLUDE

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _NORMALMAP
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _MASKMAP
#pragma shader_feature _SPECULAROCCLUSIONMAP
#pragma shader_feature _MAPPING_TRIPLANAR
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _NORMALMAP
#pragma shader_feature _MASKMAP
#pragma shader_feature _SPECULAROCCLUSIONMAP
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _DETAIL_MAP
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED

SAMPLER2D(sampler_DetailMask);
TEXTURE2D(_DetailMap);
SAMPLER2D(sampler_DetailMap);
float4 _DetailMap_ST;
float _UVDetail;
float4 _DetailMap_ST;
float _DetailAlbedoScale;
float _DetailNormalScale;
float _DetailSmoothnessScale;

TEXTURE2D(_AnisotropyMap);
SAMPLER2D(sampler_AnisotropyMap);
float _SubSurfaceRadius;
TEXTURE2D(_SubSurfaceRadiusMap);
SAMPLER2D(sampler_SubSurfaceRadiusMap);
//float _SubSurfaceRadius;
//TEXTURE2D(_SubSurfaceRadiusMap);
//SAMPLER2D(sampler_SubSurfaceRadiusMap);
// float _Thickness;
//TEXTURE2D(_ThicknessMap);

float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);
SAMPLER2D(sampler_EmissiveColorMap);
float _TexWorldScale;
float4 _UVMappingMask;
float4 _UVDetailMappingMask;
ENDHLSL

250
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl


return float2(0.0, 0.0);
#endif
}
float3 LerpWhiteTo(float3 b, float t)
{
float oneMinusT = 1.0 - t;
return float3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}
void GetBuiltinData(FragInput input, SurfaceData surfaceData, float alpha, out BuiltinData builtinData)
{

#else
builtinData.emissiveColor = _EmissiveColor * builtinData.emissiveIntensity;
#endif
#elif defined(_MASKMAP) // If we have a MaskMap, use emissive slot as a mask on baseColor
// If we have a MaskMap, use emissive slot as a mask on baseColor
#elif defined(_MASKMAP) && !defined(LAYERED_LIT_SHADER) // With layered lit we have no emissive mask option
builtinData.emissiveColor = surfaceData.baseColor * (SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).b * builtinData.emissiveIntensity).xxx;
#else
builtinData.emissiveColor = float3(0.0, 0.0, 0.0);

builtinData.distortionBlur = 0.0;
}
// Gather all kind of mapping in one struct, allow to improve code readability
struct LayerUV
{
float2 uv;

LayerUV details2;
LayerUV details3;
float2 uvStaticLightmap;
float2 uvDynamicLightmap;
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
float4 SampleLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
{

if (weights.x > 0.0)
{
}
{
}
{
}
return val;
}

}
}
#ifndef LAYERED_LIT_SHADER
// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float4 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
{
if (layerUV.isTriplanar)
{
float4 val = float4(0.0, 0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += outCoord.blendWeights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
if (weights.y > 0.0)
val += outCoord.blendWeights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
if (weights.z > 0.0)
val += outCoord.blendWeights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
return val;
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv));
}
}
// This version is for normalmap with AG encoding only (use with details map)
float4 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
{
if (layerUV.isTriplanar)
{
float4 val = float4(0.0, 0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += outCoord.blendWeights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
if (weights.y > 0.0)
val += outCoord.blendWeights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
if (weights.z > 0.0)
val += outCoord.blendWeights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
return val;
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv));
}
}
// Macro to improve readibility of surface data
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord) SampleNormalLayer(TEXTURE2D_PASS(textureName, samplerName), coord, coord.weights);
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord) SampleNormalLayerAG(TEXTURE2D_PASS(textureName, samplerName), coord, coord.weights);
#define SAMPLE_LAYER_DETAIL_TEXTURE2D
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#ifndef LAYERED_LIT_SHADER
#define LAYER_INDEX 0
#define ADD_ZERO_IDX(Name) Name
bool isTriplanar = false;
LayerTexCoord layerTexCoord[_MAX_LAYER];
LayerTexCoord layerTexCoord;
float3 triplanarBlendWeights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz); // Will be remove if triplanar not used
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz); // Will be remove if triplanar not used
// For each layer
#if defined(_LAYER_MAPPING_TRIPLANAR_0)
// Be sure that the compiler is aware that we don't touch UV1 and UV3 for base layer in case of non layer shader
// so it can remove code
_UVMappingMask.yz = flat2(0.0, 0.0);
bool isTriplanar = false;
#ifdef MAPPING_TRIPLANAR
#else
isTriplanar = false;
ComputeLayerTexCoord0(input, isTriplanar, texCoord.layerTexCoord[0]);
ApplyDisplacement0(input, texCoord.layerTexCoord[0]);
GetSurfaceData0(input, texCoord.layerTexCoord[0]);
#if define _LAYEREDLIT_2_LAYERS
ComputeLayerTexCoord
ComputeLayerTexCoord(input, isTriplanar, layerTexCoord);
ApplyDisplacement(input, layerTexCoord);
float2 offset = GetHeigthData(input, surfaceData);
input.texCoord0 += offset;
input.texCoord1 += offset;
float alpha = GetSurfaceData(input, surfaceData);
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData);
#define ADD_ZERO_IDX(Name) Name##0
// Generate function for all layer
#define LAYER_INDEX 0
#define ADD_IDX(Name) Name##0
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#define LAYER_INDEX 1
#define ADD_IDX(Name) Name##1
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#define LAYER_INDEX 2
#define ADD_IDX(Name) Name##2
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#define LAYER_INDEX 3
#define ADD_IDX(Name) Name##3
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
void ComputeMaskWeights(float3 inputMasks, out float outWeights[_MAX_LAYER])
{
float masks[_MAX_LAYER];

outWeights[0] = left;
}
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord2) SampleLayer(TEXTURE2D_ARGS(textureName##0, samplerName##0), LayerCoordinates layerCoord, 0)
#include "LitSurfaceData.hlsl"
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerCoordinates layerCoord;
ComputeLayerCoordinates(layerCoord, input);
GetHeigthData0();
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 maskValues = float3(1.0, 1.0, 1.0);
#if defined(_LAYER_MASK_MAP) || defined(_LAYER_MASK_MAP_VERTEX_COLOR)
maskValues *= SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
#endif
#if defined(_LAYER_MASK_VERTEX_COLOR) || defined(_LAYER_MASK_MAP_VERTEX_COLOR)
maskValues *= input.vertexColor.rgb;
#endif
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);
SurfaceData surfaceData0;
SurfaceData surfaceData1;
SurfaceData surfaceData2;
SurfaceData surfaceData3;
float alpha = GetSurfaceData0(input, surfaceData0);
GetBuiltinData(input, surfaceData, alpha, builtinData);
}
#if !defined(LAYERED_LIT_SHADER)
float3 BlendLayeredColor(float3 rgb0, float3 rgb1, float3 rgb2, float3 rgb3, float weight[4])
{
float3 result = float3(0.0, 0.0, 0.0);

{
float3 result = float3(0.0, 0.0, 0.0);
// TODO : real normal map blending function
result = normal0 * weight[0] + normal1 * weight[1];
result = normal0 * weight[0] + normal1 * weight[1];
#if _LAYER_COUNT >= 3
result += normal2 * weight[2];
#endif

return result;
return normalize(result);
}
float BlendLayeredScalar(float x0, float x1, float x2, float x3, float weight[4])

return result;
}
#define PROP_BLEND_COLOR(name, mask) name = BlendLayeredColor(name##0, name##1, name##2, name##3, mask);
#define PROP_BLEND_NORMAL(name, mask) name = BlendLayeredNormal(name##0, name##1, name##2, name##3, mask);
#define PROP_BLEND_SCALAR(name, mask) name = BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;
// one weight for each direction XYZ - Use vertex normal for triplanar
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz); // Will be remove if triplanar not used
bool isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_0
isTriplanar = true;
ComputeLayerTexCoord0(input, isTriplanar, layerTexCoord);
ComputeLayerTexCoord1(input, isTriplanar, layerTexCoord);
ComputeLayerTexCoord2(input, isTriplanar, layerTexCoord);
ComputeLayerTexCoord3(input, isTriplanar, layerTexCoord);
ApplyDisplacement0(input, layerTexCoord);
ApplyDisplacement1(input, layerTexCoord);
ApplyDisplacement2(input, layerTexCoord);
ApplyDisplacement3(input, layerTexCoord);
SurfaceData surfaceData0;
SurfaceData surfaceData1;
SurfaceData surfaceData2;
SurfaceData surfaceData3;
float alpha0 = GetSurfaceData0(input, layerTexCoord, surfaceData0);
float alpha1 = GetSurfaceData1(input, layerTexCoord, surfaceData1);
float alpha2 = GetSurfaceData2(input, layerTexCoord, surfaceData2);
float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3);
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 maskValues = float3(1.0, 1.0, 1.0);
#if defined(_LAYER_MASK_MAP)
maskValues *= SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
#endif
#if defined(_LAYER_MASK_VERTEX_COLOR)
maskValues *= input.vertexColor.rgb;
#endif
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);
surfaceData.baseColor = PROP_BLEND_COLOR(surfaceData.baseColor, weights);
surfaceData.specularOcclusion = PROP_BLEND_SCALAR(surfaceData.specularOcclusion, weights);
// Note: for normal map (in tangent space) it is possible to have better performance
// by blending in tangent space then transform to world and apply flip.
// Sadly this require a specific path (without taking into account that there is detail normal map)
// mean it add an extra cost of maintenance. We chose to not do this optimization in favor
// of simpler code and in the future will rely on shader graph to create optimize code.
surfaceData.normalWS = PROP_BLEND_NORMAL(surfaceData.normalWS, weights);
surfaceData.perceptualSmoothness = PROP_BLEND_SCALAR(surfaceData.perceptualSmoothness, weights);
surfaceData.ambientOcclusion = PROP_BLEND_SCALAR(surfaceData.ambientOcclusion, weights);
surfaceData.metallic = PROP_BLEND_SCALAR(surfaceData.metallic, weights);
// Init other unused parameter
surfaceData.materialId = 0;
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;
surfaceData.subSurfaceRadius = 1.0;
surfaceData.thickness = 0.0;
surfaceData.subSurfaceProfile = 0;
surfaceData.coatNormalWS = float3(1.0, 0.0, 0.0);
surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
float alpha = PROP_BLEND_SCALAR(alpha, weights);
GetBuiltinData(input, surfaceData, alpha, builtinData);
}
#endif // #ifndef LAYERED_LIT_SHADER

24
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl


float2 uv1 : TEXCOORD1;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
float2 uv2 : TEXCOORD2;
#endif
#endif
#ifdef _REQUIRE_UV3
float2 uv3 : TEXCOORD3;
#endif
float4 tangentOS : TANGENT; // Always present as we require it also in case of anisotropic lighting
float4 color : COLOR;

#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
float2 texCoord2;
#endif
#ifdef _REQUIRE_UV3
float2 texCoord3;
#endif
float3 tangentToWorld[3];
float4 color;
};

float4 positionCS : SV_Position;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV3)
float4 interpolators[6] : TEXCOORD0;
#else
float4 interpolators[5] : TEXCOORD0;

output.interpolators[4] = input.color;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV3)
output.interpolators[5] = float4(0.0, 0.0, 0.0, 0.0);
output.interpolators[5] = float4(input.texCoord2.xy, 0.0, 0.0);
output.interpolators[5].xy = input.texCoord2.xy;
#endif
#ifdef _REQUIRE_UV3
output.interpolators[5].zw = input.texCoord3.xy;
#endif
#endif
return output;

#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
output.texCoord2 = input.interpolators[5].xy;
#endif
#ifdef _REQUIRE_UV3
output.texCoord3 = input.interpolators[5].zw;
#endif
#if SHADER_STAGE_FRAGMENT

139
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl


void ADD_IDX(ComputeLayerTexCoord)(FragInput input, int index, bool isTriplanar, out LayerTexCoord outLayerTexCoord)
void ADD_IDX(ComputeLayerTexCoord)(FragInput input, bool isTriplanar, inout LayerTexCoord outLayerTexCoord)
// TODO: Do we want to manage local or world triplanar/planar
//float3 position = localTriplanar ? TransformWorldToObject(input.positionWS) : input.positionWS;
float3 position = input.positionWS;
position *= ADD_IDX(_TexWorldScale);
ADD_IDX(_UVMappingMask).z * input.positionWS.xz * ADD_IDX(_TexWorldScale);
ADD_IDX(_UVMappingMask).z * input.texCoord3 +
ADD_IDX(_UVMappingMask).w * positionWS.xz;
ADD_IDX(_UVDetailsMappingMask).y * input.texCoord1;
ADD_IDX(_UVDetailsMappingMask).y * input.texCoord1 +
ADD_IDX(_UVDetailsMappingMask).z * input.texCoord3 +
// Note that if base is planar, detail map is planar
ADD_IDX(_UVMappingMask).w * positionWS.xz;
// TODO: local or world triplanar
//float3 position = localTriplanar ? TransformWorldToObject(input.positionWS) : input.positionWS;
float3 position = input.positionWS;
position *= ADD_IDX(_TexWorldScale);
ADD_IDX(layerTexCoord.base).uvYZ = position.yz;
ADD_IDX(layerTexCoord.base).uvZX = position.xy;
ADD_IDX(layerTexCoord.base).uvXY = position.xz;

ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(position.xz, ADD_IDX(_DetailMap));
layerTexCoord.uvStaticLightmap = input.texCoord1;
layerTexCoord.uvDynamicLightmap = input.texCoord2;
void ADD_IDX(ApplyDisplacement)(FragInput input, inout LayerTexCoord layerTexCoord)
void ADD_IDX(ApplyDisplacement)(inout FragInput input, inout LayerTexCoord layerTexCoord)
// TODO: in case of shader graph, a node like parallax must be nullify if use to generate code for Meta pass
#ifndef _HEIGHTMAP_AS_DISPLACEMENT
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS); // This should be remove by the compiler as we usually cal it before.
float height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
#ifndef _HEIGHTMAP_AS_DISPLACEMENT
// Hope the compiler can optimize this in case of multiple layer
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
float2 offset = ParallaxOffset(viewDirTS, height);
ADD_IDX(layerTexCoord.base).uv += offset;

ADD_IDX(layerTexCoord.details).uvZX += offset;
ADD_IDX(layerTexCoord.details).uvXY += offset;
// Only modify tex coord for first layer, this will be use by for builtin data (like lightmap)
layerTexCoord.uvStaticLightmap += offset;
layerTexCoord.uvDynamicLightmap += offset;
input.texCoord0 += offset;
input.texCoord1 += offset;
input.texCoord2 += offset;
input.texCoord3 += offset;
}
#endif
#endif

float ADD_IDX(GetSurfaceData)(FragInput input, int index, inout LayerTexCoord layerTexCoord, out SurfaceData surfaceData)
float ADD_IDX(GetSurfaceData)(FragInput input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData)
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
float alpha = ADD_IDX(_BaseColor).a;
#else
float alpha = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).a * ADD_IDX(_BaseColor).a;
#endif
// Perform alha test very early to save performance (a killed pixel will not sample textures)
#ifdef _ALPHATEST_ON
clip(alpha - _AlphaCutoff);
#endif
float detailMask = SAMPLE_LAYER_TEXTURE2D(_DetailMask, sampler_DetailMask, layerTexCoord).b;
float4 detail = SAMPLE_LAYER_DETAIL_TEXTURE2D(_DetailMap, sampler_DetailMap, layerTexCoord);
float detailAlbedo = detail.r;
float detailSmoothness = detail.b;
float detailMask = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMask), ADD_ZERO_IDX(sampler_DetailMask), ADD_IDX(layerTexCoord.base)).b;
float2 detailAlbedoAndSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details)).rb;
float detailAlbedo = detailAlbedoAndSmoothness.r;
float detailSmoothness = detailAlbedoAndSmoothness.b;
float3 detailNormalTS = UnpackNormalAG(detail, _DetailNormalScale);
// Resample the detail map but this time for the normal map. This call should be optimize by the compiler
// We split both call due to trilinear mapping
float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details)).rb;
// TODO: Use heightmap as a derivative with Morten Mikklesen approach
// Or reconstruct
float U = SAMPLE_LAYER_TEXTURE2D(_DetailMap, sampler_DetailMap, texCoordDetail + float2(0.005, 0)).a;
float V = SAMPLE_LAYER_TEXTURE2D(_DetailMap, sampler_DetailMap, texCoordDetail + float2(0, 0.005)).a;
float dHdU = U - detail.a; //create bump map U offset
float dHdV = V - detail.a; //create bump map V offset
//float3 detailNormal = 1 - float3(dHdU, dHdV, 0.05); //create the tangent space normal
// TODO: Use heightmap as a derivative with Morten Mikklesen approach, how this work with our abstraction and triplanar ?
//float3 detailNormal = UnpackNormalAG(unifiedDetail.r).a;
surfaceData.baseColor = SAMPLE_LAYER_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, input.texCoord0).rgb * _BaseColor.rgb;
surfaceData.baseColor = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).rgb * ADD_IDX(_BaseColor).rgb;
surfaceData.baseColor *= LerpWhiteTo(2.0 * saturate(detailAlbedo * _DetailAlbedoScale), detailMask);
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
float alpha = _BaseColor.a;
#else
float alpha = SAMPLE_LAYER_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, input.texCoord0).a * _BaseColor.a;
#endif
#ifdef _ALPHATEST_ON
clip(alpha - _AlphaCutoff);
surfaceData.baseColor *= LerpWhiteTo(2.0 * saturate(detailAlbedo * ADD_IDX(_DetailAlbedoScale)), detailMask);
surfaceData.specularOcclusion = SAMPLE_LAYER_TEXTURE2D(_SpecularOcclusionMap, sampler_SpecularOcclusionMap, input.texCoord0).a;
surfaceData.specularOcclusion = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_SpecularOcclusionMap), ADD_ZERO_IDX(sampler_SpecularOcclusionMap), ADD_IDX(layerTexCoord.base)).a;
#else
// Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
//surfaceData.specularOcclusion = saturate(1.0 + horizonFade * dot(r, input.tangentToWorld[2].xyz);

#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
float3 normalTS = UnpackNormalAG(SAMPLE_LAYER_TEXTURE2D(_NormalMap, sampler_NormalMap, input.texCoord0));
float3 normalTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base));
normalTS = lerp(normalTS, blendNormal(normalTS, detailNormalTS), detailMask);
normalTS = lerp(normalTS, BlendNormal(normalTS, detailNormalTS), detailMask);
float3 normalOS = SAMPLE_LAYER_TEXTURE2D(_NormalMap, sampler_NormalMap, input.texCoord0).rgb;
// TODO: We are suppose to do * 2 - 1 here. how to deal with triplanar...
float3 normalOS = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base)).rgb;
surfaceData.normalWS = lerp(surfaceData.normalWS, blendNormal(surfaceData.normalWS, detailNormalWS), detailMask);
surfaceData.normalWS = lerp(surfaceData.normalWS, BlendNormal(surfaceData.normalWS, detailNormalWS), detailMask);
#endif
#endif
#else

#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, input.texCoord0).a;
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).a;
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).a;
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_MaskMap), ADD_ZERO_IDX(sampler_MaskMap), ADD_IDX(layerTexCoord.base)).a;
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * saturate(detailSmoothness * _DetailSmoothnessScale), detailMask);
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * saturate(detailSmoothness * ADD_IDX(_DetailSmoothnessScale)), detailMask);
surfaceData.materialId = 0;
surfaceData.metallic = SAMPLE_LAYER_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).r;
surfaceData.ambientOcclusion = SAMPLE_LAYER_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).g;
surfaceData.metallic = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_MaskMap), ADD_ZERO_IDX(sampler_MaskMap), ADD_IDX(layerTexCoord.base)).r;
surfaceData.ambientOcclusion = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_MaskMap), ADD_ZERO_IDX(sampler_MaskMap), ADD_IDX(layerTexCoord.base)).g;
#else
surfaceData.metallic = 1.0;
surfaceData.ambientOcclusion = 1.0;

// This part of the code is not used in case of layered shader but we keep the same macro system for simplicity
surfaceData.materialId = 0; // TODO
float3 tangentTS = UnpackNormalAG(SAMPLE_TEXTURE2D(_TangentMap, sampler_TangentMap, input.texCoord0));
float3 tangentTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base)));
surfaceData.tangentWS = SAMPLE_TEXTURE2D(_TangentMap, sampler_TangentMap, input.texCoord0).rgb;
surfaceData.tangentWS = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base)).rgb;
#endif
#else
surfaceData.tangentWS = input.tangentToWorld[0].xyz;

#ifdef _ANISOTROPYMAP
surfaceData.anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, input.texCoord0).g;
surfaceData.anisotropy = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_AnisotropyMap), ADD_ZERO_IDX(sampler_AnisotropyMap), ADD_IDX(layerTexCoord.base)).g;
#else
surfaceData.anisotropy = 1.0;
#endif

surfaceData.specularColor = float3(0.0, 0.0, 0.0);
#else // #if !defined(LAYERED_LIT_SHADER)
// Mandatory to setup value to keep compiler quiet
// Layered shader only support materialId 0
surfaceData.materialId = 0;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;
surfaceData.subSurfaceRadius = 1.0;
surfaceData.thickness = 0.0;
surfaceData.subSurfaceProfile = 0;
surfaceData.coatNormalWS = float3(1.0, 0.0, 0.0);
surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
#endif // #if !defined(LAYERED_LIT_SHADER)
return alpha;

10
Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl


// ref https://gist.github.com/selfshadow/8048308
// Reoriented Normal Mapping
// Blending when n1 and n2 are already 'unpacked' and normalised
float3 blendNormalRNM(float3 n1, float3 n2)
float3 BlendNormalRNM(float3 n1, float3 n2)
{
float3 t = n1.xyz + float3(0.0, 0.0, 1.0);
float3 u = n2.xyz * float3(-1.0, -1.0, 1.0);

float3 blendNormal(float3 n1, float3 n2)
float3 BlendNormal(float3 n1, float3 n2)
{
return normalize(float3(n1.xy * n2.z + n2.xy * n1.z, n1.z * n2.z));
}

blendWeights /= dot(blendWeights.x, 1.0);
return blendWeights;
}
float3 LerpWhiteTo(float3 b, float t)
{
float oneMinusT = 1.0 - t;
return float3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}
#endif // UNITY_COMMON_MATERIAL_INCLUDED
正在加载...
取消
保存