浏览代码

Merge branch 'HDRP/staging' into RemoveSkyInLuxMeter

/main
GitHub 6 年前
当前提交
ee4e73a4
共有 42 个文件被更改,包括 806 次插入678 次删除
  1. 6
      TestProjects/LWGraphicsTest/Assets/Scenes/045_CustomLWPipe/CustomLWPipe.cs
  2. 6
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  3. 5
      com.unity.render-pipelines.high-definition/HDRP/Debug/DebugColorPicker.shader
  4. 1
      com.unity.render-pipelines.high-definition/HDRP/Debug/LightingDebug.cs
  5. 13
      com.unity.render-pipelines.high-definition/HDRP/Debug/LightingDebug.cs.hlsl
  6. 160
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template
  7. 104
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs
  8. 161
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template
  9. 6
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs
  10. 7
      com.unity.render-pipelines.lightweight/CHANGELOG.md
  11. 18
      com.unity.render-pipelines.lightweight/LWRP/DefaultRendererSetup.cs
  12. 130
      com.unity.render-pipelines.lightweight/LWRP/Editor/LightweightPipelineAssetEditor.cs
  13. 4
      com.unity.render-pipelines.lightweight/LWRP/LightweightForwardRenderer.cs
  14. 3
      com.unity.render-pipelines.lightweight/LWRP/Passes/BeginXRRenderingPass.cs
  15. 10
      com.unity.render-pipelines.lightweight/LWRP/Passes/CopyColorPass.cs
  16. 12
      com.unity.render-pipelines.lightweight/LWRP/Passes/CopyDepthPass.cs
  17. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/CreateLightweightRenderTexturesPass.cs
  18. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/DepthOnlyPass.cs
  19. 7
      com.unity.render-pipelines.lightweight/LWRP/Passes/DirectionalShadowsPass.cs
  20. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/DrawSkyboxPass.cs
  21. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/EndXRRenderingPass.cs
  22. 16
      com.unity.render-pipelines.lightweight/LWRP/Passes/FinalBlitPass.cs
  23. 11
      com.unity.render-pipelines.lightweight/LWRP/Passes/LightweightForwardPass.cs
  24. 4
      com.unity.render-pipelines.lightweight/LWRP/Passes/LocalShadowsPass.cs
  25. 3
      com.unity.render-pipelines.lightweight/LWRP/Passes/OpaquePostProcessPass.cs
  26. 9
      com.unity.render-pipelines.lightweight/LWRP/Passes/RenderOpaqueForwardPass.cs
  27. 7
      com.unity.render-pipelines.lightweight/LWRP/Passes/RenderTransparentForwardPass.cs
  28. 16
      com.unity.render-pipelines.lightweight/LWRP/Passes/SceneViewDepthCopy.cs
  29. 11
      com.unity.render-pipelines.lightweight/LWRP/Passes/ScreenSpaceShadowResolvePass.cs
  30. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/ScriptableRenderPass.cs
  31. 3
      com.unity.render-pipelines.lightweight/LWRP/Passes/SetupForwardRenderingPass.cs
  32. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/SetupLightweightConstanstPass.cs
  33. 2
      com.unity.render-pipelines.lightweight/LWRP/Passes/TransparentPostProcessPass.cs
  34. 7
      com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Shadows.hlsl
  35. 92
      com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl
  36. 6
      com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs
  37. 483
      com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs
  38. 10
      com.unity.shadergraph/Editor/Data/Util/ShaderStringBuilder.cs
  39. 71
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/SharedCode.template.hlsl
  40. 9
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/SharedCode.template.hlsl.meta
  41. 50
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/VertexAnimation.template.hlsl
  42. 9
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/VertexAnimation.template.hlsl.meta

6
TestProjects/LWGraphicsTest/Assets/Scenes/045_CustomLWPipe/CustomLWPipe.cs


[NonSerialized]
private bool m_Initialized = false;
private void Init(LightweightForwardRenderer renderer)
private void Init()
{
if (m_Initialized)
return;

m_SetupLightweightConstants = new SetupLightweightConstanstPass();
m_RenderOpaqueForwardPass = new RenderOpaqueForwardPass(renderer.GetMaterial(MaterialHandles.Error));
m_RenderOpaqueForwardPass = new RenderOpaqueForwardPass();
m_Initialized = true;
}

{
Init(renderer);
Init();
renderer.Clear();

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


## [3.2.0-preview]
### Added
- Added a luminance meter in the debug menu
- The lux meter isn't affected by the sky anymore
- Fix issue with package upgrading (HDRP resources asset is now versionned to worarkound package manager limitation)
- Fix lux meter mode - The lux meter isn't affected by the sky anymore
## [3.1.0-preview]

5
com.unity.render-pipelines.high-definition/HDRP/Debug/DebugColorPicker.shader


//Decompress value if luxMeter is active
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER && _ColorPickerMode != COLORPICKERDEBUGMODE_NONE)
result.rgb = result.rgb * LUXMETER_COMPRESSION_RATIO;
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUMINANCE_METER)
{
result = Luminance(result.rgb);
}
if (_FalseColor)
result.rgb = FasleColorRemap(Luminance(result.rgb), _FalseColorThresholds);

1
com.unity.render-pipelines.high-definition/HDRP/Debug/LightingDebug.cs


DiffuseLighting,
SpecularLighting,
LuxMeter,
LuminanceMeter,
VisualizeCascade,
VisualizeShadowMasks,
IndirectDiffuseOcclusion,

13
com.unity.render-pipelines.high-definition/HDRP/Debug/LightingDebug.cs.hlsl


#define DEBUGLIGHTINGMODE_DIFFUSE_LIGHTING (1)
#define DEBUGLIGHTINGMODE_SPECULAR_LIGHTING (2)
#define DEBUGLIGHTINGMODE_LUX_METER (3)
#define DEBUGLIGHTINGMODE_VISUALIZE_CASCADE (4)
#define DEBUGLIGHTINGMODE_VISUALIZE_SHADOW_MASKS (5)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION (6)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION (7)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION (8)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION (9)
#define DEBUGLIGHTINGMODE_LUMINANCE_METER (4)
#define DEBUGLIGHTINGMODE_VISUALIZE_CASCADE (5)
#define DEBUGLIGHTINGMODE_VISUALIZE_SHADOW_MASKS (6)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION (7)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION (8)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION (9)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION (10)
//
// UnityEngine.Experimental.Rendering.HDPipeline.DebugScreenSpaceTracing: static fields

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


Pass
{
// based on HDPBRPass.template
Name "${PassName}"
Tags { "LightMode" = "${LightMode}" }
Name "$splice(PassName)"
Tags { "LightMode" = "$splice(LightMode)" }
${Blending}
${Culling}
${ZTest}
${ZWrite}
${Stencil}
${ColorMask}
$splice(Blending)
$splice(Culling)
$splice(ZTest)
$splice(ZWrite)
$splice(Stencil)
$splice(ColorMask)
//-------------------------------------------------------------------------------------
// End Render Modes
//-------------------------------------------------------------------------------------

#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
//#pragma enable_d3d11_debug_symbols
#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
//#pragma enable_d3d11_debug_symbols
//-------------------------------------------------------------------------------------
// Variant Definitions (active field translations to HDRP defines)

//-------------------------------------------------------------------------------------
// Defines
//-------------------------------------------------------------------------------------
${Defines}
$splice(Defines)
// this translates the new dependency tracker into the old preprocessor definitions for the existing HDRP shader code
$AttributesMesh.normalOS: #define ATTRIBUTES_NEED_NORMAL

//-------------------------------------------------------------------------------------
// Interpolator Packing And Struct Declarations
//-------------------------------------------------------------------------------------
${InterpolatorPacking}
$buildType(AttributesMesh)
$buildType(VaryingsMeshToPS)
$buildType(VaryingsMeshToDS)
//-------------------------------------------------------------------------------------
// End Interpolator Packing And Struct Declarations
//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
${Graph}
$splice(Graph)
#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 = GetAbsolutePositionWS(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;
ZERO_INITIALIZE(FragInputs, output);
// Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).
// TODO: this is a really poor workaround, but the variable is used in a bunch of places
// to compute normals which are then passed on elsewhere to compute other values...
output.worldToTangent = k_identity3x3;
output.positionSS = input.positionCS; // input.positionCS is SV_Position
$FragInputs.positionRWS: output.positionRWS = input.positionRWS;
$FragInputs.worldToTangent: output.worldToTangent = BuildWorldToTangent(input.tangentWS, input.normalWS);
$FragInputs.texCoord0: output.texCoord0 = input.texCoord0;
$FragInputs.texCoord1: output.texCoord1 = input.texCoord1;
$FragInputs.texCoord2: output.texCoord2 = input.texCoord2;
$FragInputs.texCoord3: output.texCoord3 = input.texCoord3;
$FragInputs.color: output.color = input.color;
#if SHADER_STAGE_FRAGMENT
$FragInputs.isFrontFace: output.isFrontFace = IS_FRONT_VFACE(input.cullFace, true, false); // TODO: SHADER_STAGE_FRAGMENT only
$FragInputs.isFrontFace: // Handle handness of the view matrix (In Unity view matrix default to a determinant of -1)
$FragInputs.isFrontFace: // when we render a cubemap the view matrix handness is flipped (due to convention used for cubemap) we have a determinant of +1
$FragInputs.isFrontFace: output.isFrontFace = _DetViewMatrix < 0.0 ? output.isFrontFace : !output.isFrontFace;
#endif // SHADER_STAGE_FRAGMENT
return output;
}
SurfaceDescriptionInputs FragInputsToSurfaceDescriptionInputs(FragInputs input, float3 viewWS)
{
SurfaceDescriptionInputs output;
ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
$SurfaceDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = normalize(input.worldToTangent[2].xyz);
$SurfaceDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_M); // transposed multiplication by inverse matrix to handle normal scale
$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.ObjectSpaceTangent: output.ObjectSpaceTangent = TransformWorldToObjectDir(output.WorldSpaceTangent);
$SurfaceDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
$SurfaceDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
$SurfaceDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = input.worldToTangent[1].xyz;
$SurfaceDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = TransformWorldToObjectDir(output.WorldSpaceBiTangent);
$SurfaceDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
$SurfaceDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
$SurfaceDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = normalize(viewWS);
$SurfaceDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = TransformWorldToViewDir(output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$SurfaceDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = GetAbsolutePositionWS(input.positionRWS);
$SurfaceDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = TransformWorldToObject(input.positionRWS);
$SurfaceDescriptionInputs.ViewSpacePosition: float4 posViewSpace = TransformWorldToView(input.positionRWS);
$SurfaceDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = posViewSpace.xyz / posViewSpace.w;
$SurfaceDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionRWS), _ProjectionParams.x);
$SurfaceDescriptionInputs.uv0: output.uv0 = float4(input.texCoord0, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv1: output.uv1 = float4(input.texCoord1, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv2: output.uv2 = float4(input.texCoord2, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv3: output.uv3 = float4(input.texCoord3, 0.0f, 0.0f);
$features.modifyMesh: $include("VertexAnimation.template.hlsl")
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
$include("SharedCode.template.hlsl")
return output;
}
// existing HDRP code uses the combined function to go directly from packed to frag inputs
FragInputs UnpackVaryingsMeshToFragInputs(PackedVaryingsMeshToPS input)
{
VaryingsMeshToPS unpacked= UnpackVaryingsMeshToPS(input);
return BuildFragInputs(unpacked);
}
void BuildSurfaceData(FragInputs fragInputs, SurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData)
{

//-------------------------------------------------------------------------------------
// Pass Includes
//-------------------------------------------------------------------------------------
${Includes}
$splice(Includes)
//-------------------------------------------------------------------------------------
// End Pass Includes
//-------------------------------------------------------------------------------------

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


namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public static class HDRPShaderStructs
internal static class HDRPShaderStructs
struct AttributesMesh
internal struct AttributesMesh
{
[Semantic("POSITION")] Vector3 positionOS;
[Semantic("NORMAL")][Optional] Vector3 normalOS;

[Semantic("COLOR")][Optional] Vector4 color;
};
struct VaryingsMeshToPS
[InterpolatorPack]
internal struct VaryingsMeshToPS
{
[Semantic("SV_Position")] Vector4 positionCS;
[Optional] Vector3 positionRWS;

};
};
struct VaryingsMeshToDS
[InterpolatorPack]
internal struct VaryingsMeshToDS
{
Vector3 positionRWS;
Vector3 normalWS;

};
};
struct FragInputs
internal struct FragInputs
{
public static Dependency[] dependencies = new Dependency[]
{

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

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

}
}
}
public static void Generate(
ShaderGenerator codeResult,
HashSet<string> activeFields)
{
// propagate requirements using dependencies
{
ShaderSpliceUtil.ApplyDependencies(
activeFields,
new List<Dependency[]>()
{
FragInputs.dependencies,
VaryingsMeshToPS.standardDependencies,
SurfaceDescriptionInputs.dependencies,
VertexDescriptionInputs.dependencies
});
}
// generate code based on requirements
ShaderSpliceUtil.BuildType(typeof(AttributesMesh), activeFields, codeResult);
ShaderSpliceUtil.BuildType(typeof(VaryingsMeshToPS), activeFields, codeResult);
ShaderSpliceUtil.BuildType(typeof(VaryingsMeshToDS), activeFields, codeResult);
ShaderSpliceUtil.BuildPackedType(typeof(VaryingsMeshToPS), activeFields, codeResult);
ShaderSpliceUtil.BuildPackedType(typeof(VaryingsMeshToDS), activeFields, codeResult);
}
};
public struct Pass

{
public static bool GenerateShaderPass(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, HashSet<string> activeFields, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
{
var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);
string templatePath = Path.Combine(Path.Combine(HDUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph");
string templateLocation = Path.Combine(templatePath, pass.TemplateName);
if (!File.Exists(templateLocation))
{
// TODO: produce error here

bool debugOutput = false;
if (sourceAssetDependencyPaths != null)
sourceAssetDependencyPaths.Add(templateLocation);
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool<INode>.Get();

HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);
// apply dependencies to the active fields, and build interpolators (TODO: split this function)
var packedInterpolatorCode = new ShaderGenerator();
HDRPShaderStructs.Generate(
packedInterpolatorCode,
activeFields);
// propagate active field requirements using dependencies
ShaderSpliceUtil.ApplyDependencies(
activeFields,
new List<Dependency[]>()
{
HDRPShaderStructs.FragInputs.dependencies,
HDRPShaderStructs.VaryingsMeshToPS.standardDependencies,
HDRPShaderStructs.SurfaceDescriptionInputs.dependencies,
HDRPShaderStructs.VertexDescriptionInputs.dependencies
});
// debug output all active fields
var interpolatorDefines = new ShaderGenerator();

// 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("${Defines}", defines.GetShaderString(2, false));
namedFragments.Add("${Graph}", graph.GetShaderString(2, false));
namedFragments.Add("${LightMode}", pass.LightMode);
namedFragments.Add("${PassName}", pass.Name);
namedFragments.Add("${Includes}", shaderPassIncludes.GetShaderString(2, false));
namedFragments.Add("${InterpolatorPacking}", packedInterpolatorCode.GetShaderString(2, false));
namedFragments.Add("${Blending}", blendCode.ToString());
namedFragments.Add("${Culling}", cullCode.ToString());
namedFragments.Add("${ZTest}", zTestCode.ToString());
namedFragments.Add("${ZWrite}", zWriteCode.ToString());
namedFragments.Add("${Stencil}", stencilCode.ToString());
namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
namedFragments.Add("${LOD}", materialOptions.lod.ToString());
namedFragments.Add("Defines", defines.GetShaderString(2, false));
namedFragments.Add("Graph", graph.GetShaderString(2, false));
namedFragments.Add("LightMode", pass.LightMode);
namedFragments.Add("PassName", pass.Name);
namedFragments.Add("Includes", shaderPassIncludes.GetShaderString(2, false));
namedFragments.Add("Blending", blendCode.ToString());
namedFragments.Add("Culling", cullCode.ToString());
namedFragments.Add("ZTest", zTestCode.ToString());
namedFragments.Add("ZWrite", zWriteCode.ToString());
namedFragments.Add("Stencil", stencilCode.ToString());
namedFragments.Add("ColorMask", colorMaskCode.ToString());
namedFragments.Add("LOD", materialOptions.lod.ToString());
// this is the format string for building the 'C# qualified assembly type names' for $buildType() commands
string buildTypeAssemblyNameFormat = "UnityEditor.Experimental.Rendering.HDPipeline.HDRPShaderStructs+{0}, " + typeof(HDSubShaderUtilities).Assembly.FullName.ToString();
// process the template to generate the shader code for this pass
ShaderSpliceUtil.TemplatePreprocessor templatePreprocessor =
new ShaderSpliceUtil.TemplatePreprocessor(activeFields, namedFragments, debugOutput, templatePath, sourceAssetDependencyPaths, buildTypeAssemblyNameFormat);
// process the template to generate the shader code for this pass TODO: could make this a shared function
string[] templateLines = File.ReadAllLines(templateLocation);
System.Text.StringBuilder builder = new System.Text.StringBuilder();
foreach (string line in templateLines)
{
ShaderSpliceUtil.PreprocessShaderCode(line, activeFields, namedFragments, builder, debugOutput);
}
templatePreprocessor.ProcessTemplateFile(templateLocation);
result.AddShaderChunk(builder.ToString(), false);
result.AddShaderChunk(templatePreprocessor.GetShaderCode().ToString(), false);
return true;
}

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


Pass
{
// based on HDUnlitPassForward.template
Name "${PassName}"
Tags { "LightMode" = "${LightMode}" }
Name "$splice(PassName)"
Tags { "LightMode" = "$splice(LightMode)" }
${Blending}
${Culling}
${ZTest}
${ZWrite}
${Stencil}
${ColorMask}
$splice(Blending)
$splice(Culling)
$splice(ZTest)
$splice(ZWrite)
$splice(Stencil)
$splice(ColorMask)
//-------------------------------------------------------------------------------------
// End Render Modes
//-------------------------------------------------------------------------------------

#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
//#pragma enable_d3d11_debug_symbols
#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
//#pragma enable_d3d11_debug_symbols
//-------------------------------------------------------------------------------------
// Variant Definitions (active field translations to HDRP defines)

//-------------------------------------------------------------------------------------
// Defines
//-------------------------------------------------------------------------------------
${Defines}
$splice(Defines)
// this translates the new dependency tracker into the old preprocessor definitions for the existing HDRP shader code
$AttributesMesh.normalOS: #define ATTRIBUTES_NEED_NORMAL

//-------------------------------------------------------------------------------------
// Interpolator Packing And Struct Declarations
//-------------------------------------------------------------------------------------
${InterpolatorPacking}
$buildType(AttributesMesh)
$buildType(VaryingsMeshToPS)
$buildType(VaryingsMeshToDS)
//-------------------------------------------------------------------------------------
// End Interpolator Packing And Struct Declarations
//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
${Graph}
$splice(Graph)
#ifdef HAVE_MESH_MODIFICATION
// TODO: we should share this between template files somehow
VertexDescriptionInputs AttributesMeshToVertexDescriptionInputs(AttributesMesh input)
{
VertexDescriptionInputs output;
ZERO_INITIALIZE(VertexDescriptionInputs, output);
$features.modifyMesh: $include("VertexAnimation.template.hlsl")
$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 = GetAbsolutePositionWS(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;
$include("SharedCode.template.hlsl")
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;
ZERO_INITIALIZE(FragInputs, output);
// Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).
// TODO: this is a really poor workaround, but the variable is used in a bunch of places
// to compute normals which are then passed on elsewhere to compute other values...
output.worldToTangent = k_identity3x3;
output.positionSS = input.positionCS; // input.positionCS is SV_Position
$FragInputs.positionRWS: output.positionRWS = input.positionRWS;
$FragInputs.worldToTangent: output.worldToTangent = BuildWorldToTangent(input.tangentWS, input.normalWS);
$FragInputs.texCoord0: output.texCoord0 = input.texCoord0;
$FragInputs.texCoord1: output.texCoord1 = input.texCoord1;
$FragInputs.texCoord2: output.texCoord2 = input.texCoord2;
$FragInputs.texCoord3: output.texCoord3 = input.texCoord3;
$FragInputs.color: output.color = input.color;
#if SHADER_STAGE_FRAGMENT
$FragInputs.isFrontFace: output.isFrontFace = IS_FRONT_VFACE(input.cullFace, true, false); // TODO: SHADER_STAGE_FRAGMENT only
$FragInputs.isFrontFace: // Handle handness of the view matrix (In Unity view matrix default to a determinant of -1)
$FragInputs.isFrontFace: // when we render a cubemap the view matrix handness is flipped (due to convention used for cubemap) we have a determinant of +1
$FragInputs.isFrontFace: output.isFrontFace = _DetViewMatrix < 0.0 ? output.isFrontFace : !output.isFrontFace;
#endif // SHADER_STAGE_FRAGMENT
return output;
}
SurfaceDescriptionInputs FragInputsToSurfaceDescriptionInputs(FragInputs input, float3 viewWS)
{
SurfaceDescriptionInputs output;
ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
$SurfaceDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = normalize(input.worldToTangent[2].xyz);
$SurfaceDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_M); // transposed multiplication by inverse matrix to handle normal scale
$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.ObjectSpaceTangent: output.ObjectSpaceTangent = TransformWorldToObjectDir(output.WorldSpaceTangent);
$SurfaceDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
$SurfaceDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
$SurfaceDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = input.worldToTangent[1].xyz;
$SurfaceDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = TransformWorldToObjectDir(output.WorldSpaceBiTangent);
$SurfaceDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
$SurfaceDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
$SurfaceDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = normalize(viewWS);
$SurfaceDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = TransformWorldToViewDir(output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$SurfaceDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = GetAbsolutePositionWS(input.positionRWS);
$SurfaceDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = TransformWorldToObject(input.positionRWS);
$SurfaceDescriptionInputs.ViewSpacePosition: float4 posViewSpace = TransformWorldToView(input.positionRWS);
$SurfaceDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = posViewSpace.xyz / posViewSpace.w;
$SurfaceDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionRWS), _ProjectionParams.x);
$SurfaceDescriptionInputs.uv0: output.uv0 = float4(input.texCoord0, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv1: output.uv1 = float4(input.texCoord1, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv2: output.uv2 = float4(input.texCoord2, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv3: output.uv3 = float4(input.texCoord3, 0.0f, 0.0f);
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
return output;
}
// existing HDRP code uses the combined function to go directly from packed to frag inputs
FragInputs UnpackVaryingsMeshToFragInputs(PackedVaryingsMeshToPS input)
{
VaryingsMeshToPS unpacked= UnpackVaryingsMeshToPS(input);
return BuildFragInputs(unpacked);
}
void BuildSurfaceData(FragInputs fragInputs, SurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData)
{

//-------------------------------------------------------------------------------------
// Pass Includes
//-------------------------------------------------------------------------------------
${Includes}
$splice(Includes)
//-------------------------------------------------------------------------------------
// End Pass Includes
//-------------------------------------------------------------------------------------

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


public void PushColorPickerDebugTexture(CommandBuffer cmd, RTHandleSystem.RTHandle textureID, HDCamera hdCamera)
{
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None || m_DebugDisplaySettings.falseColorDebugSettings.falseColor)
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None || m_DebugDisplaySettings.falseColorDebugSettings.falseColor || m_DebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.LuminanceMeter)
{
using (new ProfilingSample(cmd, "Push To Color Picker"))
{

// TODO TEMP: Not sure I want to keep this special case. Gotta see how to get rid of it (not sure it will work correctly for non-full viewports.
public void PushColorPickerDebugTexture(HDCamera hdCamera, CommandBuffer cmd, RenderTargetIdentifier textureID)
{
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None || m_DebugDisplaySettings.falseColorDebugSettings.falseColor)
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None || m_DebugDisplaySettings.falseColorDebugSettings.falseColor || m_DebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.LuminanceMeter)
{
using (new ProfilingSample(cmd, "Push To Color Picker"))
{

DecalSystem.instance.RenderDebugOverlay(hdCamera, cmd, m_CurrentDebugDisplaySettings, ref x, ref y, overlaySize, hdCamera.actualWidth);
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None || m_CurrentDebugDisplaySettings.falseColorDebugSettings.falseColor)
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None || m_CurrentDebugDisplaySettings.falseColorDebugSettings.falseColor || m_CurrentDebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.LuminanceMeter)
{
ColorPickerDebugSettings colorPickerDebugSettings = m_CurrentDebugDisplaySettings.colorPickerDebugSettings;
FalseColorDebugSettings falseColorDebugSettings = m_CurrentDebugDisplaySettings.falseColorDebugSettings;

7
com.unity.render-pipelines.lightweight/CHANGELOG.md


and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [3.2.0-preview]
### Changed
- The UI for Lightweight asset has been updated with new categories. A more clean structure and foldouts has been added to keep things organized.
### Fixed
- Scriptable passes no longer have missing material references. Now they access cached materials in the renderer.(case 1061353)
- When you change a Shadow Cascade option in the Pipeline Asset, this no longer warns you that you've exceeded the array size for the _WorldToShadow property.
- Terrain shader optimizations.
## [3.1.0-preview]

18
com.unity.render-pipelines.lightweight/LWRP/DefaultRendererSetup.cs


[NonSerialized]
private bool m_Initialized = false;
private void Init(LightweightForwardRenderer renderer)
private void Init()
{
if (m_Initialized)
return;

m_LocalShadowPass = new LocalShadowsPass();
m_SetupForwardRenderingPass = new SetupForwardRenderingPass();
m_ScreenSpaceShadowResovePass = new ScreenSpaceShadowResolvePass(renderer.GetMaterial(MaterialHandles.ScrenSpaceShadow));
m_ScreenSpaceShadowResovePass = new ScreenSpaceShadowResolvePass();
m_RenderOpaqueForwardPass = new RenderOpaqueForwardPass(renderer.GetMaterial(MaterialHandles.Error));
m_RenderOpaqueForwardPass = new RenderOpaqueForwardPass();
m_CopyDepthPass = new CopyDepthPass(renderer.GetMaterial(MaterialHandles.DepthCopy));
m_CopyColorPass = new CopyColorPass(renderer.GetMaterial(MaterialHandles.Sampling));
m_RenderTransparentForwardPass = new RenderTransparentForwardPass(renderer.GetMaterial(MaterialHandles.Error));
m_CopyDepthPass = new CopyDepthPass();
m_CopyColorPass = new CopyColorPass();
m_RenderTransparentForwardPass = new RenderTransparentForwardPass();
m_FinalBlitPass = new FinalBlitPass(renderer.GetMaterial(MaterialHandles.Blit));
m_FinalBlitPass = new FinalBlitPass();
m_SceneViewDepthCopyPass = new SceneViewDepthCopyPass(renderer.GetMaterial(MaterialHandles.DepthCopy));
m_SceneViewDepthCopyPass = new SceneViewDepthCopyPass();
#endif
// RenderTexture format depends on camera and pipeline (HDR, non HDR, etc)

public void Setup(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults, ref RenderingData renderingData)
{
Init(renderer);
Init();
renderer.Clear();

130
com.unity.render-pipelines.lightweight/LWRP/Editor/LightweightPipelineAssetEditor.cs


[CustomEditor(typeof(LightweightPipelineAsset))]
public class LightweightPipelineAssetEditor : Editor
{
bool generalSettingsFoldout = false;
bool qualitySettingsFoldout = false;
bool shadowsSettingsFoldout = false;
public static GUIContent renderingLabel = new GUIContent("Rendering");
public static GUIContent qualityLabel = new GUIContent("Quality");
public static GUIContent capabilitiesLabel = new GUIContent("Capabilities");
public static GUIContent featuresLabel = new GUIContent("Shader Features");
public static GUIContent renderScaleLabel = new GUIContent("Render Scale", "Scales the camera render target allowing the game to render at a resolution different than native resolution. UI is always rendered at native resolution.");

SerializedProperty m_CustomShaderVariantStripSettingsProp;
SerializedProperty m_XRConfig;
public override void OnInspectorGUI()
{
serializedObject.Update();

DrawCapabilitiesSettings();
DrawShaderFeaturesSettings();
DrawQualitySettings();
DrawShadowSettings();
EditorGUILayout.PropertyField(m_XRConfig);
serializedObject.ApplyModifiedProperties();

{
{
m_RenderScale = serializedObject.FindProperty("m_RenderScale");
m_MaxPixelLights = serializedObject.FindProperty("m_MaxPixelLights");
m_SupportsVertexLightProp = serializedObject.FindProperty("m_SupportsVertexLight");

m_ShowOpaqueTextureScale.valueChanged.AddListener(Repaint);
m_ShowOpaqueTextureScale.value = m_RequireOpaqueTextureProp.boolValue;
m_XRConfig = serializedObject.FindProperty("m_SavedXRConfig");
}
void OnDisable()

m_ShowOpaqueTextureScale.target = m_RequireOpaqueTextureProp.boolValue;
}
void DrawGeneralSettings()
void DrawShaderFeaturesSettings()
EditorGUILayout.LabelField(Styles.generalSettingsLabel, EditorStyles.boldLabel);
EditorGUILayout.LabelField(Styles.featuresLabel, EditorStyles.boldLabel);
m_RenderScale.floatValue = EditorGUILayout.Slider(Styles.renderScaleLabel, m_RenderScale.floatValue, k_MinRenderScale, k_MaxRenderScale);
m_MaxPixelLights.intValue = EditorGUILayout.IntSlider(Styles.maxPixelLightsLabel, m_MaxPixelLights.intValue, 0, k_MaxSupportedPixelLights);
EditorGUILayout.PropertyField(m_SupportsVertexLightProp, Styles.enableVertexLightLabel);
EditorGUILayout.PropertyField(m_DirectionalShadowsSupportedProp, Styles.supportsDirectionalShadows);
EditorGUILayout.PropertyField(m_LocalShadowSupportedProp, Styles.supportsLocalShadows);
EditorGUI.BeginDisabledGroup(!(m_DirectionalShadowsSupportedProp.boolValue || m_LocalShadowSupportedProp.boolValue));
EditorGUILayout.PropertyField(m_SoftShadowsSupportedProp, Styles.supportsSoftShadows);
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
bool directionalShadows = m_DirectionalShadowsSupportedProp.boolValue;
if (directionalShadows)
void DrawGeneralSettings()
{
generalSettingsFoldout = EditorGUILayout.Foldout(generalSettingsFoldout, Styles.generalSettingsLabel, true);
if (generalSettingsFoldout)
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_SupportsDynamicBatching, Styles.dynamicBatching);
EditorGUILayout.PropertyField(m_RequireDepthTextureProp, Styles.requireDepthTexture);
EditorGUI.BeginDisabledGroup(!m_RequireDepthTextureProp.boolValue);
EditorGUILayout.PropertyField(m_RequireSoftParticlesProp, Styles.requireSoftParticles);
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(m_RequireOpaqueTextureProp, Styles.requireOpaqueTexture);
EditorGUI.indentLevel++;
EditorGUI.BeginDisabledGroup(!m_RequireOpaqueTextureProp.boolValue);
EditorGUILayout.PropertyField(m_OpaqueDownsamplingProp, Styles.opaqueDownsampling);
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.Space();
}
}
void DrawQualitySettings()
{
qualitySettingsFoldout = EditorGUILayout.Foldout(qualitySettingsFoldout, Styles.qualityLabel, true);
if (qualitySettingsFoldout)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_HDR, Styles.hdrContent);
EditorGUILayout.PropertyField(m_MSAA, Styles.msaaContent);
m_RenderScale.floatValue = EditorGUILayout.Slider(Styles.renderScaleLabel, m_RenderScale.floatValue, k_MinRenderScale, k_MaxRenderScale);
m_MaxPixelLights.intValue = EditorGUILayout.IntSlider(Styles.maxPixelLightsLabel, m_MaxPixelLights.intValue, 0, k_MaxSupportedPixelLights);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.Space();
}
}
void DrawShadowSettings()
{
shadowsSettingsFoldout = EditorGUILayout.Foldout(shadowsSettingsFoldout, Styles.shadowLabel, true);
if (shadowsSettingsFoldout)
{
// Directional Shadows
EditorGUI.BeginDisabledGroup(!m_DirectionalShadowsSupportedProp.boolValue);
EditorGUI.indentLevel++;
EditorGUILayout.LabelField(Styles.directionalShadowLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_DirectionalShadowAtlasResolutionProp, Styles.directionalShadowAtlasResolution);

EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
EditorGUI.EndDisabledGroup();
bool localShadows = m_LocalShadowSupportedProp.boolValue;
if (localShadows)
{
// Local Shadows
EditorGUI.BeginDisabledGroup(!m_LocalShadowSupportedProp.boolValue);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
EditorGUI.EndDisabledGroup();
if (directionalShadows || localShadows)
EditorGUILayout.PropertyField(m_SoftShadowsSupportedProp, Styles.supportsSoftShadows);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.Space();
void DrawCapabilitiesSettings()
{
EditorGUILayout.LabelField(Styles.capabilitiesLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_SupportsVertexLightProp, Styles.enableVertexLightLabel);
EditorGUILayout.PropertyField(m_RequireDepthTextureProp, Styles.requireDepthTexture);
EditorGUI.BeginDisabledGroup(!m_RequireDepthTextureProp.boolValue);
EditorGUILayout.PropertyField(m_RequireSoftParticlesProp, Styles.requireSoftParticles);
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(m_RequireOpaqueTextureProp, Styles.requireOpaqueTexture);
EditorGUI.indentLevel++;
EditorGUI.BeginDisabledGroup(!m_RequireOpaqueTextureProp.boolValue);
EditorGUILayout.PropertyField(m_OpaqueDownsamplingProp, Styles.opaqueDownsampling);
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(m_HDR, Styles.hdrContent);
EditorGUILayout.PropertyField(m_MSAA, Styles.msaaContent);
EditorGUILayout.PropertyField(m_SupportsDynamicBatching, Styles.dynamicBatching);
EditorGUILayout.PropertyField(m_DirectionalShadowsSupportedProp, Styles.supportsDirectionalShadows);
EditorGUILayout.PropertyField(m_LocalShadowSupportedProp, Styles.supportsLocalShadows);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.Space();
}
}
}

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


using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;

public void Execute(ref ScriptableRenderContext context, ref CullResults cullResults, ref RenderingData renderingData)
{
for (int i = 0; i < m_ActiveRenderPassQueue.Count; ++i)
m_ActiveRenderPassQueue[i].Execute(ref context, ref cullResults, ref renderingData);
m_ActiveRenderPassQueue[i].Execute(this, ref context, ref cullResults, ref renderingData);
public Material GetMaterial(MaterialHandles handle)
{
int handleID = (int)handle;

3
com.unity.render-pipelines.lightweight/LWRP/Passes/BeginXRRenderingPass.cs


{
public class BeginXRRenderingPass : ScriptableRenderPass
{
public override void Execute(ref ScriptableRenderContext context, ref CullResults cullResults,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{
Camera camera = renderingData.cameraData.camera;

10
com.unity.render-pipelines.lightweight/LWRP/Passes/CopyColorPass.cs


private RenderTargetHandle source { get; set; }
private RenderTargetHandle destination { get; set; }
private Material samplingMaterial { get; set; }
public CopyColorPass(Material samplingMaterial)
public CopyColorPass()
this.samplingMaterial = samplingMaterial;
m_SampleOffsetShaderHandle = Shader.PropertyToID("_SampleOffset");
}

this.destination = destination;
}
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

cmd.Blit(colorRT, opaqueColorRT);
break;
case Downsampling._4xBox:
Material samplingMaterial = renderer.GetMaterial(MaterialHandles.Sampling);
samplingMaterial.SetFloat(m_SampleOffsetShaderHandle, 2);
cmd.Blit(colorRT, opaqueColorRT, samplingMaterial, 0);
break;

}
}
}
}

12
com.unity.render-pipelines.lightweight/LWRP/Passes/CopyDepthPass.cs


{
private RenderTargetHandle source { get; set; }
private RenderTargetHandle destination { get; set; }
private Material depthCopyMaterial { get; set; }
public CopyDepthPass(Material depthCopyMaterial)
{
this.depthCopyMaterial = depthCopyMaterial;
}
const string k_DepthCopyTag = "Depth Copy";
public void Setup(RenderTargetHandle source, RenderTargetHandle destination)
{

public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
CommandBuffer cmd = CommandBufferPool.Get("Depth Copy");
CommandBuffer cmd = CommandBufferPool.Get(k_DepthCopyTag);
Material depthCopyMaterial = renderer.GetMaterial(MaterialHandles.DepthCopy);
RenderTextureDescriptor descriptor = LightweightForwardRenderer.CreateRTDesc(ref renderingData.cameraData);
descriptor.colorFormat = RenderTextureFormat.Depth;

2
com.unity.render-pipelines.lightweight/LWRP/Passes/CreateLightweightRenderTexturesPass.cs


descriptor = baseDescriptor;
}
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

2
com.unity.render-pipelines.lightweight/LWRP/Passes/DepthOnlyPass.cs


};
}
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

7
com.unity.render-pipelines.lightweight/LWRP/Passes/DirectionalShadowsPass.cs


this.destination = destination;
}
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
cmd.SetGlobalTexture(destination.id, m_DirectionalShadowmapTexture);
if (shadowData.directionalLightCascadeCount > 1)
cmd.SetGlobalMatrixArray(DirectionalShadowConstantBuffer._WorldToShadow, m_DirectionalShadowMatrices);
else
cmd.SetGlobalMatrix(DirectionalShadowConstantBuffer._WorldToShadow, m_DirectionalShadowMatrices[0]);
cmd.SetGlobalMatrixArray(DirectionalShadowConstantBuffer._WorldToShadow, m_DirectionalShadowMatrices);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowData, new Vector4(light.shadowStrength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._DirShadowSplitSpheres0, m_CascadeSplitDistances[0]);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._DirShadowSplitSpheres1, m_CascadeSplitDistances[1]);

2
com.unity.render-pipelines.lightweight/LWRP/Passes/DrawSkyboxPass.cs


{
public class DrawSkyboxPass : ScriptableRenderPass
{
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

2
com.unity.render-pipelines.lightweight/LWRP/Passes/EndXRRenderingPass.cs


{
public class EndXRRenderingPass : ScriptableRenderPass
{
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

16
com.unity.render-pipelines.lightweight/LWRP/Passes/FinalBlitPass.cs


{
public class FinalBlitPass : ScriptableRenderPass
{
const string k_FinalBlitTag = "Final Blit Pass";
private Material blitMaterial { get; set; }
public FinalBlitPass(Material blitMaterial)
{
this.blitMaterial = blitMaterial;
}
public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorAttachmentHandle)
{
this.colorAttachmentHandle = colorAttachmentHandle;

public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
Material material = renderingData.cameraData.isStereoEnabled ? null : blitMaterial;
Material material = renderingData.cameraData.isStereoEnabled ? null : renderer.GetMaterial(MaterialHandles.Blit);
CommandBuffer cmd = CommandBufferPool.Get("Final Blit Pass");
CommandBuffer cmd = CommandBufferPool.Get(k_FinalBlitTag);
cmd.SetGlobalTexture("_BlitTex", sourceRT);
// We need to handle viewport on a RT. We do it by rendering a fullscreen quad + viewport

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


private RenderTargetHandle colorAttachmentHandle { get; set; }
private RenderTargetHandle depthAttachmentHandle { get; set; }
private RenderTextureDescriptor descriptor { get; set; }
private Material errorMaterial { get; set; }
const string k_SwitchRTs = "Switch RT";
protected LightweightForwardPass(Material errorMaterial)
protected LightweightForwardPass()
{
m_LegacyShaderPassNames = new List<ShaderPassName>();
m_LegacyShaderPassNames.Add(new ShaderPassName("Always"));

m_LegacyShaderPassNames.Add(new ShaderPassName("VertexLMRGBM"));
m_LegacyShaderPassNames.Add(new ShaderPassName("VertexLM"));
this.errorMaterial = errorMaterial;
RegisterShaderPassName("LightweightForward");
RegisterShaderPassName("SRPDefaultUnlit");

}
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
protected void RenderObjectsWithError(ref ScriptableRenderContext context, ref CullResults cullResults, Camera camera, FilterRenderersSettings filterSettings, SortFlags sortFlags)
protected void RenderObjectsWithError(LightweightForwardRenderer renderer, ref ScriptableRenderContext context, ref CullResults cullResults, Camera camera, FilterRenderersSettings filterSettings, SortFlags sortFlags)
Material errorMaterial = renderer.GetMaterial(MaterialHandles.Error);
if (errorMaterial != null)
{
DrawRendererSettings errorSettings = new DrawRendererSettings(camera, m_LegacyShaderPassNames[0]);

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


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

}
}
public override void Execute(ref ScriptableRenderContext context, ref CullResults cullResults,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{
if (renderingData.shadowData.renderLocalShadows)

3
com.unity.render-pipelines.lightweight/LWRP/Passes/OpaquePostProcessPass.cs


descriptor = baseDescriptor;
}
public override void Execute(ref ScriptableRenderContext context, ref CullResults cullResults,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("Render Opaque PostProcess Effects");

9
com.unity.render-pipelines.lightweight/LWRP/Passes/RenderOpaqueForwardPass.cs


const string k_RenderOpaquesTag = "Render Opaques";
public FilterRenderersSettings opaqueFilterSettings { get; private set; }
public RenderOpaqueForwardPass(Material errorMaterial) : base(errorMaterial)
public RenderOpaqueForwardPass()
{
opaqueFilterSettings = new FilterRenderersSettings(true)
{

public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

SetRenderTarget(cmd, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, clearFlag, CoreUtils.ConvertSRGBToActiveColorSpace(clearColor));
// TODO: We need a proper way to handle multiple camera/ camera stack. Issue is: multiple cameras can share a same RT

// cmd.SetViewport(camera.pixelRect);
Camera camera = renderingData.cameraData.camera;
var drawSettings = CreateDrawRendererSettings(camera, SortFlags.CommonOpaque, rendererConfiguration, dynamicBatching);

RenderObjectsWithError(ref context, ref cullResults, camera, opaqueFilterSettings, SortFlags.None);
RenderObjectsWithError(renderer, ref context, ref cullResults, camera, opaqueFilterSettings, SortFlags.None);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);

7
com.unity.render-pipelines.lightweight/LWRP/Passes/RenderTransparentForwardPass.cs


private FilterRenderersSettings transparentFilterSettings { get; set; }
public RenderTransparentForwardPass(Material errorMaterial) : base(errorMaterial)
public RenderTransparentForwardPass()
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

context.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, transparentFilterSettings);
// Render objects that did not match any shader pass with error shader
RenderObjectsWithError(ref context, ref cullResults, camera, transparentFilterSettings, SortFlags.None);
RenderObjectsWithError(renderer, ref context, ref cullResults, camera, transparentFilterSettings, SortFlags.None);
}
context.ExecuteCommandBuffer(cmd);

16
com.unity.render-pipelines.lightweight/LWRP/Passes/SceneViewDepthCopy.cs


{
public class SceneViewDepthCopyPass : ScriptableRenderPass
{
private RenderTargetHandle source { get; set; }
private Material depthCopyMaterial { get; set; }
const string k_CopyDepthToCameraTag = "Copy Depth to Camera";
public SceneViewDepthCopyPass(Material depthCopyMaterial)
{
this.depthCopyMaterial = depthCopyMaterial;
}
private RenderTargetHandle source { get; set; }
public void Setup(RenderTargetHandle source)
{

public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
CommandBuffer cmd = CommandBufferPool.Get("Copy Depth to Camera");
CommandBuffer cmd = CommandBufferPool.Get(k_CopyDepthToCameraTag);
cmd.Blit(source.Identifier(), BuiltinRenderTextureType.CameraTarget, depthCopyMaterial);
cmd.Blit(source.Identifier(), BuiltinRenderTextureType.CameraTarget, renderer.GetMaterial(MaterialHandles.DepthCopy));
}
}

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


public class ScreenSpaceShadowResolvePass : ScriptableRenderPass
{
RenderTextureFormat m_ColorFormat;
private Material screenSpaceShadowsMaterial { get; set; }
public ScreenSpaceShadowResolvePass(Material screenSpaceShadowsMaterial)
public ScreenSpaceShadowResolvePass()
this.screenSpaceShadowsMaterial = screenSpaceShadowsMaterial;
}
private RenderTargetHandle colorAttachmentHandle { get; set; }

descriptor = baseDescriptor;
}
public override void Execute(ref ScriptableRenderContext context, ref CullResults cullResults,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{
if (renderingData.shadowData.renderedDirectionalShadowQuality == LightShadows.None)

RenderTargetIdentifier screenSpaceOcclusionTexture = colorAttachmentHandle.Identifier();
SetRenderTarget(cmd, screenSpaceOcclusionTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
ClearFlag.Color | ClearFlag.Depth, Color.white, descriptor.dimension);
cmd.Blit(screenSpaceOcclusionTexture, screenSpaceOcclusionTexture, screenSpaceShadowsMaterial);
cmd.Blit(screenSpaceOcclusionTexture, screenSpaceOcclusionTexture, renderer.GetMaterial(MaterialHandles.ScrenSpaceShadow));
if (renderingData.cameraData.isStereoEnabled)
{

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


public virtual void FrameCleanup(CommandBuffer cmd)
{}
public abstract void Execute(ref ScriptableRenderContext context,
public abstract void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData);

3
com.unity.render-pipelines.lightweight/LWRP/Passes/SetupForwardRenderingPass.cs


{
public class SetupForwardRenderingPass : ScriptableRenderPass
{
public override void Execute(ref ScriptableRenderContext context, ref CullResults cullResults,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{
// SetupCameraProperties does the following:

2
com.unity.render-pipelines.lightweight/LWRP/Passes/SetupLightweightConstanstPass.cs


CoreUtils.SetKeyword(cmd, "SOFTPARTICLES_ON", cameraData.requiresSoftParticles);
}
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

2
com.unity.render-pipelines.lightweight/LWRP/Passes/TransparentPostProcessPass.cs


descriptor = baseDescriptor;
}
public override void Execute(ref ScriptableRenderContext context,
public override void Execute(LightweightForwardRenderer renderer, ref ScriptableRenderContext context,
ref CullResults cullResults,
ref RenderingData renderingData)
{

7
com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Shadows.hlsl


// Last cascade is initialized with a no-op matrix. It always transforms
// shadow coord to half(0, 0, NEAR_PLANE). We use this trick to avoid
// branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES
#ifdef _SHADOWS_CASCADE
#else
float4x4 _WorldToShadow;
#endif
float4 _DirShadowSplitSpheres0;
float4 _DirShadowSplitSpheres1;
float4 _DirShadowSplitSpheres2;

half ComputeCascadeIndex(float3 positionWS)
{
// TODO: profile if there's a performance improvement if we avoid indexing here
float3 fromCenter0 = positionWS - _DirShadowSplitSpheres0.xyz;
float3 fromCenter1 = positionWS - _DirShadowSplitSpheres1.xyz;
float3 fromCenter2 = positionWS - _DirShadowSplitSpheres2.xyz;

half cascadeIndex = ComputeCascadeIndex(positionWS);
return mul(_WorldToShadow[cascadeIndex], float4(positionWS, 1.0));
#else
return mul(_WorldToShadow, float4(positionWS, 1.0));
return mul(_WorldToShadow[0], float4(positionWS, 1.0));
#endif
}

92
com.unity.render-pipelines.lightweight/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl


float4 uvSplat01 : TEXCOORD0; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD1; // xy: splat2, zw: splat3
float4 uvControlAndLM : TEXCOORD2; // xy: control, zw: lightmap
#if _TERRAIN_NORMAL_MAP
half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
half4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
half4 binormal : TEXCOORD5; // xyz: binormal, w: viewDir.z
#else
#if _TERRAIN_NORMAL_MAP
half3 tangent : TEXCOORD4;
half3 binormal : TEXCOORD5;
half3 viewDir : TEXCOORD4;
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float3 positionWS : TEXCOORD7;
float4 shadowCoord : TEXCOORD8;

input.positionWS = IN.positionWS;
#ifdef _TERRAIN_NORMAL_MAP
input.normalWS = TangentToWorldNormal(normalTS, IN.tangent, IN.binormal, IN.normal);
half3 viewDir = half3(IN.normal.w, IN.tangent.w, IN.binormal.w);
input.normalWS = TangentToWorldNormal(normalTS, IN.tangent.xyz, IN.binormal.xyz, IN.normal.xyz);
input.normalWS = normalize(IN.normal);
half3 viewDir = IN.viewDir;
input.normalWS = FragmentNormalWS(IN.normal);
input.viewDirectionWS = SafeNormalize(GetCameraPositionWS() - IN.positionWS);
input.viewDirectionWS = FragmentViewDirWS(viewDir);
#ifdef _SHADOWS_ENABLED
input.shadowCoord = IN.shadowCoord;
#else

#endif
}
void SplatmapMix(VertexOutput IN, half4 defaultAlpha, out half4 splat_control, out half weight, out half4 mixedDiffuse, inout half3 mixedNormal)
void SplatmapMix(VertexOutput IN, half4 defaultAlpha, out half4 splatControl, out half weight, out half4 mixedDiffuse, inout half3 mixedNormal)
splat_control = SAMPLE_TEXTURE2D(_Control, sampler_Control, IN.uvControlAndLM.xy);
weight = dot(splat_control, 1);
splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, IN.uvControlAndLM.xy);
weight = dot(splatControl, 1.0h);
clip(weight == 0.0f ? -1 : 1);
clip(weight == 0.0h ? -1.0h : 1.0h);
splat_control /= (weight + 1e-3f);
splatControl /= (weight + HALF_MIN);
mixedDiffuse = 0.0f;
mixedDiffuse += splat_control.r * SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, IN.uvSplat01.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.r);
mixedDiffuse += splat_control.g * SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, IN.uvSplat01.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.g);
mixedDiffuse += splat_control.b * SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, IN.uvSplat23.xy) * half4(1.0, 1.0, 1.0, defaultAlpha.b);
mixedDiffuse += splat_control.a * SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, IN.uvSplat23.zw) * half4(1.0, 1.0, 1.0, defaultAlpha.a);
half4 alpha = defaultAlpha * splatControl;
mixedDiffuse = 0.0h;
mixedDiffuse += SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, IN.uvSplat01.xy) * half4(splatControl.rrr, alpha.r);
mixedDiffuse += SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, IN.uvSplat01.zw) * half4(splatControl.ggg, alpha.g);
mixedDiffuse += SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, IN.uvSplat23.xy) * half4(splatControl.bbb, alpha.b);
mixedDiffuse += SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, IN.uvSplat23.zw) * half4(splatControl.aaa, alpha.a);
nrm += splat_control.r * SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, IN.uvSplat01.xy);
nrm += splat_control.g * SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, IN.uvSplat01.zw);
nrm += splat_control.b * SAMPLE_TEXTURE2D(_Normal2, sampler_Normal0, IN.uvSplat23.xy);
nrm += splat_control.a * SAMPLE_TEXTURE2D(_Normal3, sampler_Normal0, IN.uvSplat23.zw);
nrm += SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, IN.uvSplat01.xy) * splatControl.r;
nrm += SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, IN.uvSplat01.zw) * splatControl.g;
nrm += SAMPLE_TEXTURE2D(_Normal2, sampler_Normal0, IN.uvSplat23.xy) * splatControl.b;
nrm += SAMPLE_TEXTURE2D(_Normal3, sampler_Normal0, IN.uvSplat23.zw) * splatControl.a;
mixedNormal = half3(0, 0, 1);
mixedNormal = half3(0.0h, 0.0h, 1.0h);
#endif
}

#ifdef TERRAIN_SPLAT_ADDPASS
ApplyFogColor(color.rgb, half3(0,0,0), fogCoord);
#else
ApplyFog(color.rgb, fogCoord);
#endif
#ifdef TERRAIN_SPLAT_ADDPASS
ApplyFogColor(color.rgb, half3(0.0h, 0.0h, 0.0h), fogCoord);
#else
ApplyFog(color.rgb, fogCoord);
#endif
}
///////////////////////////////////////////////////////////////////////////////

o.uvControlAndLM.xy = TRANSFORM_TEX(v.texcoord, _Control);
o.uvControlAndLM.zw = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
half3 viewDir = VertexViewDirWS(GetCameraPositionWS() - positionWS.xyz);
OutputTangentToWorld(vertexTangent, v.normal, o.tangent, o.binormal, o.normal);
OutputTangentToWorld(vertexTangent, v.normal, o.tangent.xyz, o.binormal.xyz, o.normal.xyz);
o.normal.w = viewDir.x;
o.tangent.w = viewDir.y;
o.binormal.w = viewDir.z;
o.viewDir = viewDir;
#endif
o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
o.fogFactorAndVertexLight.yzw = VertexLighting(positionWS, o.normal);

#ifdef _SHADOWS_ENABLED
#if SHADOWS_SCREEN
o.shadowCoord = ComputeShadowCoord(o.clipPos);
#else
o.shadowCoord = TransformWorldToShadowCoord(positionWS);
#endif
#if SHADOWS_SCREEN
o.shadowCoord = ComputeShadowCoord(o.clipPos);
#else
o.shadowCoord = TransformWorldToShadowCoord(positionWS);
#endif
#endif
return o;

half4 SpatmapFragment(VertexOutput IN) : SV_TARGET
{
half4 splat_control;
half4 splatControl;
SplatmapMix(IN, defaultSmoothness, splat_control, weight, mixedDiffuse, normalTS);
SplatmapMix(IN, defaultSmoothness, splatControl, weight, mixedDiffuse, normalTS);
half metallic = dot(splat_control, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
half3 specular = half3(0, 0, 0);
half metallic = dot(splatControl, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
half3 specular = half3(0.0h, 0.0h, 0.0h);
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, specular, smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
half4 color = LightweightFragmentPBR(inputData, albedo, metallic, specular, smoothness, /* occlusion */ 1.0h, /* emission */ half3(0.0h, 0.0h, 0.0h), alpha);
return half4(color.rgb, 1);
return half4(color.rgb, 1.0h);
}
#endif // LIGHTWEIGHT_PASS_LIT_TERRAIN_INCLUDED

6
com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs


if (nodeList.Contains(node))
return;
var ids = node.GetInputSlots<ISlot>().Select(x => x.id);
if (slotIds != null)
IEnumerable<int> ids;
if (slotIds == null)
ids = node.GetInputSlots<ISlot>().Select(x => x.id);
else
ids = node.GetInputSlots<ISlot>().Where(x => slotIds.Contains(x.id)).Select(x => x.id);
foreach (var slot in ids)

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


}
};
[System.AttributeUsage(System.AttributeTargets.Struct)]
public class InterpolatorPack : System.Attribute
{
public InterpolatorPack()
{
}
}
// attribute used to flag a field as needing an HLSL semantic applied
// i.e. float3 position : POSITION;
// ^ semantic

}
result.Deindent();
result.AddShaderChunk("};");
object[] packAttributes = t.GetCustomAttributes(typeof(InterpolatorPack), false);
if (packAttributes.Length > 0)
{
BuildPackedType(t, activeFields, result);
}
}
public static void BuildPackedType(System.Type unpacked, HashSet<string> activeFields, ShaderGenerator result)

result.AddGenerator(unpacker);
}
// an easier to use version of substring Append() -- explicit inclusion on each end, and checks for positive length
private static void AppendSubstring(System.Text.StringBuilder target, string str, int start, bool includeStart, int end, bool includeEnd)
{
if (!includeStart)
{
start++;
}
if (!includeEnd)
{
end--;
}
int count = end - start + 1;
if (count > 0)
{
target.Append(str, start, count);
}
}
// returns the offset of the first non-whitespace character, in the range [start, end] inclusive ... will return end if none found
private static int SkipWhitespace(string str, int start, int end)
{

return index;
}
public static System.Text.StringBuilder PreprocessShaderCode(string code, HashSet<string> activeFields, Dictionary<string, string> namedFragments, System.Text.StringBuilder result, bool debugOutput)
public class TemplatePreprocessor
if (result == null)
// inputs
HashSet<string> activeFields;
Dictionary<string, string> namedFragments;
string templatePath;
bool debugOutput;
string buildTypeAssemblyNameFormat;
// intermediates
HashSet<string> includedFiles;
// outputs
ShaderStringBuilder result;
List<string> sourceAssetDependencyPaths;
public TemplatePreprocessor(HashSet<string> activeFields, Dictionary<string, string> namedFragments, bool debugOutput, string templatePath, List<string> sourceAssetDependencyPaths, string buildTypeAssemblyNameFormat, ShaderStringBuilder outShaderCodeResult = null)
{
this.activeFields = activeFields;
this.namedFragments = namedFragments;
this.debugOutput = debugOutput;
this.templatePath = templatePath;
this.sourceAssetDependencyPaths = sourceAssetDependencyPaths;
this.buildTypeAssemblyNameFormat = buildTypeAssemblyNameFormat;
this.result = outShaderCodeResult ?? new ShaderStringBuilder();
includedFiles = new HashSet<string>();
}
public ShaderStringBuilder GetShaderCode()
result = new System.Text.StringBuilder();
return result;
int cur = 0;
int end = code.Length;
bool skipEndln = false;
public void ProcessTemplateFile(string filePath)
{
if (File.Exists(filePath) &&
!includedFiles.Contains(filePath))
{
includedFiles.Add(filePath);
while (cur < end)
if (sourceAssetDependencyPaths != null)
sourceAssetDependencyPaths.Add(filePath);
string[] templateLines = File.ReadAllLines(filePath);
foreach (string line in templateLines)
{
ProcessTemplateLine(line, 0, line.Length);
}
}
}
private struct Token
int dollar = code.IndexOf('$', cur);
if (dollar < 0)
public string s;
public int start;
public int end;
public Token(string s, int start, int end)
// no escape sequence found -- just append the remaining part of the code verbatim
AppendSubstring(result, code, cur, true, end, false);
cur = end;
this.s = s;
this.start = start;
this.end = end;
else
public static Token Invalid()
// found $ escape sequence
return new Token(null, 0, 0);
}
// find the end of the line (or if none found, the end of the code)
int endln = code.IndexOf('\n', dollar + 1);
if (endln < 0)
public bool IsValid()
{
return (s != null);
}
public bool Is(string other)
{
int len = end - start;
return (other.Length == len) && (0 == string.Compare(s, start, other, 0, len));
}
public string GetString()
{
int len = end - start;
if (len > 0)
endln = end;
return s.Substring(start, end - start);
return null;
}
}
// see if the character after '$' is '{', which would indicate a named fragment splice
if ((dollar + 1 < endln) && (code[dollar + 1] == '{'))
public void ProcessTemplateLine(string line, int start, int end)
{
bool appendEndln = true;
int cur = start;
while (cur < end)
{
// find an escape code '$'
int dollar = line.IndexOf('$', cur, end - cur);
if (dollar < 0)
{
// no escape code found in the remaining code -- just append the rest verbatim
AppendSubstring(line, cur, true, end, false);
break;
}
else
// named fragment splice
// search for the '}' within the current line
int curlystart = dollar + 1;
int curlyend = -1;
if (endln > curlystart + 1)
// found $ escape sequence
Token command = ParseIdentifier(line, dollar+1, end);
if (!command.IsValid())
curlyend = code.IndexOf('}', curlystart + 1, endln - curlystart - 1);
Error("ERROR: $ must be followed by a command string (if, splice, or include)", line, dollar+1);
break;
int nameLength = curlyend - dollar + 1;
if ((curlyend < 0) || (nameLength <= 0))
else
// no } found, or zero length name
// append everything before the beginning of the escape sequence
AppendSubstring(result, code, cur, true, dollar, false);
if (curlyend < 0)
if (command.Is("include"))
result.Append("// ERROR: unterminated escape sequence ('${' and '}' must be matched)\n");
ProcessIncludeCommand(command, end);
break; // include command always ignores the rest of the line, error or not
else
else if (command.Is("splice"))
result.Append("// ERROR: name '${}' is empty\n");
if (!ProcessSpliceCommand(command, end, ref cur))
{
// error, skip the rest of the line
break;
}
// append the line (commented out) for context
result.Append("// ");
AppendSubstring(result, code, dollar, true, endln, false);
result.Append("\n");
}
else
{
// } found!
// ugh, this probably allocates memory -- wish we could do the name lookup direct from a substring
string name = code.Substring(dollar, nameLength);
// append everything before the beginning of the escape sequence
AppendSubstring(result, code, cur, true, dollar, false);
string fragment;
if ((namedFragments != null) && namedFragments.TryGetValue(name, out fragment))
else if (command.Is("buildType"))
// splice the fragment
result.Append(fragment);
// advance to just after the '}'
cur = curlyend + 1;
ProcessBuildTypeCommand(command, end);
break; // buildType command always ignores the rest of the line, error or not
// no named fragment found
result.AppendFormat("/* Could not find named fragment '{0}' */", name);
cur = curlyend + 1;
// let's see if it is a predicate
Token predicate = ParseUntil(line, dollar + 1, end, ':');
if (!predicate.IsValid())
{
Error("ERROR: unrecognized command: " + command.GetString(), line, command.start);
break;
}
else
{
if (!ProcessPredicate(predicate, end, ref cur, ref appendEndln))
{
break; // skip the rest of the line
}
}
}
if (appendEndln)
{
result.AppendNewLine();
}
}
private void ProcessIncludeCommand(Token includeCommand, int lineEnd)
{
if (Expect(includeCommand.s, includeCommand.end, '('))
{
Token param = ParseString(includeCommand.s, includeCommand.end + 1, lineEnd);
if (!param.IsValid())
{
Error("ERROR: $include expected a string file path parameter", includeCommand.s, includeCommand.end + 1);
}
// it's a predicate
// search for the colon within the current line
int colon = -1;
if (endln > dollar + 1)
var includeLocation = Path.Combine(templatePath, param.GetString());
if (!File.Exists(includeLocation))
{
Error("ERROR: $include cannot find file : " + includeLocation, includeCommand.s, param.start);
}
else
colon = code.IndexOf(':', dollar + 1, endln - dollar - 1);
// skip a line, just to be sure we've cleaned up the current line
result.AppendNewLine();
result.AppendLine("//-------------------------------------------------------------------------------------");
result.AppendLine("// TEMPLATE INCLUDE : " + param.GetString());
result.AppendLine("//-------------------------------------------------------------------------------------");
ProcessTemplateFile(includeLocation);
result.AppendNewLine();
result.AppendLine("//-------------------------------------------------------------------------------------");
result.AppendLine("// END TEMPLATE INCLUDE : " + param.GetString());
result.AppendLine("//-------------------------------------------------------------------------------------");
}
}
}
int predicateLength = colon - dollar - 1;
if ((colon < 0) || (predicateLength <= 0))
private bool ProcessSpliceCommand(Token spliceCommand, int lineEnd, ref int cur)
{
if (!Expect(spliceCommand.s, spliceCommand.end, '('))
{
return false;
}
else
{
Token param = ParseUntil(spliceCommand.s, spliceCommand.end + 1, lineEnd, ')');
if (!param.IsValid())
{
Error("ERROR: splice command is missing a ')'", spliceCommand.s, spliceCommand.start);
return false;
}
else
{
// append everything before the beginning of the escape sequence
AppendSubstring(spliceCommand.s, cur, true, spliceCommand.start-1, false);
// find the named fragment
string name = param.GetString(); // unfortunately this allocates a new string
string fragment;
if ((namedFragments != null) && namedFragments.TryGetValue(name, out fragment))
// no colon found... error! Spit out error and context
// splice the fragment
result.Append(fragment);
}
else
{
// no named fragment found
result.Append("/* WARNING: $splice Could not find named fragment '{0}' */", name);
}
// append everything before the beginning of the escape sequence
AppendSubstring(result, code, cur, true, dollar, false);
// advance to just after the ')' and continue parsing
cur = param.end + 1;
}
}
return true;
}
if (colon < 0)
{
result.Append("// ERROR: unterminated escape sequence ('$' and ':' must be matched)\n");
}
else
{
result.Append("// ERROR: predicate is zero length\n");
}
// append the line (commented out) for context
result.Append("// ");
AppendSubstring(result, code, dollar, true, endln, false);
private void ProcessBuildTypeCommand(Token command, int endLine)
{
if (Expect(command.s, command.end, '('))
{
Token param = ParseUntil(command.s, command.end + 1, endLine, ')');
if (!param.IsValid())
{
Error("ERROR: buildType command is missing a ')'", command.s, command.start);
}
else
{
string typeName = param.GetString();
string assemblyQualifiedTypeName = string.Format(buildTypeAssemblyNameFormat, typeName);
Type type = Type.GetType(assemblyQualifiedTypeName);
if (type == null)
{
Error("ERROR: buildType could not find type : " + typeName, command.s, param.start);
// colon found!
// ugh, this probably allocates memory -- wish we could do the field lookup direct from a substring
string predicate = code.Substring(dollar + 1, predicateLength);
int nonwhitespace = SkipWhitespace(code, colon + 1, endln);
if (activeFields.Contains(predicate))
{
// append everything before the beginning of the escape sequence
AppendSubstring(result, code, cur, true, dollar, false);
result.AppendLine("// Generated Type: " + typeName);
ShaderGenerator temp = new ShaderGenerator();
BuildType(type, activeFields, temp);
result.AppendLine(temp.GetShaderString(0, false));
}
}
}
}
private bool ProcessPredicate(Token predicate, int endLine, ref int cur, ref bool appendEndln)
{
// eval if(param)
string fieldName = predicate.GetString();
int nonwhitespace = SkipWhitespace(predicate.s, predicate.end + 1, endLine);
if (activeFields.Contains(fieldName))
{
// predicate is active
// append everything before the beginning of the escape sequence
AppendSubstring(predicate.s, cur, true, predicate.start-1, false);
// continue parsing the rest of the line, starting with the first nonwhitespace character
cur = nonwhitespace;
return true;
}
else
{
// predicate is not active
if (debugOutput)
{
// append everything before the beginning of the escape sequence
AppendSubstring(predicate.s, cur, true, predicate.start-1, false);
// append the rest of the line, commented out
result.Append("// ");
AppendSubstring(predicate.s, nonwhitespace, true, endLine, false);
}
else
{
// don't append anything
appendEndln = false;
}
return false;
}
}
// predicate is active, append the line
AppendSubstring(result, code, nonwhitespace, true, endln, false);
}
else
{
// predicate is not active
if (debugOutput)
{
// append everything before the beginning of the escape sequence
AppendSubstring(result, code, cur, true, dollar, false);
result.Append("// ");
AppendSubstring(result, code, nonwhitespace, true, endln, false);
}
else
{
skipEndln = true;
}
}
private Token ParseIdentifier(string code, int start, int end)
{
if (start < end)
{
char c = code[start];
if (Char.IsLetter(c) || (c == '_'))
{
int cur = start + 1;
while (cur < end)
{
c = code[cur];
if (!(Char.IsLetterOrDigit(c) || (c == '_')))
break;
cur++;
cur = endln + 1;
return new Token(code, start, cur);
return Token.Invalid();
if (!skipEndln)
private Token ParseString(string line, int start, int end)
result.AppendLine();
if (Expect(line, start, '"'))
{
return ParseUntil(line, start + 1, end, '"');
}
return Token.Invalid();
return result;
private Token ParseUntil(string line, int start, int end, char endChar)
{
int cur = start;
while (cur < end)
{
if (line[cur] == endChar)
{
return new Token(line, start, cur);
}
cur++;
}
return Token.Invalid();
}
private bool Expect(string line, int location, char expected)
{
if ((location < line.Length) && (line[location] == expected))
{
return true;
}
Error("Expected '" + expected + "'", line, location);
return false;
}
private void Error(string error, string line, int location)
{
// append the line for context
result.Append("\n");
result.Append("// ");
AppendSubstring(line, 0, true, line.Length, false);
result.Append("\n");
// append the location marker, and error description
result.Append("// ");
result.AppendSpaces(location);
result.Append("^ ");
result.Append(error);
result.Append("\n");
}
// an easier to use version of substring Append() -- explicit inclusion on each end, and checks for positive length
private void AppendSubstring(string str, int start, bool includeStart, int end, bool includeEnd)
{
if (!includeStart)
{
start++;
}
if (!includeEnd)
{
end--;
}
int count = end - start + 1;
if (count > 0)
{
result.Append(str, start, count);
}
}
}
public static void ApplyDependencies(HashSet<string> activeFields, List<Dependency[]> dependsList)

10
com.unity.shadergraph/Editor/Data/Util/ShaderStringBuilder.cs


m_StringBuilder.Append(value);
}
public void Append(string value, int start, int count)
{
m_StringBuilder.Append(value, start, count);
}
}
public void AppendSpaces(int count)
{
m_StringBuilder.Append(' ', count);
}
public void AppendIndentation()

71
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/SharedCode.template.hlsl


FragInputs BuildFragInputs(VaryingsMeshToPS input)
{
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
// Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).
// TODO: this is a really poor workaround, but the variable is used in a bunch of places
// to compute normals which are then passed on elsewhere to compute other values...
output.worldToTangent = k_identity3x3;
output.positionSS = input.positionCS; // input.positionCS is SV_Position
$FragInputs.positionRWS: output.positionRWS = input.positionRWS;
$FragInputs.worldToTangent: output.worldToTangent = BuildWorldToTangent(input.tangentWS, input.normalWS);
$FragInputs.texCoord0: output.texCoord0 = input.texCoord0;
$FragInputs.texCoord1: output.texCoord1 = input.texCoord1;
$FragInputs.texCoord2: output.texCoord2 = input.texCoord2;
$FragInputs.texCoord3: output.texCoord3 = input.texCoord3;
$FragInputs.color: output.color = input.color;
#if SHADER_STAGE_FRAGMENT
$FragInputs.isFrontFace: output.isFrontFace = IS_FRONT_VFACE(input.cullFace, true, false); // TODO: SHADER_STAGE_FRAGMENT only
$FragInputs.isFrontFace: // Handle handness of the view matrix (In Unity view matrix default to a determinant of -1)
$FragInputs.isFrontFace: // when we render a cubemap the view matrix handness is flipped (due to convention used for cubemap) we have a determinant of +1
$FragInputs.isFrontFace: output.isFrontFace = _DetViewMatrix < 0.0 ? output.isFrontFace : !output.isFrontFace;
#endif // SHADER_STAGE_FRAGMENT
return output;
}
SurfaceDescriptionInputs FragInputsToSurfaceDescriptionInputs(FragInputs input, float3 viewWS)
{
SurfaceDescriptionInputs output;
ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
$SurfaceDescriptionInputs.WorldSpaceNormal: output.WorldSpaceNormal = normalize(input.worldToTangent[2].xyz);
$SurfaceDescriptionInputs.ObjectSpaceNormal: output.ObjectSpaceNormal = mul(output.WorldSpaceNormal, (float3x3) UNITY_MATRIX_M); // transposed multiplication by inverse matrix to handle normal scale
$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.ObjectSpaceTangent: output.ObjectSpaceTangent = TransformWorldToObjectDir(output.WorldSpaceTangent);
$SurfaceDescriptionInputs.ViewSpaceTangent: output.ViewSpaceTangent = TransformWorldToViewDir(output.WorldSpaceTangent);
$SurfaceDescriptionInputs.TangentSpaceTangent: output.TangentSpaceTangent = float3(1.0f, 0.0f, 0.0f);
$SurfaceDescriptionInputs.WorldSpaceBiTangent: output.WorldSpaceBiTangent = input.worldToTangent[1].xyz;
$SurfaceDescriptionInputs.ObjectSpaceBiTangent: output.ObjectSpaceBiTangent = TransformWorldToObjectDir(output.WorldSpaceBiTangent);
$SurfaceDescriptionInputs.ViewSpaceBiTangent: output.ViewSpaceBiTangent = TransformWorldToViewDir(output.WorldSpaceBiTangent);
$SurfaceDescriptionInputs.TangentSpaceBiTangent: output.TangentSpaceBiTangent = float3(0.0f, 1.0f, 0.0f);
$SurfaceDescriptionInputs.WorldSpaceViewDirection: output.WorldSpaceViewDirection = normalize(viewWS);
$SurfaceDescriptionInputs.ObjectSpaceViewDirection: output.ObjectSpaceViewDirection = TransformWorldToObjectDir(output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.ViewSpaceViewDirection: output.ViewSpaceViewDirection = TransformWorldToViewDir(output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.TangentSpaceViewDirection: float3x3 tangentSpaceTransform = float3x3(output.WorldSpaceTangent,output.WorldSpaceBiTangent,output.WorldSpaceNormal);
$SurfaceDescriptionInputs.TangentSpaceViewDirection: output.TangentSpaceViewDirection = mul(tangentSpaceTransform, output.WorldSpaceViewDirection);
$SurfaceDescriptionInputs.WorldSpacePosition: output.WorldSpacePosition = GetAbsolutePositionWS(input.positionRWS);
$SurfaceDescriptionInputs.ObjectSpacePosition: output.ObjectSpacePosition = TransformWorldToObject(input.positionRWS);
$SurfaceDescriptionInputs.ViewSpacePosition: output.ViewSpacePosition = TransformWorldToView(input.positionRWS);
$SurfaceDescriptionInputs.TangentSpacePosition: output.TangentSpacePosition = float3(0.0f, 0.0f, 0.0f);
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionRWS), _ProjectionParams.x);
$SurfaceDescriptionInputs.uv0: output.uv0 = float4(input.texCoord0, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv1: output.uv1 = float4(input.texCoord1, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv2: output.uv2 = float4(input.texCoord2, 0.0f, 0.0f);
$SurfaceDescriptionInputs.uv3: output.uv3 = float4(input.texCoord3, 0.0f, 0.0f);
$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
return output;
}
// existing HDRP code uses the combined function to go directly from packed to frag inputs
FragInputs UnpackVaryingsMeshToFragInputs(PackedVaryingsMeshToPS input)
{
VaryingsMeshToPS unpacked= UnpackVaryingsMeshToPS(input);
return BuildFragInputs(unpacked);
}

9
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/SharedCode.template.hlsl.meta


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

50
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/VertexAnimation.template.hlsl


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 = GetAbsolutePositionWS(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;
}

9
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/VertexAnimation.template.hlsl.meta


fileFormatVersion: 2
guid: 0c7cf800109d94245b1843175a674ab4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存