浏览代码

Merge pull request #1209 from Unity-Technologies/LWRP

LWRP
/main
GitHub 7 年前
当前提交
ab445387
共有 89 个文件被更改,包括 3340 次插入1695 次删除
  1. 51
      ScriptableRenderPipeline/Core/CoreRP/Editor/MaterialUpgrader.cs
  2. 4
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/EntityLighting.hlsl
  3. 39
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineAsset.cs
  4. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.asset
  5. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.cs
  6. 30
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightAssetEditor.cs
  7. 101
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightShaderGUI.cs
  8. 58
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardGUI.cs
  9. 4
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardParticlesShaderGUI.cs
  10. 62
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardSimpleLightingGUI.cs
  11. 117
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightUnlitGUI.cs
  12. 17
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightPBRExtraPasses.template
  13. 13
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template
  14. 33
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightUnlitExtraPasses.template
  15. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template
  16. 20
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightConstantBuffer.cs
  17. 830
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  18. 160
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs
  19. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShaderUtils.cs
  20. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-Default.mat
  21. 10
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-StandardSimpleLighting.mat
  22. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl
  23. 16
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Input.hlsl
  24. 87
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl
  25. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl
  26. 112
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl
  27. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl
  28. 84
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Particles.hlsl
  29. 155
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl
  30. 30
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl
  31. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightBlit.shader
  32. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightCopyDepth.shader
  33. 12
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader
  34. 19
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandard.shader
  35. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticles.shader
  36. 18
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticlesSimpleLighting.shader
  37. 18
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticlesUnlit.shader
  38. 24
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardSimpleLighting.shader
  39. 59
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardUnlit.shader
  40. 631
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs
  41. 11
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs.meta
  42. 71
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceCommon.hlsl
  43. 97
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfacePBR.hlsl
  44. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfacePBR.hlsl.meta
  45. 33
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceSimple.hlsl
  46. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceSimple.hlsl.meta
  47. 15
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl
  48. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl.meta
  49. 146
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl
  50. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl.meta
  51. 22
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl
  52. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl.meta
  53. 17
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaSimple.hlsl
  54. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaSimple.hlsl.meta
  55. 33
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/ParticlesPBR.hlsl
  56. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/ParticlesPBR.hlsl.meta
  57. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain.meta
  58. 82
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightSampling.shader
  59. 10
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightSampling.shader.meta
  60. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain.meta
  61. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl.meta
  62. 31
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl
  63. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl.meta
  64. 41
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl
  65. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl.meta
  66. 40
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassDepthOnlyGrass.hlsl
  67. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassDepthOnlyGrass.hlsl.meta
  68. 158
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitGrass.hlsl
  69. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitGrass.hlsl.meta
  70. 165
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl
  71. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl.meta
  72. 108
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl
  73. 114
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrain.shader
  74. 69
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainAddPass.shader
  75. 10
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainAddPass.shader.meta
  76. 143
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainBase.shader
  77. 10
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainBase.shader.meta
  78. 89
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrass.shader
  79. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrass.shader.meta
  80. 89
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrassBillboard.shader
  81. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrassBillboard.shader.meta
  82. 179
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurface.hlsl
  83. 245
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardTerrain.shader
  84. 0
      /ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl.meta
  85. 0
      /ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl
  86. 0
      /ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceCommon.hlsl.meta
  87. 0
      /ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrain.shader.meta

51
ScriptableRenderPipeline/Core/CoreRP/Editor/MaterialUpgrader.cs


namespace UnityEditor.Experimental.Rendering
{
public static class DialogText
{
public static readonly string title = "Material Upgrader";
public static readonly string proceed = "Proceed";
public static readonly string ok = "Ok";
public static readonly string cancel = "Cancel";
public static readonly string noSelectionMessage = "You must select at least one material.";
public static readonly string projectBackMessage = "Make sure to have a project backup before proceeding.";
}
public class MaterialUpgrader
{
public delegate void MaterialFinalizer(Material mat);

private static readonly string projectBackMessage = "Make sure to have a project backup before proceeding.";
MaterialFinalizer m_Finalizer;
Dictionary<string, string> m_TextureRename = new Dictionary<string, string>();

public static void UpgradeProjectFolder(List<MaterialUpgrader> upgraders, string progressBarName, UpgradeFlags flags = UpgradeFlags.None)
{
if (!EditorUtility.DisplayDialog("Material Upgrader", "The upgrade will overwrite materials in your project. " + projectBackMessage, "Proceed", "Cancel"))
if (!EditorUtility.DisplayDialog(DialogText.title, "The upgrade will overwrite materials in your project. " + DialogText.projectBackMessage, DialogText.proceed, DialogText.cancel))
return;
int totalMaterialCount = 0;

public static void Upgrade(Material material, List<MaterialUpgrader> upgraders, UpgradeFlags flags)
{
if (material == null)
return;
var upgrader = GetUpgrader(upgraders, material);
if (upgrader != null)

{
var selection = Selection.objects;
if (selection == null || selection.Length == 0)
if (EditorUtility.DisplayDialog("Material Upgrader", "You must select at least one material.", "Ok"))
return;
if (selection == null)
{
EditorUtility.DisplayDialog(DialogText.title, DialogText.noSelectionMessage, DialogText.ok);
return;
}
List<Material> selectedMaterials = new List<Material>(selection.Length);
for (int i = 0; i < selection.Length; ++i)
{
Material mat = selection[i] as Material;
if (mat != null)
selectedMaterials.Add(mat);
}
int selectedMaterialsCount = selectedMaterials.Count;
if (selectedMaterialsCount == 0)
{
EditorUtility.DisplayDialog(DialogText.title, DialogText.noSelectionMessage, DialogText.ok);
return;
}
if (!EditorUtility.DisplayDialog("Material Upgrader", string.Format("The upgrade will overwrite {0} selected material{1}. ", selection.Length, (selection.Length > 1) ? "s" : "") +
projectBackMessage, "Proceed", "Cancel"))
if (!EditorUtility.DisplayDialog(DialogText.title, string.Format("The upgrade will overwrite {0} selected material{1}. ", selectedMaterialsCount, selectedMaterialsCount > 1 ? "s" : "") +
DialogText.projectBackMessage, DialogText.proceed, DialogText.cancel))
Debug.Log(selection.Length);
for (int i = 0; i < selection.Length; i++)
for (int i = 0; i < selectedMaterialsCount; i++)
if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", i, selection.Length, lastMaterialName), (float)i / (float)selection.Length))
if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", i, selectedMaterialsCount, lastMaterialName), (float)i / (float)selectedMaterialsCount))
var material = selection[i] as Material;
var material = selectedMaterials[i];
Upgrade(material, upgraders, flags);
if (material != null)
lastMaterialName = material.name;

4
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/EntityLighting.hlsl


real3 UnpackLightmapRGBM(real4 rgbmInput, real4 decodeInstructions)
{
return rgbmInput.rgb * pow(rgbmInput.a, decodeInstructions.y) * decodeInstructions.x;
return rgbmInput.rgb * PositivePow(rgbmInput.a, decodeInstructions.y) * decodeInstructions.x;
}
real3 UnpackLightmapDoubleLDR(real4 encodedColor, real4 decodeInstructions)

real alpha = max(decodeInstructions.w * (encodedIrradiance.a - 1.0) + 1.0, 0.0);
// If Linear mode is not supported we can skip exponent part
return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * encodedIrradiance.rgb;
return (decodeInstructions.x * PositivePow(alpha, decodeInstructions.y)) * encodedIrradiance.rgb;
}
real3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), float2 uv, float4 transform, bool encodedLightmap, real4 decodeInstructions)

39
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineAsset.cs


_8x = 8
}
public enum Downsampling
{
None = 0,
_2xBilinear,
_4xBox,
_4xBilinear
}
public enum DefaultMaterialType
{
Standard = 0,

[SerializeField] private bool m_SupportsVertexLight = false;
[SerializeField] private bool m_RequireDepthTexture = false;
[SerializeField] private bool m_RequireSoftParticles = false;
[SerializeField] private bool m_RequireOpaqueTexture = false;
[SerializeField] private Downsampling m_OpaqueDownsampling = Downsampling._2xBilinear;
[SerializeField] private float m_ShadowNearPlaneOffset = 2.0f;
[SerializeField] private float m_ShadowDistance = 50.0f;
[SerializeField] private ShadowCascades m_ShadowCascades = ShadowCascades.FOUR_CASCADES;
[SerializeField] private float m_Cascade2Split = 0.25f;

"LightweightAsset.asset", null, null);
}
//[MenuItem("Assets/Create/Rendering/Lightweight Pipeline Resources", priority = CoreUtils.assetCreateMenuPriority1)]
static void CreateLightweightPipelineResources()
{

var instance = CreateInstance<LightweightPipelineEditorResources>();
AssetDatabase.CreateAsset(instance, string.Format("Assets/{0}.asset", typeof(LightweightPipelineEditorResources).Name));
}
class CreateLightweightPipelineAsset : EndNameEditAction
{

private static T LoadResourceFile<T>() where T : ScriptableObject
{
T resourceAsset = null;
var guids = AssetDatabase.FindAssets(typeof(T).Name + " t:scriptableobject", new []{m_SearchPathProject});
var guids = AssetDatabase.FindAssets(typeof(T).Name + " t:scriptableobject", new[] {m_SearchPathProject});
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);

public bool RequireDepthTexture
{
get { return m_RequireDepthTexture; }
set { m_RequireDepthTexture = value; }
}
public bool RequireSoftParticles

public bool RequireOpaqueTexture
{
get { return m_RequireOpaqueTexture; }
set { m_RequireOpaqueTexture = value; }
}
public Downsampling OpaqueDownsampling
{
get { return m_OpaqueDownsampling; }
set { m_OpaqueDownsampling = value; }
}
public bool SupportsHDR
{
get { return m_SupportsHDR; }

{
get { return (int)m_ShadowAtlasResolution; }
private set { m_ShadowAtlasResolution = (ShadowResolution)value; }
}
public float ShadowNearOffset
{
get { return m_ShadowNearPlaneOffset; }
private set { m_ShadowNearPlaneOffset = value; }
}
public float ShadowDistance

public Shader ScreenSpaceShadowShader
{
get { return resources != null ? resources.ScreenSpaceShadowShader : null; }
}
public Shader SamplingShader
{
get { return resources != null ? resources.SamplingShader : null; }
}
}
}

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.asset


CopyDepthShader: {fileID: 4800000, guid: d6dae50ee9e1bfa4db75f19f99355220, type: 3}
ScreenSpaceShadowShader: {fileID: 4800000, guid: 0f854b35a0cf61a429bd5dcfea30eddd,
type: 3}
SamplingShader: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3}

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.cs


public Shader BlitShader;
public Shader CopyDepthShader;
public Shader ScreenSpaceShadowShader;
public Shader SamplingShader;
}

30
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightAssetEditor.cs


public static GUIContent requireSoftParticles = new GUIContent("Soft Particles", "If enabled the pipeline will enable SOFT_PARTICLES keyword.");
public static GUIContent requireOpaqueTexture = new GUIContent("Opaque Texture", "If enabled the pipeline will copy the screen to texture after opaque objects are drawn. For transparent objects this can be bound in shaders as _CameraOpaqueTexture.");
public static GUIContent opaqueDownsampling = new GUIContent("Opaque Downsampling", "The downsampling method that is used for the opaque texture");
public static GUIContent shadowNearPlaneOffset = new GUIContent("Near Plane Offset",
"Offset shadow near plane to account for large triangles being distorted by pancaking.");
public static GUIContent shadowDistante = new GUIContent("Distance", "Max shadow rendering distance.");

public static string[] shadowTypeOptions = {"No Shadows", "Hard Shadows", "Hard and Soft Shadows"};
public static string[] shadowCascadeOptions = {"No Cascades", "Two Cascades", "Four Cascades"};
public static string[] opaqueDownsamplingOptions = {"None", "2x (Bilinear)", "4x (Box)", "4x (Bilinear)"};
AnimBool m_ShowOpaqueTextureScale = new AnimBool();
private int kMaxSupportedPixelLights = 8;
private float kMinRenderScale = 0.1f;

private SerializedProperty m_SupportsVertexLightProp;
private SerializedProperty m_RequireDepthTextureProp;
private SerializedProperty m_RequireSoftParticlesProp;
private SerializedProperty m_RequireOpaqueTextureProp;
private SerializedProperty m_OpaqueDownsamplingProp;
private SerializedProperty m_ShadowNearPlaneOffsetProp;
private SerializedProperty m_ShadowDistanceProp;
private SerializedProperty m_ShadowAtlasResolutionProp;
private SerializedProperty m_ShadowCascadesProp;

m_SupportsVertexLightProp = serializedObject.FindProperty("m_SupportsVertexLight");
m_RequireDepthTextureProp = serializedObject.FindProperty("m_RequireDepthTexture");
m_RequireSoftParticlesProp = serializedObject.FindProperty("m_RequireSoftParticles");
m_RequireOpaqueTextureProp = serializedObject.FindProperty("m_RequireOpaqueTexture");
m_OpaqueDownsamplingProp = serializedObject.FindProperty("m_OpaqueDownsampling");
m_ShadowNearPlaneOffsetProp = serializedObject.FindProperty("m_ShadowNearPlaneOffset");
m_ShadowDistanceProp = serializedObject.FindProperty("m_ShadowDistance");
m_ShadowAtlasResolutionProp = serializedObject.FindProperty("m_ShadowAtlasResolution");
m_ShadowCascadesProp = serializedObject.FindProperty("m_ShadowCascades");

m_ShowSoftParticles.valueChanged.AddListener(Repaint);
m_ShowSoftParticles.value = m_RequireSoftParticlesProp.boolValue;
m_ShowOpaqueTextureScale.valueChanged.AddListener(Repaint);
m_ShowOpaqueTextureScale.value = m_RequireOpaqueTextureProp.boolValue;
m_ShowOpaqueTextureScale.valueChanged.RemoveListener(Repaint);
m_ShowOpaqueTextureScale.target = m_RequireOpaqueTextureProp.boolValue;
}
void DrawAnimatedProperty(SerializedProperty prop, GUIContent content, AnimBool animation)

EditorGUILayout.PropertyField(prop, content);
}
void DrawAnimatedPopup(SerializedProperty prop, GUIContent content, string[] options, AnimBool animation)
{
using (var group = new EditorGUILayout.FadeGroupScope(animation.faded))
if (group.visible)
CoreEditorUtils.DrawPopup(content, prop, options);
}
public override void OnInspectorGUI()
{
serializedObject.Update();

EditorGUILayout.PropertyField(m_SupportsVertexLightProp, Styles.enableVertexLightLabel);
EditorGUILayout.PropertyField(m_RequireDepthTextureProp, Styles.requireDepthTexture);
DrawAnimatedProperty(m_RequireSoftParticlesProp, Styles.requireSoftParticles, m_ShowSoftParticles);
EditorGUILayout.PropertyField(m_RequireOpaqueTextureProp, Styles.requireOpaqueTexture);
DrawAnimatedPopup(m_OpaqueDownsamplingProp, Styles.opaqueDownsampling, Styles.opaqueDownsamplingOptions, m_ShowOpaqueTextureScale);
EditorGUILayout.PropertyField(m_HDR, Styles.hdrContent);
EditorGUILayout.PropertyField(m_MSAA, Styles.msaaContent);

EditorGUI.indentLevel++;
CoreEditorUtils.DrawPopup(Styles.shadowType, m_ShadowTypeProp, Styles.shadowTypeOptions);
EditorGUILayout.PropertyField(m_ShadowAtlasResolutionProp, Styles.shadowAtlasResolution);
EditorGUILayout.PropertyField(m_ShadowNearPlaneOffsetProp, Styles.shadowNearPlaneOffset);
m_ShadowDistanceProp.floatValue = Mathf.Max(0.0f, EditorGUILayout.FloatField(Styles.shadowDistante, m_ShadowDistanceProp.floatValue));
CoreEditorUtils.DrawPopup(Styles.shadowCascades, m_ShadowCascadesProp, Styles.shadowCascadeOptions);

101
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightShaderGUI.cs


using System;
using UnityEditor;
using UnityEngine;

Multiply
}
public abstract void FindProperties(MaterialProperty[] props);
public abstract void ShaderPropertiesGUI(Material material);
private static class Styles
{
public static string renderingOptionsLabel = "Rendering Options";
public static string surfaceType = "Surface Type";
public static string blendingMode = "Blending Mode";
public static GUIContent twoSidedText = new GUIContent("Two Sided", "Render front and back faces");
public static GUIContent alphaClipText = new GUIContent("Alpha Clip", "Enable Alpha Clip");
public static GUIContent alphaClipThresholdText = new GUIContent("Clip Threshold", "Threshold for alpha clip");
public static readonly string[] surfaceNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
}
protected MaterialEditor m_MaterialEditor;
protected MaterialProperty surfaceTypeProp;
protected MaterialProperty blendModeProp;
protected MaterialProperty cullingProp;
protected MaterialProperty alphaClipProp;
protected MaterialProperty alphaCutoffProp;
private bool m_FirstTimeApply = true;
public virtual void FindProperties(MaterialProperty[] properties)
{
surfaceTypeProp = FindProperty("_Surface", properties);
blendModeProp = FindProperty("_Blend", properties);
cullingProp = FindProperty("_Cull", properties);
alphaClipProp = FindProperty("_AlphaClip", properties);
alphaCutoffProp = FindProperty("_Cutoff", properties);
}
public virtual void ShaderPropertiesGUI(Material material)
{
DoPopup(Styles.surfaceType, surfaceTypeProp, Styles.surfaceNames);
if ((SurfaceType)material.GetFloat("_Surface") == SurfaceType.Transparent)
DoPopup(Styles.blendingMode, blendModeProp, Styles.blendNames);
EditorGUI.BeginChangeCheck();
bool twoSidedEnabled = EditorGUILayout.Toggle(Styles.twoSidedText, cullingProp.floatValue == 0);
if (EditorGUI.EndChangeCheck())
cullingProp.floatValue = twoSidedEnabled ? 0 : 2;
EditorGUI.BeginChangeCheck();
bool alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipText, alphaClipProp.floatValue == 1);
if (EditorGUI.EndChangeCheck())
alphaClipProp.floatValue = alphaClipEnabled ? 1 : 0;
if (alphaClipProp.floatValue == 1)
m_MaterialEditor.ShaderProperty(alphaCutoffProp, Styles.alphaClipThresholdText, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
EditorGUILayout.Space();
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly

ShaderPropertiesGUI(material);
}
protected void DoPopup(string label, MaterialProperty property, string[] options)
{
EditorGUI.showMixedValue = property.hasMixedValue;
var mode = property.floatValue;
EditorGUI.BeginChangeCheck();
mode = EditorGUILayout.Popup(label, (int)mode, options);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo(label);
property.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
if(alphaClip)
if (alphaClip)
if(surfaceType == SurfaceType.Opaque)
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);

material.SetShaderPassEnabled("ShadowCaster", true);
}
else
{
{
BlendMode blendMode = (BlendMode)material.GetFloat("_Blend");
switch (blendMode)
{

}
}
protected MaterialEditor m_MaterialEditor;
private bool m_FirstTimeApply = true;
protected void DoPopup(string label, MaterialProperty property, string[] options)
{
EditorGUI.showMixedValue = property.hasMixedValue;
var mode = property.floatValue;
EditorGUI.BeginChangeCheck();
mode = EditorGUILayout.Popup(label, (int)mode, options);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo(label);
property.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void DoMaterialRenderingOptions()
{
EditorGUILayout.Space();
GUILayout.Label(Styles.renderingOptionsLabel, EditorStyles.boldLabel);
m_MaterialEditor.EnableInstancingField();
m_MaterialEditor.DoubleSidedGIField();
}
}

58
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardGUI.cs


private static class Styles
{
public static GUIContent twoSidedText = new GUIContent("Two Sided", "Render front and back faces");
public static GUIContent alphaClipText = new GUIContent("Alpha Clip", "Enable Alpha Clip");
public static GUIContent clipThresholdText = new GUIContent("Clip Threshold", "Threshold for alpha clip");
public static GUIContent specularMapText = new GUIContent("Specular", "Specular (RGB) and Smoothness (A)");
public static GUIContent metallicMapText = new GUIContent("Metallic", "Metallic (R) and Smoothness (A)");
public static GUIContent smoothnessText = new GUIContent("Smoothness", "Smoothness value");

public static GUIContent bumpScaleNotSupported = new GUIContent("Bump scale is not supported on mobile platforms");
public static GUIContent fixNow = new GUIContent("Fix now");
public static string primaryMapsText = "Main Maps";
public static string secondaryMapsText = "Secondary Maps";
public static string forwardText = "Forward Rendering Options";
public static string surfaceProperties = "Surface Properties";
public static string surfaceType = "Surface Type";
public static string blendingMode = "Blending Mode";
public static string advancedText = "Advanced Options";
public static readonly string[] surfaceNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
private MaterialProperty surfaceType;
private MaterialProperty blendMode;
private MaterialProperty culling;
private MaterialProperty alphaClip;
private MaterialProperty alphaThreshold;
private MaterialProperty smoothness;
private MaterialProperty smoothnessScale;

public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
surfaceType = FindProperty("_Surface", properties);
blendMode = FindProperty("_Blend", properties);
culling = FindProperty("_Cull", properties);
alphaClip = FindProperty("_AlphaClip", properties);
alphaThreshold = FindProperty("_Cutoff", properties);
smoothness = FindProperty("_Glossiness", properties);
smoothnessScale = FindProperty("_GlossMapScale", properties, false);

EditorGUI.BeginChangeCheck();
{
DoPopup(Styles.workflowModeText, workflowMode, Styles.workflowNames);
DoPopup(Styles.surfaceType, surfaceType, Styles.surfaceNames);
if ((SurfaceType)material.GetFloat("_Surface") == SurfaceType.Transparent)
DoPopup(Styles.blendingMode, blendMode, Styles.blendNames);
EditorGUI.BeginChangeCheck();
bool twoSidedEnabled = EditorGUILayout.Toggle(Styles.twoSidedText, culling.floatValue == 0);
if (EditorGUI.EndChangeCheck())
culling.floatValue = twoSidedEnabled ? 0 : 2;
EditorGUI.BeginChangeCheck();
bool alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipText, alphaClip.floatValue == 1);
if (EditorGUI.EndChangeCheck())
alphaClip.floatValue = alphaClipEnabled ? 1 : 0;
base.ShaderPropertiesGUI(material);
GUILayout.Label(Styles.surfaceProperties, EditorStyles.boldLabel);
// Primary properties
GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel);
DoAlbedoArea(material);
DoAlbedoArea();
DoMetallicSpecularArea();
DoNormalArea();

}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in blendMode.targets)
foreach (var obj in blendModeProp.targets)
EditorGUILayout.Space();
// NB renderqueue editor is not shown on purpose: we want to override it based on blend mode
GUILayout.Label(Styles.advancedText, EditorStyles.boldLabel);
m_MaterialEditor.EnableInstancingField();
m_MaterialEditor.DoubleSidedGIField();
DoMaterialRenderingOptions();
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)

MaterialChanged(material);
}
void DoAlbedoArea(Material material)
void DoAlbedoArea()
if (material.GetFloat("_AlphaClip") == 1)
{
m_MaterialEditor.ShaderProperty(alphaThreshold, Styles.clipThresholdText.text, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
}
}
void DoNormalArea()

4
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardParticlesShaderGUI.cs


metallicMap = FindProperty("_MetallicGlossMap", props, false);
metallic = FindProperty("_Metallic", props, false);
smoothness = FindProperty("_Glossiness", props, false);
bumpScale = FindProperty("_BumpScale", props);
bumpMap = FindProperty("_BumpMap", props);
bumpScale = FindProperty("_BumpScale", props, false);
bumpMap = FindProperty("_BumpMap", props, false);
emissionEnabled = FindProperty("_EmissionEnabled", props);
emissionColorForRendering = FindProperty("_EmissionColor", props);
emissionMap = FindProperty("_EmissionMap", props);

62
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardSimpleLightingGUI.cs


public class LightweightStandardSimpleLightingGUI : LightweightShaderGUI
{
private const float kMinShininessValue = 0.01f;
private MaterialProperty surfaceTypeProp;
private MaterialProperty blendModeProp;
private MaterialProperty culling;
private MaterialProperty alphaClip;
private MaterialProperty alphaThresholdProp;
private MaterialProperty specularSourceProp;
private MaterialProperty glossinessSourceProp;
private MaterialProperty specularGlossMapProp;

private static class Styles
{
public static GUIContent twoSidedLabel = new GUIContent("Two Sided", "Render front and back faces");
public static GUIContent alphaClipLabel = new GUIContent("Alpha Clip", "Enable Alpha Clip");
public static GUIContent[] albedoGlosinessLabels =
{
new GUIContent("Base (RGB) Glossiness (A)", "Base Color (RGB) and Glossiness (A)"),

public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map");
public static GUIContent emissionMapLabel = new GUIContent("Emission Map", "Emission Map");
public static readonly string[] surfaceNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendNames = Enum.GetNames(typeof(UpgradeBlendMode));
public static string surfaceTypeLabel = "Surface Type";
public static string blendingModeLabel = "Blending Mode";
public static string surfaceProperties = "Surface Properties";
public static string specularSourceLabel = "Specular";
public static string glossinessSourceLabel = "Glossiness Source";
public static string glossinessSource = "Glossiness Source";

public static string clipThresholdLabel = "Clip Threshold";
public static string advancedText = "Advanced Options";
surfaceTypeProp = FindProperty("_Surface", properties);
blendModeProp = FindProperty("_Blend", properties);
culling = FindProperty("_Cull", properties);
alphaClip = FindProperty("_AlphaClip", properties);
base.FindProperties(properties);
alphaThresholdProp = FindProperty("_Cutoff", properties);
specularSourceProp = FindProperty("_SpecSource", properties);
glossinessSourceProp = FindProperty("_GlossinessSource", properties);
specularGlossMapProp = FindProperty("_SpecGlossMap", properties);

{
EditorGUI.BeginChangeCheck();
{
base.ShaderPropertiesGUI(material);
GUILayout.Label(Styles.surfaceProperties, EditorStyles.boldLabel);
DoSurfaceArea();
DoSpecular();

m_MaterialEditor.TextureScaleOffsetProperty(albedoMapProp);
if (EditorGUI.EndChangeCheck())
emissionMapProp.textureScaleAndOffset = albedoMapProp.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake
}
GUILayout.Label(Styles.advancedText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.EnableInstancingField();
EditorGUI.indentLevel--;
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in blendModeProp.targets)

EditorGUILayout.Space();
EditorGUILayout.Space();
DoMaterialRenderingOptions();
}
public override void MaterialChanged(Material material)

private bool RequiresAlpha()
{
SurfaceType surfaceType = (SurfaceType) surfaceTypeProp.floatValue;
return alphaClip.floatValue > 0.0f || surfaceType == SurfaceType.Transparent;
return alphaClipProp.floatValue > 0.0f || surfaceType == SurfaceType.Transparent;
int surfaceTypeValue = (int)surfaceTypeProp.floatValue;
EditorGUI.BeginChangeCheck();
surfaceTypeValue = EditorGUILayout.Popup(Styles.surfaceTypeLabel, surfaceTypeValue, Styles.surfaceNames);
if (EditorGUI.EndChangeCheck())
surfaceTypeProp.floatValue = surfaceTypeValue;
if((SurfaceType)surfaceTypeValue == SurfaceType.Transparent)
{
int blendModeValue = (int)blendModeProp.floatValue;
EditorGUI.BeginChangeCheck();
blendModeValue = EditorGUILayout.Popup(Styles.blendingModeLabel, blendModeValue, Styles.blendNames);
if (EditorGUI.EndChangeCheck())
blendModeProp.floatValue = blendModeValue;
}
EditorGUI.BeginChangeCheck();
bool twoSidedEnabled = EditorGUILayout.Toggle(Styles.twoSidedLabel, culling.floatValue == 0);
if (EditorGUI.EndChangeCheck())
culling.floatValue = twoSidedEnabled ? 0 : 2;
EditorGUI.BeginChangeCheck();
bool alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipLabel, alphaClip.floatValue == 1);
if (EditorGUI.EndChangeCheck())
alphaClip.floatValue = alphaClipEnabled ? 1 : 0;
int surfaceTypeValue = (int)surfaceTypeProp.floatValue;
if ((SurfaceType)surfaceTypeValue == SurfaceType.Opaque)
{
int glossSource = (int)glossinessSourceProp.floatValue;

{
m_MaterialEditor.TexturePropertySingleLine(Styles.albedoAlphaLabel, albedoMapProp, albedoColorProp);
}
if (alphaClipEnabled)
m_MaterialEditor.ShaderProperty(alphaThresholdProp, Styles.clipThresholdLabel, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
}
private void DoSpecular()

117
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightUnlitGUI.cs


using System;
using UnityEditor;
using UnityEngine;
using UnityEditor.Experimental.Rendering.LightweightPipeline;
public enum UnlitBlendMode
{
Alpha, // Old school alpha-blending mode, fresnel does not affect amount of transparency
Additive,
Multiply
}
private MaterialProperty surfaceTypeProp;
private MaterialProperty blendModeProp;
private MaterialProperty culling;
private MaterialProperty alphaClip;
private MaterialProperty alphaCutoffProp;
public static GUIContent twoSidedLabel = new GUIContent("Two Sided", "Render front and back faces");
public static GUIContent alphaClipLabel = new GUIContent("Alpha Clip", "Enable Alpha Clip");
public static GUIContent[] mainTexLabels =
{
new GUIContent("MainTex (RGB)", "Base Color"),

public static string surfaceProperties = "Surface Properties";
public static readonly string[] surfaceNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendNames = Enum.GetNames(typeof(UnlitBlendMode));
public static string surfaceTypeLabel = "Surface Type";
public static string blendingModeLabel = "Blending Mode";
public static string clipThresholdLabel = "Clip Threshold";
surfaceTypeProp = FindProperty("_Surface", properties);
blendModeProp = FindProperty("_Blend", properties);
culling = FindProperty("_Cull", properties);
alphaClip = FindProperty("_AlphaClip", properties);
base.FindProperties(properties);
alphaCutoffProp = FindProperty("_Cutoff", properties);
sampleGIProp = FindProperty("_SampleGI", properties, false);
bumpMap = FindProperty("_BumpMap", properties, false);
}

EditorGUI.BeginChangeCheck();
{
DoPopup(Styles.surfaceTypeLabel, surfaceTypeProp, Styles.surfaceNames);
base.ShaderPropertiesGUI(material);
GUILayout.Label(Styles.surfaceProperties, EditorStyles.boldLabel);
if((SurfaceType)surfaceTypeValue == SurfaceType.Transparent)
DoPopup(Styles.blendingModeLabel, blendModeProp, Styles.blendNames);
EditorGUI.BeginChangeCheck();
bool twoSidedEnabled = EditorGUILayout.Toggle(Styles.twoSidedLabel, culling.floatValue == 0);
if (EditorGUI.EndChangeCheck())
culling.floatValue = twoSidedEnabled ? 0 : 2;
EditorGUI.BeginChangeCheck();
bool alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipLabel, alphaClip.floatValue == 1);
if (EditorGUI.EndChangeCheck())
alphaClip.floatValue = alphaClipEnabled ? 1 : 0;
if (alphaClipProp.floatValue >= 1.0f)
surfaceTypeValue = 1;
if (alphaClipEnabled)
m_MaterialEditor.ShaderProperty(alphaCutoffProp, Styles.clipThresholdLabel, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
m_MaterialEditor.TextureScaleOffsetProperty(mainTexProp);
EditorGUILayout.Space();
EditorGUILayout.Space();
m_MaterialEditor.TextureScaleOffsetProperty(mainTexProp);
}
if (EditorGUI.EndChangeCheck())
{

EditorGUILayout.Space();
EditorGUILayout.Space();
DoMaterialRenderingOptions();
SetupMaterialBlendMode(material);
SetMaterialKeywords(material);
}
static void SetMaterialKeywords(Material material)
{
bool alphaClip = material.GetFloat("_AlphaClip") == 1;
if(alphaClip)
material.EnableKeyword("_ALPHATEST_ON");
else
material.DisableKeyword("_ALPHATEST_ON");
SurfaceType surfaceType = (SurfaceType)material.GetFloat("_Surface");
if(surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = -1;
material.SetShaderPassEnabled("ShadowCaster", true);
}
else
{
UnlitBlendMode blendMode = (UnlitBlendMode)material.GetFloat("_Blend");
switch (blendMode)
{
case UnlitBlendMode.Alpha:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
case UnlitBlendMode.Additive:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
case UnlitBlendMode.Multiply:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
}
}
}
}

17
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightPBRExtraPasses.template


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
// -------------------------------------
// Material Keywords
#pragma shader_feature _ALPHATEST_ON
//--------------------------------------
// GPU Instancing

#pragma fragment ShadowPassFragment
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
ENDHLSL

ZWrite On
ColorMask 0
Cull ${Culling}
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library

#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature _ALPHATEST_ON
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
ENDHLSL
}

#pragma shader_feature _SPECGLOSSMAP
#include "LWRP/ShaderLibrary/LightweightPassMeta.hlsl"
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl"
}
}

13
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------

#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ FOG_LINEAR FOG_EXP2
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing

o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
o.clipPos = clipPos;
o.shadowCoord = ComputeShadowCoord(o.clipPos);
#ifdef _SHADOWS_ENABLED
#if SHADOWS_SCREEN
o.shadowCoord = ComputeShadowCoord(clipPos);
#else
o.shadowCoord = TransformWorldToShadowCoord(lwWorldPos);
#endif
#endif
return o;
}

33
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightUnlitExtraPasses.template


Pass
{
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
Cull ${Culling}
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
ENDHLSL
}
Pass
{

Cull ${Culling}
#pragma exclude_renderers d3d11_9x
// -------------------------------------
// Material Keywords
#pragma shader_feature _ALPHATEST_ON
#include "LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl"
}
}

6
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog

#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/Lighting.hlsl"
#include "CoreRP/ShaderLibrary/Color.hlsl"
#include "LWRP/ShaderLibrary/InputSurface.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl"
#include "ShaderGraphLibrary/Functions.hlsl"
${Defines}

float AlphaClipThreshold = 0;
${SurfaceOutputRemap}
#if _AlphaClip
#if _AlphaClip
clip(Alpha - AlphaClipThreshold);
#endif
return half4(Color, Alpha);

20
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightConstantBuffer.cs


{
public static int _MainLightPosition;
public static int _MainLightColor;
public static int _MainLightDistanceAttenuation;
public static int _MainLightSpotDir;
public static int _MainLightSpotAttenuation;
public static int _MainLightCookie;
public static int _WorldToLight;

public static int _AdditionalLightDistanceAttenuation;
public static int _AdditionalLightSpotDir;
public static int _AdditionalLightSpotAttenuation;
public static int _LightIndexBuffer;
public static int _ScaledScreenParams;
public static class ShadowConstantBuffer
public static class DirectionalShadowConstantBuffer
{
public static int _WorldToShadow;
public static int _ShadowData;

public static int _ShadowOffset2;
public static int _ShadowOffset3;
public static int _ShadowmapSize;
}
public static class LocalShadowConstantBuffer
{
public static int _LocalWorldToShadowAtlas;
public static int _LocalShadowStrength;
public static int _LocalShadowOffset0;
public static int _LocalShadowOffset1;
public static int _LocalShadowOffset2;
public static int _LocalShadowOffset3;
public static int _LocalShadowmapSize;
}
}

830
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
文件差异内容过多而无法显示
查看文件

160
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs


using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
{

}
}
public class LightComparer : IComparer<VisibleLight>
[Flags]
public enum FrameRenderingConfiguration
public Camera CurrCamera { get; set; }
None = 0,
Stereo = (1 << 0),
Msaa = (1 << 1),
BeforeTransparentPostProcess = (1 << 2),
PostProcess = (1 << 3),
DepthPrePass = (1 << 4),
DepthCopy = (1 << 5),
DefaultViewport = (1 << 6),
IntermediateTexture = (1 << 7)
}
public int Compare(VisibleLight lhs, VisibleLight rhs)
public static class LightweightUtils
{
static Mesh s_FullscreenMesh = null;
public static Mesh fullscreenMesh
Light lhsLight = lhs.light;
Light rhsLight = rhs.light;
// Particle Lights have the Light reference set to null
// They are at the end of the priority
if (lhsLight == null) return 1;
if (rhsLight == null) return -1;
// Prioritize lights marked as important
if (lhsLight.renderMode != rhsLight.renderMode)
get
if (lhsLight.renderMode == LightRenderMode.ForcePixel) return -1;
if (rhsLight.renderMode == LightRenderMode.ForcePixel) return 1;
}
if (s_FullscreenMesh != null)
return s_FullscreenMesh;
// Prioritize Directional Lights
if (lhs.lightType != rhs.lightType)
{
if (lhs.lightType == LightType.Directional) return -1;
if (rhs.lightType == LightType.Directional) return 1;
}
float topV = 1.0f;
float bottomV = 0.0f;
// Prioritize Shadows Lights Soft > Hard > None
if (lhsLight.shadows != rhsLight.shadows)
return (int)rhsLight.shadows - (int)lhsLight.shadows;
Mesh mesh = new Mesh {name = "Fullscreen Quad"};
mesh.SetVertices(new List<Vector3>
{
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(-1.0f, 1.0f, 0.0f),
new Vector3( 1.0f, -1.0f, 0.0f),
new Vector3( 1.0f, 1.0f, 0.0f)
});
// Prioritize lights with cookies
if (lhsLight.cookie != rhsLight.cookie)
return (lhsLight.cookie != null) ? -1 : 1;
mesh.SetUVs(0, new List<Vector2>
{
new Vector2(0.0f, bottomV),
new Vector2(0.0f, topV),
new Vector2(1.0f, bottomV),
new Vector2(1.0f, topV)
});
// If directional sort by intensity
if (lhs.lightType == LightType.Directional)
{
return (int)(rhsLight.intensity * 100.0f) - (int)(lhsLight.intensity * 100.0f);
mesh.SetIndices(new[] { 0, 1, 2, 2, 1, 3 }, MeshTopology.Triangles, 0, false);
mesh.UploadMeshData(true);
return mesh;
// Punctual lights are sorted per-object by the engine based on distance to object center + luminance
// Here we sort globally the light list per camera distance to fit the closest lights in the global light buffer
// Check MAX_VISIBLE_LIGHTS in the LightweightLighting.cginc to see the max global buffer list size
int lhsDistance = (int)(SquaredDistanceToCamera(lhsLight.transform.position) * 100.0f);
int rhsDistance = (int)(SquaredDistanceToCamera(rhsLight.transform.position) * 100.0f);
int result = lhsDistance - rhsDistance;
return result;
public float SquaredDistanceToCamera(Vector3 lightPos)
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
Vector3 lightCameraVector = lightPos - CurrCamera.transform.position;
return Vector3.Dot(lightCameraVector, lightCameraVector);
commandBuffer.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, shaderPassId, properties);
}
public class LightEqualityComparer : IEqualityComparer<VisibleLight>
{
public bool Equals(VisibleLight x, VisibleLight y)
public static void StartStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
if (x.light == null && y.light == null)
return true;
if (x.light == null || y.light == null)
return false;
return x.light.GetInstanceID() == y.light.GetInstanceID();
if (HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
context.StartMultiEye(camera);
public int GetHashCode(VisibleLight obj)
public static void StopStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
if (obj.light == null) // Particle light weirdness
return obj.GetHashCode();
return obj.light.GetInstanceID();
if (HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
context.StopMultiEye(camera);
}
[Flags]
public enum FrameRenderingConfiguration
{
None = 0,
Stereo = (1 << 0),
Msaa = (1 << 1),
BeforeTransparentPostProcess = (1 << 2),
PostProcess = (1 << 3),
DepthPrePass = (1 << 4),
DepthCopy = (1 << 5),
DefaultViewport = (1 << 6),
IntermediateTexture = (1 << 7)
}
public static class LightweightUtils
{
public static void GetLightCookieMatrix(VisibleLight light, out Matrix4x4 cookieMatrix)
{
cookieMatrix = Matrix4x4.Inverse(light.localToWorld);

public static bool HasFlag(FrameRenderingConfiguration mask, FrameRenderingConfiguration flag)
{
return (mask & flag) != 0;
}
public static Mesh CreateQuadMesh(bool uvStartsAtTop)
{
float topV, bottomV;
if (uvStartsAtTop)
{
topV = 0.0f;
bottomV = 1.0f;
}
else
{
topV = 1.0f;
bottomV = 0.0f;
}
Mesh mesh = new Mesh();
mesh.vertices = new Vector3[]
{
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(-1.0f, 1.0f, 0.0f),
new Vector3(1.0f, -1.0f, 0.0f),
new Vector3(1.0f, 1.0f, 0.0f)
};
mesh.uv = new Vector2[]
{
new Vector2(0.0f, bottomV),
new Vector2(0.0f, topV),
new Vector2(1.0f, bottomV),
new Vector2(1.0f, topV)
};
mesh.triangles = new int[] { 0, 1, 2, 2, 1, 3 };
return mesh;
}
}
}

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShaderUtils.cs


"LightweightPipeline/Standard (Physically Based)",
"LightweightPipeline/Standard (Simple Lighting)",
"LightweightPipeline/Standard Unlit",
"LightweightPipeline/Standard Terrain",
"LightweightPipeline/Terrain/Standard Terrain",
"LightweightPipeline/Particles/Standard",
"LightweightPipeline/Particles/Standard Unlit",
"Hidden/LightweightPipeline/Blit",

6
ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-Default.mat


m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaClip: 0
- _Blend: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0

- _SpecSource: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Surface: 0
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 0.5, g: 0.5, b: 0.5, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 1, g: 1, b: 1, a: 1}

10
ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-StandardSimpleLighting.mat


m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaClip: 0
- _Blend: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0

- _Mode: 0
- _Parallax: 0.02
- _ReflectionSource: 0
- _Shininess: 0.15
- _Shininess: 0.5
- _Surface: 0
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 0.5, g: 0.5, b: 0.5, a: 1}
- _SpecColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}

5
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl


#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#endif
float4 GetScaledScreenParams()
{
return _ScaledScreenParams;
}
void AlphaDiscard(half alpha, half cutoff, half offset = 0.0h)
{
#ifdef _ALPHATEST_ON

16
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Input.hlsl


#define MAX_VISIBLE_LIGHTS 16
// Must match check of use compute buffer in LightweightPipeline.cs
// GLES check here because of WebGL 1.0 support
// TODO: check performance of using StructuredBuffer on mobile as well
#if defined(SHADER_API_MOBILE) || defined(SHADER_API_GLES)
#define USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA 0
#else
#define USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA 1
#endif
struct InputData
{
float3 positionWS;

CBUFFER_START(_PerCamera)
float4 _MainLightPosition;
half4 _MainLightColor;
half4 _MainLightDistanceAttenuation;
half4 _MainLightSpotDir;
half4 _MainLightSpotAttenuation;
float4x4 _WorldToLight;
half4 _AdditionalLightCount;

half4 _AdditionalLightSpotDir[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightSpotAttenuation[MAX_VISIBLE_LIGHTS];
float4 _ScaledScreenParams;
StructuredBuffer<int> _LightIndexBuffer;
#define UNITY_MATRIX_M unity_ObjectToWorld
#define UNITY_MATRIX_I_M unity_WorldToObject

87
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl


#include "Core.hlsl"
#include "Shadows.hlsl"
#ifdef NO_ADDITIONAL_LIGHTS
#undef _ADDITIONAL_LIGHTS
#endif
// If lightmap is not defined than we evaluate GI (ambient + probes) from SH
// We might do it fully or partially in vertex to save shader ALU
#if !defined(LIGHTMAP_ON)

// Abstraction over Light shading data.
struct Light
{
int index;
half3 direction;
half3 color;
half attenuation;

// We use a shared distance attenuation for additional directional and puctual lights
// for directional lights attenuation will be 1
half quadFalloff = distanceAttenuation.x;
half denom = distanceSqr * quadFalloff + 1.0;
half lightAtten = 1.0 / denom;
half denom = distanceSqr * quadFalloff + 1.0h;
half lightAtten = 1.0h / denom;
// We need to smoothly fade attenuation to light range. We start fading linearly at 80% of light range
// Therefore:

{
half4 directionAndAttenuation = GetLightDirectionAndAttenuation(lightInput, positionWS);
// Cookies are only computed for main light
directionAndAttenuation.w *= CookieAttenuation(positionWS);
// Cookies disabled for now due to amount of shader variants
//directionAndAttenuation.w *= CookieAttenuation(positionWS);
return directionAndAttenuation;
}

///////////////////////////////////////////////////////////////////////////////
Light GetMainLight(float3 positionWS)
Light GetMainLight()
LightInput lightInput;
lightInput.position = _MainLightPosition;
lightInput.color = _MainLightColor.rgb;
lightInput.distanceAttenuation = _MainLightDistanceAttenuation;
lightInput.spotDirection = _MainLightSpotDir;
lightInput.spotAttenuation = _MainLightSpotAttenuation;
half4 directionAndRealtimeAttenuation = GetMainLightDirectionAndAttenuation(lightInput, positionWS);
light.direction = directionAndRealtimeAttenuation.xyz;
light.attenuation = directionAndRealtimeAttenuation.w;
light.subtractiveModeAttenuation = lightInput.distanceAttenuation.w;
light.color = lightInput.color;
light.index = 0;
light.direction = _MainLightPosition.xyz;
light.attenuation = 1.0;
light.subtractiveModeAttenuation = _MainLightPosition.w;
light.color = _MainLightColor.rgb;
Light GetLight(int i, float3 positionWS)
Light GetLight(half i, float3 positionWS)
half4 indices = (i < 4) ? unity_4LightIndices0 : unity_4LightIndices1;
int index = (i < 4) ? i : i - 4;
int lightIndex = indices[index];
#if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
int lightIndex = _LightIndexBuffer[unity_LightIndicesOffsetAndCount.x + i];
#else
// The following code is more optimal than indexing unity_4LightIndices0.
// Conditional moves are branch free even on mali-400
half i_rem = (i < 2.0h) ? i : i - 2.0h;
half2 lightIndex2 = (i < 2.0h) ? unity_4LightIndices0.xy : unity_4LightIndices0.zw;
int lightIndex = (i_rem < 1.0h) ? lightIndex2.x : lightIndex2.y;
#endif
// The following code will turn into a branching madhouse on platforms that don't support
// dynamic indexing. Ideally we need to configure light data at a cluster of
// objects granularity level. We will only be able to do that when scriptable culling kicks in.
// TODO: Use StructuredBuffer on PC/Console and profile access speed on mobile that support it.
lightInput.position = _AdditionalLightPosition[lightIndex];
lightInput.color = _AdditionalLightColor[lightIndex].rgb;
lightInput.distanceAttenuation = _AdditionalLightDistanceAttenuation[lightIndex];

half4 directionAndRealtimeAttenuation = GetLightDirectionAndAttenuation(lightInput, positionWS);
Light light;
light.index = lightIndex;
light.direction = directionAndRealtimeAttenuation.xyz;
light.attenuation = directionAndRealtimeAttenuation.w;
light.subtractiveModeAttenuation = lightInput.distanceAttenuation.w;

half GetPixelLightCount()
{
// TODO: we need to expose in SRP api an ability for the pipeline cap the amount of lights
// in the culling. This way we could do the loop branch with an uniform
// This would be helpful to support baking exceeding lights in SH as well
return min(_AdditionalLightCount.x, unity_LightIndicesOffsetAndCount.y);
}

// If lightmap: sampleData.xy = lightmapUV
// If probe: sampleData.xyz = L2 SH terms
#ifdef LIGHTMAP_ON
#define SAMPLE_GI(lmName, shName, normalWSName) SampleGI(lmName, normalWSName)
half3 SampleGI(float2 sampleData, half3 normalWS)
{
return SampleLightmap(sampleData, normalWS);
}
#define SAMPLE_GI(lmName, shName, normalWSName) SampleLightmap(lmName, normalWSName)
#define SAMPLE_GI(lmName, shName, normalWSName) SampleGI(shName, normalWSName)
half3 SampleGI(half3 sampleData, half3 normalWS)
{
// If lightmap is not enabled we sample GI from SH
return SampleSHPixel(sampleData, normalWS);
}
#define SAMPLE_GI(lmName, shName, normalWSName) SampleSHPixel(shName, normalWSName)
#endif
half3 GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion)

// 1) Gives good estimate of illumination as if light would've been shadowed during the bake.
// We only subtract the main direction light. This is accounted in the contribution term below.
half shadowStrength = GetShadowStrength();
half contributionTerm = saturate(dot(mainLight.direction, normalWS)) * (1.0 - _MainLightPosition.w);
half shadowStrength = _ShadowData.x;
half contributionTerm = saturate(dot(mainLight.direction, normalWS));
half3 lambert = mainLight.color * contributionTerm;
half3 estimatedLightContributionMaskedByInverseOfShadow = lambert * (1.0 - mainLight.attenuation);
half3 subtractedLightmap = bakedGI - estimatedLightContributionMaskedByInverseOfShadow;

BRDFData brdfData;
InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
Light mainLight = GetMainLight(inputData.positionWS);
mainLight.attenuation *= RealtimeShadowAttenuation(inputData.shadowCoord);
Light mainLight = GetMainLight();
mainLight.attenuation = MainLightRealtimeShadowAttenuation(inputData.shadowCoord);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);

for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetLight(i, inputData.positionWS);
light.attenuation *= LocalLightRealtimeShadowAttenuation(light.index, inputData.positionWS);
color += LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS);
}
#endif

half4 LightweightFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half shininess, half3 emission, half alpha)
{
Light mainLight = GetMainLight(inputData.positionWS);
mainLight.attenuation *= RealtimeShadowAttenuation(inputData.shadowCoord);
Light mainLight = GetMainLight();
mainLight.attenuation = MainLightRealtimeShadowAttenuation(inputData.shadowCoord);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 attenuatedLightColor = mainLight.color * mainLight.attenuation;

for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetLight(i, inputData.positionWS);
light.attenuation *= LocalLightRealtimeShadowAttenuation(light.index, inputData.positionWS);
half3 attenuatedLightColor = light.color * light.attenuation;
diffuseColor += LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
specularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, specularGloss, shininess);

half3 fullDiffuse = diffuseColor + inputData.vertexLighting;
half3 finalColor = fullDiffuse * diffuse + emission;
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
finalColor += specularColor;
#endif

5
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl


#define LIGHTWEIGHT_PASS_DEPTH_ONLY_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/InputSurface.hlsl"
struct VertexInput
{

VertexOutput o = (VertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
o.uv = TransformMainTextureCoord(v.texcoord);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.clipPos = TransformObjectToHClip(v.position.xyz);
return o;
}

Alpha(MainTexture(IN.uv).a);
Alpha(SampleAlbedoAlpha(IN.uv, TEXTURE2D_PARAM(_MainTex, sampler_MainTex)).a, _Color, _Cutoff);
return 0;
}
#endif

112
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl


#ifndef LIGHTWEIGHT_PASS_LIT_INCLUDED
#define LIGHTWEIGHT_PASS_LIT_INCLUDED
#include "LWRP/ShaderLibrary/InputSurface.hlsl"
#include "LWRP/ShaderLibrary/Lighting.hlsl"
struct LightweightVertexInput

{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
#ifdef _ADDITIONAL_LIGHTS
float3 posWS : TEXCOORD2;
#endif
#ifdef _NORMALMAP
half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x

void InitializeInputData(LightweightVertexOutput IN, half3 normalTS, out InputData inputData)
{
inputData.positionWS = IN.posWSShininess.xyz;
inputData = (InputData)0;
#ifdef _ADDITIONAL_LIGHTS
inputData.positionWS = IN.posWS;
#endif
#ifdef _NORMALMAP
half3 viewDir = half3(IN.normal.w, IN.tangent.w, IN.binormal.w);

UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.uv = TransformMainTextureCoord(v.texcoord);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.posWSShininess.xyz = TransformObjectToWorld(v.vertex.xyz);
o.clipPos = TransformWorldToHClip(o.posWSShininess.xyz);
float3 posWS = TransformObjectToWorld(v.vertex.xyz);
o.clipPos = TransformWorldToHClip(posWS);
half3 viewDir = VertexViewDirWS(GetCameraPositionWS() - o.posWSShininess.xyz);
half3 viewDir = VertexViewDirWS(GetCameraPositionWS() - posWS);
#ifdef _NORMALMAP
o.normal.w = viewDir.x;

OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(o.normal.xyz, o.vertexSH);
half3 vertexLight = VertexLighting(o.posWSShininess.xyz, o.normal.xyz);
half3 vertexLight = VertexLighting(posWS, o.normal.xyz);
half fogFactor = ComputeFogFactor(o.clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);

#else
o.shadowCoord = TransformWorldToShadowCoord(o.posWSShininess.xyz);
o.shadowCoord = TransformWorldToShadowCoord(posWS);
#endif
#ifdef _ADDITIONAL_LIGHTS
o.posWS = posWS;
#endif
return o;

ApplyFog(color.rgb, inputData.fogCoord);
return color;
}
// Used in Standard (Simple Lighting) shader
// TODO: we only need to specialise this because of _Shininess prop
// Once we refactor SimpleLighting shader we will be able to share vertex
// between PBS and Simple
LightweightVertexOutput LitPassVertexSimple(LightweightVertexInput v)
{
LightweightVertexOutput o = (LightweightVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.uv = TransformMainTextureCoord(v.texcoord);
o.posWSShininess.xyz = TransformObjectToWorld(v.vertex.xyz);
o.posWSShininess.w = _Shininess * 128.0;
o.clipPos = TransformWorldToHClip(o.posWSShininess.xyz);
half3 viewDir = VertexViewDirWS(GetCameraPositionWS() - o.posWSShininess.xyz);
#ifdef _NORMALMAP
o.normal.w = viewDir.x;
o.tangent.w = viewDir.y;
o.binormal.w = viewDir.z;
#else
o.viewDir = viewDir;
#endif
// initializes o.normal and if _NORMALMAP also o.tangent and o.binormal
OUTPUT_NORMAL(v, o);
// We either sample GI from lightmap or SH.
// Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
// see DECLARE_LIGHTMAP_OR_SH macro.
// The following funcions initialize the correct variable with correct data
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(o.normal.xyz, o.vertexSH);
half3 vertexLight = VertexLighting(o.posWSShininess.xyz, o.normal.xyz);
half fogFactor = ComputeFogFactor(o.clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#ifdef _SHADOWS_ENABLED
#if SHADOWS_SCREEN
o.shadowCoord = ComputeShadowCoord(o.clipPos);
#else
o.shadowCoord = TransformWorldToShadowCoord(o.posWSShininess.xyz);
#endif
#endif
return o;
}
// Used for StandardSimpleLighting shader
half4 LitPassFragmentSimple(LightweightVertexOutput IN) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);
float2 uv = IN.uv;
half4 diffuseAlpha = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
half3 diffuse = diffuseAlpha.rgb * _Color.rgb;
half alpha = diffuseAlpha.a * _Color.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
diffuse *= alpha;
#endif
#ifdef _NORMALMAP
half3 normalTS = Normal(uv);
#else
half3 normalTS = half3(0, 0, 1);
#endif
half3 emission = Emission(uv);
half4 specularGloss = SpecularGloss(uv, diffuseAlpha.a);
half shininess = IN.posWSShininess.w;
InputData inputData;
InitializeInputData(IN, normalTS, inputData);
return LightweightFragmentBlinnPhong(inputData, diffuse, specularGloss, shininess, emission, alpha);
};
#endif

5
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl


#define LIGHTWEIGHT_PASS_SHADOW_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/InputSurface.hlsl"
// x: global clip space bias, y: normal world space bias
float4 _ShadowBias;

VertexOutput o;
UNITY_SETUP_INSTANCE_ID(v);
o.uv = TransformMainTextureCoord(v.texcoord);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.clipPos = GetShadowPositionHClip(v);
return o;
}

Alpha(MainTexture(IN.uv).a);
Alpha(SampleAlbedoAlpha(IN.uv, TEXTURE2D_PARAM(_MainTex, sampler_MainTex)).a, _Color, _Cutoff);
return 0;
}

84
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Particles.hlsl


#ifndef LIGHTWEIGHT_PARTICLES_INCLUDED
#define LIGHTWEIGHT_PARTICLES_INCLUDED
#include "InputSurface.hlsl"
#include "InputSurfaceCommon.hlsl"
TEXTURE2D(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half4 _EmissionColor;
half4 _SpecColor;
#if defined (_COLORADDSUBDIFF_ON)
half4 _ColorAddSubDiff;
#endif
half _Cutoff;
half _Shininess;
half _Metallic;
half _Glossiness;
half _BumpScale;
CBUFFER_END
TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
#define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x
#define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y

#if defined (_COLORADDSUBDIFF_ON)
half4 _ColorAddSubDiff;
#endif
// Color function
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)

return color;
}
half3 NormalTS(VertexOutputLit IN)
half3 SampleNormalTS(VertexOutputLit IN, TEXTURE2D_ARGS(bumpMap, sampler_bumpMap), half scale = 1.0h)
half4 n = readTexture(TEXTURE2D_PARAM(bumpMap, sampler_bumpMap), IN);
return UnpackNormal(readTexture(TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap), IN));
return UnpackNormal(n);
return UnpackNormalScale(readTexture(TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap), IN), _BumpScale);
return UnpackNormalScale(n, scale);
#endif
#else
return half3(0.0h, 0.0h, 1.0h);

half3 Emission(VertexOutputLit IN)
half3 SampleEmission(VertexOutputLit IN, half3 emissionColor, TEXTURE2D_ARGS(emissionMap, sampler_emissionMap))
return readTexture(TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap), IN).rgb * _EmissionColor.rgb;
return readTexture(TEXTURE2D_PARAM(emissionMap, sampler_emissionMap), IN).rgb * emissionColor.rgb;
half4 Albedo(VertexOutputLit IN)
half4 SampleAlbedo(VertexOutputLit IN, TEXTURE2D_ARGS(albedoMap, sampler_albedoMap))
half4 albedo = readTexture(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), IN) * IN.color;
half4 albedo = readTexture(TEXTURE2D_PARAM(albedoMap, sampler_albedoMap), IN) * _Color;
// No distortion Support
fragColorMode(IN);

return albedo;
}
half4 SpecularGloss(VertexOutputLit IN, half alpha)
half4 SampleSpecularGloss(VertexOutputLit IN, half alpha, half4 specColor, TEXTURE2D_ARGS(specGlossMap, sampler_specGlossMap))
specularGloss = readTexture(TEXTURE2D_PARAM(_SpecGlossMap, sampler_SpecGlossMap), IN);
specularGloss = readTexture(TEXTURE2D_PARAM(specGlossMap, sampler_specGlossMap), IN);
specularGloss = _SpecColor;
specularGloss = specColor;
#endif
#ifdef _GLOSSINESS_FROM_BASE_ALPHA

}
half AlphaBlendAndTest(half alpha)
half AlphaBlendAndTest(half alpha, half cutoff)
{
#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON) || defined(_ALPHAOVERLAY_ON)
half result = alpha;

AlphaDiscard(result, _Cutoff, 0.0001h);
AlphaDiscard(alpha, cutoff, 0.0001h);
return result;
}

#endif
}
void InitializeSurfaceData(VertexOutputLit IN, out SurfaceData surfaceData)
{
half4 albedo = Albedo(IN);
#if defined(_METALLICGLOSSMAP)
half2 metallicGloss = readTexture(TEXTURE2D_PARAM(_MetallicGlossMap, sampler_MetallicGlossMap), IN).ra * half2(1.0, _Glossiness);
#else
half2 metallicGloss = half2(_Metallic, _Glossiness);
#endif
half3 normalTS = NormalTS(IN);
half3 emission = Emission(IN);
surfaceData.albedo = albedo.rbg;
surfaceData.specular = half3(0.0h, 0.0h, 0.0h);
surfaceData.normalTS = normalTS;
surfaceData.emission = emission;
surfaceData.metallic = metallicGloss.r;
surfaceData.smoothness = metallicGloss.g;
surfaceData.occlusion = 1.0;
surfaceData.alpha = AlphaBlendAndTest(albedo.a);
surfaceData.albedo = AlphaModulate(surfaceData.albedo, surfaceData.alpha);
}
void InitializeInputData(VertexOutputLit IN, half3 normalTS, out InputData input)
{
input.positionWS = IN.posWS.xyz;

input.viewDirectionWS = FragmentViewDirWS(IN.viewDirShininess.xyz);
input.shadowCoord = float4(0, 0, 0, 0);
input.fogCoord = IN.posWS.w;
input.fogCoord = (half)IN.posWS.w;
#endif // LIGHTWEIGHT_PARTICLES_INCLUDED

155
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl


TEXTURE2D_SHADOW(_ShadowMap);
SAMPLER_CMP(sampler_ShadowMap);
CBUFFER_START(_ShadowBuffer)
TEXTURE2D_SHADOW(_LocalShadowMapAtlas);
SAMPLER_CMP(sampler_LocalShadowMapAtlas);
CBUFFER_START(_DirectionalShadowBuffer)
// Last cascade is initialized with a no-op matrix. It always transforms
// shadow coord to half(0, 0, NEAR_PLANE). We use this trick to avoid
// branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES

float4 _ShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
CBUFFER_END
CBUFFER_START(_LocalShadowBuffer)
float4x4 _LocalWorldToShadowAtlas[4];
half _LocalShadowStrength[4];
half4 _LocalShadowOffset0;
half4 _LocalShadowOffset1;
half4 _LocalShadowOffset2;
half4 _LocalShadowOffset3;
float4 _LocalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
CBUFFER_END
#if UNITY_REVERSED_Z
#define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z <= UNITY_RAW_FAR_CLIP_VALUE
#else

half GetShadowStrength()
struct ShadowSamplingData
{
half4 shadowOffset0;
half4 shadowOffset1;
half4 shadowOffset2;
half4 shadowOffset3;
float4 shadowmapSize;
};
ShadowSamplingData GetMainLightShadowSamplingData()
{
ShadowSamplingData shadowSamplingData;
shadowSamplingData.shadowOffset0 = _ShadowOffset0;
shadowSamplingData.shadowOffset1 = _ShadowOffset1;
shadowSamplingData.shadowOffset2 = _ShadowOffset2;
shadowSamplingData.shadowOffset3 = _ShadowOffset3;
shadowSamplingData.shadowmapSize = _ShadowmapSize;
return shadowSamplingData;
}
ShadowSamplingData GetLocalLightShadowSamplingData()
{
ShadowSamplingData shadowSamplingData;
shadowSamplingData.shadowOffset0 = _LocalShadowOffset0;
shadowSamplingData.shadowOffset1 = _LocalShadowOffset1;
shadowSamplingData.shadowOffset2 = _LocalShadowOffset2;
shadowSamplingData.shadowOffset3 = _LocalShadowOffset3;
shadowSamplingData.shadowmapSize = _LocalShadowmapSize;
return shadowSamplingData;
}
half GetMainLightShadowStrength()
inline half SampleScreenSpaceShadowMap(float4 shadowCoord)
half GetLocalLightShadowStrenth(int lightIndex)
{
return _LocalShadowStrength[lightIndex];
}
half SampleScreenSpaceShadowMap(float4 shadowCoord)
{
shadowCoord.xy /= shadowCoord.w;

return attenuation;
}
inline real SampleShadowmap(float4 shadowCoord)
real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), ShadowSamplingData samplingData, half shadowStrength)
{
shadowCoord.xyz /= shadowCoord.w;

#ifdef SHADER_API_MOBILE
// 4-tap hardware comparison
real4 attenuation4;
attenuation4.x = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset0.xyz);
attenuation4.y = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset1.xyz);
attenuation4.z = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset2.xyz);
attenuation4.w = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset3.xyz);
attenuation4.x = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset0.xyz);
attenuation4.y = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset1.xyz);
attenuation4.z = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset2.xyz);
attenuation4.w = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset3.xyz);
SampleShadow_ComputeSamples_Tent_7x7(_ShadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
SampleShadow_ComputeSamples_Tent_7x7(samplingData.shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation += fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[9].xy, shadowCoord.z));
attenuation += fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[10].xy, shadowCoord.z));
attenuation += fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[11].xy, shadowCoord.z));
attenuation += fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[12].xy, shadowCoord.z));
attenuation += fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[13].xy, shadowCoord.z));
attenuation += fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[14].xy, shadowCoord.z));
attenuation += fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[15].xy, shadowCoord.z));
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation += fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[9].xy, shadowCoord.z));
attenuation += fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[10].xy, shadowCoord.z));
attenuation += fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[11].xy, shadowCoord.z));
attenuation += fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[12].xy, shadowCoord.z));
attenuation += fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[13].xy, shadowCoord.z));
attenuation += fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[14].xy, shadowCoord.z));
attenuation += fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[15].xy, shadowCoord.z));
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz);
attenuation = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz);
#if SHADER_HINT_NICE_QUALITY
// Apply shadow strength
attenuation = LerpWhiteTo(attenuation, GetShadowStrength());
#endif
attenuation = LerpWhiteTo(attenuation, shadowStrength);
inline half ComputeCascadeIndex(float3 positionWS)
half ComputeCascadeIndex(float3 positionWS)
{
// TODO: profile if there's a performance improvement if we avoid indexing here
float3 fromCenter0 = positionWS.xyz - _DirShadowSplitSpheres[0].xyz;

return ComputeScreenPos(clipPos);
}
half RealtimeShadowAttenuation(float4 shadowCoord)
half MainLightRealtimeShadowAttenuation(float4 shadowCoord)
#ifndef _SHADOWS_ENABLED
return 1.0h;
#endif
#if defined(NO_SHADOWS)
#if defined(NO_SHADOWS) || !defined(_SHADOWS_ENABLED)
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
half shadowStrength = GetMainLightShadowStrength();
return SampleShadowmap(shadowCoord, TEXTURE2D_PARAM(_ShadowMap, sampler_ShadowMap), shadowSamplingData, shadowStrength);
#endif
return SampleShadowmap(shadowCoord);
}
half LocalLightRealtimeShadowAttenuation(int lightIndex, float3 positionWS)
{
// TODO: We can't add more keywords to standard shaders. For now we use
// same _SHADOWS_ENABLED keywords for local lights. In the future we can use
// _LOCAL_SHADOWS_ENABLED keyword
// For now disabling local shadows on mobile until we can get the keyword stripping
//#if defined(NO_SHADOWS) || !defined(_LOCAL_SHADOWS_ENABLED)
#if defined(NO_SHADOWS) || !defined(_SHADOWS_ENABLED) || defined(SHADER_API_MOBILE)
return 1.0h;
#else
float4 shadowCoord = mul(_LocalWorldToShadowAtlas[lightIndex], float4(positionWS, 1.0));
ShadowSamplingData shadowSamplingData = GetLocalLightShadowSamplingData();
half shadowStrength = GetLocalLightShadowStrenth(lightIndex);
return SampleShadowmap(shadowCoord, TEXTURE2D_PARAM(_LocalShadowMapAtlas, sampler_LocalShadowMapAtlas), shadowSamplingData, shadowStrength);
#endif
}

30
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl


#ifndef LIGHTWEIGHT_PASS_META_INCLUDED
#define LIGHTWEIGHT_PASS_META_INCLUDED
#include "LWRP/ShaderLibrary/InputSurface.hlsl"
#include "LWRP/ShaderLibrary/Lighting.hlsl"
CBUFFER_START(UnityMetaPass)

{
MetaVertexOuput o;
o.pos = MetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST);
o.uv = TransformMainTextureCoord(v.uv0);
o.uv = TRANSFORM_TEX(v.uv0, _MainTex);
}
half4 LightweightFragmentMeta(MetaVertexOuput i) : SV_Target
{
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(i.uv, surfaceData);
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
MetaInput o;
o.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5;
o.SpecularColor = surfaceData.specular;
o.Emission = surfaceData.emission;
return MetaFragment(o);
}
half4 LightweightFragmentMetaSimple(MetaVertexOuput i) : SV_Target
{
float2 uv = i.uv;
MetaInput o;
o.Albedo = _Color.rgb * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv).rgb;
o.SpecularColor = SpecularGloss(uv, 1.0).xyz;
o.Emission = Emission(uv);
return MetaFragment(o);
}
#endif

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightBlit.shader


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex Vertex
#pragma fragment Fragment

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightCopyDepth.shader


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex vert
#pragma fragment frag

12
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader


HLSLINCLUDE
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
//Keep compiler quiet about Shadows.hlsl.
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "CoreRP/ShaderLibrary/EntityLighting.hlsl"

{
UNITY_SETUP_INSTANCE_ID(i);
#if !defined(UNITY_STEREO_INSTANCING_ENABLED)
// Completely unclear why i.stereoTargetEyeIndex doesn't work here, considering
// Completely unclear why i.stereoTargetEyeIndex doesn't work here, considering
// this has to be correct in order for the texture array slices to be rasterized to
// We can limit this workaround to stereo instancing for now.
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);

//Fetch shadow coordinates for cascade.
float4 coords = TransformWorldToShadowCoord(wpos);
return SampleShadowmap(coords);
// Screenspace shadowmap is only used for directional lights which use orthogonal projection.
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
half shadowStrength = GetMainLightShadowStrength();
return SampleShadowmap(coords, TEXTURE2D_PARAM(_ShadowMap, sampler_ShadowMap), shadowSamplingData, shadowStrength);
{
{
ZTest Always
ZWrite Off
Cull Off

#pragma multi_compile _ _SHADOWS_CASCADE
#pragma vertex Vertex
#pragma fragment Fragment
ENDHLSL

19
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandard.shader


// Specular vs Metallic workflow
[HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0
_Color("Color", Color) = (1,1,1,1)
_Color("Color", Color) = (0.5,0.5,0.5,1)
_MainTex("Albedo", 2D) = "white" {}
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5

// Required to compile gles 2.0 with standard SRP library
// All shaders must be compiled with HLSLcc and currently only gles is not using HLSLcc by default
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------

#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// TODO: Enabled this when we have C# keyword stripping
//#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords

#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassLit.hlsl"
ENDHLSL
}

HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
ENDHLSL
}

ZWrite On
ColorMask 0
Cull[_Cull]
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex

// GPU Instancing
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
ENDHLSL
}

HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex LightweightVertexMeta
#pragma fragment LightweightFragmentMeta

#pragma shader_feature _SPECGLOSSMAP
#include "LWRP/ShaderLibrary/LightweightPassMeta.hlsl"
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl"
ENDHLSL
}

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticles.shader


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex ParticlesLitVertex
#pragma fragment ParticlesLitFragment
#pragma multi_compile __ SOFTPARTICLES_ON

#define NO_SHADOWS 1
#include "LWRP/ShaderLibrary/Particles.hlsl"
#include "LWRP/ShaderLibrary/ParticlesPBR.hlsl"
#include "LWRP/ShaderLibrary/Lighting.hlsl"
VertexOutputLit ParticlesLitVertex(appdata_particles v)

o.color = v.color * _Color;
o.viewDirShininess.w = 0.0;
o.color = v.color;
// TODO: Instancing
// vertColor(v.color);
vertTexcoord(v, o);
vertFading(o, o.posWS, o.clipPos);
return o;

18
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticlesSimpleLighting.shader


#pragma vertex ParticlesLitVertex
#pragma fragment ParticlesLitFragment
#pragma multi_compile __ SOFTPARTICLES_ON
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON

OUTPUT_NORMAL(v, o);
o.color = v.color * _Color;
o.color = v.color;
// TODO: Instancing
// vertColor(o.color);
vertTexcoord(v, o);
vertFading(o, o.posWS, o.clipPos);
return o;

{
half4 albedo = Albedo(IN);
half alpha = AlphaBlendAndTest(albedo.a);
half3 diffuse = AlphaModulate(albedo.rgb, alpha);
half3 normalTS = NormalTS(IN);
half3 emission = Emission(IN);
half4 specularGloss = SpecularGloss(IN, albedo.a);
half4 albedo = SampleAlbedo(IN, TEXTURE2D_PARAM(_MainTex, sampler_MainTex));
half3 diffuse = AlphaModulate(albedo.rgb, albedo.a);
half alpha = AlphaBlendAndTest(albedo.a, _Cutoff);
half3 normalTS = SampleNormalTS(IN, TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap));
half3 emission = SampleEmission(IN, _EmissionColor.rgb, TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap));
half4 specularGloss = SampleSpecularGloss(IN, albedo.a, _SpecColor, TEXTURE2D_PARAM(_SpecGlossMap, sampler_SpecGlossMap));
half shininess = IN.viewDirShininess.w;
InputData inputData;

18
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticlesUnlit.shader


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma multi_compile __ SOFTPARTICLES_ON
#pragma multi_compile_fog
#pragma target 2.0

#pragma fragment fragParticleUnlit
#include "LWRP/ShaderLibrary/Particles.hlsl"
#include "LWRP/ShaderLibrary/Core.hlsl"
VertexOutputLit vertParticleUnlit(appdata_particles v)
{

o.posWS.xyz = TransformObjectToWorld(v.vertex.xyz);
o.posWS.w = ComputeFogFactor(o.clipPos.z);
o.clipPos = TransformWorldToHClip(o.posWS.xyz);
o.color = v.color * _Color;
o.color = v.color;
vertColor(o.color);
// TODO: Instancing
//vertColor(o.color);
vertTexcoord(v, o);
vertFading(o, o.posWS, o.clipPos);

half4 fragParticleUnlit(VertexOutputLit IN) : SV_Target
{
half4 albedo = Albedo(IN);
half alpha = AlphaBlendAndTest(albedo.a);
half3 emission = Emission(IN);
half3 diffuse = AlphaModulate(albedo.rgb, alpha);
half4 albedo = SampleAlbedo(IN, TEXTURE2D_PARAM(_MainTex, sampler_MainTex));
half3 diffuse = AlphaModulate(albedo.rgb, albedo.a);
half alpha = AlphaBlendAndTest(albedo.a, _Cutoff);
half3 emission = SampleEmission(IN, _EmissionColor.rgb, TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap));
half fogFactor = IN.posWS.w;
ApplyFogColor(result, half3(0, 0, 0), fogFactor);
return half4(result, alpha);

24
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardSimpleLighting.shader


// Keep properties of StandardSpecular shader for upgrade reasons.
Properties
{
_Color("Color", Color) = (1,1,1,1)
_Color("Color", Color) = (0.5, 0.5, 0.5, 1)
_Shininess("Shininess", Range(0.01, 1.0)) = 1.0
_Shininess("Shininess", Range(0.01, 1.0)) = 0.5
_GlossMapScale("Smoothness Factor", Range(0.0, 1.0)) = 1.0
_Glossiness("Glossiness", Range(0.0, 1.0)) = 0.5

_SpecColor("Specular", Color) = (1.0, 1.0, 1.0)
_SpecColor("Specular", Color) = (0.5, 0.5, 0.5)
_SpecGlossMap("Specular", 2D) = "white" {}
[HideInInspector] _GlossinessSource("Glossiness Source", Float) = 0.0
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0

HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------

#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// TODO: Enabled this when we have C# keyword stripping
//#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED

#pragma vertex LitPassVertexSimple
#pragma fragment LitPassFragmentSimple
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "LWRP/ShaderLibrary/LightweightPassLit.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceSimple.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl"
ENDHLSL
}

HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------

#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "LWRP/ShaderLibrary/InputSurfaceSimple.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
ENDHLSL
}

ZWrite On
ColorMask 0
Cull[_Cull]
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex

// GPU Instancing
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/InputSurfaceSimple.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
ENDHLSL
}

HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex LightweightVertexMeta
#pragma fragment LightweightFragmentMetaSimple

#include "LWRP/ShaderLibrary/LightweightPassMeta.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceSimple.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassMetaSimple.hlsl"
ENDHLSL
}
}

59
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardUnlit.shader


}
SubShader
{
Tags { "RenderType" = "Opaque" "IgnoreProjectors" = "True" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"}
Tags { "RenderType" = "Opaque" "IgnoreProjectors" = "True" "RenderPipeline" = "LightweightPipeline" }
LOD 100
Blend [_SrcBlend][_DstBlend]

HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma shader_feature _ALPHAPREMULTIPLY_ON
#pragma multi_compile_fog
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/InputSurface.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl"
struct VertexInput
{

{
float3 uv0AndFogCoord : TEXCOORD0; // xy: uv0, z: fogCoord
#if _SAMPLE_GI
float4 lightmapOrVertexSH : TEXCOORD1;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
half3 normal : TEXCOORD2;
#if _NORMALMAP
half3 tangent : TEXCOORD3;

UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = TransformObjectToHClip(v.vertex.xyz);
o.uv0AndFogCoord.xy = TRANSFORM_TEX(v.uv, _MainTex);
o.uv0AndFogCoord.z = ComputeFogFactor(o.vertex.z);

OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapOrVertexSH.xy);
OUTPUT_SH(o.normal, o.lightmapOrVertexSH);
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(o.normal, o.vertexSH);
#endif
return o;
}

half2 uv = IN.uv0AndFogCoord.xy;
half4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
half3 color = texColor.rgb * _Color.rgb;
half alpha = texColor.a * _Color.a;
half alpha = texColor.a * _Color.a;
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
#if _SAMPLE_GI
#if _NORMALMAP
half3 normalWS = TangentToWorldNormal(surfaceData.normalTS, IN.tangent, IN.binormal, IN.normal);

color *= SampleGI(IN.lightmapOrVertexSH, normalWS);
color += SAMPLE_GI(IN.lightmapUV, IN.vertexSH, normalWS);
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
ENDHLSL
}
}

631
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs


using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
{
[Serializable]
public class ShadowSettings
{
public LightShadows directionalShadowQuality;
public bool screenSpace;
public int directionalShadowAtlasWidth;
public int directionalShadowAtlasHeight;
public LightShadows localLightsShadowQuality;
public int localShadowAtlasWidth;
public int localShadowAtlasHeight;
public int bufferBitCount;
public float maxShadowDistance;
public int directionalLightCascadeCount;
public Vector3 directionalLightCascades;
public RenderTextureFormat shadowmapTextureFormat;
public RenderTextureFormat screenspaceShadowmapTextureFormat;
static ShadowSettings defaultShadowSettings = null;
public static ShadowSettings Default
{
get
{
if (defaultShadowSettings == null)
{
defaultShadowSettings = new ShadowSettings();
defaultShadowSettings.directionalShadowQuality = LightShadows.None;
defaultShadowSettings.screenSpace = true;
defaultShadowSettings.directionalShadowAtlasHeight = defaultShadowSettings.directionalShadowAtlasWidth = 2048;
defaultShadowSettings.localLightsShadowQuality = LightShadows.None;
defaultShadowSettings.localShadowAtlasWidth = 512;
defaultShadowSettings.localShadowAtlasHeight = 512;
defaultShadowSettings.bufferBitCount = 16;
defaultShadowSettings.directionalLightCascadeCount = 1;
defaultShadowSettings.directionalLightCascades = new Vector3(0.05F, 0.2F, 0.3F);
defaultShadowSettings.shadowmapTextureFormat = RenderTextureFormat.Shadowmap;
defaultShadowSettings.screenspaceShadowmapTextureFormat = RenderTextureFormat.R8;
}
return defaultShadowSettings;
}
}
}
public struct ShadowSliceData
{
public Matrix4x4 shadowTransform;
public int offsetX;
public int offsetY;
public int resolution;
public void Clear()
{
shadowTransform = Matrix4x4.identity;
offsetX = offsetY = 0;
resolution = 1024;
}
}
public class LightweightShadowPass
{
public bool IsDirectionalShadowsEnabled { get { return m_ShadowSettings.directionalShadowQuality != LightShadows.None; } }
public bool IsLocalShadowsEnabled { get { return m_ShadowSettings.localLightsShadowQuality != LightShadows.None; }}
public bool RequireScreenSpaceShadowmap { get { return IsDirectionalShadowsEnabled && m_ShadowSettings.screenSpace; } }
public bool HasDirectionalShadowmap { get { return m_DirectionalShadowmapQuality != LightShadows.None; } }
public bool HasLocalLightsShadowmap { get { return m_LocalShadowmapQuality != LightShadows.None; } }
public float RenderingDistance { get { return m_ShadowSettings.maxShadowDistance; } }
private const int kMaxCascades = 4;
private int m_ShadowCasterCascadesCount;
private int m_DirectionalShadowmapID;
private int m_LocalShadowmapID;
private int m_ScreenSpaceShadowmapID;
private ShadowSettings m_ShadowSettings = ShadowSettings.Default;
private Material m_ScreenSpaceShadowsMaterial;
private RenderTexture m_DirectionalShadowmapTexture;
private RenderTexture m_LocalShadowmapTexture;
private RenderTargetIdentifier m_ScreenSpaceShadowmapTexture;
private RenderTextureDescriptor m_DirectionalShadowmapDescriptor;
private RenderTextureDescriptor m_LocalShadowmapDescriptor;
private LightShadows m_DirectionalShadowmapQuality;
private LightShadows m_LocalShadowmapQuality;
private Matrix4x4[] m_DirectionalShadowMatrices;
private ShadowSliceData[] m_CascadeSlices;
private Vector4[] m_CascadeSplitDistances;
private Vector4 m_CascadeSplitRadii;
private Matrix4x4[] m_LocalShadowMatrices;
private ShadowSliceData[] m_LocalLightSlices;
private float[] m_LocalShadowStrength;
public LightweightShadowPass(LightweightPipelineAsset pipelineAsset, int maxLocalLightsCount)
{
BuildShadowSettings(pipelineAsset);
m_DirectionalShadowMatrices = new Matrix4x4[kMaxCascades + 1];
m_CascadeSlices = new ShadowSliceData[kMaxCascades];
m_CascadeSplitDistances = new Vector4[kMaxCascades];
m_LocalShadowMatrices = new Matrix4x4[maxLocalLightsCount];
m_LocalLightSlices = new ShadowSliceData[maxLocalLightsCount];
m_LocalShadowStrength = new float[maxLocalLightsCount];
DirectionalShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_WorldToShadow");
DirectionalShadowConstantBuffer._ShadowData = Shader.PropertyToID("_ShadowData");
DirectionalShadowConstantBuffer._DirShadowSplitSpheres = Shader.PropertyToID("_DirShadowSplitSpheres");
DirectionalShadowConstantBuffer._DirShadowSplitSphereRadii = Shader.PropertyToID("_DirShadowSplitSphereRadii");
DirectionalShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_ShadowOffset0");
DirectionalShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_ShadowOffset1");
DirectionalShadowConstantBuffer._ShadowOffset2 = Shader.PropertyToID("_ShadowOffset2");
DirectionalShadowConstantBuffer._ShadowOffset3 = Shader.PropertyToID("_ShadowOffset3");
DirectionalShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_ShadowmapSize");
LocalShadowConstantBuffer._LocalWorldToShadowAtlas = Shader.PropertyToID("_LocalWorldToShadowAtlas");
LocalShadowConstantBuffer._LocalShadowStrength = Shader.PropertyToID("_LocalShadowStrength");
LocalShadowConstantBuffer._LocalShadowOffset0 = Shader.PropertyToID("_LocalShadowOffset0");
LocalShadowConstantBuffer._LocalShadowOffset1 = Shader.PropertyToID("_LocalShadowOffset1");
LocalShadowConstantBuffer._LocalShadowOffset2 = Shader.PropertyToID("_LocalShadowOffset2");
LocalShadowConstantBuffer._LocalShadowOffset3 = Shader.PropertyToID("_LocalShadowOffset3");
LocalShadowConstantBuffer._LocalShadowmapSize = Shader.PropertyToID("_LocalShadowmapSize");
m_DirectionalShadowmapID = Shader.PropertyToID("_ShadowMap");
m_LocalShadowmapID = Shader.PropertyToID("_LocalShadowMapAtlas");
m_ScreenSpaceShadowmapID = Shader.PropertyToID("_ScreenSpaceShadowMap");
m_ScreenSpaceShadowmapTexture = new RenderTargetIdentifier(m_ScreenSpaceShadowmapID);
m_DirectionalShadowmapDescriptor = new RenderTextureDescriptor(m_ShadowSettings.directionalShadowAtlasWidth,
m_ShadowSettings.directionalShadowAtlasHeight, m_ShadowSettings.shadowmapTextureFormat, m_ShadowSettings.bufferBitCount);
m_LocalShadowmapDescriptor = new RenderTextureDescriptor(m_ShadowSettings.localShadowAtlasWidth,
m_ShadowSettings.localShadowAtlasHeight, m_ShadowSettings.shadowmapTextureFormat, m_ShadowSettings.bufferBitCount);
m_ScreenSpaceShadowsMaterial = CoreUtils.CreateEngineMaterial(pipelineAsset.ScreenSpaceShadowShader);
Clear();
}
public void InitializeResources(CommandBuffer cmd, RenderTextureDescriptor renderTextureDesc)
{
if (RequireScreenSpaceShadowmap)
{
renderTextureDesc.depthBufferBits = 0;
renderTextureDesc.colorFormat = m_ShadowSettings.screenspaceShadowmapTextureFormat;
cmd.GetTemporaryRT(m_ScreenSpaceShadowmapID, renderTextureDesc, FilterMode.Bilinear);
}
}
public void Dispose(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(m_ScreenSpaceShadowmapID);
if (m_DirectionalShadowmapTexture)
{
RenderTexture.ReleaseTemporary(m_DirectionalShadowmapTexture);
m_DirectionalShadowmapTexture = null;
}
if (m_LocalShadowmapTexture)
{
RenderTexture.ReleaseTemporary(m_LocalShadowmapTexture);
m_LocalShadowmapTexture = null;
}
}
public bool Execute(ref CullResults cullResults, ref LightData lightData, ref ScriptableRenderContext context)
{
Clear();
bool directionalShadowmapRendered = false;
if (IsDirectionalShadowsEnabled)
directionalShadowmapRendered = RenderDirectionalCascadeShadowmap(ref cullResults, ref lightData, ref context);
if (IsLocalShadowsEnabled)
RenderLocalShadowmapAtlas(ref cullResults, ref lightData, ref context);
return directionalShadowmapRendered && m_ShadowSettings.screenSpace;
}
public void CollectShadows(Camera camera, FrameRenderingConfiguration frameRenderingConfiguration, ref ScriptableRenderContext context)
{
CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");
SetShadowCollectPassKeywords(cmd);
// Note: The source isn't actually 'used', but there's an engine peculiarity (bug) that
// doesn't like null sources when trying to determine a stereo-ized blit. So for proper
// stereo functionality, we use the screen-space shadow map as the source (until we have
// a better solution).
// An alternative would be DrawProcedural, but that would require further changes in the shader.
cmd.SetRenderTarget(m_ScreenSpaceShadowmapTexture);
cmd.ClearRenderTarget(true, true, Color.white);
cmd.Blit(m_ScreenSpaceShadowmapTexture, m_ScreenSpaceShadowmapTexture, m_ScreenSpaceShadowsMaterial);
LightweightUtils.StartStereoRendering(camera, ref context, frameRenderingConfiguration);
context.ExecuteCommandBuffer(cmd);
LightweightUtils.StopStereoRendering(camera, ref context, frameRenderingConfiguration);
CommandBufferPool.Release(cmd);
}
private void BuildShadowSettings(LightweightPipelineAsset pipelineAsset)
{
// Until we can have keyword stripping forcing single cascade hard shadows on gles2
bool supportsScreenSpaceShadows = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2;
bool supportsLocalShadows = Application.isMobilePlatform || Application.platform == RuntimePlatform.WebGLPlayer;
m_ShadowSettings = ShadowSettings.Default;
m_ShadowSettings.directionalShadowQuality = (LightShadows)pipelineAsset.ShadowSetting;
m_ShadowSettings.screenSpace = supportsScreenSpaceShadows;
m_ShadowSettings.directionalLightCascadeCount = (m_ShadowSettings.screenSpace) ? pipelineAsset.CascadeCount : 1;
m_ShadowSettings.directionalShadowAtlasWidth = pipelineAsset.ShadowAtlasResolution;
m_ShadowSettings.directionalShadowAtlasHeight = pipelineAsset.ShadowAtlasResolution;
m_ShadowSettings.maxShadowDistance = pipelineAsset.ShadowDistance;
m_ShadowSettings.shadowmapTextureFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.Shadowmap)
? RenderTextureFormat.Shadowmap
: RenderTextureFormat.Depth;
m_ShadowSettings.screenspaceShadowmapTextureFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8)
? RenderTextureFormat.R8
: RenderTextureFormat.ARGB32;
switch (m_ShadowSettings.directionalLightCascadeCount)
{
case 1:
m_ShadowSettings.directionalLightCascades = new Vector3(1.0f, 0.0f, 0.0f);
break;
case 2:
m_ShadowSettings.directionalLightCascades = new Vector3(pipelineAsset.Cascade2Split, 1.0f, 0.0f);
break;
default:
m_ShadowSettings.directionalLightCascades = pipelineAsset.Cascade4Split;
break;
}
// Until we can have keyword stripping we disable local light shadows on mobile
m_ShadowSettings.localLightsShadowQuality = (supportsLocalShadows) ? LightShadows.Hard : LightShadows.None;
}
private void Clear()
{
m_DirectionalShadowmapTexture = null;
m_LocalShadowmapTexture = null;
m_DirectionalShadowmapQuality = LightShadows.None;
m_LocalShadowmapQuality = LightShadows.None;
for (int i = 0; i < m_DirectionalShadowMatrices.Length; ++i)
m_DirectionalShadowMatrices[i] = Matrix4x4.identity;
for (int i = 0; i < m_LocalShadowMatrices.Length; ++i)
m_LocalShadowMatrices[i] = Matrix4x4.identity;
for (int i = 0; i < m_CascadeSplitDistances.Length; ++i)
m_CascadeSplitDistances[i] = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
m_CascadeSplitRadii = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < m_CascadeSlices.Length; ++i)
m_CascadeSlices[i].Clear();
for (int i = 0; i < m_LocalLightSlices.Length; ++i)
m_LocalLightSlices[i].Clear();
for (int i = 0; i < m_LocalShadowStrength.Length; ++i)
m_LocalShadowStrength[i] = 0.0f;
}
private void SetShadowCollectPassKeywords(CommandBuffer cmd)
{
CoreUtils.SetKeyword(cmd, "_SHADOWS_SOFT", m_DirectionalShadowmapQuality == LightShadows.Soft);
CoreUtils.SetKeyword(cmd, "_SHADOWS_CASCADE", m_ShadowSettings.directionalLightCascadeCount > 1);
}
private bool RenderDirectionalCascadeShadowmap(ref CullResults cullResults, ref LightData lightData, ref ScriptableRenderContext context)
{
int shadowLightIndex = lightData.mainLightIndex;
if (shadowLightIndex == -1)
return false;
VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
Light light = shadowLight.light;
Debug.Assert(shadowLight.lightType == LightType.Directional);
if (light.shadows == LightShadows.None)
return false;
CommandBuffer cmd = CommandBufferPool.Get("Prepare Directional Shadowmap");
m_ShadowCasterCascadesCount = m_ShadowSettings.directionalLightCascadeCount;
int shadowResolution = GetMaxTileResolutionInAtlas(m_ShadowSettings.directionalShadowAtlasWidth, m_ShadowSettings.directionalShadowAtlasHeight, m_ShadowCasterCascadesCount);
float shadowNearPlane = light.shadowNearPlane;
Bounds bounds;
if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
return false;
Matrix4x4 view, proj;
var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);
m_DirectionalShadowmapTexture = RenderTexture.GetTemporary(m_DirectionalShadowmapDescriptor);
m_DirectionalShadowmapTexture.filterMode = FilterMode.Bilinear;
m_DirectionalShadowmapTexture.wrapMode = TextureWrapMode.Clamp;
CoreUtils.SetRenderTarget(cmd, m_DirectionalShadowmapTexture, ClearFlag.Depth);
bool success = false;
for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
{
success = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
cascadeIndex, m_ShadowCasterCascadesCount, m_ShadowSettings.directionalLightCascades, shadowResolution, shadowNearPlane, out view, out proj,
out settings.splitData);
float cullingSphereRadius = settings.splitData.cullingSphere.w;
m_CascadeSplitDistances[cascadeIndex] = settings.splitData.cullingSphere;
m_CascadeSplitRadii[cascadeIndex] = cullingSphereRadius * cullingSphereRadius;
if (!success)
break;
m_CascadeSlices[cascadeIndex].offsetX = (cascadeIndex % 2) * shadowResolution;
m_CascadeSlices[cascadeIndex].offsetY = (cascadeIndex / 2) * shadowResolution;
m_CascadeSlices[cascadeIndex].resolution = shadowResolution;
m_CascadeSlices[cascadeIndex].shadowTransform = GetShadowTransform(proj, view);
// If we have shadow cascades baked into the atlas we bake cascade transform
// in each shadow matrix to save shader ALU and L/S
if (m_ShadowCasterCascadesCount > 1)
ApplySliceTransform(ref m_CascadeSlices[cascadeIndex], m_ShadowSettings.directionalShadowAtlasWidth, m_ShadowSettings.directionalShadowAtlasHeight);
SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex], proj, view, settings);
}
if (success)
{
m_DirectionalShadowmapQuality = (m_ShadowSettings.directionalShadowQuality != LightShadows.Soft) ? LightShadows.Hard : light.shadows;
// In order to avoid shader variants explosion we only do hard shadows when sampling shadowmap in the lit pass.
// GLES2 platform is forced to hard single cascade shadows.
if (!m_ShadowSettings.screenSpace)
m_DirectionalShadowmapQuality = LightShadows.Hard;
SetupDirectionalShadowReceiverConstants(cmd, shadowLight, ref context);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
return success;
}
private void RenderLocalShadowmapAtlas(ref CullResults cullResults, ref LightData lightData, ref ScriptableRenderContext context)
{
List<int> localLightIndices = lightData.localLightIndices;
List<VisibleLight> visibleLights = lightData.visibleLights;
int shadowCastingLightsCount = 0;
int localLightsCount = localLightIndices.Count;
for (int i = 0; i < localLightsCount; ++i)
{
VisibleLight shadowLight = visibleLights[localLightIndices[i]];
if (shadowLight.lightType == LightType.Spot && shadowLight.light.shadows != LightShadows.None)
shadowCastingLightsCount++;
}
if (shadowCastingLightsCount == 0)
return;
CommandBuffer cmd = CommandBufferPool.Get("Prepare Local Lights Shadowmap");
Matrix4x4 view, proj;
Bounds bounds;
// TODO: Add support to point light shadows. We make a simplification here that only works
// for spot lights and with max spot shadows per pass.
int atlasWidth = m_ShadowSettings.localShadowAtlasWidth;
int atlasHeight = m_ShadowSettings.localShadowAtlasHeight;
int sliceResolution = GetMaxTileResolutionInAtlas(atlasWidth, atlasHeight, shadowCastingLightsCount);
int shadowSampling = 0;
m_LocalShadowmapTexture = RenderTexture.GetTemporary(m_LocalShadowmapDescriptor);
m_LocalShadowmapTexture.filterMode = FilterMode.Bilinear;
m_LocalShadowmapTexture.wrapMode = TextureWrapMode.Clamp;
CoreUtils.SetRenderTarget(cmd, m_LocalShadowmapTexture, ClearFlag.Depth);
for (int i = 0; i < localLightsCount; ++i)
{
int shadowLightIndex = localLightIndices[i];
VisibleLight shadowLight = visibleLights[shadowLightIndex];
Light light = shadowLight.light;
// TODO: Add support to point light shadows
if (shadowLight.lightType != LightType.Spot || shadowLight.light.shadows == LightShadows.None)
continue;
if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
continue;
var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);
if (cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out view, out proj, out settings.splitData))
{
// This way of computing the shadow slice only work for spots and with most 4 shadow casting lights per pass
// Change this when point lights are supported.
Debug.Assert(localLightsCount <= 4 && shadowLight.lightType == LightType.Spot);
// TODO: We need to pass bias and scale list to shader to be able to support multiple
// shadow casting local lights.
m_LocalLightSlices[i].offsetX = (i % 2) * sliceResolution;
m_LocalLightSlices[i].offsetY = (i / 2) * sliceResolution;
m_LocalLightSlices[i].resolution = sliceResolution;
m_LocalLightSlices[i].shadowTransform = GetShadowTransform(proj, view);
if (shadowCastingLightsCount > 1)
ApplySliceTransform(ref m_LocalLightSlices[i], atlasWidth, atlasHeight);
SetupShadowCasterConstants(cmd, ref shadowLight, proj, sliceResolution);
RenderShadowSlice(cmd, ref context, ref m_LocalLightSlices[i], proj, view, settings);
m_LocalShadowStrength[i] = light.shadowStrength;
shadowSampling = Math.Max(shadowSampling, (int)light.shadows);
}
}
SetupLocalLightsShadowReceiverConstants(cmd, ref context);
m_LocalShadowmapQuality = (LightShadows)Math.Min(shadowSampling, (int)m_ShadowSettings.directionalShadowQuality);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
private Matrix4x4 GetShadowTransform(Matrix4x4 proj, Matrix4x4 view)
{
// Currently CullResults ComputeDirectionalShadowMatricesAndCullingPrimitives doesn't
// apply z reversal to projection matrix. We need to do it manually here.
if (SystemInfo.usesReversedZBuffer)
{
proj.m20 = -proj.m20;
proj.m21 = -proj.m21;
proj.m22 = -proj.m22;
proj.m23 = -proj.m23;
}
Matrix4x4 worldToShadow = proj * view;
var textureScaleAndBias = Matrix4x4.identity;
textureScaleAndBias.m00 = 0.5f;
textureScaleAndBias.m11 = 0.5f;
textureScaleAndBias.m22 = 0.5f;
textureScaleAndBias.m03 = 0.5f;
textureScaleAndBias.m23 = 0.5f;
textureScaleAndBias.m13 = 0.5f;
// Apply texture scale and offset to save a MAD in shader.
return textureScaleAndBias * worldToShadow;
}
private void ApplySliceTransform(ref ShadowSliceData shadowSliceData, int atlasWidth, int atlasHeight)
{
Matrix4x4 sliceTransform = Matrix4x4.identity;
float oneOverAtlasWidth = 1.0f / atlasWidth;
float oneOverAtlasHeight = 1.0f / atlasHeight;
sliceTransform.m00 = shadowSliceData.resolution * oneOverAtlasWidth;
sliceTransform.m11 = shadowSliceData.resolution * oneOverAtlasHeight;
sliceTransform.m03 = shadowSliceData.offsetX * oneOverAtlasWidth;
sliceTransform.m13 = shadowSliceData.offsetY * oneOverAtlasHeight;
// Apply shadow slice scale and offset
shadowSliceData.shadowTransform = sliceTransform * shadowSliceData.shadowTransform;
}
private void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, ref ShadowSliceData shadowSliceData,
Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings)
{
cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution));
cmd.EnableScissorRect(new Rect(shadowSliceData.offsetX + 4, shadowSliceData.offsetY + 4, shadowSliceData.resolution - 8, shadowSliceData.resolution - 8));
cmd.SetViewProjectionMatrices(view, proj);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
context.DrawShadows(ref settings);
cmd.DisableScissorRect();
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
}
private int GetMaxTileResolutionInAtlas(int atlasWidth, int atlasHeight, int tileCount)
{
int resolution = Mathf.Min(atlasWidth, atlasHeight);
if (tileCount > Mathf.Log(resolution))
{
Debug.LogError(
String.Format(
"Cannot fit {0} tiles into current shadowmap atlas of size ({1}, {2}). ShadowMap Resolution set to zero.",
tileCount, atlasWidth, atlasHeight));
return 0;
}
int currentTileCount = atlasWidth / resolution * atlasHeight / resolution;
while (currentTileCount < tileCount)
{
resolution = resolution >> 1;
currentTileCount = atlasWidth / resolution * atlasHeight / resolution;
}
return resolution;
}
private void SetupShadowCasterConstants(CommandBuffer cmd, ref VisibleLight visibleLight, Matrix4x4 proj, float cascadeResolution)
{
Light light = visibleLight.light;
float bias = 0.0f;
float normalBias = 0.0f;
// Use same kernel radius as built-in pipeline so we can achieve same bias results
// with the default light bias parameters.
const float kernelRadius = 3.65f;
if (visibleLight.lightType == LightType.Directional)
{
// Scale bias by cascade's world space depth range.
// Directional shadow lights have orthogonal projection.
// proj.m22 = -2 / (far - near) since the projection's depth range is [-1.0, 1.0]
// In order to be correct we should multiply bias by 0.5 but this introducing aliasing along cascades more visible.
float sign = (SystemInfo.usesReversedZBuffer) ? 1.0f : -1.0f;
bias = light.shadowBias * proj.m22 * sign;
// Currently only square POT cascades resolutions are used.
// We scale normalBias
double frustumWidth = 2.0 / (double)proj.m00;
double frustumHeight = 2.0 / (double)proj.m11;
float texelSizeX = (float)(frustumWidth / (double)cascadeResolution);
float texelSizeY = (float)(frustumHeight / (double)cascadeResolution);
float texelSize = Mathf.Max(texelSizeX, texelSizeY);
// Since we are applying normal bias on caster side we want an inset normal offset
// thus we use a negative normal bias.
normalBias = -light.shadowNormalBias * texelSize * kernelRadius;
}
else if (visibleLight.lightType == LightType.Spot)
{
float sign = (SystemInfo.usesReversedZBuffer) ? -1.0f : 1.0f;
bias = light.shadowBias * sign;
normalBias = 0.0f;
}
else
{
Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
}
Vector3 lightDirection = -visibleLight.localToWorld.GetColumn(2);
cmd.SetGlobalVector("_ShadowBias", new Vector4(bias, normalBias, 0.0f, 0.0f));
cmd.SetGlobalVector("_LightDirection", new Vector4(lightDirection.x, lightDirection.y, lightDirection.z, 0.0f));
}
private void SetupDirectionalShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight, ref ScriptableRenderContext context)
{
Light light = shadowLight.light;
int cascadeCount = m_ShadowCasterCascadesCount;
for (int i = 0; i < kMaxCascades; ++i)
m_DirectionalShadowMatrices[i] = (cascadeCount >= i) ? m_CascadeSlices[i].shadowTransform : Matrix4x4.identity;
// We setup and additional a no-op WorldToShadow matrix in the last index
// because the ComputeCascadeIndex function in Shadows.hlsl can return an index
// out of bounds. (position not inside any cascade) and we want to avoid branching
Matrix4x4 noOpShadowMatrix = Matrix4x4.zero;
noOpShadowMatrix.m33 = (SystemInfo.usesReversedZBuffer) ? 1.0f : 0.0f;
m_DirectionalShadowMatrices[kMaxCascades] = noOpShadowMatrix;
float invShadowAtlasWidth = 1.0f / m_ShadowSettings.directionalShadowAtlasWidth;
float invShadowAtlasHeight = 1.0f / m_ShadowSettings.directionalShadowAtlasHeight;
float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
cmd.SetGlobalTexture(m_DirectionalShadowmapID, m_DirectionalShadowmapTexture);
cmd.SetGlobalMatrixArray(DirectionalShadowConstantBuffer._WorldToShadow, m_DirectionalShadowMatrices);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowData, new Vector4(light.shadowStrength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVectorArray(DirectionalShadowConstantBuffer._DirShadowSplitSpheres, m_CascadeSplitDistances);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._DirShadowSplitSphereRadii, m_CascadeSplitRadii);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset0, new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset1, new Vector4(invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset2, new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset3, new Vector4(invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth, invShadowAtlasHeight,
m_ShadowSettings.directionalShadowAtlasWidth, m_ShadowSettings.directionalShadowAtlasHeight));
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
}
private void SetupLocalLightsShadowReceiverConstants(CommandBuffer cmd, ref ScriptableRenderContext context)
{
for (int i = 0; i < m_LocalLightSlices.Length; ++i)
m_LocalShadowMatrices[i] = m_LocalLightSlices[i].shadowTransform;
float invShadowAtlasWidth = 1.0f / m_ShadowSettings.localShadowAtlasWidth;
float invShadowAtlasHeight = 1.0f / m_ShadowSettings.localShadowAtlasHeight;
float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
cmd.SetGlobalTexture(m_LocalShadowmapID, m_LocalShadowmapTexture);
cmd.SetGlobalMatrixArray(LocalShadowConstantBuffer._LocalWorldToShadowAtlas, m_LocalShadowMatrices);
cmd.SetGlobalFloatArray(LocalShadowConstantBuffer._LocalShadowStrength, m_LocalShadowStrength);
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset0, new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset1, new Vector4(invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset2, new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset3, new Vector4(invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowmapSize, new Vector4(invShadowAtlasWidth, invShadowAtlasHeight,
m_ShadowSettings.localShadowAtlasWidth, m_ShadowSettings.localShadowAtlasHeight));
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
}
};
}

11
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs.meta


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

71
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceCommon.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_COMMON_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_COMMON_INCLUDED
#include "Core.hlsl"
#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "CoreRP/ShaderLibrary/CommonMaterial.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_BumpMap); SAMPLER(sampler_BumpMap);
TEXTURE2D(_EmissionMap); SAMPLER(sampler_EmissionMap);
// Must match Lightweigth ShaderGraph master node
struct SurfaceData
{
half3 albedo;
half3 specular;
half metallic;
half smoothness;
half3 normalTS;
half3 emission;
half occlusion;
half alpha;
};
///////////////////////////////////////////////////////////////////////////////
// Material Property Helpers //
///////////////////////////////////////////////////////////////////////////////
half Alpha(half albedoAlpha, half4 color, half cutoff)
{
#if !defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) && !defined(_GLOSSINESS_FROM_BASE_ALPHA)
half alpha = albedoAlpha * color.a;
#else
half alpha = color.a;
#endif
#if defined(_ALPHATEST_ON)
clip(alpha - cutoff);
#endif
return alpha;
}
half4 SampleAlbedoAlpha(float2 uv, TEXTURE2D_ARGS(albedoAlphaMap, sampler_albedoAlphaMap))
{
return SAMPLE_TEXTURE2D(albedoAlphaMap, sampler_albedoAlphaMap, uv);
}
half3 SampleNormal(float2 uv, TEXTURE2D_ARGS(bumpMap, sampler_bumpMap), half scale = 1.0h)
{
#if _NORMALMAP
half4 n = SAMPLE_TEXTURE2D(bumpMap, sampler_bumpMap, uv);
#if BUMP_SCALE_NOT_SUPPORTED
return UnpackNormal(n);
#else
return UnpackNormalScale(n, scale);
#endif
#else
return half3(0.0h, 0.0h, 1.0h);
#endif
}
half3 SampleEmission(float2 uv, half3 emissionColor, TEXTURE2D_ARGS(emissionMap, sampler_emissionMap))
{
#ifndef _EMISSION
return 0;
#else
return SAMPLE_TEXTURE2D(emissionMap, sampler_emissionMap, uv).rgb * emissionColor;
#endif
}
#endif // LIGHTWEIGHT_INPUT_SURFACE_COMMON_INCLUDED

97
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfacePBR.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED
#include "Core.hlsl"
#include "CoreRP/ShaderLibrary/CommonMaterial.hlsl"
#include "InputSurfaceCommon.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Glossiness;
half _GlossMapScale;
half _Metallic;
half _BumpScale;
half _OcclusionStrength;
CBUFFER_END
TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap);
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
#ifdef _SPECULAR_SETUP
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv)
#else
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv)
#endif
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)
{
half4 specGloss;
#ifdef _METALLICSPECGLOSSMAP
specGloss = SAMPLE_METALLICSPECULAR(uv);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _GlossMapScale;
#else
specGloss.a *= _GlossMapScale;
#endif
#else // _METALLICSPECGLOSSMAP
#if _SPECULAR_SETUP
specGloss.rgb = _SpecColor.rgb;
#else
specGloss.rgb = _Metallic.rrr;
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _GlossMapScale;
#else
specGloss.a = _Glossiness;
#endif
#endif
return specGloss;
}
half SampleOcclusion(float2 uv)
{
#ifdef _OCCLUSIONMAP
#if (SHADER_TARGET < 30)
// SM20: instruction count limitation
// SM20: simpler occlusion
return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
#else
half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
return LerpWhiteTo(occ, _OcclusionStrength);
#endif
#else
return 1.0;
#endif
}
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_PARAM(_MainTex, sampler_MainTex));
outSurfaceData.alpha = Alpha(albedoAlpha.a, _Color, _Cutoff);
half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a);
outSurfaceData.albedo = albedoAlpha.rgb * _Color.rgb;
#if _SPECULAR_SETUP
outSurfaceData.metallic = 1.0h;
outSurfaceData.specular = specGloss.rgb;
#else
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
#endif
outSurfaceData.smoothness = specGloss.a;
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap), _BumpScale);
outSurfaceData.occlusion = SampleOcclusion(uv);
outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap));
}
#endif // LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfacePBR.hlsl.meta


fileFormatVersion: 2
guid: c46f85bf266d7496d9b3659acfbdc711
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

33
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceSimple.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_SIMPLE_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_SIMPLE_INCLUDED
#include "Core.hlsl"
#include "InputSurfaceCommon.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Shininess;
CBUFFER_END
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
half4 SampleSpecularGloss(half2 uv, half alpha, half4 specColor, TEXTURE2D_ARGS(specGlossMap, sampler_specGlossMap))
{
half4 specularGloss = half4(0.0h, 0.0h, 0.0h, 1.0h);
#ifdef _SPECGLOSSMAP
specularGloss = SAMPLE_TEXTURE2D(specGlossMap, sampler_specGlossMap, uv);
#elif defined(_SPECULAR_COLOR)
specularGloss = specColor;
#endif
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
specularGloss.a = alpha;
#endif
return specularGloss;
}
#endif // LIGHTWEIGHT_INPUT_SURFACE_SIMPLE_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceSimple.hlsl.meta


fileFormatVersion: 2
guid: ad863d097888f42c6bcf419efb2946c5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

15
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_UNLIT_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_UNLIT_INCLUDED
#include "Core.hlsl"
#include "InputSurfaceCommon.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half _Cutoff;
half _Glossiness;
half _Metallic;
CBUFFER_END
#endif // LIGHTWEIGHT_INPUT_SURFACE_UNLIT_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl.meta


fileFormatVersion: 2
guid: e7ba75cc852b14b7f934978b5697bf1b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

146
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl


#ifndef LIGHTWEIGHT_PASS_LIT_INCLUDED
#define LIGHTWEIGHT_PASS_LIT_INCLUDED
#include "LWRP/ShaderLibrary/Lighting.hlsl"
struct LightweightVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct LightweightVertexOutput
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
#ifdef _NORMALMAP
half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
half4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
half4 binormal : TEXCOORD5; // xyz: binormal, w: viewDir.z
#else
half3 normal : TEXCOORD3;
half3 viewDir : TEXCOORD4;
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
#ifdef _SHADOWS_ENABLED
float4 shadowCoord : TEXCOORD7;
#endif
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(LightweightVertexOutput IN, half3 normalTS, out InputData inputData)
{
inputData.positionWS = IN.posWSShininess.xyz;
#ifdef _NORMALMAP
half3 viewDir = half3(IN.normal.w, IN.tangent.w, IN.binormal.w);
inputData.normalWS = TangentToWorldNormal(normalTS, IN.tangent.xyz, IN.binormal.xyz, IN.normal.xyz);
#else
half3 viewDir = IN.viewDir;
inputData.normalWS = FragmentNormalWS(IN.normal);
#endif
inputData.viewDirectionWS = FragmentViewDirWS(viewDir);
#ifdef _SHADOWS_ENABLED
inputData.shadowCoord = IN.shadowCoord;
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = IN.fogFactorAndVertexLight.x;
inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.vertexSH, inputData.normalWS);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard (Simple Lighting) shader
LightweightVertexOutput LitPassVertexSimple(LightweightVertexInput v)
{
LightweightVertexOutput o = (LightweightVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.posWSShininess.xyz = TransformObjectToWorld(v.vertex.xyz);
o.posWSShininess.w = _Shininess * 128.0;
o.clipPos = TransformWorldToHClip(o.posWSShininess.xyz);
half3 viewDir = VertexViewDirWS(GetCameraPositionWS() - o.posWSShininess.xyz);
#ifdef _NORMALMAP
o.normal.w = viewDir.x;
o.tangent.w = viewDir.y;
o.binormal.w = viewDir.z;
#else
o.viewDir = viewDir;
#endif
// initializes o.normal and if _NORMALMAP also o.tangent and o.binormal
OUTPUT_NORMAL(v, o);
// We either sample GI from lightmap or SH.
// Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
// see DECLARE_LIGHTMAP_OR_SH macro.
// The following funcions initialize the correct variable with correct data
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(o.normal.xyz, o.vertexSH);
half3 vertexLight = VertexLighting(o.posWSShininess.xyz, o.normal.xyz);
half fogFactor = ComputeFogFactor(o.clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#ifdef _SHADOWS_ENABLED
#if SHADOWS_SCREEN
o.shadowCoord = ComputeShadowCoord(o.clipPos);
#else
o.shadowCoord = TransformWorldToShadowCoord(o.posWSShininess.xyz);
#endif
#endif
return o;
}
// Used for StandardSimpleLighting shader
half4 LitPassFragmentSimple(LightweightVertexOutput IN) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);
float2 uv = IN.uv;
half4 diffuseAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_PARAM(_MainTex, sampler_MainTex));
half3 diffuse = diffuseAlpha.rgb * _Color.rgb;
half alpha = diffuseAlpha.a * _Color.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
diffuse *= alpha;
#endif
half3 normalTS = SampleNormal(uv, TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap));
half3 emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap));
half4 specularGloss = SampleSpecularGloss(uv, diffuseAlpha.a, _SpecColor, TEXTURE2D_PARAM(_SpecGlossMap, sampler_SpecGlossMap));
half shininess = IN.posWSShininess.w;
InputData inputData;
InitializeInputData(IN, normalTS, inputData);
return LightweightFragmentBlinnPhong(inputData, diffuse, specularGloss, shininess, emission, alpha);
};
#endif

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl.meta


fileFormatVersion: 2
guid: ee447e65526c7db45a978c16b28827a9
timeCreated: 1488965025
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

22
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl


#ifndef LIGHTWEIGHT_PASS_META_PBR_INCLUDED
#define LIGHTWEIGHT_PASS_META_PBR_INCLUDED
#include "LightweightPassMetaCommon.hlsl"
half4 LightweightFragmentMeta(MetaVertexOuput i) : SV_Target
{
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(i.uv, surfaceData);
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
MetaInput o;
o.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5;
o.SpecularColor = surfaceData.specular;
o.Emission = surfaceData.emission;
return MetaFragment(o);
}
#endif // LIGHTWEIGHT_PASS_META_PBR_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl.meta


fileFormatVersion: 2
guid: dcf4e762d48204e33b575f8007e3d563
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

17
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaSimple.hlsl


#ifndef LIGHTWEIGHT_PASS_META_SIMPLE_INCLUDED
#define LIGHTWEIGHT_PASS_META_SIMPLE_INCLUDED
#include "LightweightPassMetaCommon.hlsl"
half4 LightweightFragmentMetaSimple(MetaVertexOuput i) : SV_Target
{
float2 uv = i.uv;
MetaInput o;
o.Albedo = _Color.rgb * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv).rgb;
o.SpecularColor = SampleSpecularGloss(uv, 1.0h, _SpecColor, TEXTURE2D_PARAM(_SpecGlossMap, sampler_SpecGlossMap)).xyz;
o.Emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap));
return MetaFragment(o);
}
#endif // LIGHTWEIGHT_PASS_META_SIMPLE_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaSimple.hlsl.meta


fileFormatVersion: 2
guid: ffc632d1e38ef4682807a89afb2b966f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

33
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/ParticlesPBR.hlsl


#ifndef LIGHTWEIGHT_PARTICLES_PBR_INCLUDED
#define LIGHTWEIGHT_PARTICLES_PBR_INCLUDED
#include "Particles.hlsl"
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
void InitializeSurfaceData(VertexOutputLit IN, out SurfaceData surfaceData)
{
half4 albedo = SampleAlbedo(IN, TEXTURE2D_PARAM(_MainTex, sampler_MainTex));
#if defined(_METALLICGLOSSMAP)
half2 metallicGloss = readTexture(TEXTURE2D_PARAM(_MetallicGlossMap, sampler_MetallicGlossMap), IN).ra * half2(1.0, _Glossiness);
#else
half2 metallicGloss = half2(_Metallic, _Glossiness);
#endif
half3 normalTS = SampleNormalTS(IN, TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap), _BumpScale);
half3 emission = SampleEmission(IN, _EmissionColor.rgb, TEXTURE2D_PARAM(_EmissionMap, sampler_EmissionMap));
surfaceData.albedo = albedo.rgb;
surfaceData.specular = half3(0.0h, 0.0h, 0.0h);
surfaceData.normalTS = normalTS;
surfaceData.emission = emission;
surfaceData.metallic = metallicGloss.r;
surfaceData.smoothness = metallicGloss.g;
surfaceData.occlusion = 1.0;
surfaceData.albedo = AlphaModulate(surfaceData.albedo, albedo.a);
surfaceData.alpha = AlphaBlendAndTest(albedo.a, _Cutoff);
}
#endif // LIGHTWEIGHT_PARTICLES_PBR_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/ParticlesPBR.hlsl.meta


fileFormatVersion: 2
guid: a3129e299d0744bb7bd42c2cea7cea2b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

8
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain.meta


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

82
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightSampling.shader


Shader "Hidden/LightweightPipeline/Sampling"
{
Properties
{
_MainTex("Albedo", 2D) = "white" {}
}
HLSLINCLUDE
#include "LWRP/ShaderLibrary/Core.hlsl"
struct VertexInput
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Interpolators
{
float4 pos : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
Interpolators Vertex(VertexInput i)
{
Interpolators o;
UNITY_SETUP_INSTANCE_ID(i);
UNITY_TRANSFER_INSTANCE_ID(i, o);
o.pos = TransformObjectToHClip(i.vertex.xyz);
o.texcoord.xy = i.texcoord;
return o;
}
half4 DownsampleBox4Tap(TEXTURE2D_ARGS(tex, samplerTex), float2 uv, float2 texelSize, float amount)
{
float4 d = texelSize.xyxy * float4(-amount, -amount, amount, amount);
half4 s;
s = (SAMPLE_TEXTURE2D(tex, samplerTex, uv + d.xy));
s += (SAMPLE_TEXTURE2D(tex, samplerTex, uv + d.zy));
s += (SAMPLE_TEXTURE2D(tex, samplerTex, uv + d.xw));
s += (SAMPLE_TEXTURE2D(tex, samplerTex, uv + d.zw));
return s * 0.25h;
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline"}
LOD 100
// 0 - Downsample - Box filtering
Pass
{
Tags { "LightMode" = "LightweightForward"}
ZTest Always
ZWrite Off
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma vertex Vertex
#pragma fragment FragBoxDownsample
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
float4 _MainTex_TexelSize;
float _SampleOffset;
half4 FragBoxDownsample(Interpolators i) : SV_Target
{
half4 col = DownsampleBox4Tap(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), i.texcoord, _MainTex_TexelSize.xy, _SampleOffset);
return half4(col.rgb, 1);
}
ENDHLSL
}
}
}

10
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightSampling.shader.meta


fileFormatVersion: 2
guid: 04c410c9937594faa893a11dceb85f7e
timeCreated: 1505729520
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

8
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain.meta


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

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl.meta


fileFormatVersion: 2
guid: ca55f7593a02f4c1ab1bdbc03282d7af
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

31
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "CoreRP/ShaderLibrary/CommonMaterial.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceCommon.hlsl"
CBUFFER_START(_Terrain)
half _Metallic0, _Metallic1, _Metallic2, _Metallic3;
half _Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3;
float4 _Control_ST;
half4 _Splat0_ST, _Splat1_ST, _Splat2_ST, _Splat3_ST;
CBUFFER_END
TEXTURE2D(_Control); SAMPLER(sampler_Control);
TEXTURE2D(_Splat0); SAMPLER(sampler_Splat0);
TEXTURE2D(_Splat1);
TEXTURE2D(_Splat2);
TEXTURE2D(_Splat3);
#ifdef _TERRAIN_NORMAL_MAP
TEXTURE2D(_Normal0); SAMPLER(sampler_Normal0);
TEXTURE2D(_Normal1);
TEXTURE2D(_Normal2);
TEXTURE2D(_Normal3);
#endif
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
#endif // LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl.meta


fileFormatVersion: 2
guid: a817cb90496894b368593402e13b040c
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

41
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_TERRAIN_BASE_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_TERRAIN_BASE_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "CoreRP/ShaderLibrary/CommonMaterial.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceCommon.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half _Cutoff;
CBUFFER_END
TEXTURE2D(_MetallicTex); SAMPLER(sampler_MetallicTex);
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)
{
half4 specGloss;
specGloss = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, uv);
specGloss.a = albedoAlpha;
return specGloss;
}
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
half4 albedoSmoothness= SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
outSurfaceData.alpha = 1;
half4 specGloss = SampleMetallicSpecGloss(uv, albedoSmoothness.a);
outSurfaceData.albedo = albedoSmoothness.rgb;
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
outSurfaceData.smoothness = specGloss.a;
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_PARAM(_BumpMap, sampler_BumpMap));
outSurfaceData.occlusion = 1;
outSurfaceData.emission = 0;
}
#endif // LIGHTWEIGHT_INPUT_SURFACE_TERRAIN_BASE_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl.meta


fileFormatVersion: 2
guid: fbd614929e4f04b8584f224142f1259d
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

40
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassDepthOnlyGrass.hlsl


#ifndef LIGHTWEIGHT_PASS_DEPTH_ONLY_INCLUDED
#define LIGHTWEIGHT_PASS_DEPTH_ONLY_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
struct VertexInput
{
float4 position : POSITION;
half4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput
{
float2 uv : TEXCOORD0;
half4 color : TEXCOORD1;
float4 clipPos : SV_POSITION;
};
VertexOutput DepthOnlyVertex(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
// _WaveAndDistance.z == 0 for MeshLit
float waveAmount = v.color.a * _WaveAndDistance.z;
o.color = TerrainWaveGrass (v.position, waveAmount, v.color);
o.clipPos = TransformObjectToHClip(v.position.xyz);
return o;
}
half4 DepthOnlyFragment(VertexOutput IN) : SV_TARGET
{
Alpha(SampleAlbedoAlpha(IN.uv, TEXTURE2D_PARAM(_MainTex, sampler_MainTex)).a, IN.color, _Cutoff);
return 0;
}
#endif

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassDepthOnlyGrass.hlsl.meta


fileFormatVersion: 2
guid: 4f907bbd39d214935a038247d3b26b9b
timeCreated: 1488965025
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

158
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitGrass.hlsl


#ifndef LIGHTWEIGHT_PASS_LIT_INCLUDED
#define LIGHTWEIGHT_PASS_LIT_INCLUDED
#include "LWRP/ShaderLibrary/Lighting.hlsl"
struct GrassVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
half4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct GrassVertexOutput
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
half3 normal : TEXCOORD3;
half3 viewDir : TEXCOORD4;
half4 fogFactorAndVertexLight : TEXCOORD5; // x: fogFactor, yzw: vertex light
#ifdef _SHADOWS_ENABLED
float4 shadowCoord : TEXCOORD6;
#endif
half4 color : TEXCOORD7;
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(GrassVertexOutput IN, out InputData inputData)
{
inputData.positionWS = IN.posWSShininess.xyz;
half3 viewDir = IN.viewDir;
inputData.normalWS = FragmentNormalWS(IN.normal);
inputData.viewDirectionWS = FragmentViewDirWS(viewDir);
#ifdef _SHADOWS_ENABLED
inputData.shadowCoord = IN.shadowCoord;
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = IN.fogFactorAndVertexLight.x;
inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.vertexSH, inputData.normalWS);
}
void InitializeVertData(GrassVertexInput IN, inout GrassVertexOutput vertData)
{
vertData.uv = IN.texcoord;
vertData.posWSShininess.xyz = TransformObjectToWorld(IN.vertex.xyz);
vertData.posWSShininess.w = 32;
vertData.clipPos = TransformWorldToHClip(vertData.posWSShininess.xyz);
half3 viewDir = VertexViewDirWS(GetCameraPositionWS() - vertData.posWSShininess.xyz);
vertData.viewDir = viewDir;
// initializes o.normal and if _NORMALMAP also o.tangent and o.binormal
OUTPUT_NORMAL(IN, vertData);
// We either sample GI from lightmap or SH.
// Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
// see DECLARE_LIGHTMAP_OR_SH macro.
// The following funcions initialize the correct variable with correct data
OUTPUT_LIGHTMAP_UV(IN.lightmapUV, unity_LightmapST, vertData.lightmapUV);
OUTPUT_SH(vertData.normal.xyz, vertData.vertexSH);
half3 vertexLight = VertexLighting(vertData.posWSShininess.xyz, vertData.normal.xyz);
half fogFactor = ComputeFogFactor(vertData.clipPos.z);
vertData.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#ifdef _SHADOWS_ENABLED
#if SHADOWS_SCREEN
vertData.shadowCoord = ComputeShadowCoord(vertData.clipPos);
#else
vertData.shadowCoord = TransformWorldToShadowCoord(vertData.posWSShininess.xyz);
#endif
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Grass: appdata_full usage
// color - .xyz = color, .w = wave scale
// normal - normal
// tangent.xy - billboard extrusion
// texcoord - UV coords
// texcoord1 - 2nd UV coords
GrassVertexOutput WavingGrassVert(GrassVertexInput v)
{
GrassVertexOutput o = (GrassVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
// _WaveAndDistance.z == 0 for MeshLit
float waveAmount = v.color.a * _WaveAndDistance.z;
o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
InitializeVertData(v, o);
return o;
}
GrassVertexOutput WavingGrassBillboardVert(GrassVertexInput v)
{
GrassVertexOutput o = (GrassVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TerrainBillboardGrass (v.vertex, v.tangent.xy);
// wave amount defined by the grass height
float waveAmount = v.tangent.y;
o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
InitializeVertData(v, o);
return o;
}
// Used for StandardSimpleLighting shader
half4 LitPassFragmentGrass(GrassVertexOutput IN) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);
float2 uv = IN.uv;
half4 diffuseAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_PARAM(_MainTex, sampler_MainTex));
half3 diffuse = diffuseAlpha.rgb * IN.color.rgb;
half alpha = diffuseAlpha.a;
AlphaDiscard(alpha, _Cutoff);
alpha *= IN.color.a;
half3 emission = 0;
half4 specularGloss = 0.1;// SampleSpecularGloss(uv, diffuseAlpha.a, _SpecColor, TEXTURE2D_PARAM(_SpecGlossMap, sampler_SpecGlossMap));
half shininess = IN.posWSShininess.w;
InputData inputData;
InitializeInputData(IN, inputData);
return LightweightFragmentBlinnPhong(inputData, diffuse, specularGloss, shininess, emission, alpha);
};
#endif

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitGrass.hlsl.meta


fileFormatVersion: 2
guid: b4bc78a1364154f15b718a412e9710b6
timeCreated: 1488965025
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

165
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl


#ifndef LIGHTWEIGHT_PASS_LIT_TERRAIN_INCLUDED
#define LIGHTWEIGHT_PASS_LIT_TERRAIN_INCLUDED
#include "LWRP/ShaderLibrary/Lighting.hlsl"
struct VertexInput
{
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
struct VertexOutput
{
float4 uvSplat01 : TEXCOORD0; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD1; // xy: splat2, zw: splat3
float4 uvControlAndLM : TEXCOORD2; // xy: control, zw: lightmap
half3 normal : TEXCOORD3;
#if _TERRAIN_NORMAL_MAP
half3 tangent : TEXCOORD4;
half3 binormal : TEXCOORD5;
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float3 positionWS : TEXCOORD7;
float4 shadowCoord : TEXCOORD8;
float4 clipPos : SV_POSITION;
};
void InitializeInputData(VertexOutput IN, half3 normalTS, out InputData input)
{
input = (InputData)0;
input.positionWS = IN.positionWS;
#ifdef _TERRAIN_NORMAL_MAP
input.normalWS = TangentToWorldNormal(normalTS, IN.tangent, IN.binormal, IN.normal);
#else
input.normalWS = normalize(IN.normal);
#endif
input.viewDirectionWS = SafeNormalize(GetCameraPositionWS() - IN.positionWS);
#ifdef _SHADOWS_ENABLED
input.shadowCoord = IN.shadowCoord;
#else
input.shadowCoord = float4(0, 0, 0, 0);
#endif
input.fogCoord = IN.fogFactorAndVertexLight.x;
input.vertexLighting = IN.fogFactorAndVertexLight.yzw;
#ifdef LIGHTMAP_ON
input.bakedGI = SampleLightmap(IN.uvControlAndLM.zw, input.normalWS);
#endif
}
void SplatmapMix(VertexOutput IN, half4 defaultAlpha, out half4 splat_control, out half weight, out half4 mixedDiffuse, inout half3 mixedNormal)
{
splat_control = SAMPLE_TEXTURE2D(_Control, sampler_Control, IN.uvControlAndLM.xy);
weight = dot(splat_control, 1);
#if !defined(SHADER_API_MOBILE) && defined(TERRAIN_SPLAT_ADDPASS)
clip(weight == 0.0f ? -1 : 1);
#endif
// Normalize weights before lighting and restore weights in final modifier functions so that the overal
// lighting result can be correctly weighted.
splat_control /= (weight + 1e-3f);
mixedDiffuse = 0.0f;
mixedDiffuse += splat_control.r * SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, IN.uvSplat01.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.r);
mixedDiffuse += splat_control.g * SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, IN.uvSplat01.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.g);
mixedDiffuse += splat_control.b * SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, IN.uvSplat23.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.b);
mixedDiffuse += splat_control.a * SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, IN.uvSplat23.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.a);
#ifdef _TERRAIN_NORMAL_MAP
half4 nrm = 0.0f;
nrm += splat_control.r * SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, IN.uvSplat01.xy);
nrm += splat_control.g * SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, IN.uvSplat01.zw);
nrm += splat_control.b * SAMPLE_TEXTURE2D(_Normal2, sampler_Normal0, IN.uvSplat23.xy);
nrm += splat_control.a * SAMPLE_TEXTURE2D(_Normal3, sampler_Normal0, IN.uvSplat23.zw);
mixedNormal = UnpackNormal(nrm);
#else
mixedNormal = half3(0, 0, 1);
#endif
}
void SplatmapFinalColor(inout half4 color, half fogCoord)
{
color.rgb *= color.a;
#ifdef TERRAIN_SPLAT_ADDPASS
ApplyFogColor(color.rgb, half3(0,0,0), fogCoord);
#else
ApplyFog(color.rgb, fogCoord);
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard Terrain shader
VertexOutput SplatmapVert(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
float3 positionWS = TransformObjectToWorld(v.vertex.xyz);
float4 clipPos = TransformWorldToHClip(positionWS);
o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
o.uvControlAndLM.xy = TRANSFORM_TEX(v.texcoord, _Control);
o.uvControlAndLM.zw = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
#ifdef _TERRAIN_NORMAL_MAP
float4 vertexTangent = float4(cross(v.normal, float3(0, 0, 1)), -1.0);
OutputTangentToWorld(vertexTangent, v.normal, o.tangent, o.binormal, o.normal);
#else
o.normal = TransformObjectToWorldNormal(v.normal);
#endif
o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
o.fogFactorAndVertexLight.yzw = VertexLighting(positionWS, o.normal);
o.positionWS = positionWS;
o.clipPos = clipPos;
#ifdef _SHADOWS_ENABLED
#if SHADOWS_SCREEN
o.shadowCoord = ComputeShadowCoord(o.clipPos);
#else
o.shadowCoord = TransformWorldToShadowCoord(positionWS);
#endif
#endif
return o;
}
// Used in Standard Terrain shader
half4 SpatmapFragment(VertexOutput IN) : SV_TARGET
{
half4 splat_control;
half weight;
half4 mixedDiffuse;
half4 defaultSmoothness = half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
half3 normalTS;
SplatmapMix(IN, defaultSmoothness, splat_control, weight, mixedDiffuse, normalTS);
half3 albedo = mixedDiffuse.rgb;
half smoothness = mixedDiffuse.a;
half metallic = dot(splat_control, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
half3 specular = half3(0, 0, 0);
half alpha = weight;
InputData inputData;
InitializeInputData(IN, normalTS, inputData);
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, specular, smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
SplatmapFinalColor(color, inputData.fogCoord);
return half4(color.rgb, 1);
}
#endif // LIGHTWEIGHT_PASS_LIT_TERRAIN_INCLUDED

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl.meta


fileFormatVersion: 2
guid: ad25529ea2516421ab5f1a2440bee139
timeCreated: 1488965025
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

108
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl


#ifndef LIGHTWEIGHT_INPUT_SURFACE_GRASS_INCLUDED
#define LIGHTWEIGHT_INPUT_SURFACE_GRASS_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/InputSurfaceCommon.hlsl"
// Terrain engine shader helpers
CBUFFER_START(TerrainGrass)
half4 _WavingTint;
float4 _WaveAndDistance; // wind speed, wave size, wind amount, max sqr distance
float4 _CameraPosition; // .xyz = camera position, .w = 1 / (max sqr distance)
float3 _CameraRight, _CameraUp;
CBUFFER_END
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Shininess;
CBUFFER_END
// ---- Grass helpers
// Calculate a 4 fast sine-cosine pairs
// val: the 4 input values - each must be in the range (0 to 1)
// s: The sine of each of the 4 values
// c: The cosine of each of the 4 values
void FastSinCos (float4 val, out float4 s, out float4 c) {
val = val * 6.408849 - 3.1415927;
// powers for taylor series
float4 r5 = val * val; // wavevec ^ 2
float4 r6 = r5 * r5; // wavevec ^ 4;
float4 r7 = r6 * r5; // wavevec ^ 6;
float4 r8 = r6 * r5; // wavevec ^ 8;
float4 r1 = r5 * val; // wavevec ^ 3
float4 r2 = r1 * r5; // wavevec ^ 5;
float4 r3 = r2 * r5; // wavevec ^ 7;
//Vectors for taylor's series expansion of sin and cos
float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841};
float4 cos8 = {-0.5, 0.041666666, -0.0013888889, 0.000024801587};
// sin
s = val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
// cos
c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
}
half4 TerrainWaveGrass (inout float4 vertex, float waveAmount, half4 color)
{
half4 _waveXSize = half4(0.012, 0.02, 0.06, 0.024) * _WaveAndDistance.y;
half4 _waveZSize = half4 (0.006, .02, 0.02, 0.05) * _WaveAndDistance.y;
half4 waveSpeed = half4 (1.2, 2, 1.6, 4.8);
half4 _waveXmove = half4(0.024, 0.04, -0.12, 0.096);
half4 _waveZmove = half4 (0.006, .02, -0.02, 0.1);
float4 waves;
waves = vertex.x * _waveXSize;
waves += vertex.z * _waveZSize;
// Add in time to model them over time
waves += _WaveAndDistance.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
s = s * s;
s = s * s;
half lighting = dot (s, normalize (half4 (1,1,.4,.2))) * 0.7;
s = s * waveAmount;
half3 waveMove = 0;
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
vertex.xz -= waveMove.xz * _WaveAndDistance.z;
// apply color animation
half3 waveColor = lerp (0.5, _WavingTint.rgb, lighting);
// Fade the grass out before detail distance.
// Saturate because Radeon HD drivers on OS X 10.4.10 don't saturate vertex colors properly.
half3 offset = vertex.xyz - _CameraPosition.xyz;
color.a = saturate (2 * (_WaveAndDistance.w - dot (offset, offset)) * _CameraPosition.w);
return half4(2 * waveColor * color.rgb, color.a);
}
void TerrainBillboardGrass( inout float4 pos, float2 offset )
{
float3 grasspos = pos.xyz - _CameraPosition.xyz;
if (dot(grasspos, grasspos) > _WaveAndDistance.w)
offset = 0.0;
pos.xyz += offset.x * _CameraRight.xyz;
pos.y += offset.y;
}
#endif // LIGHTWEIGHT_INPUT_SURFACE_GRASS_INCLUDED

114
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrain.shader


Shader "LightweightPipeline/Terrain/Standard Terrain"
{
Properties
{
// set by terrain engine
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "grey" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "grey" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "grey" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "grey" {}
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 0.5
// used in fallback on old cards & base map
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "grey" {}
[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"}
Pass
{
Tags { "LightMode" = "LightweightForward" }
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SpatmapFragment
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
ENDHLSL
}
Pass
{
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#include "LWRP/ShaderLibrary/InputSurfacePBR.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
ENDHLSL
}
}
Dependency "AddPassShader" = "Hidden/LightweightPipeline/Terrain/Standard Terrain Add Pass"
Dependency "BaseMapShader" = "Hidden/LightweightPipeline/Terrain/Standard Terrain Base"
Fallback "Hidden/InternalErrorShader"
}

69
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainAddPass.shader


Shader "Hidden/LightweightPipeline/Terrain/Standard Terrain Add Pass"
{
Properties
{
// set by terrain engine
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 1.0
// used in fallback on old cards & base map
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "Queue" = "Geometry-99" "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"}
Pass
{
Tags { "LightMode" = "LightweightForward" }
Blend One One
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SpatmapFragment
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
#define TERRAIN_SPLAT_ADDPASS 1
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrain.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl"
ENDHLSL
}
}
Fallback "Hidden/InternalErrorShader"
}

10
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainAddPass.shader.meta


fileFormatVersion: 2
guid: 0a7e590f3cf1d4ee8a8fab5b6eff09ef
timeCreated: 1508929790
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

143
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainBase.shader


Shader "Hidden/LightweightPipeline/Terrain/Standard Terrain Base"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo(RGB), Smoothness(A)", 2D) = "white" {}
_MetallicTex ("Metallic (R)", 2D) = "black" {}
}
SubShader
{
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"}
LOD 200
// ------------------------------------------------------------------
// Forward pass. Shades all light in a single pass. GI + emission + Fog
Pass
{
// Lightmode matches the ShaderPassName set in LightweightPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Lightweight Pipeline
Tags{"LightMode" = "LightweightForward"}
HLSLPROGRAM
// Required to compile gles 2.0 with standard SRP library
// All shaders must be compiled with HLSLcc and currently only gles is not using HLSLcc by default
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------
// Material Keywords
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// TODO: Enabled this when we have C# keyword stripping
//#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassLit.hlsl"
ENDHLSL
}
Pass
{
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassShadow.hlsl"
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Tags{"LightMode" = "Meta"}
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex LightweightVertexMeta
#pragma fragment LightweightFragmentMeta
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
#pragma shader_feature EDITOR_VISUALIZATION
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceTerrainBase.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl"
ENDHLSL
}
}
FallBack "Hidden/InternalErrorShader"
CustomEditor "LightweightStandardGUI"
}

10
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrainBase.shader.meta


fileFormatVersion: 2
guid: dd20536f4428f4376af4032e17f6add0
timeCreated: 1503472755
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

89
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrass.shader


// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Hidden/TerrainEngine/Details/WavingDoublePass" // Has to override the internal shaders so named like this
{
Properties
{
_WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
_Cutoff ("Cutoff", float) = 0.5
}
SubShader
{
Tags {"Queue" = "Geometry+200" "RenderType" = "Grass" "IgnoreProjectors" = "True" "RenderPipeline" = "LightweightPipeline" }//"DisableBatching"="True"
Cull Off
LOD 200
AlphaTest Greater [_Cutoff]
ColorMask RGB
Pass
{
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// TODO: Enabled this when we have C# keyword stripping
//#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex WavingGrassVert
#pragma fragment LitPassFragmentGrass
#define _ALPHATEST_ON
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitGrass.hlsl"
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull Off
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#define _ALPHATEST_ON
#pragma shader_feature _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassDepthOnlyGrass.hlsl"
ENDHLSL
}
}
}

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrass.shader.meta


fileFormatVersion: 2
guid: e507fdfead5ca47e8b9a768b51c291a1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

89
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrassBillboard.shader


// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Hidden/TerrainEngine/Details/BillboardWavingDoublePass" // Has to override the internal shaders so named like this
{
Properties
{
_WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
_Cutoff ("Cutoff", float) = 0.5
}
SubShader
{
Tags {"Queue" = "Geometry+200" "RenderType" = "GrassBillBoard" "IgnoreProjectors" = "True" "RenderPipeline" = "LightweightPipeline" }//"DisableBatching"="True"
Cull Off
LOD 200
AlphaTest Greater [_Cutoff]
ColorMask RGB
Pass
{
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// TODO: Enabled this when we have C# keyword stripping
//#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex WavingGrassBillboardVert
#pragma fragment LitPassFragmentGrass
#define _ALPHATEST_ON
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassLitGrass.hlsl"
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull Off
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#define _ALPHATEST_ON
#pragma shader_feature _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "LWRP/ShaderLibrary/Terrain/InputSurfaceGrass.hlsl"
#include "LWRP/ShaderLibrary/Terrain/LightweightPassDepthOnlyGrass.hlsl"
ENDHLSL
}
}
}

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightWavingGrassBillboard.shader.meta


fileFormatVersion: 2
guid: 29868e73b638e48ca99a19ea58c48d90
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

179
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurface.hlsl


#ifndef LIGHTWEIGHT_SURFACE_INPUT_INCLUDED
#define LIGHTWEIGHT_SURFACE_INPUT_INCLUDED
#include "Core.hlsl"
#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "CoreRP/ShaderLibrary/CommonMaterial.hlsl"
#ifdef _SPECULAR_SETUP
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv)
#else
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv)
#endif
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Glossiness;
half _GlossMapScale;
half _Metallic;
half _BumpScale;
half _OcclusionStrength;
half _Shininess;
CBUFFER_END
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
TEXTURE2D(_BumpMap); SAMPLER(sampler_BumpMap);
TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap);
TEXTURE2D(_EmissionMap); SAMPLER(sampler_EmissionMap);
// Must match Lightweigth ShaderGraph master node
struct SurfaceData
{
half3 albedo;
half3 specular;
half metallic;
half smoothness;
half3 normalTS;
half3 emission;
half occlusion;
half alpha;
};
///////////////////////////////////////////////////////////////////////////////
// Material Property Helpers //
///////////////////////////////////////////////////////////////////////////////
float2 TransformMainTextureCoord(float2 uv)
{
return TRANSFORM_TEX(uv, _MainTex);
}
half Alpha(half albedoAlpha)
{
#if !defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) && !defined(_GLOSSINESS_FROM_BASE_ALPHA)
half alpha = albedoAlpha * _Color.a;
#else
half alpha = _Color.a;
#endif
#if defined(_ALPHATEST_ON)
clip(alpha - _Cutoff);
#endif
return alpha;
}
half4 MainTexture(float2 uv)
{
return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
}
half3 Normal(float2 uv)
{
#if _NORMALMAP
#if BUMP_SCALE_NOT_SUPPORTED
return UnpackNormal(SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv));
#else
return UnpackNormalScale(SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv), _BumpScale);
#endif
#else
return half3(0.0h, 0.0h, 1.0h);
#endif
}
half4 SpecularGloss(half2 uv, half alpha)
{
half4 specularGloss = half4(0, 0, 0, 1);
#ifdef _SPECGLOSSMAP
specularGloss = SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv);
#elif defined(_SPECULAR_COLOR)
specularGloss = _SpecColor;
#endif
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
specularGloss.a = alpha;
#endif
return specularGloss;
}
half4 MetallicSpecGloss(float2 uv, half albedoAlpha)
{
half4 specGloss;
#ifdef _METALLICSPECGLOSSMAP
specGloss = SAMPLE_METALLICSPECULAR(uv);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _GlossMapScale;
#else
specGloss.a *= _GlossMapScale;
#endif
#else // _METALLICSPECGLOSSMAP
#if _SPECULAR_SETUP
specGloss.rgb = _SpecColor.rgb;
#else
specGloss.rgb = _Metallic.rrr;
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _GlossMapScale;
#else
specGloss.a = _Glossiness;
#endif
#endif
return specGloss;
}
half Occlusion(float2 uv)
{
#ifdef _OCCLUSIONMAP
#if (SHADER_TARGET < 30)
// SM20: instruction count limitation
// SM20: simpler occlusion
return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
#else
half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
return LerpWhiteTo(occ, _OcclusionStrength);
#endif
#else
return 1.0;
#endif
}
half3 Emission(float2 uv)
{
#ifndef _EMISSION
return 0;
#else
return SAMPLE_TEXTURE2D(_EmissionMap, sampler_EmissionMap, uv).rgb * _EmissionColor.rgb;
#endif
}
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
half4 albedoAlpha = MainTexture(uv);
half4 specGloss = MetallicSpecGloss(uv, albedoAlpha.a);
outSurfaceData.albedo = albedoAlpha.rgb * _Color.rgb;
#if _SPECULAR_SETUP
outSurfaceData.metallic = 1.0h;
outSurfaceData.specular = specGloss.rgb;
#else
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
#endif
outSurfaceData.smoothness = specGloss.a;
outSurfaceData.normalTS = Normal(uv);
outSurfaceData.occlusion = Occlusion(uv);
outSurfaceData.emission = Emission(uv);
outSurfaceData.alpha = Alpha(albedoAlpha.a);
}
#endif

245
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardTerrain.shader


Shader "LightweightPipeline/Standard Terrain"
{
Properties
{
// set by terrain engine
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 1.0
// used in fallback on old cards & base map
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"}
Pass
{
Tags { "LightMode" = "LightweightForward" }
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SpatmapFragment
// -------------------------------------
// Lightweight Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile __ _TERRAIN_NORMAL_MAP
#include "LWRP/ShaderLibrary/Lighting.hlsl"
CBUFFER_START(_Terrain)
half _Metallic0;
half _Metallic1;
half _Metallic2;
half _Metallic3;
half _Smoothness0;
half _Smoothness1;
half _Smoothness2;
half _Smoothness3;
float4 _Control_ST;
half4 _Splat0_ST, _Splat1_ST, _Splat2_ST, _Splat3_ST;
CBUFFER_END
sampler2D _Control;
sampler2D _Splat0, _Splat1, _Splat2, _Splat3;
#ifdef _TERRAIN_NORMAL_MAP
sampler2D _Normal0, _Normal1, _Normal2, _Normal3;
#endif
struct VertexInput
{
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
struct VertexOutput
{
float4 uvSplat01 : TEXCOORD0; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD1; // xy: splat2, zw: splat3
float4 uvControlAndLM : TEXCOORD2; // xy: control, zw: lightmap
half3 normal : TEXCOORD3;
#if _TERRAIN_NORMAL_MAP
half3 tangent : TEXCOORD4;
half3 binormal : TEXCOORD5;
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float3 positionWS : TEXCOORD7;
float4 shadowCoord : TEXCOORD8;
float4 clipPos : SV_POSITION;
};
void InitializeInputData(VertexOutput IN, half3 normalTS, out InputData input)
{
input = (InputData)0;
input.positionWS = IN.positionWS;
#ifdef _TERRAIN_NORMAL_MAP
input.normalWS = TangentToWorldNormal(normalTS, IN.tangent, IN.binormal, IN.normal);
#else
input.normalWS = normalize(IN.normal);
#endif
input.viewDirectionWS = SafeNormalize(GetCameraPositionWS() - IN.positionWS);
input.shadowCoord = IN.shadowCoord;
input.fogCoord = IN.fogFactorAndVertexLight.x;
#ifdef LIGHTMAP_ON
input.bakedGI = SampleLightmap(IN.uvControlAndLM.zw, input.normalWS);
#endif
}
void SplatmapMix(VertexOutput IN, half4 defaultAlpha, out half4 splat_control, out half weight, out half4 mixedDiffuse, inout half3 mixedNormal)
{
splat_control = tex2D(_Control, IN.uvControlAndLM.xy);
weight = dot(splat_control, half4(1, 1, 1, 1));
#if !defined(SHADER_API_MOBILE) && defined(TERRAIN_SPLAT_ADDPASS)
clip(weight == 0.0f ? -1 : 1);
#endif
// Normalize weights before lighting and restore weights in final modifier functions so that the overal
// lighting result can be correctly weighted.
splat_control /= (weight + 1e-3f);
mixedDiffuse = 0.0f;
mixedDiffuse += splat_control.r * tex2D(_Splat0, IN.uvSplat01.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.r);
mixedDiffuse += splat_control.g * tex2D(_Splat1, IN.uvSplat01.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.g);
mixedDiffuse += splat_control.b * tex2D(_Splat2, IN.uvSplat23.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.b);
mixedDiffuse += splat_control.a * tex2D(_Splat3, IN.uvSplat23.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.a);
#ifdef _TERRAIN_NORMAL_MAP
half4 nrm = 0.0f;
nrm += splat_control.r * tex2D(_Normal0, IN.uvSplat01.xy);
nrm += splat_control.g * tex2D(_Normal1, IN.uvSplat01.zw);
nrm += splat_control.b * tex2D(_Normal2, IN.uvSplat23.xy);
nrm += splat_control.a * tex2D(_Normal3, IN.uvSplat23.zw);
mixedNormal = UnpackNormal(nrm);
#else
mixedNormal = half3(0, 0, 1);
#endif
}
VertexOutput SplatmapVert(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
float3 positionWS = TransformObjectToWorld(v.vertex.xyz);
float4 clipPos = TransformWorldToHClip(positionWS);
o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
o.uvControlAndLM.xy = TRANSFORM_TEX(v.texcoord, _Control);
o.uvControlAndLM.zw = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
#ifdef _TERRAIN_NORMAL_MAP
float4 vertexTangent = float4(cross(v.normal, float3(0, 0, 1)), -1.0);
OutputTangentToWorld(vertexTangent, v.normal, o.tangent, o.binormal, o.normal);
#else
o.normal = TransformObjectToWorldNormal(v.normal);
#endif
o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
o.fogFactorAndVertexLight.yzw = VertexLighting(positionWS, o.normal);
o.positionWS = positionWS;
o.clipPos = clipPos;
o.shadowCoord = ComputeScreenPos(o.clipPos);
return o;
}
half4 SpatmapFragment(VertexOutput IN) : SV_TARGET
{
half4 splat_control;
half weight;
half4 mixedDiffuse;
half4 defaultSmoothness = half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
half3 normalTS;
SplatmapMix(IN, defaultSmoothness, splat_control, weight, mixedDiffuse, normalTS);
half3 albedo = mixedDiffuse.rgb;
half smoothness = mixedDiffuse.a;
half metallic = dot(splat_control, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
half3 specular = half3(0, 0, 0);
half alpha = weight;
InputData inputData;
InitializeInputData(IN, normalTS, inputData);
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, specular, smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
ApplyFog(color.rgb, inputData.fogCoord);
return color;
}
ENDHLSL
}
Pass
{
Tags{"Lightmode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#include "LWRP/ShaderLibrary/Core.hlsl"
float4 vert(float4 pos : POSITION) : SV_POSITION
{
return TransformObjectToHClip(pos.xyz);
}
half4 frag() : SV_TARGET
{
return 0;
}
ENDHLSL
}
}
Fallback "Hidden/InternalErrorShader"
}

/ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMeta.hlsl.meta → /ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl.meta

/ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMeta.hlsl → /ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl

/ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurface.hlsl.meta → /ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceCommon.hlsl.meta

/ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardTerrain.shader.meta → /ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/Terrain/LightweightStandardTerrain.shader.meta

正在加载...
取消
保存