浏览代码

Merge branch 'master' into refactor-shader-variant-per-material

/main
sebastienlagarde 7 年前
当前提交
4a622009
共有 58 个文件被更改,包括 1626 次插入749 次删除
  1. 8
      TestProjects/LWGraphicsTest/Packages/manifest.json
  2. 13
      com.unity.render-pipelines.core/CoreRP/Debugging/MousePositionDebug.cs
  3. 205
      com.unity.render-pipelines.core/CoreRP/Editor/CoreEditorUtils.cs
  4. 13
      com.unity.render-pipelines.core/CoreRP/Utilities/CoreUtils.cs
  5. 6
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  6. 5
      com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/PlanarReflectionProbeUI.Drawers.cs
  7. 4
      com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/SerializedPlanarReflectionProbe.cs
  8. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDAssetFactory.cs
  9. 16
      com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDRenderPipelineMenuItems.cs
  10. 105
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template
  11. 342
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRSubShader.cs
  12. 226
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs
  13. 94
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template
  14. 262
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitSubShader.cs
  15. 33
      com.unity.render-pipelines.high-definition/HDRP/Editor/Upgraders/HDRPVersion.cs
  16. 22
      com.unity.render-pipelines.high-definition/HDRP/Editor/Upgraders/UpgradeMenuItem.cs
  17. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  18. 14
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
  19. 16
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  20. 26
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs
  21. 12
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassVelocity.hlsl
  22. 4
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/VertMesh.hlsl
  23. 58
      com.unity.render-pipelines.lightweight/LWRP/Editor/LightweightLightEditor.cs
  24. 16
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs
  25. 16
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs
  26. 2
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template
  27. 2
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template
  28. 38
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderPreprocessor.cs
  29. 22
      com.unity.render-pipelines.lightweight/LWRP/LightweightForwardRenderer.cs
  30. 4
      com.unity.render-pipelines.lightweight/LWRP/LightweightPipeline.cs
  31. 30
      com.unity.render-pipelines.lightweight/LWRP/LightweightPipelineCore.cs
  32. 44
      com.unity.render-pipelines.lightweight/LWRP/Passes/ForwardLitPass.cs
  33. 11
      com.unity.render-pipelines.lightweight/LWRP/Passes/ScreenSpaceShadowResolvePass.cs
  34. 4
      com.unity.render-pipelines.lightweight/LWRP/Passes/ScriptableRenderPass.cs
  35. 30
      com.unity.shadergraph/CHANGELOG.md
  36. 55
      com.unity.shadergraph/Editor/Data/Graphs/PreviewProperty.cs
  37. 8
      com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs
  38. 14
      com.unity.shadergraph/Editor/Data/Nodes/Procedural/CheckerboardNode.cs
  39. 69
      com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs
  40. 16
      com.unity.shadergraph/Editor/Data/Util/ShaderGenerator.cs
  41. 1
      com.unity.shadergraph/Editor/Data/Util/ShaderGeneratorNames.cs
  42. 1
      com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs
  43. 52
      com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs
  44. 8
      com.unity.render-pipelines.core/CoreRP/Editor/Shadow.meta
  45. 3
      com.unity.shadergraph/.data/face_sign.png
  46. 3
      com.unity.shadergraph/.data/hd_render_pipeline.png
  47. 3
      com.unity.shadergraph/.data/texture_2d_lod_node.PNG
  48. 3
      com.unity.shadergraph/.data/texture_nodes.png
  49. 3
      com.unity.shadergraph/.data/vertex_position.png
  50. 18
      com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs
  51. 3
      com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs.meta
  52. 120
      com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs
  53. 11
      com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs.meta
  54. 41
      com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs
  55. 11
      com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs.meta
  56. 214
      com.unity.render-pipelines.core/CoreRP/Editor/Shadow/ShadowCascadeSplitGUI.cs
  57. 11
      com.unity.render-pipelines.core/CoreRP/Editor/Shadow/ShadowCascadeSplitGUI.cs.meta

8
TestProjects/LWGraphicsTest/Packages/manifest.json


{
"dependencies": {
"com.unity.postprocessing": "file:../../../../com.unity.postprocessing",
"com.unity.render-pipelines.core": "file:../../../../com.unity.render-pipelines.core",
"com.unity.shadergraph": "file:../../../../com.unity.shadergraph",
"com.unity.render-pipelines.lightweight": "file:../../../../com.unity.render-pipelines.lightweight"
"com.unity.postprocessing": "file:../../../com.unity.postprocessing",
"com.unity.render-pipelines.core": "file:../../../com.unity.render-pipelines.core",
"com.unity.shadergraph": "file:../../../com.unity.shadergraph",
"com.unity.render-pipelines.lightweight": "file:../../../com.unity.render-pipelines.lightweight"
}
}

13
com.unity.render-pipelines.core/CoreRP/Debugging/MousePositionDebug.cs


public static void Cleanup()
{
if (s_Instance != null)
DestroyImmediate(s_Instance.gameObject);
{
// Either we call DestroyImmediate or Destroy we get an error :(
// GameViewEventCatcher is only use for SSR debugging currently so comment this code and uncomment it if you want to debug SSR
//DestroyImmediate(s_Instance.gameObject);
//Destroy(s_Instance.gameObject);
}
}
public static void Build()

#if UNITY_EDITOR
UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
UnityEditor.SceneView.onSceneGUIDelegate += OnSceneGUI;
GameViewEventCatcher.Build();
// Disabled as it cause error: GameViewEventCatcher is only use for SSR debugging currently so comment this code and uncomment it if you want to debug SSR
//GameViewEventCatcher.Build();
#endif
}

UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
GameViewEventCatcher.Cleanup();
// Disabled as it cause error: GameViewEventCatcher is only use for SSR debugging currently so comment this code and uncomment it if you want to debug SSR
//GameViewEventCatcher.Cleanup();
#endif
}

205
com.unity.render-pipelines.core/CoreRP/Editor/CoreEditorUtils.cs


namespace UnityEditor.Experimental.Rendering
{
using UnityObject = UnityEngine.Object;
public static class CoreEditorUtils
{
// GUIContent cache utilities

mode = EditorGUILayout.Popup(label, mode, options);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(property.objectReferenceValue, property.name);
}
}
public static void DrawCascadeSplitGUI<T>(ref SerializedProperty shadowCascadeSplit)

string[] versionText = readText[0].Split(' ');
return versionText[1];
}
}
static class ShadowCascadeSplitGUI
{
private const int kSliderbarTopMargin = 2;
private const int kSliderbarHeight = 24;
private const int kSliderbarBottomMargin = 2;
private const int kPartitionHandleWidth = 2;
private const int kPartitionHandleExtraHitAreaWidth = 2;
private static readonly Color[] kCascadeColors =
{
new Color(0.5f, 0.5f, 0.6f, 1.0f),
new Color(0.5f, 0.6f, 0.5f, 1.0f),
new Color(0.6f, 0.6f, 0.5f, 1.0f),
new Color(0.6f, 0.5f, 0.5f, 1.0f),
};
// using a LODGroup skin
private static readonly GUIStyle s_CascadeSliderBG = "LODSliderRange";
private static readonly GUIStyle s_TextCenteredStyle = new GUIStyle(EditorStyles.whiteMiniLabel)
{
alignment = TextAnchor.MiddleCenter
};
// Internal struct to bundle drag information
private class DragCache
{
public int m_ActivePartition; // the cascade partition that we are currently dragging/resizing
public float m_NormalizedPartitionSize; // the normalized size of the partition (0.0f < size < 1.0f)
public Vector2 m_LastCachedMousePosition; // mouse position the last time we registered a drag or mouse down.
public DragCache(int activePartition, float normalizedPartitionSize, Vector2 currentMousePos)
{
m_ActivePartition = activePartition;
m_NormalizedPartitionSize = normalizedPartitionSize;
m_LastCachedMousePosition = currentMousePos;
}
};
private static DragCache s_DragCache;
private static readonly int s_CascadeSliderId = "s_CascadeSliderId".GetHashCode();
private static SceneView s_RestoreSceneView;
private static SceneView.CameraMode s_OldSceneDrawMode;
private static bool s_OldSceneLightingMode;
/**
* Static function to handle the GUI and User input related to the cascade slider.
*
* @param normalizedCascadePartition The array of partition sizes in the range 0.0f - 1.0f; expects ONE entry if cascades = 2, and THREE if cascades=4
* The last entry will be automatically determined by summing up the array, and doing 1.0f - sum
*/
public static void HandleCascadeSliderGUI(ref float[] normalizedCascadePartitions)
static public void CheckOutFile(bool VCSEnabled, UnityObject mat)
EditorGUILayout.LabelField("Cascade splits");
// get the inspector width since we need it while drawing the partition rects.
// Only way currently is to reserve the block in the layout using GetRect(), and then immediately drawing the empty box
// to match the call to GetRect.
// From this point on, we move to non-layout based code.
var sliderRect = GUILayoutUtility.GetRect(GUIContent.none
, s_CascadeSliderBG
, GUILayout.Height(kSliderbarTopMargin + kSliderbarHeight + kSliderbarBottomMargin)
, GUILayout.ExpandWidth(true));
GUI.Box(sliderRect, GUIContent.none);
float currentX = sliderRect.x;
float cascadeBoxStartY = sliderRect.y + kSliderbarTopMargin;
float cascadeSliderWidth = sliderRect.width - (normalizedCascadePartitions.Length * kPartitionHandleWidth);
Color origTextColor = GUI.color;
Color origBackgroundColor = GUI.backgroundColor;
int colorIndex = -1;
// setup the array locally with the last partition
float[] adjustedCascadePartitions = new float[normalizedCascadePartitions.Length + 1];
System.Array.Copy(normalizedCascadePartitions, adjustedCascadePartitions, normalizedCascadePartitions.Length);
adjustedCascadePartitions[adjustedCascadePartitions.Length - 1] = 1.0f - normalizedCascadePartitions.Sum();
// check for user input on any of the partition handles
// this mechanism gets the current event in the queue... make sure that the mouse is over our control before consuming the event
int sliderControlId = GUIUtility.GetControlID(s_CascadeSliderId, FocusType.Passive);
Event currentEvent = Event.current;
int hotPartitionHandleIndex = -1; // the index of any partition handle that we are hovering over or dragging
// draw each cascade partition
for (int i = 0; i < adjustedCascadePartitions.Length; ++i)
if (VCSEnabled)
float currentPartition = adjustedCascadePartitions[i];
colorIndex = (colorIndex + 1) % kCascadeColors.Length;
GUI.backgroundColor = kCascadeColors[colorIndex];
float boxLength = (cascadeSliderWidth * currentPartition);
UnityEditor.VersionControl.Task task = UnityEditor.VersionControl.Provider.Checkout(mat, UnityEditor.VersionControl.CheckoutMode.Both);
// main cascade box
Rect partitionRect = new Rect(currentX, cascadeBoxStartY, boxLength, kSliderbarHeight);
GUI.Box(partitionRect, GUIContent.none, s_CascadeSliderBG);
currentX += boxLength;
// cascade box percentage text
GUI.color = Color.white;
Rect textRect = partitionRect;
var cascadeText = string.Format("{0}\n{1:F1}%", i, currentPartition * 100.0f);
GUI.Label(textRect, cascadeText, s_TextCenteredStyle);
// no need to draw the partition handle for last box
if (i == adjustedCascadePartitions.Length - 1)
break;
// partition handle
GUI.backgroundColor = Color.black;
Rect handleRect = partitionRect;
handleRect.x = currentX;
handleRect.width = kPartitionHandleWidth;
GUI.Box(handleRect, GUIContent.none, s_CascadeSliderBG);
// we want a thin handle visually (since wide black bar looks bad), but a slightly larger
// hit area for easier manipulation
Rect handleHitRect = handleRect;
handleHitRect.xMin -= kPartitionHandleExtraHitAreaWidth;
handleHitRect.xMax += kPartitionHandleExtraHitAreaWidth;
if (handleHitRect.Contains(currentEvent.mousePosition))
hotPartitionHandleIndex = i;
// add regions to slider where the cursor changes to Resize-Horizontal
if (s_DragCache == null)
if (!task.success)
EditorGUIUtility.AddCursorRect(handleHitRect, MouseCursor.ResizeHorizontal, sliderControlId);
Debug.Log(task.text + " " + task.resultCode);
currentX += kPartitionHandleWidth;
}
GUI.color = origTextColor;
GUI.backgroundColor = origBackgroundColor;
EventType eventType = currentEvent.GetTypeForControl(sliderControlId);
switch (eventType)
{
case EventType.MouseDown:
if (hotPartitionHandleIndex >= 0)
{
s_DragCache = new DragCache(hotPartitionHandleIndex, normalizedCascadePartitions[hotPartitionHandleIndex], currentEvent.mousePosition);
if (GUIUtility.hotControl == 0)
GUIUtility.hotControl = sliderControlId;
currentEvent.Use();
// Switch active scene view into shadow cascades visualization mode, once we start
// tweaking cascade splits.
if (s_RestoreSceneView == null)
{
s_RestoreSceneView = SceneView.lastActiveSceneView;
if (s_RestoreSceneView != null)
{
s_OldSceneDrawMode = s_RestoreSceneView.cameraMode;
s_OldSceneLightingMode = s_RestoreSceneView.m_SceneLighting;
s_RestoreSceneView.cameraMode = SceneView.GetBuiltinCameraMode(DrawCameraMode.ShadowCascades);
}
}
}
break;
case EventType.MouseUp:
// mouseUp event anywhere should release the hotcontrol (if it belongs to us), drags (if any)
if (GUIUtility.hotControl == sliderControlId)
{
GUIUtility.hotControl = 0;
currentEvent.Use();
}
s_DragCache = null;
// Restore previous scene view drawing mode once we stop tweaking cascade splits.
if (s_RestoreSceneView != null)
{
s_RestoreSceneView.cameraMode = s_OldSceneDrawMode;
s_RestoreSceneView.m_SceneLighting = s_OldSceneLightingMode;
s_RestoreSceneView = null;
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl != sliderControlId)
break;
// convert the mouse movement to normalized cascade width. Make sure that we are safe to apply the delta before using it.
float delta = (currentEvent.mousePosition - s_DragCache.m_LastCachedMousePosition).x / cascadeSliderWidth;
bool isLeftPartitionHappy = ((adjustedCascadePartitions[s_DragCache.m_ActivePartition] + delta) > 0.0f);
bool isRightPartitionHappy = ((adjustedCascadePartitions[s_DragCache.m_ActivePartition + 1] - delta) > 0.0f);
if (isLeftPartitionHappy && isRightPartitionHappy)
{
s_DragCache.m_NormalizedPartitionSize += delta;
normalizedCascadePartitions[s_DragCache.m_ActivePartition] = s_DragCache.m_NormalizedPartitionSize;
if (s_DragCache.m_ActivePartition < normalizedCascadePartitions.Length - 1)
normalizedCascadePartitions[s_DragCache.m_ActivePartition + 1] -= delta;
GUI.changed = true;
}
s_DragCache.m_LastCachedMousePosition = currentEvent.mousePosition;
currentEvent.Use();
break;
}
}
}

13
com.unity.render-pipelines.core/CoreRP/Utilities/CoreUtils.cs


return fogEnable;
}
static public void CheckOutFile(bool VSCEnabled, UnityObject mat)
{
if (VSCEnabled)
{
UnityEditor.VersionControl.Task task = UnityEditor.VersionControl.Provider.Checkout(mat, UnityEditor.VersionControl.CheckoutMode.Both);
if (!task.success)
{
Debug.Log(task.text + " " + task.resultCode);
}
}
}
}
}

6
com.unity.render-pipelines.high-definition/CHANGELOG.md


- Allow to double click on a render pipeline asset to setup it automatically in GraphicSettings
- Add shortcut to create DensityVolume and PlanarReflection in hierarchy
- Add a DefaultHDMirrorMaterial material for PlanarReflection
- Added a script to be able to update material to newer version of Unity
- Added a script to be able to upgrade material to newer version of HDRP
- Removed useless duplication of ForwardError passes.
### Changed, Removals and deprecations
- Removed GlobalLightLoopSettings.maxPlanarReflectionProbes and instead use value of GlobalLightLoopSettings.planarReflectionProbeCacheSize

- Fix discrepency between object motion vector and camera motion vector
- Fix issue with spot and dir light gizmo axis not highlighted correctly
- Fix potential crash while register debug windows inputs at startup
- Fix warning when creating Planar reflection
- Fix specular lighting debug mode (was rendering black)
- Allow projector decal with null material to allow to configure decal when HDRP is not set
## [2018.1 undecided]

5
com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/PlanarReflectionProbeUI.Drawers.cs


);
Inspector = CED.Group(
SectionProbeModeSettings,
//SectionProbeModeSettings,
CED.space,
CED.Action((s, d, o) => EditorGUILayout.LabelField(_.GetContent("Proxy Volume"), EditorStyles.boldLabel)),
CED.Action(Drawer_FieldProxyVolumeReference),

GUI.enabled = false;
EditorGUILayout.PropertyField(d.refreshMode, _.GetContent("Refresh Mode"));
EditorGUILayout.PropertyField(d.capturePositionMode, _.GetContent("Capture Position Mode"));
d.refreshMode.enumValueIndex = (int)ReflectionProbeRefreshMode.EveryFrame;
d.capturePositionMode.enumValueIndex = (int)PlanarReflectionProbe.CapturePositionMode.MirrorCamera;
GUI.enabled = true;
}

{
GUI.enabled = false;
EditorGUILayout.PropertyField(d.mode, _.GetContent("Type"));
d.mode.enumValueIndex = (int)ReflectionProbeMode.Realtime;
GUI.enabled = true;
}

4
com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/SerializedPlanarReflectionProbe.cs


{
serializedObject.Update();
mode.enumValueIndex = (int)ReflectionProbeMode.Realtime;
refreshMode.enumValueIndex = (int)ReflectionProbeRefreshMode.EveryFrame;
capturePositionMode.enumValueIndex = (int)PlanarReflectionProbe.CapturePositionMode.MirrorCamera;
var updateProxyVolume = reflectionProxyVolume != null
&& serializedObject.targetObjects.Length != reflectionProxyVolume.serializedObject.targetObjects.Length;
if (!updateProxyVolume && reflectionProxyVolume != null)

2
com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDAssetFactory.cs


newAsset.skyboxCubemap = Shader.Find("Skybox/Cubemap");
// Material
newAsset.preIntegratedFGD = Load<Shader>(HDRenderPipelinePath + "Material/PreIntegratedFGD.shader");
newAsset.preIntegratedFGD = Load<Shader>(HDRenderPipelinePath + "Material/PreIntegratedFGD/PreIntegratedFGD.shader");
// Utilities / Core
newAsset.encodeBC6HCS = Load<ComputeShader>(CorePath + "CoreResources/EncodeBC6H.compute");

16
com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDRenderPipelineMenuItems.cs


{
var materials = Resources.FindObjectsOfTypeAll<Material>();
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
CoreUtils.CheckOutFile(VSCEnabled, mat);
CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
LayeredLitGUI.SynchronizeAllLayers(mat);
EditorUtility.SetDirty(mat);
}

for (var i = 0; i < openedScenes.Length; ++i)
openedScenes[i] = SceneManager.GetSceneAt(i).path;
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
try
{

{
var scenePath = AssetDatabase.GUIDToAssetPath(scenes[i]);
var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(scenePath);
CoreUtils.CheckOutFile(VSCEnabled, sceneAsset);
CoreEditorUtils.CheckOutFile(VCSEnabled, sceneAsset);
EditorSceneManager.OpenScene(scenePath);
var sceneName = Path.GetFileNameWithoutExtension(scenePath);

{
var matIds = AssetDatabase.FindAssets("t:Material");
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
for (int i = 0, length = matIds.Length; i < length; i++)
{

string.Format("{0} / {1} materials cleaned.", i, length),
(i / (float)(length - 1)) * progressScale + progressOffset);
CoreUtils.CheckOutFile(VSCEnabled, mat);
CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
var h = Debug.unityLogger.logHandler;
Debug.unityLogger.logHandler = new UnityContextualLogHandler(mat);
HDEditorUtils.ResetMaterialKeywords(mat);

{
var materials = Resources.FindObjectsOfTypeAll<Material>();
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool anyMaterialDirty = false; // Will be true if any material is dirty.

string.Format("{0}{1} / {2} materials cleaned.", descriptionPrefix, i, length),
(i / (float)(length - 1)) * progressScale + progressOffset);
CoreUtils.CheckOutFile(VSCEnabled, materials[i]);
CoreEditorUtils.CheckOutFile(VCSEnabled, materials[i]);
if (HDEditorUtils.ResetMaterialKeywords(materials[i]))
{

105
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template


//-------------------------------------------------------------------------------------
HLSLPROGRAM
// Variant Definitions
// Variant Definitions (active field translations to HDRP defines)
${VariantDefines}
$AlphaTest: #define _ALPHATEST_ON 1
$Material.SubsurfaceScattering: #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1
$Material.Transmission: #define _MATERIAL_FEATURE_TRANSMISSION 1
$Material.Anisotropy: #define _MATERIAL_FEATURE_ANISOTROPY 1
$Material.ClearCoat: #define _MATERIAL_FEATURE_CLEAR_COAT 1
$Material.Iridescence: #define _MATERIAL_FEATURE_IRIDESCENCE 1
$Material.SpecularColor: #define _MATERIAL_FEATURE_SPECULAR_COLOR 1
$SurfaceType.Transparent: #define _SURFACE_TYPE_TRANSPARENT 1
$BlendMode.Alpha: #define _BLENDMODE_ALPHA 1
$BlendMode.Add: #define _BLENDMODE_ADD 1
//-------------------------------------------------------------------------------------
// End Variant
//-------------------------------------------------------------------------------------

// Use surface gradient normal mapping as it handle correctly triplanar normal mapping and multiple UVSet
// this modifies the normal calculation
// #define SURFACE_GRADIENT
// This shader support vertex modification (or not)
// TODO - move to PBR shader control
// #define HAVE_VERTEX_MODIFICATION
// If we use subsurface scattering, enable output split lighting (for forward pass)
#if defined(_MATID_SSS) && !defined(_SURFACE_TYPE_TRANSPARENT)

$VaryingsMeshToPS.texCoord3: #define VARYINGS_NEED_TEXCOORD3
$VaryingsMeshToPS.color: #define VARYINGS_NEED_COLOR
$VaryingsMeshToPS.cullFace: #define VARYINGS_NEED_CULLFACE
$features.modifyMesh: #define HAVE_MESH_MODIFICATION
#include "ShaderGraphLibrary/Functions.hlsl"
#include "HDRP/ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "HDRP/Debug/DebugDisplay.hlsl"

// End graph generated code
//-------------------------------------------------------------------------------------
// TODO: Do we want to build include functionality for sharing these preprocessed functions across templates?
#ifdef HAVE_MESH_MODIFICATION
// TODO: we should share this between template files somehow
VertexDescriptionInputs AttributesMeshToVertexDescriptionInputs(AttributesMesh input)
{
VertexDescriptionInputs output;
ZERO_INITIALIZE(VertexDescriptionInputs, output);
$VertexDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = input.normalOS;
$VertexDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = TransformObjectToWorldNormal(input.normalOS);
$VertexDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = TransformWorldToViewDir(output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
$VertexDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = input.tangentOS;
$VertexDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = TransformObjectToWorldDir(input.tangentOS.xyz);
$VertexDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
$VertexDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
$VertexDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = normalize(cross(input.normalOS, input.tangentOS) * (input.tangentOS.w > 0.0f ? 1.0f : -1.0f) * GetOddNegativeScale());
$VertexDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = TransformObjectToWorldDir(output.ObjectSpaceBiTangent);
$VertexDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
$VertexDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
$VertexDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = input.positionOS;
$VertexDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = TransformObjectToWorld(input.positionOS);
$VertexDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = TransformWorldToView(output.WorldSpacePosition);
$VertexDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
$VertexDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = GetWorldSpaceNormalizeViewDir(output.WorldSpacePosition);
$VertexDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
$VertexDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = TransformWorldToViewDir(output.WorldSpaceViewDirection);
$VertexDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(output.WorldSpacePosition), _ProjectionParams.x);
$VertexDescriptionInputs.uv0: output.uv0 = float4(input.uv0, 0.0f, 0.0f);
$VertexDescriptionInputs.uv1: output.uv1 = float4(input.uv1, 0.0f, 0.0f);
$VertexDescriptionInputs.uv2: output.uv2 = float4(input.uv2, 0.0f, 0.0f);
$VertexDescriptionInputs.uv3: output.uv3 = float4(input.uv3, 0.0f, 0.0f);
$VertexDescriptionInputs.VertexColor: output.VertexColor = input.color;
return output;
}
AttributesMesh ApplyMeshModification(AttributesMesh input)
{
// build graph inputs
VertexDescriptionInputs vertexDescriptionInputs = AttributesMeshToVertexDescriptionInputs(input);
// evaluate vertex graph
VertexDescription vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
// copy graph output to the results
$VertexDescription.Position: input.positionOS = vertexDescription.Position;
return input;
}
#endif // HAVE_MESH_MODIFICATION
// TODO: Do we want to build include functionality for sharing these preprocessed functions across templates?
FragInputs BuildFragInputs(VaryingsMeshToPS input)
{
FragInputs output;

$SurfaceDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_I_V); // transposed multiplication by inverse matrix to handle normal scale
$SurfaceDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
$SurfaceDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = input.worldToTangent[0].xyz;
$SurfaceDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = input.worldToTangent[0].xyz;
$SurfaceDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = mul((float3x3) unity_WorldToObject, output.WorldSpaceTangent);
$SurfaceDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = mul((float3x3) UNITY_MATRIX_V, output.WorldSpaceTangent);
$SurfaceDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);

$SurfaceDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
// TODO: positionSS is SV_Position, graph input expects screenPosition to be 0..1 across the active viewport (?)
$SurfaceDescriptionInputs.screenPosition: output.screenPosition = input.positionSS;
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionWS), _ProjectionParams.x);
$SurfaceDescriptionInputs.vertexColor: output.vertexColor = input.color;
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
return output;
}

// Perform alpha test very early to save performance (a killed pixel will not sample textures)
// TODO: split graph evaluation to grab just alpha dependencies first? tricky..
#ifdef _ALPHATEST_ON
DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
#endif
$AlphaTest: DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData);

builtinData.opacity = surfaceDescription.Alpha;
builtinData.bakeDiffuseLighting = SampleBakedGI(fragInputs.positionWS, bentNormalWS, fragInputs.texCoord1, fragInputs.texCoord2); // see GetBuiltinData()
// It is safe to call this function here as surfaceData have been filled
// We want to know if we must enable transmission on GI for SSS material, if the material have no SSS, this code will be remove by the compiler.
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);

builtinData.bakeDiffuseLighting += SampleBakedGI(fragInputs.positionWS, -fragInputs.worldToTangent[2], fragInputs.texCoord1, fragInputs.texCoord2) * bsdfData.transmittance;
}
builtinData.emissiveIntensity = 1.0f;
$SurfaceDescription.Emission: builtinData.emissiveColor = surfaceDescription.Emission;
builtinData.velocity = float2(0.0, 0.0);
#ifdef SHADOWS_SHADOWMASK

//-------------------------------------------------------------------------------------
ENDHLSL
}
}

342
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRSubShader.cs


using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Linq;
using UnityEditor.Graphing;

PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};
Pass m_PassGBufferWithPrepass = new Pass()

PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};
Pass m_PassMETA = new Pass()

"AttributesMesh.uv1",
"AttributesMesh.color",
"AttributesMesh.uv2", // SHADERPASS_LIGHT_TRANSPORT always uses uv2
// "FragInputs.worldToTangent",
// "FragInputs.positionWS",
},
PixelShaderSlots = new List<int>()
{

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
// VertexShaderSlots = new List<int>()
// {
// PBRMasterNode.PositionSlotId
// }
};
Pass m_PassShadowCaster = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

{
"FragInputs.positionWS",
},
PixelShaderSlots = new List<int>()
{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
StencilOverride = new List<string>()
{
"// If velocity pass (motion vectors) is enabled we tag the stencil so it don't perform CameraMotionVelocity",

" Comp Always",
" Pass Replace",
"}"
}
},
PixelShaderSlots = new List<int>()
{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassDistortion = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassTransparentDepthPrepass = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassTransparentBackface = new Pass()

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassForward = new Pass()

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
};
Pass m_PassTransparentDepthPostpass = new Pass()

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
private static string GetVariantDefines(PBRMasterNode masterNode)
private static HashSet<string> GetActiveFieldsFromMasterNode(INode iMasterNode, Pass pass)
ShaderGenerator defines = new ShaderGenerator();
HashSet<string> activeFields = new HashSet<string>();
PBRMasterNode masterNode = iMasterNode as PBRMasterNode;
if (masterNode == null)
{
return activeFields;
}
// TODO:
// _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
// _MATERIAL_FEATURE_TRANSMISSION
// _MATERIAL_FEATURE_ANISOTROPY
// _MATERIAL_FEATURE_CLEAR_COAT
// _MATERIAL_FEATURE_IRIDESCENCE
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
switch (masterNode.model)
{

defines.AddShaderChunk("#define _MATERIAL_FEATURE_SPECULAR_COLOR 1", true);
activeFields.Add("Material.SpecularColor");
break;
default:
// TODO: error!

// #pragma shader_feature _ALPHATEST_ON
defines.AddShaderChunk("#define _ALPHATEST_ON 1", true);
activeFields.Add("AlphaTest");
}
// if (kTesselationMode != TessellationMode.None)

// #pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR // MOVE to a node
// #pragma shader_feature _NORMALMAP_TANGENT_SPACE
// #pragma shader_feature _ _REQUIRE_UV2 _REQUIRE_UV3
//
// #pragma shader_feature _NORMALMAP
if (masterNode.IsSlotConnected(PBRMasterNode.NormalSlotId))
{
defines.AddShaderChunk("#define _NORMALMAP 1", true);
}
// #pragma shader_feature _MASKMAP
// #pragma shader_feature _BENTNORMALMAP

// #pragma shader_feature _TANGENTMAP
// #pragma shader_feature _ANISOTROPYMAP
// #pragma shader_feature _DETAIL_MAP // MOVE to a node
// #pragma shader_feature _SUBSURFACE_RADIUS_MAP
// #pragma shader_feature _THICKNESSMAP
// #pragma shader_feature _SPECULARCOLORMAP

if (masterNode.surfaceType != SurfaceType.Opaque)
{
// transparent-only defines
defines.AddShaderChunk("#define _SURFACE_TYPE_TRANSPARENT 1", true);
activeFields.Add("SurfaceType.Transparent");
defines.AddShaderChunk("#define _BLENDMODE_ALPHA 1", true);
activeFields.Add("BlendMode.Alpha");
defines.AddShaderChunk("#define _BLENDMODE_ADD 1", true);
activeFields.Add("BlendMode.Add");
}
// else if (masterNode.alphaMode == PBRMasterNode.AlphaMode.PremultiplyAlpha) // TODO
// {

{
// opaque-only defines
}
// MaterialId are used as shader feature to allow compiler to optimize properly
// Note _MATID_STANDARD is not define as there is always the default case "_". We assign default as _MATID_STANDARD, so we never test _MATID_STANDARD
// #pragma shader_feature _ _MATID_SSS _MATID_ANISO _MATID_SPECULAR _MATID_CLEARCOAT
// enable dithering LOD crossfade
// #pragma multi_compile _ LOD_FADE_CROSSFADE

return defines.GetShaderString(2);
return activeFields;
private static bool GenerateShaderPass(PBRMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
private static bool GenerateShaderPassLit(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
{
var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDEditorUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);
if (!File.Exists(templateLocation))

if (sourceAssetDependencyPaths != null)
sourceAssetDependencyPaths.Add(templateLocation);
// grab all of the active nodes
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var graphRequirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.Fragment);
var pixelRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false); // TODO: is ShaderStageCapability.Fragment correct?
var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);
// Function Registry tracks functions to remove duplicates, it wraps a string builder that stores the combined function string
// TODO: this can be a shared function for all HDRP master nodes -- From here through GraphUtil.GenerateSurfaceDescription(..)
// TODO: this can be a shared function -- From here through GraphUtil.GenerateSurfaceDescription(..)
var activeSlots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
{
MaterialSlot slot = masterNode.FindSlot<MaterialSlot>(id);
if (slot != null)
{
activeSlots.Add(slot);
}
}
var pixelSlots = HDSubShaderUtilities.FindMaterialSlotsOnNode(pass.PixelShaderSlots, masterNode);
var vertexSlots = HDSubShaderUtilities.FindMaterialSlotsOnNode(pass.VertexShaderSlots, masterNode);
// properties used by either pixel and vertex shader
PropertyCollector sharedProperties = new PropertyCollector();
string graphInputStructName = "SurfaceDescriptionInputs";
string graphOutputStructName = "SurfaceDescription";
string graphEvalFunctionName = "SurfaceDescriptionFunction";
ShaderStringBuilder graphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder graphOutputs = new ShaderStringBuilder();
PropertyCollector graphProperties = new PropertyCollector();
string pixelGraphInputStructName = "SurfaceDescriptionInputs";
string pixelGraphOutputStructName = "SurfaceDescription";
string pixelGraphEvalFunctionName = "SurfaceDescriptionFunction";
ShaderStringBuilder pixelGraphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder pixelGraphOutputs = new ShaderStringBuilder();
// dependency tracker -- set of active fields
HashSet<string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass);
// build initial requirements
HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, pixelRequirements);
HashSet<string> activeFields = new HashSet<string>();
GraphUtil.GenerateSurfaceDescriptionStruct(graphOutputs, activeSlots, true);
//GraphUtil.GenerateSurfaceDescriptionStruct(graphOutputs, activeSlots, true, graphOutputStructName, activeFields);
GraphUtil.GenerateSurfaceDescriptionStruct(pixelGraphOutputs, pixelSlots, true, pixelGraphOutputStructName, activeFields);
activeNodeList,
pixelNodes,
graphEvalFunction,
pixelGraphEvalFunction,
graphProperties,
graphRequirements, // TODO : REMOVE UNUSED
sharedProperties,
pixelRequirements, // TODO : REMOVE UNUSED
graphEvalFunctionName,
graphOutputStructName,
pixelGraphEvalFunctionName,
pixelGraphOutputStructName,
activeSlots,
graphInputStructName);
pixelSlots,
pixelGraphInputStructName);
string vertexGraphInputStructName = "VertexDescriptionInputs";
string vertexGraphOutputStructName = "VertexDescription";
string vertexGraphEvalFunctionName = "VertexDescriptionFunction";
ShaderStringBuilder vertexGraphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder vertexGraphOutputs = new ShaderStringBuilder();
// check for vertex animation -- enables HAVE_VERTEX_MODIFICATION
bool vertexActive = false;
if (masterNode.IsSlotConnected(PBRMasterNode.PositionSlotId))
{
vertexActive = true;
activeFields.Add("features.modifyMesh");
HDRPShaderStructs.AddActiveFieldsFromVertexGraphRequirements(activeFields, vertexRequirements);
// -------------------------------------
// Generate Output structure for Vertex Description function
GraphUtil.GenerateVertexDescriptionStruct(vertexGraphOutputs, vertexSlots, vertexGraphOutputStructName, activeFields);
// -------------------------------------
// Generate Vertex Description function
GraphUtil.GenerateVertexDescriptionFunction(
masterNode.owner as AbstractMaterialGraph,
vertexGraphEvalFunction,
functionRegistry,
sharedProperties,
mode,
vertexNodes,
vertexSlots,
vertexGraphInputStructName,
vertexGraphEvalFunctionName,
vertexGraphOutputStructName);
}
var blendCode = new ShaderStringBuilder();
var cullCode = new ShaderStringBuilder();

var colorMaskCode = new ShaderStringBuilder();
HDSubShaderUtilities.BuildRenderStatesFromPassAndMaterialOptions(pass, materialOptions, blendCode, cullCode, zTestCode, zWriteCode, stencilCode, colorMaskCode);
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
if (pass.PixelShaderSlots != null)
{
foreach (var slotId in pass.PixelShaderSlots)
{
var slot = masterNode.FindSlot<MaterialSlot>(slotId);
if (slot != null)
{
var rawSlotName = slot.RawDisplayName().ToString();
var descriptionVar = string.Format("{0}.{1}", graphOutputStructName, rawSlotName);
activeFields.Add(descriptionVar);
}
}
}
// apply dependencies to the active fields, and build interpolators (TODO: split this function)
var graphInputs = new ShaderGenerator();
graphInputs,
graphRequirements,
pass.RequiredFields,
CoordinateSpace.World,
activeFields);
// debug output all active fields

}
}
// build graph inputs structures
ShaderGenerator pixelGraphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.SurfaceDescriptionInputs), activeFields, pixelGraphInputs);
ShaderGenerator vertexGraphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.VertexDescriptionInputs), activeFields, vertexGraphInputs);
ShaderGenerator defines = new ShaderGenerator();
{
defines.AddShaderChunk(string.Format("#define SHADERPASS {0}", pass.ShaderPassName), true);

// build graph code
var graph = new ShaderGenerator();
graph.AddShaderChunk("// Graph Inputs");
graph.Indent();
graph.AddGenerator(graphInputs);
graph.Deindent();
graph.AddShaderChunk("// Graph Outputs");
graph.Indent();
graph.AddShaderChunk(graphOutputs.ToString());
//graph.AddGenerator(graphOutputs);
graph.Deindent();
graph.AddShaderChunk("// Graph Properties (uniform inputs)");
graph.AddShaderChunk(graphProperties.GetPropertiesDeclaration(1));
graph.AddShaderChunk("// Graph Node Functions");
graph.AddShaderChunk(graphNodeFunctions.ToString());
graph.AddShaderChunk("// Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(graphEvalFunction.ToString());
//graph.AddGenerator(graphEvalFunction);
graph.Deindent();
{
graph.AddShaderChunk("// Shared Graph Properties (uniform inputs)");
graph.AddShaderChunk(sharedProperties.GetPropertiesDeclaration(1));
if (vertexActive)
{
graph.AddShaderChunk("// Vertex Graph Inputs");
graph.Indent();
graph.AddGenerator(vertexGraphInputs);
graph.Deindent();
graph.AddShaderChunk("// Vertex Graph Outputs");
graph.Indent();
graph.AddShaderChunk(vertexGraphOutputs.ToString());
graph.Deindent();
}
graph.AddShaderChunk("// Pixel Graph Inputs");
graph.Indent();
graph.AddGenerator(pixelGraphInputs);
graph.Deindent();
graph.AddShaderChunk("// Pixel Graph Outputs");
graph.Indent();
graph.AddShaderChunk(pixelGraphOutputs.ToString());
graph.Deindent();
graph.AddShaderChunk("// Shared Graph Node Functions");
graph.AddShaderChunk(graphNodeFunctions.ToString());
if (vertexActive)
{
graph.AddShaderChunk("// Vertex Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(vertexGraphEvalFunction.ToString());
graph.Deindent();
}
graph.AddShaderChunk("// Pixel Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(pixelGraphEvalFunction.ToString());
graph.Deindent();
}
// build the hash table of all named fragments TODO: could make this Dictionary<string, ShaderGenerator / string> ?
Dictionary<string, string> namedFragments = new Dictionary<string, string>();

namedFragments.Add("${Stencil}", stencilCode.ToString());
namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
namedFragments.Add("${LOD}", materialOptions.lod.ToString());
namedFragments.Add("${VariantDefines}", GetVariantDefines(masterNode));
// process the template to generate the shader code for this pass TODO: could make this a shared function
string[] templateLines = File.ReadAllLines(templateLocation);

if (opaque)
{
GenerateShaderPass(masterNode, m_PassGBuffer, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassGBufferWithPrepass, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassGBuffer, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassGBufferWithPrepass, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassMETA, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassShadowCaster, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassMETA, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassDepthOnly, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassMotionVectors, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassDepthOnly, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassDistortion, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassDistortion, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassTransparentDepthPrepass, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassTransparentDepthPrepass, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassTransparentBackface, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassTransparentBackface, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassForward, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassForward, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassTransparentDepthPostpass, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassLit(masterNode, m_PassTransparentDepthPostpass, mode, materialOptions, subShader, sourceAssetDependencyPaths);
}
}
subShader.Deindent();

226
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs


};
};
struct SurfaceDescriptionInputs
// this describes the input to the pixel shader graph eval
public struct SurfaceDescriptionInputs
{
[Optional] Vector3 ObjectSpaceNormal;
[Optional] Vector3 ViewSpaceNormal;

[Optional] Vector3 WorldSpacePosition;
[Optional] Vector3 TangentSpacePosition;
[Optional] Vector4 screenPosition;
[Optional] Vector4 ScreenPosition;
[Optional] Vector4 vertexColor;
[Optional] Vector4 VertexColor;
[Optional] float FaceSign;
public static Dependency[] dependencies = new Dependency[]
{

new Dependency("SurfaceDescriptionInputs.TangentSpaceViewDirection", "SurfaceDescriptionInputs.WorldSpaceBiTangent"),
new Dependency("SurfaceDescriptionInputs.TangentSpaceViewDirection", "SurfaceDescriptionInputs.WorldSpaceNormal"),
new Dependency("SurfaceDescriptionInputs.screenPosition", "FragInputs.positionSS"),
new Dependency("SurfaceDescriptionInputs.ScreenPosition", "SurfaceDescriptionInputs.WorldSpacePosition"),
new Dependency("SurfaceDescriptionInputs.vertexColor", "FragInputs.color"),
new Dependency("SurfaceDescriptionInputs.VertexColor", "FragInputs.color"),
new Dependency("SurfaceDescriptionInputs.FaceSign", "FragInputs.isFrontFace"),
};
};
// this describes the input to the pixel shader graph eval
public struct VertexDescriptionInputs
{
[Optional] Vector3 ObjectSpaceNormal;
[Optional] Vector3 ViewSpaceNormal;
[Optional] Vector3 WorldSpaceNormal;
[Optional] Vector3 TangentSpaceNormal;
[Optional] Vector3 ObjectSpaceTangent;
[Optional] Vector3 ViewSpaceTangent;
[Optional] Vector3 WorldSpaceTangent;
[Optional] Vector3 TangentSpaceTangent;
[Optional] Vector3 ObjectSpaceBiTangent;
[Optional] Vector3 ViewSpaceBiTangent;
[Optional] Vector3 WorldSpaceBiTangent;
[Optional] Vector3 TangentSpaceBiTangent;
[Optional] Vector3 ObjectSpaceViewDirection;
[Optional] Vector3 ViewSpaceViewDirection;
[Optional] Vector3 WorldSpaceViewDirection;
[Optional] Vector3 TangentSpaceViewDirection;
[Optional] Vector3 ObjectSpacePosition;
[Optional] Vector3 ViewSpacePosition;
[Optional] Vector3 WorldSpacePosition;
[Optional] Vector3 TangentSpacePosition;
[Optional] Vector4 ScreenPosition;
[Optional] Vector4 uv0;
[Optional] Vector4 uv1;
[Optional] Vector4 uv2;
[Optional] Vector4 uv3;
[Optional] Vector4 VertexColor;
public static Dependency[] dependencies = new Dependency[]
{ // TODO: NOCHECKIN: these dependencies are not correct for vertex pass
new Dependency("VertexDescriptionInputs.ObjectSpaceNormal", "AttributesMesh.normalOS"),
new Dependency("VertexDescriptionInputs.WorldSpaceNormal", "AttributesMesh.normalOS"),
new Dependency("VertexDescriptionInputs.ViewSpaceNormal", "VertexDescriptionInputs.WorldSpaceNormal"),
new Dependency("VertexDescriptionInputs.ObjectSpaceTangent", "AttributesMesh.tangentOS"),
new Dependency("VertexDescriptionInputs.WorldSpaceTangent", "AttributesMesh.tangentOS"),
new Dependency("VertexDescriptionInputs.ViewSpaceTangent", "VertexDescriptionInputs.WorldSpaceTangent"),
new Dependency("VertexDescriptionInputs.ObjectSpaceBiTangent", "AttributesMesh.normalOS"),
new Dependency("VertexDescriptionInputs.ObjectSpaceBiTangent", "AttributesMesh.tangentOS"),
new Dependency("VertexDescriptionInputs.WorldSpaceBiTangent", "VertexDescriptionInputs.ObjectSpaceBiTangent"),
new Dependency("VertexDescriptionInputs.ViewSpaceBiTangent", "VertexDescriptionInputs.WorldSpaceBiTangent"),
new Dependency("VertexDescriptionInputs.ObjectSpacePosition", "AttributesMesh.positionOS"),
new Dependency("VertexDescriptionInputs.WorldSpacePosition", "AttributesMesh.positionOS"),
new Dependency("VertexDescriptionInputs.ViewSpacePosition", "VertexDescriptionInputs.WorldSpacePosition"),
new Dependency("VertexDescriptionInputs.WorldSpaceViewDirection", "VertexDescriptionInputs.WorldSpacePosition"),
new Dependency("VertexDescriptionInputs.ObjectSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceViewDirection"),
new Dependency("VertexDescriptionInputs.ViewSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceViewDirection"),
new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceViewDirection"),
new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceTangent"),
new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceBiTangent"),
new Dependency("VertexDescriptionInputs.TangentSpaceViewDirection", "VertexDescriptionInputs.WorldSpaceNormal"),
new Dependency("VertexDescriptionInputs.ScreenPosition", "VertexDescriptionInputs.WorldSpacePosition"),
new Dependency("VertexDescriptionInputs.uv0", "AttributesMesh.uv0"),
new Dependency("VertexDescriptionInputs.uv1", "AttributesMesh.uv1"),
new Dependency("VertexDescriptionInputs.uv2", "AttributesMesh.uv2"),
new Dependency("VertexDescriptionInputs.uv3", "AttributesMesh.uv3"),
new Dependency("VertexDescriptionInputs.VertexColor", "AttributesMesh.color"),
static void AddActiveFieldsFromGraphRequirements(HashSet<string> activeFields, ShaderGraphRequirements requirements)
// TODO: move this out of HDRPShaderStructs
static public void AddActiveFieldsFromVertexGraphRequirements(HashSet<string> activeFields, ShaderGraphRequirements requirements)
activeFields.Add("SurfaceDescriptionInputs.screenPosition");
activeFields.Add("VertexDescriptionInputs.ScreenPosition");
activeFields.Add("SurfaceDescriptionInputs.vertexColor");
activeFields.Add("VertexDescriptionInputs.VertexColor");
}
if (requirements.requiresNormal != 0)
{
if ((requirements.requiresNormal & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceNormal");
if ((requirements.requiresNormal & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceNormal");
if ((requirements.requiresNormal & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceNormal");
if ((requirements.requiresNormal & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceNormal");
}
if (requirements.requiresTangent != 0)
{
if ((requirements.requiresTangent & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceTangent");
if ((requirements.requiresTangent & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceTangent");
if ((requirements.requiresTangent & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceTangent");
if ((requirements.requiresTangent & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceTangent");
}
if (requirements.requiresBitangent != 0)
{
if ((requirements.requiresBitangent & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceBiTangent");
if ((requirements.requiresBitangent & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceBiTangent");
if ((requirements.requiresBitangent & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceBiTangent");
if ((requirements.requiresBitangent & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceBiTangent");
}
if (requirements.requiresViewDir != 0)
{
if ((requirements.requiresViewDir & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpaceViewDirection");
if ((requirements.requiresViewDir & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpaceViewDirection");
if ((requirements.requiresViewDir & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpaceViewDirection");
if ((requirements.requiresViewDir & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpaceViewDirection");
}
if (requirements.requiresPosition != 0)
{
if ((requirements.requiresPosition & NeededCoordinateSpace.Object) > 0)
activeFields.Add("VertexDescriptionInputs.ObjectSpacePosition");
if ((requirements.requiresPosition & NeededCoordinateSpace.View) > 0)
activeFields.Add("VertexDescriptionInputs.ViewSpacePosition");
if ((requirements.requiresPosition & NeededCoordinateSpace.World) > 0)
activeFields.Add("VertexDescriptionInputs.WorldSpacePosition");
if ((requirements.requiresPosition & NeededCoordinateSpace.Tangent) > 0)
activeFields.Add("VertexDescriptionInputs.TangentSpacePosition");
}
foreach (var channel in requirements.requiresMeshUVs.Distinct())
{
activeFields.Add("VertexDescriptionInputs." + channel.GetUVName());
}
}
// TODO: move this out of HDRPShaderStructs
static public void AddActiveFieldsFromPixelGraphRequirements(HashSet<string> activeFields, ShaderGraphRequirements requirements)
{
if (requirements.requiresScreenPosition)
{
activeFields.Add("SurfaceDescriptionInputs.ScreenPosition");
}
if (requirements.requiresVertexColor)
{
activeFields.Add("SurfaceDescriptionInputs.VertexColor");
}
if (requirements.requiresFaceSign)
{
activeFields.Add("SurfaceDescriptionInputs.FaceSign");
}
if (requirements.requiresNormal != 0)

}
}
// TODO : split this function into buildActiveFields and buildHLSLTypeDeclaration functions
public static void Generate(
ShaderGenerator codeResult,
ShaderGenerator graphInputsResult,
ShaderGraphRequirements graphRequirements,
public static void AddRequiredFields(
CoordinateSpace preferedCoordinateSpace,
if (preferedCoordinateSpace == CoordinateSpace.Tangent)
preferedCoordinateSpace = CoordinateSpace.World;
// build initial requirements
AddActiveFieldsFromGraphRequirements(activeFields, graphRequirements);
if (passRequiredFields != null)
{
foreach (var requiredField in passRequiredFields)

}
}
public static void Generate(
ShaderGenerator codeResult,
HashSet<string> activeFields)
{
// propagate requirements using dependencies
{
ShaderSpliceUtil.ApplyDependencies(

FragInputs.dependencies,
VaryingsMeshToPS.standardDependencies,
SurfaceDescriptionInputs.dependencies,
VertexDescriptionInputs.dependencies
});
}

ShaderSpliceUtil.BuildType(typeof(VaryingsMeshToDS), activeFields, codeResult);
ShaderSpliceUtil.BuildPackedType(typeof(VaryingsMeshToPS), activeFields, codeResult);
ShaderSpliceUtil.BuildPackedType(typeof(VaryingsMeshToDS), activeFields, codeResult);
ShaderSpliceUtil.BuildType(typeof(SurfaceDescriptionInputs), activeFields, graphInputsResult);
}
};

public static class HDSubShaderUtilities
{
public static List<MaterialSlot> FindMaterialSlotsOnNode(IEnumerable<int> slots, AbstractMaterialNode node)
{
var activeSlots = new List<MaterialSlot>();
if (slots != null)
{
foreach (var id in slots)
{
MaterialSlot slot = node.FindSlot<MaterialSlot>(id);
if (slot != null)
{
activeSlots.Add(slot);
}
}
}
return activeSlots;
}
public static void BuildRenderStatesFromPassAndMaterialOptions(
Pass pass,
SurfaceMaterialOptions materialOptions,

94
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template


//-------------------------------------------------------------------------------------
HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
//#pragma enable_d3d11_debug_symbols

#define UNITY_MATERIAL_UNLIT // Need to be define before including Material.hlsl
#include "CoreRP/ShaderLibrary/Common.hlsl"
// #include "CoreRP/ShaderLibrary/Wind.hlsl"
#include "CoreRP/ShaderLibrary/Wind.hlsl"
#include "ShaderGraphLibrary/Functions.hlsl"

$VaryingsMeshToPS.texCoord3: #define VARYINGS_NEED_TEXCOORD3
$VaryingsMeshToPS.color: #define VARYINGS_NEED_COLOR
$VaryingsMeshToPS.cullFace: #define VARYINGS_NEED_CULLFACE
$features.modifyMesh: #define HAVE_MESH_MODIFICATION
#include "ShaderGraphLibrary/Functions.hlsl"
#include "HDRP/ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "HDRP/Debug/DebugDisplay.hlsl"

// End graph generated code
//-------------------------------------------------------------------------------------
// TODO: Do we want to build include functionality for sharing these preprocessed functions across templates?
#ifdef HAVE_MESH_MODIFICATION
// TODO: we should share this between template files somehow
VertexDescriptionInputs AttributesMeshToVertexDescriptionInputs(AttributesMesh input)
{
VertexDescriptionInputs output;
ZERO_INITIALIZE(VertexDescriptionInputs, output);
$VertexDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = input.normalOS;
$VertexDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = TransformObjectToWorldNormal(input.normalOS);
$VertexDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = TransformWorldToViewDir(output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
$VertexDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = input.tangentOS;
$VertexDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = TransformObjectToWorldDir(input.tangentOS.xyz);
$VertexDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
$VertexDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
$VertexDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = normalize(cross(input.normalOS, input.tangentOS) * (input.tangentOS.w > 0.0f ? 1.0f : -1.0f) * GetOddNegativeScale());
$VertexDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = TransformObjectToWorldDir(output.ObjectSpaceBiTangent);
$VertexDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
$VertexDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
$VertexDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = input.positionOS;
$VertexDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = TransformObjectToWorld(input.positionOS);
$VertexDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = TransformWorldToView(output.WorldSpacePosition);
$VertexDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
$VertexDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = GetWorldSpaceNormalizeViewDir(output.WorldSpacePosition);
$VertexDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
$VertexDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = TransformWorldToViewDir(output.WorldSpaceViewDirection);
$VertexDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$VertexDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(output.WorldSpacePosition), _ProjectionParams.x);
$VertexDescriptionInputs.uv0: output.uv0 = float4(input.uv0, 0.0f, 0.0f);
$VertexDescriptionInputs.uv1: output.uv1 = float4(input.uv1, 0.0f, 0.0f);
$VertexDescriptionInputs.uv2: output.uv2 = float4(input.uv2, 0.0f, 0.0f);
$VertexDescriptionInputs.uv3: output.uv3 = float4(input.uv3, 0.0f, 0.0f);
$VertexDescriptionInputs.VertexColor: output.VertexColor = input.color;
return output;
}
AttributesMesh ApplyMeshModification(AttributesMesh input)
{
// build graph inputs
VertexDescriptionInputs vertexDescriptionInputs = AttributesMeshToVertexDescriptionInputs(input);
// evaluate vertex graph
VertexDescription vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
// copy graph output to the results
$VertexDescription.Position: input.positionOS = vertexDescription.Position;
return input;
}
#endif // HAVE_MESH_MODIFICATION
// TODO: Do we want to build include functionality for sharing these preprocessed functions across templates?
FragInputs BuildFragInputs(VaryingsMeshToPS input)
{
FragInputs output;

$SurfaceDescriptionInputs.ViewSpaceNormal: output.ViewSpaceNormal = mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_I_V); // transposed multiplication by inverse matrix to handle normal scale
$SurfaceDescriptionInputs.TangentSpaceNormal: output.TangentSpaceNormal = float3(0.0f, 0.0f, 1.0f);
$SurfaceDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = input.worldToTangent[0].xyz;
$SurfaceDescriptionInputs.WorldSpaceTangent: output.WorldSpaceTangent = input.worldToTangent[0].xyz;
$SurfaceDescriptionInputs.ObjectSpaceTangent: output.ObjectSpaceTangent = mul((float3x3) unity_WorldToObject, output.WorldSpaceTangent);
$SurfaceDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = mul((float3x3) UNITY_MATRIX_V, output.WorldSpaceTangent);
$SurfaceDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);

$SurfaceDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
// TODO: FragInputs.positionWS is badly named -- it's camera relative, not in world space
// we have to fix it up here to match graph input expectations
$SurfaceDescriptionInputs.screenPosition: output.screenPosition = input.positionSS;
// TODO: positionSS is SV_Position, graph input expects screenPosition to be 0..1 across the active viewport (?)
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionWS), _ProjectionParams.x);
$SurfaceDescriptionInputs.vertexColor: output.vertexColor = input.color;
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
return output;
}

// Perform alpha test very early to save performance (a killed pixel will not sample textures)
// TODO: split graph evaluation to grab just alpha dependencies first? tricky..
#ifdef _ALPHATEST_ON
DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
#endif
$AlphaTest: DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData);

builtinData.opacity = surfaceDescription.Alpha;
builtinData.bakeDiffuseLighting = float3(0.0, 0.0, 0.0);
builtinData.emissiveIntensity = 1.0f;
$SurfaceDescription.Emission: builtinData.emissiveColor = surfaceDescription.Emission;
builtinData.velocity = float2(0.0, 0.0);
builtinData.shadowMask0 = 0.0;

//-------------------------------------------------------------------------------------
ENDHLSL
}
}

262
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitSubShader.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace UnityEditor.Experimental.Rendering.HDPipeline
{
// [Serializable] ??
public class HDUnlitSubShader : IUnlitSubShader
{
Pass m_PassDepthOnly = new Pass()

{
UnlitMasterNode.AlphaSlotId,
UnlitMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

UnlitMasterNode.ColorSlotId,
UnlitMasterNode.AlphaSlotId,
UnlitMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

UnlitMasterNode.ColorSlotId,
UnlitMasterNode.AlphaSlotId,
UnlitMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

{
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
},
private static string GetVariantDefines(UnlitMasterNode masterNode)
private static HashSet<string> GetActiveFieldsFromMasterNode(INode iMasterNode, Pass pass)
ShaderGenerator defines = new ShaderGenerator();
HashSet<string> activeFields = new HashSet<string>();
// #pragma shader_feature _ALPHATEST_ON
UnlitMasterNode masterNode = iMasterNode as UnlitMasterNode;
if (masterNode == null)
{
return null;
}
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
defines.AddShaderChunk("#define _ALPHATEST_ON 1", true);
activeFields.Add("AlphaTest");
}
// if (kTesselationMode != TessellationMode.None)

// #pragma shader_feature _HEIGHTMAP
// #pragma shader_feature _TANGENTMAP
// #pragma shader_feature _ANISOTROPYMAP
// #pragma shader_feature _DETAIL_MAP // MOVE to a node
// #pragma shader_feature _SUBSURFACE_RADIUS_MAP
// #pragma shader_feature _THICKNESSMAP
// #pragma shader_feature _SPECULARCOLORMAP

if (masterNode.surfaceType != SurfaceType.Opaque)
{
// transparent-only defines
defines.AddShaderChunk("#define _SURFACE_TYPE_TRANSPARENT 1", true);
activeFields.Add("SurfaceType.Transparent");
defines.AddShaderChunk("#define _BLENDMODE_ALPHA 1", true);
activeFields.Add("BlendMode.Alpha");
defines.AddShaderChunk("#define _BLENDMODE_ADD 1", true);
activeFields.Add("BlendMode.Add");
}
// else if (masterNode.alphaMode == PBRMasterNode.AlphaMode.PremultiplyAlpha) // TODO
// {

// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON
return defines.GetShaderString(2);
return activeFields;
private static bool GenerateShaderPass(UnlitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
private static bool GenerateShaderPassUnlit(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
{
var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDEditorUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);
if (!File.Exists(templateLocation))

}
sourceAssetDependencyPaths.Add(templateLocation);
if (sourceAssetDependencyPaths != null)
sourceAssetDependencyPaths.Add(templateLocation);
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
// grab all of the active nodes
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var pixelNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var graphRequirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.All, true, true);
var pixelRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false); // TODO: is ShaderStageCapability.Fragment correct?
var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);
// Function Registry tracks functions to remove duplicates, it wraps a string builder that stores the combined function string
// TODO: this can be a shared function for all HDRP master nodes -- From here through GraphUtil.GenerateSurfaceDescription(..)
// TODO: this can be a shared function -- From here through GraphUtil.GenerateSurfaceDescription(..)
var activeSlots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
{
MaterialSlot slot = masterNode.FindSlot<MaterialSlot>(id);
if (slot != null)
{
activeSlots.Add(slot);
}
}
var pixelSlots = HDSubShaderUtilities.FindMaterialSlotsOnNode(pass.PixelShaderSlots, masterNode);
var vertexSlots = HDSubShaderUtilities.FindMaterialSlotsOnNode(pass.VertexShaderSlots, masterNode);
// properties used by either pixel and vertex shader
PropertyCollector sharedProperties = new PropertyCollector();
string graphInputStructName = "SurfaceDescriptionInputs";
string graphOutputStructName = "SurfaceDescription";
string graphEvalFunctionName = "SurfaceDescriptionFunction";
var graphEvalFunction = new ShaderStringBuilder();
var graphOutputs = new ShaderStringBuilder();
PropertyCollector graphProperties = new PropertyCollector();
string pixelGraphInputStructName = "SurfaceDescriptionInputs";
string pixelGraphOutputStructName = "SurfaceDescription";
string pixelGraphEvalFunctionName = "SurfaceDescriptionFunction";
ShaderStringBuilder pixelGraphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder pixelGraphOutputs = new ShaderStringBuilder();
// dependency tracker -- set of active fields
HashSet<string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass);
// build initial requirements
HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, pixelRequirements);
HashSet<string> activeFields = new HashSet<string>();
GraphUtil.GenerateSurfaceDescriptionStruct(graphOutputs, activeSlots, true);
GraphUtil.GenerateSurfaceDescriptionStruct(pixelGraphOutputs, pixelSlots, true, pixelGraphOutputStructName, activeFields);
activeNodeList,
pixelNodes,
graphEvalFunction,
pixelGraphEvalFunction,
graphProperties,
graphRequirements, // TODO : REMOVE UNUSED
sharedProperties,
pixelRequirements, // TODO : REMOVE UNUSED
graphEvalFunctionName,
graphOutputStructName,
pixelGraphEvalFunctionName,
pixelGraphOutputStructName,
activeSlots,
graphInputStructName);
pixelSlots,
pixelGraphInputStructName);
string vertexGraphInputStructName = "VertexDescriptionInputs";
string vertexGraphOutputStructName = "VertexDescription";
string vertexGraphEvalFunctionName = "VertexDescriptionFunction";
ShaderStringBuilder vertexGraphEvalFunction = new ShaderStringBuilder();
ShaderStringBuilder vertexGraphOutputs = new ShaderStringBuilder();
// check for vertex animation -- enables HAVE_VERTEX_MODIFICATION
bool vertexActive = false;
if (masterNode.IsSlotConnected(PBRMasterNode.PositionSlotId))
{
vertexActive = true;
activeFields.Add("features.modifyMesh");
HDRPShaderStructs.AddActiveFieldsFromVertexGraphRequirements(activeFields, vertexRequirements);
// -------------------------------------
// Generate Output structure for Vertex Description function
GraphUtil.GenerateVertexDescriptionStruct(vertexGraphOutputs, vertexSlots, vertexGraphOutputStructName, activeFields);
// -------------------------------------
// Generate Vertex Description function
GraphUtil.GenerateVertexDescriptionFunction(
masterNode.owner as AbstractMaterialGraph,
vertexGraphEvalFunction,
functionRegistry,
sharedProperties,
mode,
vertexNodes,
vertexSlots,
vertexGraphInputStructName,
vertexGraphEvalFunctionName,
vertexGraphOutputStructName);
}
var blendCode = new ShaderStringBuilder();
var cullCode = new ShaderStringBuilder();

var colorMaskCode = new ShaderStringBuilder();
HDSubShaderUtilities.BuildRenderStatesFromPassAndMaterialOptions(pass, materialOptions, blendCode, cullCode, zTestCode, zWriteCode, stencilCode, colorMaskCode);
if (masterNode.twoSided.isOn)
{
activeFields.Add("DoubleSided");
if (pass.ShaderPassName != "SHADERPASS_VELOCITY") // HACK to get around lack of a good interpolator dependency system
{ // we need to be able to build interpolators using multiple input structs
// also: should only require isFrontFace if Normals are required...
activeFields.Add("DoubleSided.Mirror"); // TODO: change this depending on what kind of normal flip you want..
activeFields.Add("FragInputs.isFrontFace"); // will need this for determining normal flip mode
}
}
HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
if (pass.PixelShaderSlots != null)
{
foreach (var slotId in pass.PixelShaderSlots)
{
var slot = masterNode.FindSlot<MaterialSlot>(slotId);
if (slot != null)
{
var rawSlotName = slot.RawDisplayName().ToString();
var descriptionVar = string.Format("{0}.{1}", graphOutputStructName, rawSlotName);
activeFields.Add(descriptionVar);
}
}
}
// apply dependencies to the active fields, and build interpolators (TODO: split this function)
var graphInputs = new ShaderGenerator();
graphInputs,
graphRequirements,
pass.RequiredFields,
CoordinateSpace.World,
activeFields);
// debug output all active fields

}
}
// build graph inputs structures
ShaderGenerator pixelGraphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.SurfaceDescriptionInputs), activeFields, pixelGraphInputs);
ShaderGenerator vertexGraphInputs = new ShaderGenerator();
ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.VertexDescriptionInputs), activeFields, vertexGraphInputs);
ShaderGenerator defines = new ShaderGenerator();
{
defines.AddShaderChunk(string.Format("#define SHADERPASS {0}", pass.ShaderPassName), true);

// build graph code
var graph = new ShaderGenerator();
graph.AddShaderChunk("// Graph Inputs");
graph.Indent();
graph.AddGenerator(graphInputs);
graph.Deindent();
graph.AddShaderChunk("// Graph Outputs");
graph.Indent();
graph.AddShaderChunk(graphOutputs.ToString());
//graph.AddGenerator(graphOutputs);
graph.Deindent();
graph.AddShaderChunk("// Graph Properties (uniform inputs)");
graph.AddShaderChunk(graphProperties.GetPropertiesDeclaration(1));
graph.AddShaderChunk("// Graph Node Functions");
graph.AddShaderChunk(graphNodeFunctions.ToString());
graph.AddShaderChunk("// Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(graphEvalFunction.ToString());
//graph.AddGenerator(graphEvalFunction);
graph.Deindent();
{
graph.AddShaderChunk("// Shared Graph Properties (uniform inputs)");
graph.AddShaderChunk(sharedProperties.GetPropertiesDeclaration(1));
if (vertexActive)
{
graph.AddShaderChunk("// Vertex Graph Inputs");
graph.Indent();
graph.AddGenerator(vertexGraphInputs);
graph.Deindent();
graph.AddShaderChunk("// Vertex Graph Outputs");
graph.Indent();
graph.AddShaderChunk(vertexGraphOutputs.ToString());
graph.Deindent();
}
graph.AddShaderChunk("// Pixel Graph Inputs");
graph.Indent();
graph.AddGenerator(pixelGraphInputs);
graph.Deindent();
graph.AddShaderChunk("// Pixel Graph Outputs");
graph.Indent();
graph.AddShaderChunk(pixelGraphOutputs.ToString());
graph.Deindent();
graph.AddShaderChunk("// Shared Graph Node Functions");
graph.AddShaderChunk(graphNodeFunctions.ToString());
if (vertexActive)
{
graph.AddShaderChunk("// Vertex Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(vertexGraphEvalFunction.ToString());
graph.Deindent();
}
graph.AddShaderChunk("// Pixel Graph Evaluation");
graph.Indent();
graph.AddShaderChunk(pixelGraphEvalFunction.ToString());
graph.Deindent();
}
// build the hash table of all named fragments TODO: could make this Dictionary<string, ShaderGenerator / string> ?
Dictionary<string, string> namedFragments = new Dictionary<string, string>();

namedFragments.Add("${Stencil}", stencilCode.ToString());
namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
namedFragments.Add("${LOD}", materialOptions.lod.ToString());
namedFragments.Add("${VariantDefines}", GetVariantDefines(masterNode));
// process the template to generate the shader code for this pass TODO: could make this a shared function
string[] templateLines = File.ReadAllLines(templateLocation);

// bool transparent = (masterNode.surfaceType != SurfaceType.Opaque);
bool distortionActive = false;
GenerateShaderPass(masterNode, m_PassDepthOnly, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassForward, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassMETA, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassUnlit(masterNode, m_PassDepthOnly, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassUnlit(masterNode, m_PassForward, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassUnlit(masterNode, m_PassMETA, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPass(masterNode, m_PassDistortion, mode, materialOptions, subShader, sourceAssetDependencyPaths);
GenerateShaderPassUnlit(masterNode, m_PassDistortion, mode, materialOptions, subShader, sourceAssetDependencyPaths);
}
}
subShader.Deindent();

33
com.unity.render-pipelines.high-definition/HDRP/Editor/Upgraders/HDRPVersion.cs


[InitializeOnLoad]
public class HDRPVersion
{
static public float hdrpVersion = 1.0f;
static public int hdrpVersion = 1;
static public float GetCurrentHDRPProjectVersion()
static public int GetCurrentHDRPProjectVersion()
version[0] = "0.9"; // Note: When we don't know what a project is, assume worst case
version[0] = "0"; // Note: When we don't know what a project is, assume worst case 0
try
{

{
Debug.LogWarning("Unable to read from ProjectSettings/HDRPProjectVersion.txt - Assign default version value");
// Don't display warning
//Debug.LogWarning("Unable to read from ProjectSettings/HDRPProjectVersion.txt - Assign default version value");
return float.Parse(version[0]);
return int.Parse(version[0]);
}
static public void WriteCurrentHDRPProjectVersion()

// Compare project version with current version - Trigger an upgrade if user ask for it
if (GetCurrentHDRPProjectVersion() < hdrpVersion)
{
if (EditorUtility.DisplayDialog("A newer version of Unity has been detected",
"Do you want to upgrade your materials to newer version?\n You can also upgrade manually materials in Edit -> Render Pipeline submenu", "Yes", "No"))
if (EditorUtility.DisplayDialog("A newer version of HDRP has been detected",
"Do you want to upgrade your materials to newer version?\n You can also upgrade manually materials in 'Edit -> Render Pipeline' submenu", "Yes", "No"))
}
}
// Update current project version with HDRP version
WriteCurrentHDRPProjectVersion();
public class FileModificationWarning : UnityEditor.AssetModificationProcessor
{
static string[] OnWillSaveAssets(string[] paths)
{
foreach (string path in paths)
{
// Detect when we save project and write our HDRP version at this time.
if (path == "ProjectSettings/ProjectSettings.asset")
{
// Update current project version with HDRP version
HDRPVersion.WriteCurrentHDRPProjectVersion();
}
}
return paths;
}
}
}

22
com.unity.render-pipelines.high-definition/HDRP/Editor/Upgraders/UpgradeMenuItem.cs


string.Format("{0} / {1} materials subsurface updated.", i, length),
i / (float)(length - 1));
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
if (mat.shader.name == "HDRenderPipeline/LitTessellation" ||
mat.shader.name == "HDRenderPipeline/Lit" ||

if (mat.HasProperty("_SSSAndTransmissionType"))
{
CoreUtils.CheckOutFile(VSCEnabled, mat);
CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
int materialSSSAndTransmissionID = mat.GetInt("_SSSAndTransmissionType");

string.Format("{0} / {1} materials updated.", i, length),
i / (float)(length - 1));
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
if (mat.shader.name == "HDRenderPipeline/LitTessellation" ||
mat.shader.name == "HDRenderPipeline/Lit")

{
CoreUtils.CheckOutFile(VSCEnabled, mat);
CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
float valueMax = mat.GetFloat("_HeightMax");
float valueMin = mat.GetFloat("_HeightMin");

if (mat.HasProperty("_HeightPoMAmplitude0"))
{
CoreUtils.CheckOutFile(VSCEnabled, mat);
CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
for (int x = 0; x < numLayer; ++x)
{

static void UpdateMaterialToNewerVersion(string caption, UpdateMaterial updateMaterial, UpdateMaterialFile updateMaterialFile = null)
{
bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
var matIds = AssetDatabase.FindAssets("t:Material");
List<string> materialFiles = new List<string>(); // Contain the list dirty files

if (dirty)
{
// Checkout the file and tag it as dirty
CoreUtils.CheckOutFile(VSCEnabled, mat);
CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
EditorUtility.SetDirty(mat);
materialFiles.Add(path);
}

}
}
[MenuItem("Edit/Render Pipeline/Update all Materials to latest version", priority = CoreUtils.editMenuPriority3)]
[MenuItem("Edit/Render Pipeline/Single step upgrade script/Upgrade all Materials EmissionColor", priority = CoreUtils.editMenuPriority3)]
static public void UpdateMaterialToNewerVersionEmissiveColor()
{
UpdateMaterialToNewerVersion("(EmissiveColor)", UpdateMaterial_EmissiveColor, UpdateMaterialFile_EmissiveColor);
}
[MenuItem("Edit/Render Pipeline/Upgrade all Materials to latest version", priority = CoreUtils.editMenuPriority3)]
static public void UpdateMaterialToNewerVersion()
{
// Add here all the material upgrade function supported in this version

2
com.unity.render-pipelines.high-definition/HDRP/Material/LayeredLit/LayeredLitData.hlsl


// Normalize
maxHeight = GetMaxHeight(maskedHeights);
maskedHeights = maskedHeights / maxHeight.xxxx;
maskedHeights = maskedHeights / max(maxHeight.xxxx, 1e-6);
return maskedHeights.yzwx;
}

14
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl


if (_DebugLightingMode != 0)
{
bool keepSpecular = false;
// Caution: _DebugLightingMode is used in other part of the code, don't do anything outside of
// current cases
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
else
keepSpecular = true;
else
keepSpecular = true;
if (!keepSpecular)
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)
{

16
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl


if (_DebugLightingMode != 0)
{
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
// Caution: _DebugLightingMode is used in other part of the code, don't do anything outside of
// current cases
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
//diffuseLighting = aoFactor.indirectSpecularOcclusion;
diffuseLighting = aoFactor.indirectSpecularOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
// diffuseLighting = lighting.indirect.specularTransmitted;
// diffuseLighting = lighting.indirect.specularTransmitted;
break;
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION:
//if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
// diffuseLighting = lighting.indirect.specularReflected;
break;
}
}

26
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs


RTHandleSystem.RTHandle m_DistortionBuffer;
// The pass "SRPDefaultUnlit" is a fall back to legacy unlit rendering and is required to support unity 2d + unity UI that render in the scene.
ShaderPassName[] m_ForwardAndForwardOnlyPassNames = { new ShaderPassName(), new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_ForwardOnlyPassNames = { new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_ForwardAndForwardOnlyPassNames = { HDShaderPassNames.s_ForwardOnlyName, HDShaderPassNames.s_ForwardName, HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_ForwardOnlyPassNames = { HDShaderPassNames.s_ForwardOnlyName, HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_AllTransparentPassNames = { HDShaderPassNames.s_TransparentBackfaceName,
HDShaderPassNames.s_ForwardOnlyName,

StartStereoRendering(renderContext, hdCamera);
RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Opaque);
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Opaque);
// SSS pass here handle both SSS material from deferred and forward
m_SSSBufferManager.SubsurfaceScatteringPass(hdCamera, cmd, diffusionProfileSettings,

// Render pre refraction objects
RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.PreRefraction);
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.PreRefraction);
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Transparent);
// Render All forward error
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd);
// Fill depth buffer to reduce artifact for transparent object during postprocess
RenderTransparentDepthPostpass(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Transparent);

HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer);
}
m_ForwardAndForwardOnlyPassNames[0] = m_ForwardOnlyPassNames[0] =
HDShaderPassNames.s_ForwardOnlyName;
m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardName;
var passNames = hdCamera.frameSettings.enableForwardRenderingOnly
? m_ForwardAndForwardOnlyPassNames
: m_ForwardOnlyPassNames;

// This is use to Display legacy shader with an error shader
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
void RenderForwardError(CullResults cullResults, HDCamera hdCamera, ScriptableRenderContext renderContext, CommandBuffer cmd, ForwardPass pass)
void RenderForwardError(CullResults cullResults, HDCamera hdCamera, ScriptableRenderContext renderContext, CommandBuffer cmd)
if (pass == ForwardPass.Opaque)
{
RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, m_ForwardErrorPassNames, 0, null, null, m_ErrorMaterial);
}
else
{
RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, m_ForwardErrorPassNames, 0, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent, null, m_ErrorMaterial);
}
RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, m_ForwardErrorPassNames, 0, RenderQueueRange.all, null, m_ErrorMaterial);
}
}

12
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassVelocity.hlsl


else
{
bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target
//Need to apply any vertex animation to the previous worldspace position, if we want it to show up in the velocity buffer
// Need to apply any vertex animation to the previous worldspace position, if we want it to show up in the velocity buffer
#if defined(HAVE_MESH_MODIFICATION)
AttributesMesh previousMesh = inputMesh;
if (hasDeformation)
previousMesh.positionOS = inputPass.previousPositionOS;
previousMesh = ApplyMeshModification(previousMesh);
float3 previousPositionWS = mul(unity_MatrixPreviousM, float4(previousMesh.positionOS, 1.0)).xyz;
#else
#endif
#ifdef ATTRIBUTES_NEED_NORMAL
float3 normalWS = TransformPreviousObjectToWorldNormal(inputMesh.normalOS);
#else

4
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/VertMesh.hlsl


// TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16)
VaryingsMeshType VertMesh(AttributesMesh input)
{
#if defined(HAVE_MESH_MODIFICATION)
input = ApplyMeshModification(input);
#endif
VaryingsMeshType output;
UNITY_SETUP_INSTANCE_ID(input);

58
com.unity.render-pipelines.lightweight/LWRP/Editor/LightweightLightEditor.cs


[CustomEditorForRenderPipeline(typeof(Light), typeof(LightweightPipelineAsset))]
class LightweightLightEditor : LightEditor
{
AnimBool m_AnimShowSpotOptions = new AnimBool();
AnimBool m_AnimShowPointOptions = new AnimBool();
AnimBool m_AnimShowDirOptions = new AnimBool();
AnimBool m_AnimShowAreaOptions = new AnimBool();
AnimBool m_AnimShowRuntimeOptions = new AnimBool();
AnimBool m_AnimShowShadowOptions = new AnimBool();
AnimBool m_AnimBakedShadowAngleOptions = new AnimBool();
AnimBool m_AnimBakedShadowRadiusOptions = new AnimBool();
AnimBool m_AnimShowLightBounceIntensity = new AnimBool();
AnimBool m_AnimSpotOptions = new AnimBool();
AnimBool m_AnimPointOptions = new AnimBool();
AnimBool m_AnimDirOptions = new AnimBool();
AnimBool m_AnimAreaOptions = new AnimBool();
AnimBool m_AnimRuntimeOptions = new AnimBool();
AnimBool m_AnimShadowOptions = new AnimBool();
AnimBool m_AnimShadowAngleOptions = new AnimBool();
AnimBool m_AnimShadowRadiusOptions = new AnimBool();
AnimBool m_AnimLightBounceIntensity = new AnimBool();
class Styles
{

// When we are switching between two light types that don't show the range (directional and area lights)
// we want the fade group to stay hidden.
using (var group = new EditorGUILayout.FadeGroupScope(1.0f - m_AnimShowDirOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(1.0f - m_AnimDirOptions.faded))
settings.DrawRange(m_AnimShowAreaOptions.target);
settings.DrawRange(m_AnimAreaOptions.target);
using (var group = new EditorGUILayout.FadeGroupScope(m_AnimShowSpotOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(m_AnimSpotOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(m_AnimShowAreaOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(m_AnimAreaOptions.faded))
if (group.visible)
settings.DrawArea();

using (var group = new EditorGUILayout.FadeGroupScope(1.0f - m_AnimShowAreaOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(1.0f - m_AnimAreaOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(m_AnimShowLightBounceIntensity.faded))
using (var group = new EditorGUILayout.FadeGroupScope(m_AnimLightBounceIntensity.faded))
if (group.visible)
settings.DrawBounceIntensity();

void UpdateShowOptions(bool initialize)
{
SetOptions(m_AnimShowSpotOptions, initialize, spotOptionsValue);
SetOptions(m_AnimShowPointOptions, initialize, pointOptionsValue);
SetOptions(m_AnimShowDirOptions, initialize, dirOptionsValue);
SetOptions(m_AnimShowAreaOptions, initialize, areaOptionsValue);
SetOptions(m_AnimShowShadowOptions, initialize, shadowOptionsValue);
SetOptions(m_AnimShowRuntimeOptions, initialize, runtimeOptionsValue);
SetOptions(m_AnimBakedShadowAngleOptions, initialize, bakedShadowAngle);
SetOptions(m_AnimBakedShadowRadiusOptions, initialize, bakedShadowRadius);
SetOptions(m_AnimShowLightBounceIntensity, initialize, showLightBounceIntensity);
SetOptions(m_AnimSpotOptions, initialize, spotOptionsValue);
SetOptions(m_AnimPointOptions, initialize, pointOptionsValue);
SetOptions(m_AnimDirOptions, initialize, dirOptionsValue);
SetOptions(m_AnimAreaOptions, initialize, areaOptionsValue);
SetOptions(m_AnimShadowOptions, initialize, shadowOptionsValue);
SetOptions(m_AnimRuntimeOptions, initialize, runtimeOptionsValue);
SetOptions(m_AnimShadowAngleOptions, initialize, bakedShadowAngle);
SetOptions(m_AnimShadowRadiusOptions, initialize, bakedShadowRadius);
SetOptions(m_AnimLightBounceIntensity, initialize, showLightBounceIntensity);
}
void DrawSpotAngle()

void ShadowsGUI()
{
// Shadows drop-down. Area lights can only be baked and always have shadows.
float show = 1.0f - m_AnimShowAreaOptions.faded;
float show = 1.0f - m_AnimAreaOptions.faded;
show *= m_AnimShowShadowOptions.faded;
show *= m_AnimShadowOptions.faded;
using (var group = new EditorGUILayout.FadeGroupScope(show * m_AnimBakedShadowRadiusOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(show * m_AnimShadowRadiusOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(show * m_AnimBakedShadowAngleOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(show * m_AnimShadowAngleOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(show * m_AnimShowRuntimeOptions.faded))
using (var group = new EditorGUILayout.FadeGroupScope(show * m_AnimRuntimeOptions.faded))
if (group.visible)
settings.DrawRuntimeShadow();
EditorGUI.indentLevel -= 1;

16
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs


// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();

if (surfaceRequirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
if (surfaceRequirements.requiresFaceSign)
surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct())
surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
}

pixelShaderSurfaceRemap.AppendLine("{0} = surf.{0};", slot.shaderOutputName);
}
// -------------------------------------
// Extra pixel shader work
var faceSign = new ShaderStringBuilder();
if (pixelRequirements.requiresFaceSign)
faceSign.AppendLine(", half FaceSign : VFACE");
// ----------------------------------------------------- //
// FINALIZE //
// ----------------------------------------------------- //

resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString());
resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString());
resultPass = resultPass.Replace("${FaceSign}", faceSign.ToString());
resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceRemap}", pixelShaderSurfaceRemap.ToString());

// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
// -------------------------------------

16
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs


// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();

if (surfaceRequirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
if (surfaceRequirements.requiresFaceSign)
surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct())
surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
}

pixelShaderSurfaceRemap.AppendLine("{0} = surf.{0};", slot.shaderOutputName);
}
// -------------------------------------
// Extra pixel shader work
var faceSign = new ShaderStringBuilder();
if (pixelRequirements.requiresFaceSign)
faceSign.AppendLine(", half FaceSign : VFACE");
// ----------------------------------------------------- //
// FINALIZE //
// ----------------------------------------------------- //

resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString());
resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString());
resultPass = resultPass.Replace("${FaceSign}", faceSign.ToString());
resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceRemap}", pixelShaderSurfaceRemap.ToString());

// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
var vertexNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
// -------------------------------------

2
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template


return o;
}
half4 frag (GraphVertexOutput IN) : SV_Target
half4 frag (GraphVertexOutput IN ${FaceSign}) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);

2
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template


return o;
}
half4 frag (GraphVertexOutput IN) : SV_Target
half4 frag (GraphVertexOutput IN ${FaceSign}) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);

38
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderPreprocessor.cs


namespace UnityEditor.Experimental.Rendering.LightweightPipeline
{
public static class LightweightKeyword
{
public static readonly ShaderKeyword AdditionalLights = new ShaderKeyword(LightweightKeywordStrings.AdditionalLights);
public static readonly ShaderKeyword VertexLights = new ShaderKeyword(LightweightKeywordStrings.VertexLights);
public static readonly ShaderKeyword MixedLightingSubtractive = new ShaderKeyword(LightweightKeywordStrings.MixedLightingSubtractive);
public static readonly ShaderKeyword MainLightCookie = new ShaderKeyword(LightweightKeywordStrings.MainLightCookie);
public static readonly ShaderKeyword DirectionalShadows = new ShaderKeyword(LightweightKeywordStrings.DirectionalShadows);
public static readonly ShaderKeyword LocalShadows = new ShaderKeyword(LightweightKeywordStrings.LocalShadows);
public static readonly ShaderKeyword SoftShadows = new ShaderKeyword(LightweightKeywordStrings.SoftShadows);
public static readonly ShaderKeyword Lightmap = new ShaderKeyword("LIGHTMAP_ON");
public static readonly ShaderKeyword DirectionalLightmap = new ShaderKeyword("DIRLIGHTMAP_COMBINED");
}
public class ShaderPreprocessor : IPreprocessShaders
{
#if LOG_VARIANTS

bool StripUnusedVariant(PipelineCapabilities capabilities, ShaderCompilerData compilerData)
{
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.AdditionalLights) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.AdditionalLights) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.VertexLights) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.VertexLights) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.DirectionalShadows) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.DirectionalShadows) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.LocalShadows) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.LocalShadows) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.SoftShadows) &&
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.SoftShadows) &&
!CoreUtils.HasFlag(capabilities, PipelineCapabilities.SoftShadows))
return true;

bool StripInvalidVariants(ShaderCompilerData compilerData)
{
bool isShadowVariant = compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.DirectionalShadows) ||
compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.LocalShadows);
bool isShadowVariant = compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.DirectionalShadows) ||
compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.LocalShadows);
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.SoftShadows) && !isShadowVariant)
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.SoftShadows) && !isShadowVariant)
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.VertexLights) &&
!compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.AdditionalLights))
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.VertexLights) &&
!compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.AdditionalLights))
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.DirectionalLightmap) &&
!compilerData.shaderKeywordSet.IsEnabled(LightweightKeywords.Lightmap))
if (compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.DirectionalLightmap) &&
!compilerData.shaderKeywordSet.IsEnabled(LightweightKeyword.Lightmap))
return true;
return false;

22
com.unity.render-pipelines.lightweight/LWRP/LightweightForwardRenderer.cs


EnqueuePass(cmd, RenderPassHandles.LocalShadows, baseDescriptor);
bool requiresDepthAttachment = requiresCameraDepth && !requiresDepthPrepass;
bool requiresColorAttachment = RequiresColorAttachment(ref renderingData.cameraData, baseDescriptor) || requiresDepthAttachment;
bool requiresColorAttachment = RequiresIntermediateColorTexture(ref renderingData.cameraData, baseDescriptor, requiresDepthAttachment);
int[] colorHandles = (requiresColorAttachment) ? new[] {RenderTargetHandles.Color} : null;
int depthHandle = (requiresColorAttachment) ? RenderTargetHandles.DepthAttachment : -1;
EnqueuePass(cmd, RenderPassHandles.ForwardLit, baseDescriptor, colorHandles, depthHandle, renderingData.cameraData.msaaSamples);

// Note: Scene view camera always perform depth prepass
CommandBuffer cmd = CommandBufferPool.Get("Copy Depth to Camera");
CoreUtils.SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget);
cmd.EnableShaderKeyword(LightweightKeywords.DepthNoMsaa);
cmd.DisableShaderKeyword(LightweightKeywords.DepthMsaa2);
cmd.DisableShaderKeyword(LightweightKeywords.DepthMsaa4);
cmd.EnableShaderKeyword(LightweightKeywordStrings.DepthNoMsaa);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthMsaa2);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthMsaa4);
cmd.Blit(GetSurface(RenderTargetHandles.DepthTexture), BuiltinRenderTextureType.CameraTarget, GetMaterial(MaterialHandles.DepthCopy));
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);

public RenderTargetIdentifier GetSurface(int handle)
{
if (handle == -1)
return BuiltinRenderTextureType.CameraTarget;
if (handle < 0 || !m_ResourceMap.TryGetValue(handle, out renderTargetID))
if (!m_ResourceMap.TryGetValue(handle, out renderTargetID))
{
Debug.LogError(string.Format("Handle {0} has not any surface registered to it.", handle));
return new RenderTargetIdentifier();

m_ActiveRenderPassQueue.Add(pass);
}
bool RequiresColorAttachment(ref CameraData cameraData, RenderTextureDescriptor baseDescriptor)
bool RequiresIntermediateColorTexture(ref CameraData cameraData, RenderTextureDescriptor baseDescriptor, bool requiresCameraDepth)
if (cameraData.isOffscreenRender)
return false;
return cameraData.isSceneViewCamera || isScaledRender || cameraData.isHdrEnabled ||
cameraData.postProcessEnabled || cameraData.requiresOpaqueTexture || isTargetTexture2DArray;
return requiresCameraDepth || cameraData.isSceneViewCamera || isScaledRender || cameraData.isHdrEnabled ||
cameraData.postProcessEnabled || cameraData.requiresOpaqueTexture || isTargetTexture2DArray || !cameraData.isDefaultViewport;
}
bool CanCopyDepth(ref CameraData cameraData)

4
com.unity.render-pipelines.lightweight/LWRP/LightweightPipeline.cs


context.ExecuteCommandBuffer(cmd);
cmd.Clear();
#if UNITY_EDITOR
#endif
{
m_IsCameraRendering = true;
#if UNITY_EDITOR

m_Renderer.Setup(ref context, ref m_CullResults, ref renderingData);
m_Renderer.Execute(ref context, ref m_CullResults, ref renderingData);
}
#if UNITY_EDITOR
catch (Exception)
{
CommandBufferPool.Release(cmd);

#endif
{
m_IsCameraRendering = false;
}

30
com.unity.render-pipelines.lightweight/LWRP/LightweightPipelineCore.cs


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

}
}
public static class LightweightKeywords
public static class LightweightKeywordStrings
public static readonly string AdditionalLightsText = "_ADDITIONAL_LIGHTS";
public static readonly string VertexLightsText = "_VERTEX_LIGHTS";
public static readonly string MixedLightingSubtractiveText = "_MIXED_LIGHTING_SUBTRACTIVE";
public static readonly string MainLightCookieText = "_MAIN_LIGHT_COOKIE";
public static readonly string DirectionalShadowsText = "_SHADOWS_ENABLED";
public static readonly string LocalShadowsText = "_LOCAL_SHADOWS_ENABLED";
public static readonly string SoftShadowsText = "_SHADOWS_SOFT";
public static readonly string CascadeShadowsText = "_SHADOWS_CASCADE";
public static readonly string AdditionalLights = "_ADDITIONAL_LIGHTS";
public static readonly string VertexLights = "_VERTEX_LIGHTS";
public static readonly string MixedLightingSubtractive = "_MIXED_LIGHTING_SUBTRACTIVE";
public static readonly string MainLightCookie = "_MAIN_LIGHT_COOKIE";
public static readonly string DirectionalShadows = "_SHADOWS_ENABLED";
public static readonly string LocalShadows = "_LOCAL_SHADOWS_ENABLED";
public static readonly string SoftShadows = "_SHADOWS_SOFT";
public static readonly string CascadeShadows = "_SHADOWS_CASCADE";
public static readonly ShaderKeyword AdditionalLights = new ShaderKeyword(AdditionalLightsText);
public static readonly ShaderKeyword VertexLights = new ShaderKeyword(VertexLightsText);
public static readonly ShaderKeyword MixedLightingSubtractive = new ShaderKeyword(MixedLightingSubtractiveText);
public static readonly ShaderKeyword MainLightCookie = new ShaderKeyword(MainLightCookieText);
public static readonly ShaderKeyword DirectionalShadows = new ShaderKeyword(DirectionalShadowsText);
public static readonly ShaderKeyword LocalShadows = new ShaderKeyword(LocalShadowsText);
public static readonly ShaderKeyword SoftShadows = new ShaderKeyword(SoftShadowsText);
public static readonly ShaderKeyword Lightmap = new ShaderKeyword("LIGHTMAP_ON");
public static readonly ShaderKeyword DirectionalLightmap = new ShaderKeyword("DIRLIGHTMAP_COMBINED");
}
public partial class LightweightPipeline

44
com.unity.render-pipelines.lightweight/LWRP/Passes/ForwardLitPass.cs


using System.Diagnostics;
using UnityEngine.Experimental.GlobalIllumination;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.XR;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
{

{
int vertexLightsCount = lightData.totalAdditionalLightsCount - lightData.pixelAdditionalLightsCount;
CoreUtils.SetKeyword(cmd, LightweightKeywords.AdditionalLightsText, lightData.totalAdditionalLightsCount > 0);
CoreUtils.SetKeyword(cmd, LightweightKeywords.MixedLightingSubtractiveText, m_MixedLightingSetup == MixedLightingSetup.Subtractive);
CoreUtils.SetKeyword(cmd, LightweightKeywords.VertexLightsText, vertexLightsCount > 0);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.AdditionalLights, lightData.totalAdditionalLightsCount > 0);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.MixedLightingSubtractive, m_MixedLightingSetup == MixedLightingSetup.Subtractive);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.VertexLights, vertexLightsCount > 0);
// CoreUtils.SetKeyword(cmd, LightweightKeywords.MainLightCookieText, mainLightIndex != -1 && LightweightUtils.IsSupportedCookieType(visibleLights[mainLightIndex].lightType) && visibleLights[mainLightIndex].light.cookie != null);
// CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.MainLightCookieText, mainLightIndex != -1 && LightweightUtils.IsSupportedCookieType(visibleLights[mainLightIndex].lightType) && visibleLights[mainLightIndex].light.cookie != null);
LightShadows directionalShadowQuality = shadowData.renderedDirectionalShadowQuality;
LightShadows localShadowQuality = shadowData.renderedLocalShadowQuality;

shadowData.supportsSoftShadows;
CoreUtils.SetKeyword(cmd, LightweightKeywords.DirectionalShadowsText, directionalShadowQuality != LightShadows.None);
CoreUtils.SetKeyword(cmd, LightweightKeywords.LocalShadowsText, localShadowQuality != LightShadows.None);
CoreUtils.SetKeyword(cmd, LightweightKeywords.SoftShadowsText, hasSoftShadows);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.DirectionalShadows, directionalShadowQuality != LightShadows.None);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.LocalShadows, localShadowQuality != LightShadows.None);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.SoftShadows, hasSoftShadows);
// TODO: Remove this. legacy particles support will be removed from Unity in 2018.3. This should be a shader_feature instead with prop exposed in the Standard particles shader.
CoreUtils.SetKeyword(cmd, "SOFTPARTICLES_ON", cameraData.requiresSoftParticles);

ClearFlag clearFlag = GetCameraClearFlag(camera);
SetRenderTarget(cmd, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(camera.backgroundColor));
// If rendering to an intermediate RT we resolve viewport on blit due to offset not being supported
// while rendering to a RT.
if (colorAttachmentHandle == -1 && cameraData.isDefaultViewport)
cmd.SetViewport(camera.pixelRect);
// TODO: We need a proper way to handle multiple camera/ camera stack. Issue is: multiple cameras can share a same RT
// (e.g, split screen games). However devs have to be dilligent with it and know when to clear/preserve color.
// For now we make it consistent by resolving viewport with a RT until we can have a proper camera management system
//if (colorAttachmentHandle == -1 && !cameraData.isDefaultViewport)
// cmd.SetViewport(camera.pixelRect);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();

CommandBuffer cmd = CommandBufferPool.Get("Final Blit Pass");
cmd.SetGlobalTexture("_BlitTex", sourceRT);
// We need to handle viewport on a RT. We do it by rendering a fullscreen quad + viewport
SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.All, Color.black);
SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.None, Color.black);
cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
cmd.SetViewport(cameraData.camera.pixelRect);
LightweightPipeline.DrawFullScreen(cmd, material);

if (cameraData.msaaSamples > 1)
{
cmd.DisableShaderKeyword(LightweightKeywords.DepthNoMsaa);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthNoMsaa);
cmd.DisableShaderKeyword(LightweightKeywords.DepthMsaa2);
cmd.EnableShaderKeyword(LightweightKeywords.DepthMsaa4);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthMsaa2);
cmd.EnableShaderKeyword(LightweightKeywordStrings.DepthMsaa4);
cmd.EnableShaderKeyword(LightweightKeywords.DepthMsaa2);
cmd.DisableShaderKeyword(LightweightKeywords.DepthMsaa4);
cmd.EnableShaderKeyword(LightweightKeywordStrings.DepthMsaa2);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthMsaa4);
cmd.EnableShaderKeyword(LightweightKeywords.DepthNoMsaa);
cmd.DisableShaderKeyword(LightweightKeywords.DepthMsaa2);
cmd.DisableShaderKeyword(LightweightKeywords.DepthMsaa4);
cmd.EnableShaderKeyword(LightweightKeywordStrings.DepthNoMsaa);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthMsaa2);
cmd.DisableShaderKeyword(LightweightKeywordStrings.DepthMsaa4);
LightweightPipeline.CopyTexture(cmd, depthSurface, copyDepthSurface, m_DepthCopyMaterial);
}
context.ExecuteCommandBuffer(cmd);

11
com.unity.render-pipelines.lightweight/LWRP/Passes/ScreenSpaceShadowResolvePass.cs


{
public class ScreenSpaceShadowResolvePass : ScriptableRenderPass
{
public bool softShadows { get; set; }
RenderTextureFormat m_ColorFormat;
Material m_ScreenSpaceShadowsMaterial;

: RenderTextureFormat.ARGB32;
m_ScreenSpaceShadowsMaterial = renderer.GetMaterial(MaterialHandles.ScrenSpaceShadow);
softShadows = false;
}
public override void Setup(CommandBuffer cmd, RenderTextureDescriptor baseDescriptor, int[] colorAttachmentHandles, int depthAttachmentHandle = -1, int samples = 1)

return;
CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");
SetShadowCollectPassKeywords(cmd, renderingData.shadowData.directionalLightCascadeCount);
SetShadowCollectPassKeywords(cmd, ref renderingData.shadowData);
// 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

CommandBufferPool.Release(cmd);
}
void SetShadowCollectPassKeywords(CommandBuffer cmd, int cascadeCount)
void SetShadowCollectPassKeywords(CommandBuffer cmd, ref ShadowData shadowData)
CoreUtils.SetKeyword(cmd, LightweightKeywords.SoftShadowsText, softShadows);
CoreUtils.SetKeyword(cmd, LightweightKeywords.CascadeShadowsText, cascadeCount > 1);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.SoftShadows, shadowData.renderedDirectionalShadowQuality == LightShadows.Soft);
CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.CascadeShadows, shadowData.directionalLightCascadeCount > 1);
}
}
}

4
com.unity.render-pipelines.lightweight/LWRP/Passes/ScriptableRenderPass.cs


public TextureDimension textureDimension { get; private set; }
protected List<ShaderPassName> m_ShaderPassNames = new List<ShaderPassName>();
public int samples { get; private set; }
int samples;
protected List<ShaderPassName> m_ShaderPassNames = new List<ShaderPassName>();
public ScriptableRenderPass(LightweightForwardRenderer renderer)
{

30
com.unity.shadergraph/CHANGELOG.md


# Next version
### HD Render Pipeline support
![](.data/hd_render_pipeline.png)
Shader Graph now supports the High Definition Render Pipeline with both PBR and Unlit Master nodes. Shaders built with Shader Graph work with both the Lightweight and HD render pipelines.
### Vertex position
![](.data/vertex_position.png)
You can now modify vertex position via the Position slot on the PBR and Unlit Master nodes. By default, the input to this node is object space position. Custom inputs to this slot should specify the absolute local position of a given vertex. Certain nodes (such as Procedural Shapes) are not viable in the vertex shader. Such nodes are incompatible with this slot.
### Master node settings
![](.data/menu_settings.png)

You can now change the path of Shader Graphs and Sub Graphs. When you change the path of a Shader Graph, this modifies the location it has in the shader selection list. When you change the path of Sub Graph, it will have a different location in the node creation menu.
### Is Front Face node
![](.data/face_sign.png)
With this node, you can change graph output depending on the face sign of a given fragment. If the current fragment is part of a front face, the node returns True. For a back face, the node returns False.
Note: This functionality requires that you have enabled **two sided** on the Master node.
### Gradient nodes

### Texture3D and Texture2D Array
![](.data/texture_nodes.png)
This change expands Unity's support for Texture types via two new property types and four new nodes. These allow you to define and sample Texture 3D and Texture 2D Array type assets in Shader Graph.
### Texture 2D LOD node
![](.data/texture_2d_lod_node.png)
This adds a new node for LOD functionality on a Texture 2D Sample. Sample Texture 2D LOD uses the exact same input and output slots as Sample Texture 2D, but also includes an input for level of detail adjustments via a Vector1 slot.
### Show generated code

- Your system locale can no longer cause incorrect commands due to full stops being converted to commas.
- Deserialization of subgraphs now works correctly.
- Sub graphs are now suffixed with (sub), so you can tell them apart from other nodes.
- The preview of a node does not obstruct the selection outliner anymore.

55
com.unity.shadergraph/Editor/Data/Graphs/PreviewProperty.cs


}
[StructLayout(LayoutKind.Explicit)]
struct Data
struct ClassData
[FieldOffset(0)]
public Color colorValue;
[FieldOffset(0)]
public Texture textureValue;
[FieldOffset(0)]

}
[StructLayout(LayoutKind.Explicit)]
struct StructData
{
[FieldOffset(0)]
public Color colorValue;
[FieldOffset(0)]
public Vector4 vector4Value;
[FieldOffset(0)]

}
Data m_Data;
ClassData m_ClassData;
StructData m_StructData;
public Color colorValue
{

throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Color, propType));
return m_Data.colorValue;
return m_StructData.colorValue;
m_Data.colorValue = value;
m_StructData.colorValue = value;
}
}

{
if (propType != PropertyType.Texture2D && propType != PropertyType.Texture2DArray && propType != PropertyType.Texture3D)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Texture2D, propType));
return m_Data.textureValue;
return m_ClassData.textureValue;
m_Data.textureValue = value;
m_ClassData.textureValue = value;
}
}

{
if (propType != PropertyType.Cubemap)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Cubemap, propType));
return m_Data.cubemapValue;
return m_ClassData.cubemapValue;
m_Data.cubemapValue = value;
m_ClassData.cubemapValue = value;
}
}

{
if (propType != PropertyType.Gradient)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Gradient, propType));
return m_Data.gradientValue;
return m_ClassData.gradientValue;
m_Data.gradientValue = value;
m_ClassData.gradientValue = value;
}
}

{
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Vector4, propType));
return m_Data.vector4Value;
return m_StructData.vector4Value;
}
set
{

m_Data.vector4Value = value;
m_StructData.vector4Value = value;
}
}

{
if (propType != PropertyType.Vector1)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Vector1, propType));
return m_Data.floatValue;
return m_StructData.floatValue;
m_Data.floatValue = value;
m_StructData.floatValue = value;
}
}

{
if (propType != PropertyType.Boolean)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Boolean, propType));
return m_Data.booleanValue;
return m_StructData.booleanValue;
m_Data.booleanValue = value;
m_StructData.booleanValue = value;
}
}

public void SetMaterialPropertyBlockValue(MaterialPropertyBlock block)
{
if ((propType == PropertyType.Texture2D || propType == PropertyType.Texture2DArray || propType == PropertyType.Texture3D) && textureValue != null)
block.SetTexture(name, m_Data.textureValue);
block.SetTexture(name, m_ClassData.textureValue);
block.SetTexture(name, m_Data.cubemapValue);
block.SetTexture(name, m_ClassData.cubemapValue);
block.SetColor(name, m_Data.colorValue);
block.SetColor(name, m_StructData.colorValue);
block.SetVector(name, m_Data.vector4Value);
block.SetVector(name, m_StructData.vector4Value);
block.SetFloat(name, m_Data.floatValue);
block.SetFloat(name, m_StructData.floatValue);
block.SetFloat(name, m_Data.booleanValue ? 1 : 0);
block.SetFloat(name, m_StructData.booleanValue ? 1 : 0);
}
}

8
com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs


public NeededCoordinateSpace requiresPosition;
public bool requiresScreenPosition;
public bool requiresVertexColor;
public bool requiresFaceSign;
public List<UVChannel> requiresMeshUVs;
public static ShaderGraphRequirements none

newReqs.requiresPosition = other.requiresPosition | requiresPosition;
newReqs.requiresScreenPosition = other.requiresScreenPosition | requiresScreenPosition;
newReqs.requiresVertexColor = other.requiresVertexColor | requiresVertexColor;
newReqs.requiresFaceSign = other.requiresFaceSign | requiresFaceSign;
newReqs.requiresMeshUVs = new List<UVChannel>();
if (requiresMeshUVs != null)

return newReqs;
}
public static ShaderGraphRequirements FromNodes<T>(List<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true, bool HDRPBehavior = false)
public static ShaderGraphRequirements FromNodes<T>(List<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true)
where T : class, INode
{
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal(stageCapability));

NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition(stageCapability));
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
bool requiresFaceSign = nodes.OfType<IMayRequireFaceSign>().Any(x => x.RequiresFaceSign());
var meshUV = new List<UVChannel>();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)

| requiresNormal;
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace && !HDRPBehavior)
if (needsTangentSpace)
{
requiresBitangent |= NeededCoordinateSpace.World;
requiresNormal |= NeededCoordinateSpace.World;

requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor,
requiresFaceSign = requiresFaceSign,
requiresMeshUVs = meshUV
};

14
com.unity.shadergraph/Editor/Data/Nodes/Procedural/CheckerboardNode.cs


return
@"
{
UV = UV + 0.25 / Frequency;
UV = (UV.xy + 0.5) * Frequency;
{precision} width = 0.5;
{precision}2 distance3 = 2.0 * abs(frac((UV.xy + 0.5) * Frequency) - 0.5) - width;
{precision}2 scale = 0.5 / duv_length.xy;
{precision}2 blend_out = saturate(scale / 3);
{precision}2 vector_alpha = clamp(distance3 * scale.xy * blend_out.xy, -1.0, 1.0);
{precision} alpha = saturate(vector_alpha.x * vector_alpha.y);
{precision} width = 1.0;
{precision}2 distance3 = 4.0 * abs(frac(UV + 0.25) - 0.5) - width;
{precision}2 scale = 0.35 / duv_length.xy;
{precision} freqLimiter = sqrt(clamp(1.1f - max(duv_length.x, duv_length.y), 0.0, 1.0));
{precision}2 vector_alpha = clamp(distance3 * scale.xy, -1.0, 1.0);
{precision} alpha = saturate(0.5f + 0.5f * vector_alpha.x * vector_alpha.y * freqLimiter);
Out = lerp(ColorA, ColorB, alpha.xxx);
}";
}

69
com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs


{
return 2;
}
else if (typeName.Equals("float"))
else if (typeName.Equals("Single"))
{
return 1;
}

if (requirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
if (requirements.requiresFaceSign)
surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
results.previewMode = PreviewMode.Preview3D;
if (!isUber)
{

return results;
}
public static void GenerateSurfaceDescriptionStruct(ShaderStringBuilder surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster)
public static void GenerateSurfaceDescriptionStruct(ShaderStringBuilder surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster, string structName = "SurfaceDescription", HashSet<string> activeFields = null)
surfaceDescriptionStruct.AppendLine("struct SurfaceDescription");
surfaceDescriptionStruct.AppendLine("struct {0}", structName);
{
string hlslName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName);
NodeUtils.GetHLSLSafeName(slot.shaderOutputName));
//surfaceDescriptionStruct.Deindent();
hlslName);
if (activeFields != null)
{
activeFields.Add(structName + "." + hlslName);
}
}
if (activeFields != null)
{
activeFields.Add(structName + ".PreviewOutput");
}
}
}
}

var usedSlots = slots ?? masterNode.GetInputSlots<MaterialSlot>();
foreach (var input in usedSlots)
{
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
if (input != null)
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), masterNode.GetSlotValue(input.id, mode));
}
else
{
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode));
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
{
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), masterNode.GetSlotValue(input.id, mode));
}
else
{
surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode));
}
}
}
}

}
const string k_VertexDescriptionStructName = "VertexDescription";
public static void GenerateVertexDescriptionStruct(ShaderStringBuilder builder, List<MaterialSlot> slots)
public static void GenerateVertexDescriptionStruct(ShaderStringBuilder builder, List<MaterialSlot> slots, string structName = k_VertexDescriptionStructName, HashSet<string> activeFields = null)
builder.AppendLine("struct {0}", k_VertexDescriptionStructName);
builder.AppendLine("struct {0}", structName);
builder.AppendLine("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), NodeUtils.GetHLSLSafeName(slot.shaderOutputName));
{
string hlslName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName);
builder.AppendLine("{0} {1};",
NodeUtils.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType),
hlslName);
if (activeFields != null)
{
activeFields.Add(structName + "." + hlslName);
}
}
}
}

FunctionRegistry functionRegistry,
PropertyCollector shaderProperties,
GenerationMode mode,
List<AbstractMaterialNode> nodes,
List<INode> nodes,
string graphInputStructName = "VertexDescriptionInputs")
string graphInputStructName = "VertexDescriptionInputs",
string functionName = "PopulateVertexData",
string graphOutputStructName = k_VertexDescriptionStructName)
{
if (graph == null)
return;

graph.CollectShaderProperties(shaderProperties, mode);
builder.AppendLine("{0} PopulateVertexData(VertexDescriptionInputs IN)", k_VertexDescriptionStructName);
builder.AppendLine("{0} {1}({2} IN)", graphOutputStructName, functionName, graphInputStructName);
builder.AppendLine("{0} description = ({0})0;", k_VertexDescriptionStructName);
foreach (var node in nodes)
builder.AppendLine("{0} description = ({0})0;", graphOutputStructName);
foreach (var node in nodes.OfType<AbstractMaterialNode>())
{
var generatesFunction = node as IGeneratesFunction;
if (generatesFunction != null)

16
com.unity.shadergraph/Editor/Data/Util/ShaderGenerator.cs


if (combinedRequirements.requiresScreenPosition)
{
var screenPosition = "ComputeScreenPos(mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), v.vertex.xyz)), _ProjectionParams.x)";
var screenPosition = "ComputeScreenPos(mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), v.vertex)), _ProjectionParams.x)";
vertexShader.AppendLine("float4 {0} = {1};", ShaderGeneratorNames.ScreenPosition, screenPosition);
if (graphModelRequirements.requiresScreenPosition)
{

if (pixelRequirements.requiresScreenPosition)
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.ScreenPosition);
if (pixelRequirements.requiresFaceSign)
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.FaceSign);
foreach (var channel in pixelRequirements.requiresMeshUVs.Distinct())
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.GetUVName(channel));

pixelShaderSurfaceRemap.AppendLine("return surf.PreviewOutput;");
}
// -------------------------------------
// Extra pixel shader work
var faceSign = new ShaderStringBuilder();
if (shaderGraphRequirements.requiresFaceSign)
faceSign.AppendLine(", half FaceSign : VFACE");
res = res.Replace("${FaceSign}", faceSign.ToString());
res = res.Replace("${LocalPixelShader}", pixelShader.ToString());
res = res.Replace("${SurfaceInputs}", pixelShaderSurfaceInputs.ToString());
res = res.Replace("${SurfaceOutputRemap}", pixelShaderSurfaceRemap.ToString());

return o;
}
float4 frag (GraphVertexOutput IN) : SV_Target
float4 frag (GraphVertexOutput IN ${FaceSign}) : SV_Target
{
${LocalPixelShader}
SurfaceDescriptionInputs surfaceInput = (SurfaceDescriptionInputs)0;;

1
com.unity.shadergraph/Editor/Data/Util/ShaderGeneratorNames.cs


public const string ScreenPosition = "ScreenPosition";
public const string VertexColor = "VertexColor";
public const string FaceSign = "FaceSign";
public static string GetUVName(this UVChannel channel)

1
com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs


if (m_PreviewContainer.parent != this)
{
Add(m_PreviewContainer);
m_PreviewContainer.PlaceBehind(this.Q("selection-border"));
}
m_PreviewFiller.AddToClassList("expanded");
m_PreviewFiller.RemoveFromClassList("collapsed");

52
com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs


List<PropertyCollector.TextureInfo> configuredTextures;
string path = ctx.assetPath;
string shaderString = null;
var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths);
var shader = ShaderUtil.CreateShaderAsset(text);
EditorMaterialUtility.SetShaderDefaults(
shader,
configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
EditorMaterialUtility.SetShaderNonModifiableDefaults(
shader,
configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
ctx.AddObjectToAsset("MainAsset", shader);
ctx.SetMainObject(shader);
foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
}
internal static string GetShaderText(string path, out List<PropertyCollector.TextureInfo> configuredTextures, List<string> sourceAssetDependencyPaths)
{
string shaderString = null;
var shaderName = Path.GetFileNameWithoutExtension(path);
try
{

shaderName = graph.path + "/" + shaderName;
shaderString = graph.GetShader(shaderName, GenerationMode.ForReals, out configuredTextures, sourceAssetDependencyPaths);
foreach (var node in graph.GetNodes<AbstractMaterialNode>())
node.GetSourceAssetDependencies(sourceAssetDependencyPaths);
if (sourceAssetDependencyPaths != null)
{
foreach (var node in graph.GetNodes<AbstractMaterialNode>())
node.GetSourceAssetDependencies(sourceAssetDependencyPaths);
}
}
catch (Exception)
{

var text = shaderString ?? k_ErrorShader.Replace("Hidden/GraphErrorShader2", shaderName);
var shader = ShaderUtil.CreateShaderAsset(text);
EditorMaterialUtility.SetShaderDefaults(
shader,
configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
EditorMaterialUtility.SetShaderNonModifiableDefaults(
shader,
configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
return shaderString ?? k_ErrorShader.Replace("Hidden/GraphErrorShader2", shaderName);
}
ctx.AddObjectToAsset("MainAsset", shader);
ctx.SetMainObject(shader);
foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
internal static string GetShaderText(string path, out List<PropertyCollector.TextureInfo> configuredTextures)
{
return GetShaderText(path, out configuredTextures, null);
}
}

8
com.unity.render-pipelines.core/CoreRP/Editor/Shadow.meta


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

3
com.unity.shadergraph/.data/face_sign.png


version https://git-lfs.github.com/spec/v1
oid sha256:056f160ee81fcdeb3f3a26a0116846de50b68bafa0c65db8731f5aca37ee74e7
size 43759

3
com.unity.shadergraph/.data/hd_render_pipeline.png


version https://git-lfs.github.com/spec/v1
oid sha256:aff2679b3a603812e63290cea0829d6d354a94e02765513bb214faa4331adfdd
size 1516111

3
com.unity.shadergraph/.data/texture_2d_lod_node.PNG


version https://git-lfs.github.com/spec/v1
oid sha256:b262d71d68d478f6b6c3dc3086451a764e065b8608a65104e17cb8aefefa5f76
size 238646

3
com.unity.shadergraph/.data/texture_nodes.png


version https://git-lfs.github.com/spec/v1
oid sha256:6e4d23f6b0f35ae888614f05c00c28ca5e064b03bf010159950acaf9e12366d5
size 131836

3
com.unity.shadergraph/.data/vertex_position.png


version https://git-lfs.github.com/spec/v1
oid sha256:3ae6d830f7cff2331af0145171c3287021e8d31e64c97633b06c5155332ddbfe
size 395709

18
com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs


using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
public interface IMayRequireFaceSign
{
bool RequiresFaceSign(ShaderStageCapability stageCapability = ShaderStageCapability.Fragment);
}
public static class IMayRequireFaceSignExtensions
{
public static bool RequiresFaceSign(this ISlot slot)
{
var mayRequireFaceSign = slot as IMayRequireFaceSign;
return mayRequireFaceSign != null && mayRequireFaceSign.RequiresFaceSign();
}
}
}

3
com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs.meta


fileFormatVersion: 2
guid: 23f5d9c2f1ec442a7b8c59e893a6724d
timeCreated: 1512469767

120
com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs


using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Sample Texture 2D LOD")]
public class SampleTexture2DLODNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 5;
public const int OutputSlotGId = 6;
public const int OutputSlotBId = 7;
public const int OutputSlotAId = 8;
public const int TextureInputId = 1;
public const int UVInput = 2;
public const int SamplerInput = 3;
public const int LODInput = 4;
const string kOutputSlotRGBAName = "RGBA";
const string kOutputSlotRName = "R";
const string kOutputSlotGName = "G";
const string kOutputSlotBName = "B";
const string kOutputSlotAName = "A";
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kLODInputName = "LOD";
public override bool hasPreview { get { return true; } }
public SampleTexture2DLODNode()
{
name = "Sample Texture 2D LOD";
UpdateNodeAfterDeserialization();
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Sample-Texture-2D-LOD-Node"; }
}
[SerializeField]
private TextureType m_TextureType = TextureType.Default;
[EnumControl("Type")]
public TextureType textureType
{
get { return m_TextureType; }
set
{
if (m_TextureType == value)
return;
m_TextureType = value;
Dirty(ModificationScope.Graph);
}
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.All));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(LODInput, kLODInputName, kLODInputName, SlotType.Input, 0));
RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInput, SamplerInput, LODInput });
}
// Node generations
public virtual void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var uvName = GetSlotValue(UVInput, generationMode);
//Sampler input slot
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
var lodSlot = GetSlotValue(LODInput, generationMode);
var id = GetSlotValue(TextureInputId, generationMode);
var result = string.Format("{0}4 {1} = SAMPLE_TEXTURE2D_LOD({2}, {3}, {4}, {5});"
, precision
, GetVariableNameForSlot(OutputSlotRGBAId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : "sampler" + id
, uvName
, lodSlot);
visitor.AddShaderChunk(result, true);
if (textureType == TextureType.Normal)
visitor.AddShaderChunk(string.Format("{0}.rgb = UnpackNormalmapRGorAG({0});", GetVariableNameForSlot(OutputSlotRGBAId)), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.r;", precision, GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.g;", precision, GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.b;", precision, GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.a;", precision, GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)), true);
}
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
{
s_TempSlots.Clear();
GetInputSlots(s_TempSlots);
foreach (var slot in s_TempSlots)
{
if (slot.RequiresMeshUV(channel))
return true;
}
return false;
}
}
}

11
com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs.meta


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

41
com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs


using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
[Title("Utility", "Logic", "Is Front Face")]
public class IsFrontFaceNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireFaceSign
{
public IsFrontFaceNode()
{
name = "Is Front Face";
UpdateNodeAfterDeserialization();
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Is-Front-Face-Node"; }
}
public override bool hasPreview { get { return false; } }
public const int OutputSlotId = 0;
private const string kOutputSlotName = "Out";
public override void UpdateNodeAfterDeserialization()
{
AddSlot(new BooleanMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, true, ShaderStageCapability.Fragment));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
visitor.AddShaderChunk(string.Format("{0} {1} = max(0, IN.{2});", precision, GetVariableNameForSlot(OutputSlotId), ShaderGeneratorNames.FaceSign), true);
}
public bool RequiresFaceSign(ShaderStageCapability stageCapability = ShaderStageCapability.Fragment)
{
return true;
}
}
}

11
com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs.meta


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

214
com.unity.render-pipelines.core/CoreRP/Editor/Shadow/ShadowCascadeSplitGUI.cs


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using UnityEngine;
namespace UnityEditor.Experimental.Rendering
{
static class ShadowCascadeSplitGUI
{
private const int kSliderbarTopMargin = 2;
private const int kSliderbarHeight = 24;
private const int kSliderbarBottomMargin = 2;
private const int kPartitionHandleWidth = 2;
private const int kPartitionHandleExtraHitAreaWidth = 2;
private static readonly Color[] kCascadeColors =
{
new Color(0.5f, 0.5f, 0.6f, 1.0f),
new Color(0.5f, 0.6f, 0.5f, 1.0f),
new Color(0.6f, 0.6f, 0.5f, 1.0f),
new Color(0.6f, 0.5f, 0.5f, 1.0f),
};
// using a LODGroup skin
private static readonly GUIStyle s_CascadeSliderBG = "LODSliderRange";
private static readonly GUIStyle s_TextCenteredStyle = new GUIStyle(EditorStyles.whiteMiniLabel)
{
alignment = TextAnchor.MiddleCenter
};
// Internal struct to bundle drag information
private class DragCache
{
public int m_ActivePartition; // the cascade partition that we are currently dragging/resizing
public float m_NormalizedPartitionSize; // the normalized size of the partition (0.0f < size < 1.0f)
public Vector2 m_LastCachedMousePosition; // mouse position the last time we registered a drag or mouse down.
public DragCache(int activePartition, float normalizedPartitionSize, Vector2 currentMousePos)
{
m_ActivePartition = activePartition;
m_NormalizedPartitionSize = normalizedPartitionSize;
m_LastCachedMousePosition = currentMousePos;
}
};
private static DragCache s_DragCache;
private static readonly int s_CascadeSliderId = "s_CascadeSliderId".GetHashCode();
private static SceneView s_RestoreSceneView;
private static SceneView.CameraMode s_OldSceneDrawMode;
private static bool s_OldSceneLightingMode;
/**
* Static function to handle the GUI and User input related to the cascade slider.
*
* @param normalizedCascadePartition The array of partition sizes in the range 0.0f - 1.0f; expects ONE entry if cascades = 2, and THREE if cascades=4
* The last entry will be automatically determined by summing up the array, and doing 1.0f - sum
*/
public static void HandleCascadeSliderGUI(ref float[] normalizedCascadePartitions)
{
EditorGUILayout.LabelField("Cascade splits");
// get the inspector width since we need it while drawing the partition rects.
// Only way currently is to reserve the block in the layout using GetRect(), and then immediately drawing the empty box
// to match the call to GetRect.
// From this point on, we move to non-layout based code.
var sliderRect = GUILayoutUtility.GetRect(GUIContent.none
, s_CascadeSliderBG
, GUILayout.Height(kSliderbarTopMargin + kSliderbarHeight + kSliderbarBottomMargin)
, GUILayout.ExpandWidth(true));
GUI.Box(sliderRect, GUIContent.none);
float currentX = sliderRect.x;
float cascadeBoxStartY = sliderRect.y + kSliderbarTopMargin;
float cascadeSliderWidth = sliderRect.width - (normalizedCascadePartitions.Length * kPartitionHandleWidth);
Color origTextColor = GUI.color;
Color origBackgroundColor = GUI.backgroundColor;
int colorIndex = -1;
// setup the array locally with the last partition
float[] adjustedCascadePartitions = new float[normalizedCascadePartitions.Length + 1];
System.Array.Copy(normalizedCascadePartitions, adjustedCascadePartitions, normalizedCascadePartitions.Length);
adjustedCascadePartitions[adjustedCascadePartitions.Length - 1] = 1.0f - normalizedCascadePartitions.Sum();
// check for user input on any of the partition handles
// this mechanism gets the current event in the queue... make sure that the mouse is over our control before consuming the event
int sliderControlId = GUIUtility.GetControlID(s_CascadeSliderId, FocusType.Passive);
Event currentEvent = Event.current;
int hotPartitionHandleIndex = -1; // the index of any partition handle that we are hovering over or dragging
// draw each cascade partition
for (int i = 0; i < adjustedCascadePartitions.Length; ++i)
{
float currentPartition = adjustedCascadePartitions[i];
colorIndex = (colorIndex + 1) % kCascadeColors.Length;
GUI.backgroundColor = kCascadeColors[colorIndex];
float boxLength = (cascadeSliderWidth * currentPartition);
// main cascade box
Rect partitionRect = new Rect(currentX, cascadeBoxStartY, boxLength, kSliderbarHeight);
GUI.Box(partitionRect, GUIContent.none, s_CascadeSliderBG);
currentX += boxLength;
// cascade box percentage text
GUI.color = Color.white;
Rect textRect = partitionRect;
var cascadeText = string.Format("{0}\n{1:F1}%", i, currentPartition * 100.0f);
GUI.Label(textRect, cascadeText, s_TextCenteredStyle);
// no need to draw the partition handle for last box
if (i == adjustedCascadePartitions.Length - 1)
break;
// partition handle
GUI.backgroundColor = Color.black;
Rect handleRect = partitionRect;
handleRect.x = currentX;
handleRect.width = kPartitionHandleWidth;
GUI.Box(handleRect, GUIContent.none, s_CascadeSliderBG);
// we want a thin handle visually (since wide black bar looks bad), but a slightly larger
// hit area for easier manipulation
Rect handleHitRect = handleRect;
handleHitRect.xMin -= kPartitionHandleExtraHitAreaWidth;
handleHitRect.xMax += kPartitionHandleExtraHitAreaWidth;
if (handleHitRect.Contains(currentEvent.mousePosition))
hotPartitionHandleIndex = i;
// add regions to slider where the cursor changes to Resize-Horizontal
if (s_DragCache == null)
{
EditorGUIUtility.AddCursorRect(handleHitRect, MouseCursor.ResizeHorizontal, sliderControlId);
}
currentX += kPartitionHandleWidth;
}
GUI.color = origTextColor;
GUI.backgroundColor = origBackgroundColor;
EventType eventType = currentEvent.GetTypeForControl(sliderControlId);
switch (eventType)
{
case EventType.MouseDown:
if (hotPartitionHandleIndex >= 0)
{
s_DragCache = new DragCache(hotPartitionHandleIndex, normalizedCascadePartitions[hotPartitionHandleIndex], currentEvent.mousePosition);
if (GUIUtility.hotControl == 0)
GUIUtility.hotControl = sliderControlId;
currentEvent.Use();
// Switch active scene view into shadow cascades visualization mode, once we start
// tweaking cascade splits.
if (s_RestoreSceneView == null)
{
s_RestoreSceneView = SceneView.lastActiveSceneView;
if (s_RestoreSceneView != null)
{
s_OldSceneDrawMode = s_RestoreSceneView.cameraMode;
s_OldSceneLightingMode = s_RestoreSceneView.m_SceneLighting;
s_RestoreSceneView.cameraMode = SceneView.GetBuiltinCameraMode(DrawCameraMode.ShadowCascades);
}
}
}
break;
case EventType.MouseUp:
// mouseUp event anywhere should release the hotcontrol (if it belongs to us), drags (if any)
if (GUIUtility.hotControl == sliderControlId)
{
GUIUtility.hotControl = 0;
currentEvent.Use();
}
s_DragCache = null;
// Restore previous scene view drawing mode once we stop tweaking cascade splits.
if (s_RestoreSceneView != null)
{
s_RestoreSceneView.cameraMode = s_OldSceneDrawMode;
s_RestoreSceneView.m_SceneLighting = s_OldSceneLightingMode;
s_RestoreSceneView = null;
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl != sliderControlId)
break;
// convert the mouse movement to normalized cascade width. Make sure that we are safe to apply the delta before using it.
float delta = (currentEvent.mousePosition - s_DragCache.m_LastCachedMousePosition).x / cascadeSliderWidth;
bool isLeftPartitionHappy = ((adjustedCascadePartitions[s_DragCache.m_ActivePartition] + delta) > 0.0f);
bool isRightPartitionHappy = ((adjustedCascadePartitions[s_DragCache.m_ActivePartition + 1] - delta) > 0.0f);
if (isLeftPartitionHappy && isRightPartitionHappy)
{
s_DragCache.m_NormalizedPartitionSize += delta;
normalizedCascadePartitions[s_DragCache.m_ActivePartition] = s_DragCache.m_NormalizedPartitionSize;
if (s_DragCache.m_ActivePartition < normalizedCascadePartitions.Length - 1)
normalizedCascadePartitions[s_DragCache.m_ActivePartition + 1] -= delta;
GUI.changed = true;
}
s_DragCache.m_LastCachedMousePosition = currentEvent.mousePosition;
currentEvent.Use();
break;
}
}
}
}

11
com.unity.render-pipelines.core/CoreRP/Editor/Shadow/ShadowCascadeSplitGUI.cs.meta


fileFormatVersion: 2
guid: 1a130d84c83d6d24a9c62c149265bfbc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存