浏览代码

Merge branch 'master' into feature/SSR

# Conflicts:
#	ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
#	ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
#	ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
/main
Frédéric Vauchelles 7 年前
当前提交
09596c67
共有 154 个文件被更改,包括 2842 次插入1903 次删除
  1. 51
      ScriptableRenderPipeline/Core/CoreRP/Editor/MaterialUpgrader.cs
  2. 61
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Common.hlsl
  3. 4
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/EntityLighting.hlsl
  4. 9
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ImageBasedLighting.hlsl
  5. 8
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Wind.hlsl
  6. 76
      ScriptableRenderPipeline/Core/CoreRP/Utilities/CoreUtils.cs
  7. 95
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  8. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugColorPicker.shader
  9. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  10. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl
  11. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader
  12. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugViewMaterialGBuffer.shader
  13. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugViewTiles.shader
  14. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs
  15. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs.hlsl
  16. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/MaterialDebug.cs.hlsl
  17. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs
  18. 66
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs
  19. 72
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  20. 24
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  21. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Deferred.shader
  22. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/DeferredDirectionalShadow.compute
  23. 106
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  24. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Deferred.compute
  25. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  26. 19
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl
  27. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/VolumeProjection.hlsl
  28. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  29. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs.hlsl
  30. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  31. 104
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  32. 326
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  33. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitData.hlsl
  34. 52
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl
  35. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs
  36. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/CameraMotionVectors.shader
  37. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/CopyStencilBuffer.shader
  38. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassDBuffer.hlsl
  39. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/VaryingMesh.hlsl
  40. 175
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl
  41. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl
  42. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/OpaqueAtmosphericScattering.shader
  43. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Wind/ShaderWindSettings.cs
  44. 100
      ScriptableRenderPipeline/LightweightPipeline/CHANGELOG.md
  45. 39
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineAsset.cs
  46. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.asset
  47. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.cs
  48. 30
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightAssetEditor.cs
  49. 101
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightShaderGUI.cs
  50. 58
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardGUI.cs
  51. 4
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardParticlesShaderGUI.cs
  52. 62
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardSimpleLightingGUI.cs
  53. 117
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightUnlitGUI.cs
  54. 17
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightPBRExtraPasses.template
  55. 13
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template
  56. 33
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightUnlitExtraPasses.template
  57. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template
  58. 20
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightConstantBuffer.cs
  59. 830
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  60. 160
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs
  61. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShaderUtils.cs
  62. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-Default.mat
  63. 10
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Materials/Lightweight-StandardSimpleLighting.mat
  64. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl
  65. 16
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Input.hlsl
  66. 87
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl
  67. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassDepthOnly.hlsl
  68. 112
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl
  69. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl
  70. 84
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Particles.hlsl
  71. 155
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl
  72. 30
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaCommon.hlsl
  73. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightBlit.shader
  74. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightCopyDepth.shader
  75. 12
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader
  76. 19
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandard.shader
  77. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticles.shader
  78. 18
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticlesSimpleLighting.shader
  79. 18
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardParticlesUnlit.shader
  80. 24
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardSimpleLighting.shader
  81. 59
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardUnlit.shader
  82. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LTCAreaLight/LtcData.DisneyDiffuse.cs
  83. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LTCAreaLight/LtcData.GGX.cs
  84. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LTCAreaLight.meta
  85. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/PreIntegratedFGD.meta
  86. 631
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs
  87. 11
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs.meta
  88. 71
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceCommon.hlsl
  89. 97
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfacePBR.hlsl
  90. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfacePBR.hlsl.meta
  91. 33
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceSimple.hlsl
  92. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceSimple.hlsl.meta
  93. 15
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl
  94. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/InputSurfaceUnlit.hlsl.meta
  95. 146
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl
  96. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLitSimple.hlsl.meta
  97. 22
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl
  98. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassMetaPBR.hlsl.meta

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


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

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

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

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

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

61
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Common.hlsl


// ----------------------------------------------------------------------------
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane).
// Does not correctly handle oblique view frustums.
// Does NOT correctly handle oblique view frustums.
// Does NOT work with orthographic projection.
// zBufferParam = { (f-n)/n, 1, (f-n)/n*f, 1/f }
float Linear01DepthFromNear(float depth, float4 zBufferParam)
{

// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane).
// Does not correctly handle oblique view frustums.
// Does NOT work with orthographic projections.
// Does NOT correctly handle oblique view frustums.
// zBufferParam = { (f-n)/n, 1, (f-n)/n*f, 1/f }
float Linear01Depth(float depth, float4 zBufferParam)
{

// Z buffer to linear depth.
// Does not correctly handle oblique view frustums.
// Does NOT correctly handle oblique view frustums.
// Does NOT work with orthographic projection.
// zBufferParam = { (f-n)/n, 1, (f-n)/n*f, 1/f }
float LinearEyeDepth(float depth, float4 zBufferParam)
{

// Z buffer to linear depth.
// Correctly handles oblique view frustums. Only valid for projection matrices!
// Correctly handles oblique view frustums.
// Does NOT work with orthographic projection.
// The view space uses a right-handed coordinate system.
return -viewSpaceZ;
// If the matrix is right-handed, we have to flip the Z axis to get a positive value.
return abs(viewSpaceZ);
// Correctly handles oblique view frustums.
// Works in all cases.
float LinearEyeDepth(float3 positionWS, float4x4 viewProjMatrix)
// Assumes that the 'positionWS' is in front of the camera.
float LinearEyeDepth(float3 positionWS, float4x4 viewMatrix)
return mul(viewProjMatrix, float4(positionWS, 1.0)).w;
float viewSpaceZ = mul(viewMatrix, float4(positionWS, 1.0)).z;
// If the matrix is right-handed, we have to flip the Z axis to get a positive value.
return abs(viewSpaceZ);
}
// 'z' is the view space Z position (linear depth).

return mul(clipSpaceTransform, float4(position, 1.0));
}
// The returned Z value is the depth buffer value (and NOT linear view space Z value).
// Use case examples:
// (position = positionCS) => (clipSpaceTransform = use default)
// (position = positionVS) => (clipSpaceTransform = UNITY_MATRIX_P)

PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize, float deviceDepth, float linearDepth, float3 positionWS, uint2 tileCoord)
{
PositionInputs posInput = GetPositionInput(positionSS, invScreenSize, tileCoord);
posInput.deviceDepth = deviceDepth;
posInput.linearDepth = linearDepth;
posInput.positionWS = positionWS;
posInput.positionWS = positionWS;
posInput.deviceDepth = deviceDepth;
posInput.linearDepth = linearDepth;
return posInput;
}

// From deferred or compute shader
// depth must be the depth from the raw depth buffer. This allow to handle all kind of depth automatically with the inverse view projection matrix.
// For information. In Unity Depth is always in range 0..1 (even on OpenGL) but can be reversed.
PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize, float deviceDepth, float4x4 invViewProjMatrix, float4x4 viewProjMatrix, uint2 tileCoord)
PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize, float deviceDepth,
float4x4 invViewProjMatrix, float4x4 viewMatrix,
uint2 tileCoord)
posInput.deviceDepth = deviceDepth;
posInput.positionWS = ComputeWorldSpacePosition(posInput.positionNDC, deviceDepth, invViewProjMatrix);
// The compiler should optimize this (less expensive than reconstruct depth VS from depth buffer)
posInput.linearDepth = mul(viewProjMatrix, float4(posInput.positionWS, 1.0)).w;
posInput.positionWS = ComputeWorldSpacePosition(posInput.positionNDC, deviceDepth, invViewProjMatrix);
posInput.deviceDepth = deviceDepth;
posInput.linearDepth = LinearEyeDepth(posInput.positionWS, viewMatrix);
PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize, float deviceDepth, float4x4 invViewProjMatrix, float4x4 viewProjMatrix)
PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize, float deviceDepth,
float4x4 invViewProjMatrix, float4x4 viewMatrix)
return GetPositionInput(positionSS, invScreenSize, deviceDepth, invViewProjMatrix, viewProjMatrix, uint2(0, 0));
return GetPositionInput(positionSS, invScreenSize, deviceDepth, invViewProjMatrix, viewMatrix, uint2(0, 0));
void ApplyDepthOffsetPositionInput(float3 V, float depthOffsetVS, float4x4 viewProjMatrix, inout PositionInputs posInput)
void ApplyDepthOffsetPositionInput(float3 V, float depthOffsetVS, float3 viewForwardDir, float4x4 viewProjMatrix, inout PositionInputs posInput)
posInput.deviceDepth = ComputeNormalizedDeviceCoordinatesWithZ(posInput.positionWS, viewProjMatrix).z;
float4 positionCS = mul(viewProjMatrix, float4(posInput.positionWS, 1.0));
posInput.linearDepth = positionCS.w;
posInput.deviceDepth = positionCS.z / positionCS.w;
// Transform the displacement along the view vector to the displacement along the forward vector.
// Use abs() to make sure we get the sign right.
// 'depthOffsetVS' applies in the direction away from the camera.
posInput.linearDepth += depthOffsetVS * abs(dot(V, viewForwardDir));
}
// ----------------------------------------------------------------------------

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


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

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

9
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ImageBasedLighting.hlsl


return lerp(N, R, lerpFactor);
}
// To simulate the streching of highlight at grazing angle for IBL we shrink the roughness
// which allow to fake an anisotropic specular lobe.
// Ref: http://www.frostbite.com/2015/08/stochastic-screen-space-reflections/ - slide 84
real AnisotropicStrechAtGrazingAngle(real perceptualRoughness, real NdotV)
{
real p = perceptualRoughness;
return p * lerp(saturate(NdotV * 2.0) * p, p, p);
}
// ----------------------------------------------------------------------------
// Importance sampling BSDF functions
// ----------------------------------------------------------------------------

8
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Wind.hlsl


// TODO: no global variable or resource declarations in the Shader Library. Functions and macros only!
TEXTURE2D(WIND_SETTINGS_TexNoise);
TEXTURE2D(_WIND_SETTINGS_TexNoise);
TEXTURE2D(WIND_SETTINGS_TexGust);
TEXTURE2D(_WIND_SETTINGS_TexGust);
SAMPLER(sampler_WIND_SETTINGS_TexGust);
float4 WIND_SETTINGS_WorldDirectionAndSpeed;

float3 texNoise(float3 worldPos, float LOD)
{
return SAMPLE_TEXTURE2D_LOD(WIND_SETTINGS_TexNoise, sampler_WIND_SETTINGS_TexNoise, worldPos.xz, LOD).xyz -0.5;
return SAMPLE_TEXTURE2D_LOD(_WIND_SETTINGS_TexNoise, sampler_WIND_SETTINGS_TexNoise, worldPos.xz, LOD).xyz -0.5;
return SAMPLE_TEXTURE2D_LOD(WIND_SETTINGS_TexGust, sampler_WIND_SETTINGS_TexGust, worldPos.xz, LOD).x;
return SAMPLE_TEXTURE2D_LOD(_WIND_SETTINGS_TexGust, sampler_WIND_SETTINGS_TexGust, worldPos.xz, LOD).x;
}

76
ScriptableRenderPipeline/Core/CoreRP/Utilities/CoreUtils.cs


return mesh;
}
public static void DisplayUnsupportedAPIMessage()
public static void DisplayUnsupportedMessage(string msg)
Debug.LogError("Platform " + SystemInfo.operatingSystem + " with device " + SystemInfo.graphicsDeviceType.ToString() + " is not supported, no rendering will occur");
Debug.LogError(msg);
sv.ShowNotification(new GUIContent("Platform " + SystemInfo.operatingSystem + " with device " + SystemInfo.graphicsDeviceType.ToString() + " is not supported, no rendering will occur"));
sv.ShowNotification(new GUIContent(msg));
public static void DisplayUnsupportedAPIMessage()
{
string msg = "Platform " + SystemInfo.operatingSystem + " with device " + SystemInfo.graphicsDeviceType.ToString() + " is not supported, no rendering will occur";
DisplayUnsupportedMessage(msg);
}
public static void DisplayUnsupportedXRMessage()
{
string msg = "AR/VR devices are not supported, no rendering will occur";
DisplayUnsupportedMessage(msg);
}
// Returns 'true' if "Animated Materials" are enabled for the view associated with the given camera.
public static bool AreAnimatedMaterialsEnabled(Camera camera)
{
bool animateMaterials = true;
#if UNITY_EDITOR
animateMaterials = Application.isPlaying;
if (camera.cameraType == CameraType.SceneView)
{
animateMaterials = false;
// Determine whether the "Animated Materials" checkbox is checked for the current view.
foreach (UnityEditor.SceneView sv in Resources.FindObjectsOfTypeAll(typeof(UnityEditor.SceneView)))
{
if (sv.camera == camera && sv.sceneViewState.showMaterialUpdate)
{
animateMaterials = true;
break;
}
}
}
else if (camera.cameraType == CameraType.Preview)
{
animateMaterials = false;
// Determine whether the "Animated Materials" checkbox is checked for the current view.
foreach (UnityEditor.MaterialEditor med in Resources.FindObjectsOfTypeAll(typeof(UnityEditor.MaterialEditor)))
{
// Warning: currently, there's no way to determine whether a given camera corresponds to this MaterialEditor.
// Therefore, if at least one of the visible MaterialEditors is in Play Mode, all of them will play.
if (med.isVisible && med.RequiresConstantRepaint())
{
animateMaterials = true;
break;
}
}
}
// TODO: how to handle reflection views? We don't know the parent window they are being rendered into,
// so we don't know whether we can animate them...
//
// IMHO, a better solution would be:
// A window invokes a camera render. The camera knows which window called it, so it can query its properies
// (such as animated materials). This camera provides the space-time position. It should also be able
// to access the rendering settings somehow. Using this information, it is then able to construct the
// primary view with information about camera-relative rendering, LOD, time, rendering passes/features
// enabled, etc. We then render this view. It can have multiple sub-views (shadows, reflections).
// They inherit all the properties of the primary view, but also have the ability to override them
// (e.g. primary cam pos and time are retained, matrices are modified, SSS and tessellation are disabled).
// These views can then have multiple sub-views (probably not practical for games),
// which simply amounts to a recursive call, and then the story repeats itself.
//
// TLDR: we need to know the caller and its status/properties to make decisions.
#endif
return animateMaterials;
}
}
}

95
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


public Matrix4x4 viewMatrix;
public Matrix4x4 projMatrix;
public Matrix4x4 nonJitteredProjMatrix;
public Vector4 worldSpaceCameraPos;
public float detViewMatrix;
public Vector4 screenSize;
public Frustum frustum;
public Vector4[] frustumPlaneEquations;

public Vector4 viewParam;
public Vector4 zBufferParams;
public Vector4 unity_OrthoParams;
public Vector4 projectionParams;
public Vector4 screenParams;
public PostProcessRenderContext postprocessRenderContext;
public Matrix4x4[] viewMatrixStereo;

// avoid one-frame jumps/hiccups with temporal effects (motion blur, TAA...)
public bool isFirstFrame { get; private set; }
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
// TODO: pass this as "_ZBufferParams" if the projection matrix is oblique.
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
get
{
var p = projMatrix;

// In stereo, this corresponds to the center eye position
var pos = camera.transform.position;
worldSpaceCameraPos = pos;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{

projMatrix = gpuProj;
nonJitteredProjMatrix = gpuNonJitteredProj;
cameraPos = pos;
viewParam = new Vector4(viewMatrix.determinant, 0.0f, 0.0f, 0.0f);
detViewMatrix = viewMatrix.determinant;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{

frustum = Frustum.Create(viewProjMatrix, true, true);
float n = camera.nearClipPlane;
float f = camera.farClipPlane;
// Analyze the projection matrix.
// p[2][3] = (reverseZ ? 1 : -1) * (depth_0_1 ? 1 : 2) * (f * n) / (f - n)
float scale = projMatrix[2, 3] / (f * n) * (f - n);
bool depth_0_1 = Mathf.Abs(scale) < 1.5f;
bool reverseZ = scale > 0;
bool flipProj = projMatrix.inverse.MultiplyPoint(new Vector3(0, 1, 0)).y < 0;
// http://www.humus.name/temp/Linearize%20depth.txt
if (reverseZ)
{
zBufferParams = new Vector4(-1 + f/n, 1, -1/f + 1/n, 1/f);
}
else
{
zBufferParams = new Vector4(1 - f/n, f/n, 1/f - 1/n, 1/n);
}
projectionParams = new Vector4(flipProj ? -1 : 1, n, f, 1.0f / f);
float orthoHeight = camera.orthographic ? 2 * camera.orthographicSize : 0;
float orthoWidth = orthoHeight * camera.aspect;
unity_OrthoParams = new Vector4(orthoWidth, orthoHeight, 0, camera.orthographic ? 1 : 0);
frustum = Frustum.Create(viewProjMatrix, depth_0_1, reverseZ);
// Left, right, top, bottom, near, far.
for (int i = 0; i < 6; i++)

RTHandles.SetReferenceSize(m_ActualWidth, m_ActualHeight, frameSettings.enableMSAA, m_msaaSamples);
historyRTSystem.SetReferenceSize(m_ActualWidth, m_ActualHeight, frameSettings.enableMSAA, m_msaaSamples);
historyRTSystem.Swap();
int maxWidth = RTHandles.maxWidth;
int maxHeight = RTHandles.maxHeight;

screenSize = new Vector4(screenWidth, screenHeight, 1.0f / screenWidth, 1.0f / screenHeight);
screenParams = new Vector4(screenSize.x, screenSize.y, 1 + screenSize.z, 1 + screenSize.w);
}
// Stopgap method used to extract stereo combined matrix state.

// What constants in UnityPerPass need updating for stereo considerations?
// _ViewProjMatrix - It is used directly for generating tesselation factors. This should be the same
// across both eyes for consistency, and to keep shadow-generation eye-independent
// _ViewParam - Used for isFrontFace determination, should be the same for both eyes. There is the scenario
// _DetViewMatrix - Used for isFrontFace determination, should be the same for both eyes. There is the scenario
// where there might be multi-eye sets that are divergent enough where this assumption is not valid,
// but that's a future problem
// _InvProjParam - Intention was for generating linear depths, but not currently used. Will need to be stereo-ized if

var stereoCombinedProjMatrix = cullingParams.cullStereoProj;
projMatrix = GL.GetGPUProjectionMatrix(stereoCombinedProjMatrix, true);
viewParam = new Vector4(viewMatrix.determinant, 0.0f, 0.0f, 0.0f);
detViewMatrix = viewMatrix.determinant;
frustum = Frustum.Create(viewProjMatrix, true, true);

s_Cleanup.Clear();
}
public void SetupGlobalParams(CommandBuffer cmd)
// Set up UnityPerView CBuffer.
public void SetupGlobalParams(CommandBuffer cmd, float time, float lastTime)
cmd.SetGlobalMatrix(HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
cmd.SetGlobalVector(HDShaderIDs._ViewParam, viewParam);
cmd.SetGlobalVector(HDShaderIDs._InvProjParam, invProjParam);
cmd.SetGlobalMatrix(HDShaderIDs._NonJitteredViewProjMatrix, nonJitteredViewProjMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetGlobalVector(HDShaderIDs._WorldSpaceCameraPos, worldSpaceCameraPos);
cmd.SetGlobalFloat( HDShaderIDs._DetViewMatrix, detViewMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetGlobalVector(HDShaderIDs._ZBufferParams, zBufferParams);
cmd.SetGlobalVector(HDShaderIDs._ProjectionParams, projectionParams);
cmd.SetGlobalVector(HDShaderIDs.unity_OrthoParams, unity_OrthoParams);
cmd.SetGlobalVector(HDShaderIDs._ScreenParams, screenParams);
cmd.SetGlobalVector(HDShaderIDs._TaaFrameRotation, taaFrameRotation);
cmd.SetGlobalInt(HDShaderIDs._TaaFrameIndex, (int)taaFrameIndex);
cmd.SetGlobalVector(HDShaderIDs._TaaFrameRotation, taaFrameRotation);
// Time is also a part of the UnityPerView CBuffer.
// Different views can have different values of the "Animated Materials" setting.
bool animateMaterials = CoreUtils.AreAnimatedMaterialsEnabled(camera);
float ct = animateMaterials ? time : 0;
float pt = animateMaterials ? lastTime : 0;
float dt = Time.deltaTime;
float sdt = Time.smoothDeltaTime;
cmd.SetGlobalVector(HDShaderIDs._Time, new Vector4(ct * 0.05f, ct, ct * 2.0f, ct * 3.0f));
cmd.SetGlobalVector(HDShaderIDs._LastTime, new Vector4(pt * 0.05f, pt, pt * 2.0f, pt * 3.0f));
cmd.SetGlobalVector(HDShaderIDs.unity_DeltaTime, new Vector4(dt, 1.0f / dt, sdt, 1.0f / sdt));
cmd.SetGlobalVector(HDShaderIDs._SinTime, new Vector4(Mathf.Sin(ct * 0.125f), Mathf.Sin(ct * 0.25f), Mathf.Sin(ct * 0.5f), Mathf.Sin(ct)));
cmd.SetGlobalVector(HDShaderIDs._CosTime, new Vector4(Mathf.Cos(ct * 0.125f), Mathf.Cos(ct * 0.25f), Mathf.Cos(ct * 0.5f), Mathf.Cos(ct)));
}
public void SetupGlobalStereoParams(CommandBuffer cmd)

cmd.SetGlobalMatrixArray(HDShaderIDs._InvViewMatrixStereo, invViewStereo);
cmd.SetGlobalMatrixArray(HDShaderIDs._InvProjMatrixStereo, invProjStereo);
cmd.SetGlobalMatrixArray(HDShaderIDs._InvViewProjMatrixStereo, invViewProjStereo);
}
// TODO: We should set all the value below globally and not let it under the control of Unity,
// Need to test that because we are not sure in which order these value are setup, but we need to have control on them, or rename them in our shader.
// For now, apply it for all our compute shader to make it work
public void SetupComputeShader(ComputeShader cs, CommandBuffer cmd)
{
// Copy values set by Unity which are not configured in scripts.
cmd.SetComputeVectorParam(cs, HDShaderIDs.unity_OrthoParams, Shader.GetGlobalVector(HDShaderIDs.unity_OrthoParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ProjectionParams, Shader.GetGlobalVector(HDShaderIDs._ProjectionParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ScreenParams, Shader.GetGlobalVector(HDShaderIDs._ScreenParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ZBufferParams, Shader.GetGlobalVector(HDShaderIDs._ZBufferParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._WorldSpaceCameraPos, Shader.GetGlobalVector(HDShaderIDs._WorldSpaceCameraPos));
}
public RTHandleSystem.RTHandle GetPreviousFrameRT(int id)

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugColorPicker.shader


float4 mousePixelCoord = _MousePixelCoord;
if (_RequireToFlipInputTexture > 0.0)
{
mousePixelCoord.y = _ScreenParams.y - mousePixelCoord.y;
mousePixelCoord.y = _ScreenSize.y - mousePixelCoord.y;
// Note: We must not flip the mousePixelCoord.w coordinate
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs


list.Add(new DebugUI.FloatField { displayName = "Shadow Range Max Value", getter = () => lightingDebugSettings.shadowMaxValue, setter = value => lightingDebugSettings.shadowMaxValue = value });
list.Add(new DebugUI.EnumField { displayName = "Lighting Debug Mode", getter = () => (int)lightingDebugSettings.debugLightingMode, setter = value => SetDebugLightingMode((DebugLightingMode)value), autoEnum = typeof(DebugLightingMode), onValueChanged = RefreshLightingDebug });
if (lightingDebugSettings.debugLightingMode == DebugLightingMode.EnvironmentProxyVolume)
{
list.Add(new DebugUI.Container
{
children =
{
new DebugUI.FloatField { displayName = "Debug Environment Proxy Depth Scale", getter = () => lightingDebugSettings.environmentProxyDepthScale, setter = value => lightingDebugSettings.environmentProxyDepthScale = value, min = () => 0.1f, max = () => 50f }
}
});
}
list.Add(new DebugUI.EnumField { displayName = "Fullscreen Debug Mode", getter = () => (int)fullScreenDebugMode, setter = value => fullScreenDebugMode = (FullScreenDebugMode)value, enumNames = lightingFullScreenDebugStrings, enumValues = lightingFullScreenDebugValues, onValueChanged = RefreshLightingDebug });
switch (fullScreenDebugMode)
{

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl


float4 _DebugLightingSpecularColor; // x == bool override, yzw = specular color
float4 _MousePixelCoord; // xy unorm, zw norm
float4 _MouseClickPixelCoord; // xy unorm, zw norm
float _DebugEnvironmentProxyDepthScale;
float _DebugExposure;
CBUFFER_END

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader


CBUFFER_END
TEXTURE2D(_DebugFullScreenTexture);
TEXTURE2D(_DepthPyramidTexture);
StructuredBuffer<ScreenSpaceTracingDebug> _DebugScreenSpaceTracingData;
struct Attributes

const float kGrid = 64.0;
// Arrow grid (aspect ratio is kept)
float rows = floor(kGrid * _ScreenParams.y / _ScreenParams.x);
float aspect = _ScreenSize.y * _ScreenSize.z;
float rows = floor(kGrid * aspect);
float2 size = _ScreenParams.xy / float2(cols, rows);
float2 size = _ScreenSize.xy / float2(cols, rows);
float body = min(size.x, size.y) / sqrt(2.0);
float2 texcoord = input.positionCS.xy;
float2 center = (floor(texcoord / size) + 0.5) * size;

float2 arrow_coord = center / _ScreenParams.xy;
float2 arrow_coord = center * _ScreenSize.zw;
if (_RequireToFlipInputTexture > 0.0)
{

{
// Reuse depth display function from DebugViewMaterial
float depth = SAMPLE_TEXTURE2D(_DebugFullScreenTexture, s_point_clamp_sampler, input.texcoord).r;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
float linearDepth = frac(posInput.linearDepth * 0.1);
return float4(linearDepth.xxx, 1.0);
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugViewMaterialGBuffer.shader


{
// input.positionCS is SV_Position
float depth = LOAD_TEXTURE2D(_MainDepthTexture, input.positionCS.xy).x;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
BSDFData bsdfData;
BakeLightingData bakeLightingData;

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugViewTiles.shader


uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = (tileCoord + uint2((quadVertex+1) & 1, (quadVertex >> 1) & 1)) * tileSize;
float2 clipCoord = (pixelCoord / _ScreenParams.xy) * 2.0 - 1.0;
float2 clipCoord = (pixelCoord * _ScreenSize.zw) * 2.0 - 1.0;
clipCoord.y *= -1;
Varyings output;

{
// positionCS is SV_Position
float depth = LOAD_TEXTURE2D(_MainDepthTexture, input.positionCS.xy).x;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, uint2(input.positionCS.xy) / GetTileSize());
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, uint2(input.positionCS.xy) / GetTileSize());
int2 pixelCoord = posInput.positionSS.xy;
int2 tileCoord = (float2)pixelCoord / GetTileSize();

if (tileCoord.y < LIGHTCATEGORY_COUNT && tileCoord.x < maxLights + 3)
{
float depthMouse = LOAD_TEXTURE2D(_MainDepthTexture, _MousePixelCoord.xy).x;
PositionInputs mousePosInput = GetPositionInput(_MousePixelCoord.xy, _ScreenSize.zw, depthMouse, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, mouseTileCoord);
PositionInputs mousePosInput = GetPositionInput(_MousePixelCoord.xy, _ScreenSize.zw, depthMouse, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, mouseTileCoord);
uint category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;
uint start;

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs


SpecularLighting,
LuxMeter,
VisualizeCascade,
IndirectDiffuseOcclusionFromSsao,
IndirectDiffuseGtaoFromSsao,
IndirectSpecularOcclusionFromSsao,
IndirectSpecularGtaoFromSsao,
EnvironmentProxyVolume,
EnvironmentSampleCoordinates,
IndirectDiffuseOcclusion,
IndirectSpecularOcclusion,
ScreenSpaceTracingRefraction,
ScreenSpaceTracingReflection
}

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs.hlsl


#define DEBUGLIGHTINGMODE_SPECULAR_LIGHTING (2)
#define DEBUGLIGHTINGMODE_LUX_METER (3)
#define DEBUGLIGHTINGMODE_VISUALIZE_CASCADE (4)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO (5)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO (6)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO (7)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO (8)
#define DEBUGLIGHTINGMODE_ENVIRONMENT_PROXY_VOLUME (9)
#define DEBUGLIGHTINGMODE_ENVIRONMENT_SAMPLE_COORDINATES (10)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION (11)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION (12)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION (5)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION (6)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION (7)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION (8)
//
// UnityEngine.Experimental.Rendering.HDPipeline.DebugScreenSpaceTracing: static fields

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/MaterialDebug.cs.hlsl


#define DEBUGVIEWVARYING_VERTEX_NORMAL_WS (7)
#define DEBUGVIEWVARYING_VERTEX_COLOR (8)
#define DEBUGVIEWVARYING_VERTEX_COLOR_ALPHA (9)
#define DEBUGVIEWVARYING_LAST (10)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Attributes.DebugViewGbuffer: static fields

#define DEBUGVIEWGBUFFER_BAKE_SHADOW_MASK1 (13)
#define DEBUGVIEWGBUFFER_BAKE_SHADOW_MASK2 (14)
#define DEBUGVIEWGBUFFER_BAKE_SHADOW_MASK3 (15)
#define DEBUGVIEWGBUFFER_LAST (16)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Attributes.DebugViewProperties: static fields

#define DEBUGVIEWPROPERTIES_DEPTH_OFFSET (20)
#define DEBUGVIEWPROPERTIES_LIGHTMAP (21)
#define DEBUGVIEWPROPERTIES_INSTANCING (22)
#define DEBUGVIEWPROPERTIES_LAST (23)
#endif

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs


private void DrawGizmo(bool selected)
{
var col = new Color(0.0f, 0.7f, 1f, 1.0f);
col.a = selected ? 0.3f : 0.1f;
Gizmos.color = col;
Gizmos.DrawCube(Vector3.zero, Vector3.one);
col.a = selected ? 0.5f : 0.2f;
Gizmos.color = col;
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);

66
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs


using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{

private SerializedProperty m_DrawDistanceProperty;
private SerializedProperty m_FadeScaleProperty;
public class DecalBoundsHandle : BoxBoundsHandle
{
protected override Bounds OnHandleChanged(HandleDirection handle, Bounds boundsOnClick, Bounds newBounds)
{
// special case for Y axis because decal mesh is centered at 0, -0.5, 0
if (handle == HandleDirection.NegativeY)
{
m_Translation = Vector3.zero;
m_Scale = newBounds.size;
}
else if (handle == HandleDirection.PositiveY)
{
m_Translation = (newBounds.center + newBounds.extents - (m_Center + 0.5f * m_Size));
m_Scale = (m_Size + m_Translation);
}
else
{
m_Translation = newBounds.center - m_Center;
m_Scale = newBounds.size;
}
return newBounds;
}
public void SetSizeAndCenter(Vector3 inSize, Vector3 inCenter)
{
// boundsOnClick implies that it gets refreshed only if the handle is clicked on again, but we need actual center and scale which we set before handle is drawn every frame
m_Center = inCenter;
m_Size = inSize;
center = inCenter;
size = inSize;
}
private Vector3 m_Center;
private Vector3 m_Size;
public Vector3 m_Translation;
public Vector3 m_Scale;
}
private DecalBoundsHandle m_Handle = new DecalBoundsHandle();
private void OnEnable()
{

// Update material editor with the new material
m_MaterialEditor = (MaterialEditor)CreateEditor(m_DecalProjectorComponent.Mat);
}
void OnSceneGUI()
{
EditorGUI.BeginChangeCheck();
var mat = Handles.matrix;
var col = Handles.color;
Handles.color = Color.white;
// decal mesh is centered at (0, -0.5, 0)
// zero out the local scale in the matrix so that handle code gives us back the actual scale
Handles.matrix = Matrix4x4.TRS(m_DecalProjectorComponent.transform.position, m_DecalProjectorComponent.transform.rotation, Vector3.one) * Matrix4x4.Translate(new Vector3(0.0f, -0.5f* m_DecalProjectorComponent.transform.localScale.y, 0.0f));
// pass in the scale
m_Handle.SetSizeAndCenter(m_DecalProjectorComponent.transform.localScale, Vector3.zero);
m_Handle.DrawHandle();
if (EditorGUI.EndChangeCheck())
{
// adjust decal transform if handle changed
m_DecalProjectorComponent.transform.Translate(m_Handle.m_Translation);
m_DecalProjectorComponent.transform.localScale = m_Handle.m_Scale;
Repaint();
}
Handles.matrix = mat;
Handles.color = col;
}
public override void OnInspectorGUI()
{

72
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


using System.Linq;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.Experimental.GlobalIllumination;
using UnityEngine.XR;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

// Use to detect frame changes
int m_FrameCount;
float m_LastTime, m_Time;
public int GetCurrentShadowCount() { return m_LightLoop.GetCurrentShadowCount(); }
public int GetShadowAtlasCount() { return m_LightLoop.GetShadowAtlasCount(); }

m_ValidAPI = false;
return ;
}
}
m_Asset = asset;
m_GPUCopy = new GPUCopy(asset.renderPipelineResources.copyChannelCS);

RTHandles.Release(m_DebugColorPickerBuffer);
RTHandles.Release(m_DebugFullScreenTempBuffer);
m_DebugScreenSpaceTracingData.Release();
HDCamera.ClearAll();

return false;
}
// VR is not supported currently in HD
if (XRSettings.isDeviceActive)
{
CoreUtils.DisplayUnsupportedXRMessage();
return false;
}
return true;
}

{
using (new ProfilingSample(cmd, "Push Global Parameters", CustomSamplerId.PushGlobalParameters.GetSampler()))
{
hdCamera.SetupGlobalParams(cmd);
if (m_FrameSettings.enableStereo)
hdCamera.SetupGlobalStereoParams(cmd);
// Set up UnityPerFrame CBuffer.
m_SSSBufferManager.PushGlobalParams(cmd, sssParameters, m_FrameSettings);
m_DbufferManager.PushGlobalParams(cmd, m_FrameSettings);

var ssReflection = VolumeManager.instance.stack.GetComponent<ScreenSpaceReflection>()
?? ScreenSpaceReflection.@default;
ssReflection.PushShaderParameters(cmd);
// Set up UnityPerView CBuffer.
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime);
if (m_FrameSettings.enableStereo) hdCamera.SetupGlobalStereoParams(cmd);
var previousDepthPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid);
if (previousDepthPyramidRT != null)

0.0f
));
}
}
}
}
bool IsConsolePlatform()

base.Render(renderContext, cameras);
RenderPipeline.BeginFrameRendering(cameras);
if (m_FrameCount != Time.frameCount)
{
// SRP.Render() can be called several times per frame.
// Also, most Time variables do not consistently update in the Scene View.
// This makes reliable detection of the start of the new frame VERY hard.
// One of the exceptions is 'Time.realtimeSinceStartup'.
// Therefore, outside of the Play Mode we update the time at 60 fps,
// and in the Play Mode we rely on 'Time.frameCount'.
float t = Time.realtimeSinceStartup;
int c = Time.frameCount;
bool newFrame;
if (Application.isPlaying)
{
newFrame = m_FrameCount != c;
m_FrameCount = c;
}
else
{
newFrame = (t - m_Time) > 0.0166f;
if (newFrame) m_FrameCount++;
}
if (newFrame)
m_FrameCount = Time.frameCount;
// Make sure both are never 0.
m_LastTime = (m_Time > 0) ? m_Time : t;
m_Time = t;
}
}
// TODO: Render only visible probes

m_DbufferManager.vsibleDecalCount = DecalSystem.m_DecalsVisibleThisFrame;
DecalSystem.instance.UpdateCachedMaterialData(); // textures, alpha or fade distances could've changed
DecalSystem.instance.UpdateTextureAtlas(cmd); // as this is only used for transparent pass, would've been nice not to have to do this if no transparent renderers are visible
DecalSystem.instance.CreateDrawData(); // prepare data is separate from draw
DecalSystem.instance.CreateDrawData(); // prepare data is separate from draw
}
}
renderContext.SetupCameraProperties(camera, m_FrameSettings.enableStereo);

using (new ProfilingSample(cmd, "Render shadows", CustomSamplerId.RenderShadows.GetSampler()))
{
// This call overwrites camera properties passed to the shader system.
// TODO: check if statement below still apply
renderContext.SetupCameraProperties(camera, m_FrameSettings.enableStereo); // Need to recall SetupCameraProperties after RenderShadows as it modify our view/proj matrix
// Overwrite camera properties set during the shadow pass with the original camera properties.
renderContext.SetupCameraProperties(camera, m_FrameSettings.enableStereo);
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime);
if (m_FrameSettings.enableStereo) hdCamera.SetupGlobalStereoParams(cmd);
}
using (new ProfilingSample(cmd, "Deferred directional shadows", CustomSamplerId.RenderDeferredDirectionalShadow.GetSampler()))

cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._ColorPyramidTexture, colorPyramidRT);
cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBuffer);
cmd.SetComputeVectorParam(m_applyDistortionCS, HDShaderIDs._Size, size);
cmd.SetComputeVectorParam(m_applyDistortionCS, HDShaderIDs._ZBufferParams, Shader.GetGlobalVector(HDShaderIDs._ZBufferParams));
cmd.DispatchCompute(m_applyDistortionCS, m_applyDistortionKernel, Mathf.CeilToInt(size.x / x), Mathf.CeilToInt(size.y / y), 1);
}

var debugSSTThisPass = debugScreenSpaceTracing && (m_CurrentDebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingRefraction);
if (debugSSTThisPass)
{
cmd.SetGlobalBuffer(HDShaderIDs._DebugScreenSpaceTracingData, m_DebugScreenSpaceTracingData);
cmd.SetGlobalBuffer(HDShaderIDs._DebugScreenSpaceTracingData, m_DebugScreenSpaceTracingData);
cmd.SetRandomWriteTarget(7, m_DebugScreenSpaceTracingData);
}
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent);

24
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _ShowGrid = Shader.PropertyToID("_ShowGrid");
public static readonly int _ShowDepthPyramidDebug = Shader.PropertyToID("_ShowDepthPyramidDebug");
public static readonly int _DebugEnvironmentProxyDepthScale = Shader.PropertyToID("_DebugEnvironmentProxyDepthScale");
public static readonly int _DebugViewMaterial = Shader.PropertyToID("_DebugViewMaterial");
public static readonly int _DebugLightingMode = Shader.PropertyToID("_DebugLightingMode");
public static readonly int _DebugLightingSubMode = Shader.PropertyToID("_DebugLightingSubMode");

public static readonly int _DebugMipMapMode = Shader.PropertyToID("_DebugMipMapMode");
public static readonly int _UseTileLightList = Shader.PropertyToID("_UseTileLightList");
public static readonly int _Time = Shader.PropertyToID("_Time");
public static readonly int _SinTime = Shader.PropertyToID("_SinTime");
public static readonly int _CosTime = Shader.PropertyToID("_CosTime");
public static readonly int _Time = Shader.PropertyToID("_Time");
public static readonly int _LastTime = Shader.PropertyToID("_LastTime");
public static readonly int _SinTime = Shader.PropertyToID("_SinTime");
public static readonly int _CosTime = Shader.PropertyToID("_CosTime");
public static readonly int _EnvLightSkyEnabled = Shader.PropertyToID("_EnvLightSkyEnabled");
public static readonly int _AmbientOcclusionParam = Shader.PropertyToID("_AmbientOcclusionParam");
public static readonly int _SkyTexture = Shader.PropertyToID("_SkyTexture");

public static readonly int _DirectionalContactShadowSampleCount = Shader.PropertyToID("_SampleCount");
public static readonly int _DirectionalLightDirection = Shader.PropertyToID("_LightDirection");
public static readonly int unity_OrthoParams = Shader.PropertyToID("unity_OrthoParams");
public static readonly int _ZBufferParams = Shader.PropertyToID("_ZBufferParams");
public static readonly int _ScreenParams = Shader.PropertyToID("_ScreenParams");
public static readonly int _ProjectionParams = Shader.PropertyToID("_ProjectionParams");
public static readonly int _WorldSpaceCameraPos = Shader.PropertyToID("_WorldSpaceCameraPos");
public static readonly int _StencilMask = Shader.PropertyToID("_StencilMask");
public static readonly int _StencilRef = Shader.PropertyToID("_StencilRef");
public static readonly int _StencilCmp = Shader.PropertyToID("_StencilCmp");

public static readonly int _DecalCount = Shader.PropertyToID("_DecalCount");
public static readonly int _DecalDatas = Shader.PropertyToID("_DecalDatas");
public static readonly int _WorldSpaceCameraPos = Shader.PropertyToID("_WorldSpaceCameraPos");
public static readonly int _ViewMatrix = Shader.PropertyToID("_ViewMatrix");
public static readonly int _InvViewMatrix = Shader.PropertyToID("_InvViewMatrix");
public static readonly int _ProjMatrix = Shader.PropertyToID("_ProjMatrix");

public static readonly int _InvViewProjMatrix = Shader.PropertyToID("_InvViewProjMatrix");
public static readonly int _ViewParam = Shader.PropertyToID("_ViewParam");
public static readonly int _DetViewMatrix = Shader.PropertyToID("_DetViewMatrix");
public static readonly int _ZBufferParams = Shader.PropertyToID("_ZBufferParams");
public static readonly int _ProjectionParams = Shader.PropertyToID("_ProjectionParams");
public static readonly int unity_OrthoParams = Shader.PropertyToID("unity_OrthoParams");
public static readonly int _ScreenParams = Shader.PropertyToID("_ScreenParams");
public static readonly int _TaaFrameIndex = Shader.PropertyToID("_TaaFrameIndex");
public static readonly int _TaaFrameRotation = Shader.PropertyToID("_TaaFrameRotation");
public static readonly int _ViewMatrixStereo = Shader.PropertyToID("_ViewMatrixStereo");

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Deferred.shader


// input.positionCS is SV_Position
float depth = LOAD_TEXTURE2D(_MainDepthTexture, input.positionCS.xy).x;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, uint2(input.positionCS.xy) / GetTileSize());
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, uint2(input.positionCS.xy) / GetTileSize());
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
BSDFData bsdfData;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/DeferredDirectionalShadow.compute


if (depth == UNITY_RAW_FAR_CLIP_VALUE)
return;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, tileCoord);
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, tileCoord);
#ifdef ENABLE_NORMALS
BSDFData bsdfData;

106
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl


attenuation *= shadow;
}
// Environment map share function
#include "Reflection/VolumeProjection.hlsl"
void EvaluateLight_EnvIntersection(float3 positionWS, float3 normalWS, EnvLightData lightData, int influenceShapeType, inout float3 R, inout float weight)
{
// Guideline for reflection volume: In HDRenderPipeline we separate the projection volume (the proxy of the scene) from the influence volume (what pixel on the screen is affected)
// However we add the constrain that the shape of the projection and influence volume is the same (i.e if we have a sphere shape projection volume, we have a shape influence).
// It allow to have more coherence for the dynamic if in shader code.
// Users can also chose to not have any projection, in this case we use the property minProjectionDistance to minimize code change. minProjectionDistance is set to huge number
// that simulate effect of no shape projection
float3x3 worldToIS = WorldToInfluenceSpace(lightData); // IS: Influence space
float3 positionIS = WorldToInfluencePosition(lightData, worldToIS, positionWS);
float3 dirIS = mul(R, worldToIS);
float3x3 worldToPS = WorldToProxySpace(lightData); // PS: Proxy space
float3 positionPS = WorldToProxyPosition(lightData, worldToPS, positionWS);
float3 dirPS = mul(R, worldToPS);
float projectionDistance = 0;
// Process the projection
// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.
if (influenceShapeType == ENVSHAPETYPE_SPHERE)
{
projectionDistance = IntersectSphereProxy(lightData, dirPS, positionPS);
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
weight = InfluenceSphereWeight(lightData, normalWS, positionWS, positionIS, dirIS);
}
else if (influenceShapeType == ENVSHAPETYPE_BOX)
{
projectionDistance = IntersectBoxProxy(lightData, dirPS, positionPS);
// No need to normalize for fetching cubemap
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
weight = InfluenceBoxWeight(lightData, normalWS, positionWS, positionIS, dirIS);
}
// Smooth weighting
weight = Smoothstep01(weight);
weight *= lightData.weight;
}
// Ambient occlusion
struct AmbientOcclusionFactor
{
float3 indirectAmbientOcclusion;
float3 directAmbientOcclusion;
float3 indirectSpecularOcclusion;
};
void GetScreenSpaceAmbientOcclusion(float2 positionSS, float NdotV, float perceptualRoughness, float specularOcclusionFromData, out AmbientOcclusionFactor aoFactor)
{
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
#else
float indirectAmbientOcclusion = 1.0;
float directAmbientOcclusion = 1.0;
#endif
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(NdotV), indirectAmbientOcclusion, roughness);
aoFactor.indirectAmbientOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), indirectAmbientOcclusion);
aoFactor.directAmbientOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
aoFactor.indirectSpecularOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(specularOcclusionFromData, specularOcclusion));
}
void GetScreenSpaceAmbientOcclusionMultibounce(float2 positionSS, float NdotV, float perceptualRoughness, float specularOcclusionFromData, float3 diffuseColor, float3 fresnel0, out AmbientOcclusionFactor aoFactor)
{
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the diffuseColor)
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
#else
float indirectAmbientOcclusion = 1.0;
float directAmbientOcclusion = 1.0;
#endif
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(NdotV), indirectAmbientOcclusion, roughness);
aoFactor.indirectAmbientOcclusion = GTAOMultiBounce(indirectAmbientOcclusion, diffuseColor);
aoFactor.directAmbientOcclusion = GTAOMultiBounce(min(specularOcclusionFromData, specularOcclusion), fresnel0);
aoFactor.indirectSpecularOcclusion = GTAOMultiBounce(directAmbientOcclusion, diffuseColor);
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Deferred.compute


// This need to stay in sync with deferred.shader
float depth = LOAD_TEXTURE2D(_MainDepthTexture, pixelCoord.xy).x;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, tileCoord);
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, tileCoord);
// For indirect case: we can still overlap inside a tile with the sky/background, reject it
// Can't rely on stencil as we are in compute shader

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


int NumLightIndicesPerClusteredTile()
{
return 8 * (1 << k_Log2NumClusters); // total footprint for all layers of the tile (measured in light index entries)
return 32 * (1 << k_Log2NumClusters); // total footprint for all layers of the tile (measured in light index entries)
}
public void AllocResolutionDependentBuffers(int width, int height, bool stereoEnabled)

int numTilesX = (hdCamera.actualWidth + (deferredShadowTileSize - 1)) / deferredShadowTileSize;
int numTilesY = (hdCamera.actualHeight + (deferredShadowTileSize - 1)) / deferredShadowTileSize;
hdCamera.SetupComputeShader(deferredDirectionalShadowComputeShader, cmd);
// TODO: Update for stereo
cmd.DispatchCompute(deferredDirectionalShadowComputeShader, kernel, numTilesX, numTilesY, 1);

int numVariants = 1;
if (enableFeatureVariants)
numVariants = LightDefinitions.s_NumFeatureVariants;
hdCamera.SetupComputeShader(deferredComputeShader, cmd);
for (int variant = 0; variant < numVariants; variant++)
{

public void RenderDebugOverlay(HDCamera hdCamera, CommandBuffer cmd, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width)
{
LightingDebugSettings lightingDebug = debugDisplaySettings.lightingDebugSettings;
if (lightingDebug.debugLightingMode == DebugLightingMode.EnvironmentProxyVolume)
cmd.SetGlobalFloat(HDShaderIDs._DebugEnvironmentProxyDepthScale, lightingDebug.environmentProxyDepthScale);
using (new ProfilingSample(cmd, "Tiled/cluster Lighting Debug", CustomSamplerId.TPTiledLightingDebug.GetSampler()))
{

19
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl


#define SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES 0
#define SINGLE_PASS_CONTEXT_SAMPLE_SKY 1
#ifdef DEBUG_DISPLAY
float4 ApplyDebugProjectionVolume(float4 color, float3 radiusToProxy, float scale)
{
float l = length(radiusToProxy);
l = pow(l / (1 + l), scale);
return float4(l.xxx * 0.7 + color.rgb * 0.3, color.a);
}
#endif
// Note: index is whatever the lighting architecture want, it can contain information like in which texture to sample (in case we have a compressed BC6H texture and an uncompressed for real time reflection ?)
// EnvIndex can also be use to fetch in another array of struct (to atlas information etc...).
// Cubemap : texCoord = direction vector

color.rgb = SAMPLE_TEXTURE2D_ARRAY_LOD(_Env2DTextures, s_trilinear_clamp_sampler, ndc.xy, index, lod).rgb;
color.a = any(ndc.xyz < 0) || any(ndc.xyz > 1) ? 0.0 : 1.0;
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_ENVIRONMENT_SAMPLE_COORDINATES)
color = float4(ndc.xy, 0, color.a);
#endif
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_ENVIRONMENT_SAMPLE_COORDINATES)
color = float4(texCoord.xyz * 0.5 + 0.5, color.a);
#endif
}
}
else // SINGLE_PASS_SAMPLE_SKY

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/VolumeProjection.hlsl


#define ENVMAP_FEATURE_PERFACEFADE
#define ENVMAP_FEATURE_INFLUENCENORMAL
#include "../LightDefinition.cs.hlsl"
float3x3 WorldToProxySpace(EnvLightData lightData)
{
return transpose(

return projectionDistance;
}
float InfluenceSphereWeight(EnvLightData lightData, BSDFData bsdfData, float3 positionWS, float3 positionLS, float3 dirLS)
float InfluenceSphereWeight(EnvLightData lightData, float3 normalWS, float3 positionWS, float3 positionLS, float3 dirLS)
{
float lengthPositionLS = length(positionLS);
float sphereInfluenceDistance = lightData.influenceExtents.x - lightData.blendDistancePositive.x;

#if defined(ENVMAP_FEATURE_INFLUENCENORMAL)
float insideInfluenceNormalVolume = lengthPositionLS <= (lightData.influenceExtents.x - lightData.blendNormalDistancePositive.x) ? 1.0 : 0.0;
float insideWeight = InfluenceFadeNormalWeight(bsdfData.normalWS, normalize(positionWS - lightData.capturePositionWS));
float insideWeight = InfluenceFadeNormalWeight(normalWS, normalize(positionWS - lightData.capturePositionWS));
alpha *= insideInfluenceNormalVolume ? 1.0 : insideWeight;
#endif

float InfluenceBoxWeight(EnvLightData lightData, BSDFData bsdfData, float3 positionWS, float3 positionIS, float3 dirIS)
float InfluenceBoxWeight(EnvLightData lightData, float3 normalWS, float3 positionWS, float3 positionIS, float3 dirIS)
{
float3 influenceExtents = lightData.influenceExtents;
// 2. Process the position influence

float3 belowPositiveInfluenceNormalVolume = positiveDistance / max(0.0001, lightData.blendNormalDistancePositive);
float3 aboveNegativeInfluenceNormalVolume = negativeDistance / max(0.0001, lightData.blendNormalDistanceNegative);
float insideInfluenceNormalVolume = all(belowPositiveInfluenceNormalVolume >= 1.0) && all(aboveNegativeInfluenceNormalVolume >= 1.0) ? 1.0 : 0;
float insideWeight = InfluenceFadeNormalWeight(bsdfData.normalWS, normalize(positionWS - lightData.capturePositionWS));
float insideWeight = InfluenceFadeNormalWeight(normalWS, normalize(positionWS - lightData.capturePositionWS));
alpha *= insideInfluenceNormalVolume ? 1.0 : insideWeight;
#endif

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


Vector4 resolution = new Vector4(w, h, 1.0f / w, 1.0f / h);
Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, camera.viewMatrix, false);
camera.SetupComputeShader( m_VolumeVoxelizationCS, cmd);
cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, vBuffer.GetDensityBuffer());
cmd.SetComputeBufferParam( m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeBounds, s_VisibleVolumeBoundsBuffer);
cmd.SetComputeBufferParam( m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeProperties, s_VisibleVolumePropertiesBuffer);

float vFoV = camera.camera.fieldOfView * Mathf.Deg2Rad;
Vector4 resolution = new Vector4(w, h, 1.0f / w, 1.0f / h);
Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, camera.viewMatrix, false);
camera.SetupComputeShader(m_VolumetricLightingCS, cmd);
Vector2[] xySeq = GetHexagonalClosePackedSpheres7();

18
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs.hlsl


{
float4x4 worldToDecal;
float4x4 normalToWorld;
float4 diffuseScaleBias;
float4 normalScaleBias;
float4 maskScaleBias;
float4 diffuseScaleBias;
float4 normalScaleBias;
float4 maskScaleBias;
};
//

float4x4 GetNormalToWorld(DecalData value)
{
return value.normalToWorld;
}
float4 GetDiffuseScaleBias(DecalData value)
{
return value.diffuseScaleBias;
}
float4 GetNormalScaleBias(DecalData value)
{
return value.normalScaleBias;
}
float4 GetMaskScaleBias(DecalData value)
{
return value.maskScaleBias;
}
//

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl


float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord, blendMasks);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
ApplyDepthOffsetPositionInput(V, depthOffset, GetViewForwardDir(), GetWorldToHClipMatrix(), posInput);
#endif
SurfaceData surfaceData0, surfaceData1, surfaceData2, surfaceData3;

104
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs


bool m_isInit;
// For image based lighting
Material m_InitPreFGD;
RenderTexture m_PreIntegratedFGD;
// For area lighting - We pack all texture inside a texture array to reduce the number of resource required
Texture2DArray m_LtcData; // 0: m_LtcGGXMatrix - RGBA, 2: m_LtcDisneyDiffuseMatrix - RGBA, 3: m_LtcMultiGGXFresnelDisneyDiffuse - RGB, A unused
const int k_LtcLUTMatrixDim = 3; // size of the matrix (3x3)
const int k_LtcLUTResolution = 64;
// Load LUT with one scalar in alpha of a tex2D
void LoadLUT(Texture2DArray tex, int arrayElement, TextureFormat format, float[] LUTScalar)
{
const int count = k_LtcLUTResolution * k_LtcLUTResolution;
Color[] pixels = new Color[count];
for (int i = 0; i < count; i++)
{
pixels[i] = new Color(0, 0, 0, LUTScalar[i]);
}
tex.SetPixels(pixels, arrayElement);
}
// Load LUT with 3x3 matrix in RGBA of a tex2D (some part are zero)
void LoadLUT(Texture2DArray tex, int arrayElement, TextureFormat format, double[,] LUTTransformInv)
{
const int count = k_LtcLUTResolution * k_LtcLUTResolution;
Color[] pixels = new Color[count];
for (int i = 0; i < count; i++)
{
// Both GGX and Disney Diffuse BRDFs have zero values in columns 1, 3, 5, 7.
// Column 8 contains only ones.
pixels[i] = new Color((float)LUTTransformInv[i, 0],
(float)LUTTransformInv[i, 2],
(float)LUTTransformInv[i, 4],
(float)LUTTransformInv[i, 6]);
}
tex.SetPixels(pixels, arrayElement);
}
// Special-case function for 'm_LtcMultiGGXFresnelDisneyDiffuse'.
void LoadLUT(Texture2DArray tex, int arrayElement, TextureFormat format, float[] LtcGGXMagnitudeData,
float[] LtcGGXFresnelData,
float[] LtcDisneyDiffuseMagnitudeData)
{
const int count = k_LtcLUTResolution * k_LtcLUTResolution;
Color[] pixels = new Color[count];
for (int i = 0; i < count; i++)
{
// We store the result of the subtraction as a run-time optimization.
// See the footnote 2 of "LTC Fresnel Approximation" by Stephen Hill.
pixels[i] = new Color(LtcGGXMagnitudeData[i] - LtcGGXFresnelData[i],
LtcGGXFresnelData[i], LtcDisneyDiffuseMagnitudeData[i], 1);
}
tex.SetPixels(pixels, arrayElement);
}
m_InitPreFGD = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/PreIntegratedFGD");
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGB2101010, RenderTextureReadWrite.Linear);
m_PreIntegratedFGD.hideFlags = HideFlags.HideAndDontSave;
m_PreIntegratedFGD.filterMode = FilterMode.Bilinear;
m_PreIntegratedFGD.wrapMode = TextureWrapMode.Clamp;
m_PreIntegratedFGD.hideFlags = HideFlags.DontSave;
m_PreIntegratedFGD.name = CoreUtils.GetRenderTargetAutoName(128, 128, RenderTextureFormat.ARGB2101010, "PreIntegratedFGD");
m_PreIntegratedFGD.Create();
m_LtcData = new Texture2DArray(k_LtcLUTResolution, k_LtcLUTResolution, 3, TextureFormat.RGBAHalf, false /*mipmap*/, true /* linear */)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Bilinear,
name = CoreUtils.GetTextureAutoName(k_LtcLUTResolution, k_LtcLUTResolution, TextureFormat.RGBAHalf, depth: 3, dim: TextureDimension.Tex2DArray, name: "LTC_LUT")
};
LoadLUT(m_LtcData, 0, TextureFormat.RGBAHalf, s_LtcGGXMatrixData);
LoadLUT(m_LtcData, 1, TextureFormat.RGBAHalf, s_LtcDisneyDiffuseMatrixData);
// TODO: switch to RGBA64 when it becomes available.
LoadLUT(m_LtcData, 2, TextureFormat.RGBAHalf, s_LtcGGXMagnitudeData, s_LtcGGXFresnelData, s_LtcDisneyDiffuseMagnitudeData);
m_LtcData.Apply();
PreIntegratedFGD.instance.Build();
LTCAreaLight.instance.Build();
m_isInit = false;
}

CoreUtils.Destroy(m_InitPreFGD);
CoreUtils.Destroy(m_PreIntegratedFGD);
CoreUtils.Destroy(m_LtcData);
PreIntegratedFGD.instance.Cleanup();
LTCAreaLight.instance.Cleanup();
// TODO: how to delete RenderTexture ? or do we need to do it ?
m_isInit = false;
}

return;
using (new ProfilingSample(cmd, "Init PreFGD"))
{
CoreUtils.DrawFullScreen(cmd, m_InitPreFGD, new RenderTargetIdentifier(m_PreIntegratedFGD));
}
PreIntegratedFGD.instance.RenderInit(cmd);
m_isInit = true;
}

Shader.SetGlobalTexture("_PreIntegratedFGD", m_PreIntegratedFGD);
Shader.SetGlobalTexture("_LtcData", m_LtcData);
PreIntegratedFGD.instance.Bind();
LTCAreaLight.instance.Bind();
}
}
}

326
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


TEXTURE2D(_GBufferTexture2);
TEXTURE2D(_GBufferTexture3);
// Rough refraction texture
// Color pyramid (width, height, lodcount, Unused)
TEXTURE2D(_ColorPyramidTexture);
// Depth pyramid (width, height, lodcount, Unused)
TEXTURE2D(_DepthPyramidTexture);
CBUFFER_START(UnityLightingParameters)
// Buffer pyramid
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
// Screen space lighting
float _SSRefractionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
float _SSReflectionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
// Ambiant occlusion
float4 _AmbientOcclusionParam; // xyz occlusion color, w directLightStrenght
CBUFFER_END
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
// Area light textures
// TODO: This one should be set into a constant Buffer at pass frequency (with _Screensize)
TEXTURE2D(_PreIntegratedFGD);
TEXTURE2D_ARRAY(_LtcData); // We pack the 3 Ltc data inside a texture array
#define LTC_GGX_MATRIX_INDEX 0 // RGBA
#define LTC_DISNEY_DIFFUSE_MATRIX_INDEX 1 // RGBA
#define LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX 2 // RGB, A unused
#define LTC_LUT_SIZE 64
#define LTC_LUT_SCALE ((LTC_LUT_SIZE - 1) * rcp(LTC_LUT_SIZE))
#define LTC_LUT_OFFSET (0.5 * rcp(LTC_LUT_SIZE))
#include "../LTCAreaLight/LTCAreaLight.hlsl"
#include "../PreIntegratedFGD/PreIntegratedFGD.hlsl"
//-----------------------------------------------------------------------------
// Definition

//-----------------------------------------------------------------------------
#if HAS_SSREFLECTION || HAS_REFRACTION
# include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"
# include "HDRP/Lighting/LightDefinition.cs.hlsl"
#include "HDRP/Lighting/LightDefinition.cs.hlsl"
#include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"
# include "CoreRP/ShaderLibrary/Refraction.hlsl"
# define SSRTID Refraction
# include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
# undef SSRTID
#include "CoreRP/ShaderLibrary/Refraction.hlsl"
#define SSRTID Refraction
#include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
#undef SSRTID
# if defined(_REFRACTION_PLANE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelPlane(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
# elif defined(_REFRACTION_SPHERE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelSphere(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
# endif
#if defined(_REFRACTION_PLANE)
#define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelPlane(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
#elif defined(_REFRACTION_SPHERE)
#define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelSphere(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
#endif
# if defined(_REFRACTION_SSRAY_PROXY)
# define REFRACTION_SSRAY_IN ScreenSpaceProxyRaycastInput
# define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceProxyRaycastRefraction(input, hit)
# elif defined(_REFRACTION_SSRAY_HIZ)
# define REFRACTION_SSRAY_IN ScreenSpaceHiZRaymarchInput
# define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceHiZRaymarchRefraction(input, hit)
# endif
#if defined(_REFRACTION_SSRAY_PROXY)
#define REFRACTION_SSRAY_IN ScreenSpaceProxyRaycastInput
#define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceProxyRaycastRefraction(input, hit)
#elif defined(_REFRACTION_SSRAY_HIZ)
#define REFRACTION_SSRAY_IN ScreenSpaceHiZRaymarchInput
#define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceHiZRaymarchRefraction(input, hit)
#endif
#endif
#if HAS_SSREFLECTION

#endif
#include "../../Lighting/LightEvaluation.hlsl"
#include "../../Lighting/Reflection/VolumeProjection.hlsl"
//-----------------------------------------------------------------------------
// Lighting structure for light accumulation

#endif
#if !HAS_SSREFLECTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
{
{
return lighting;
}
#endif

if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
// Refraction process:
// 1. Depending on the shape model, we calculate the refracted point in world space and the optical depth
// 2. We calculate the screen space position of the refracted point
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
// a. Get the corresponding color depending on the roughness from the gaussian pyramid of the color buffer
// b. Multiply by the transmittance for absorption (depends on the optical depth)
// Refraction process:
// 1. Depending on the shape model, we calculate the refracted point in world space and the optical depth
// 2. We calculate the screen space position of the refracted point
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
// a. Get the corresponding color depending on the roughness from the gaussian pyramid of the color buffer
// b. Multiply by the transmittance for absorption (depends on the optical depth)
rayOriginWS = preLightData.transparentPositionWS;
rayDirWS = preLightData.transparentRefractV;

}
#if DEBUG_DISPLAY
bool debug = _DebugLightingMode == debugMode
bool debug = _DebugLightingMode == debugMode
&& !any(int2(_MouseClickPixelCoord.xy) - int2(posInput.positionSS));
#endif

// Initialize screen space tracing
// Initialize screen space tracing
// Common initialization
ssRayInput.rayOriginWS = rayOriginWS;
ssRayInput.rayDirWS = rayDirWS;
// Common initialization
ssRayInput.rayOriginWS = rayOriginWS;
ssRayInput.rayDirWS = rayDirWS;
ssRayInput.debug = debug;
ssRayInput.debug = debug;
// Algorithm specific initialization
// Algorithm specific initialization
ssRayInput.maxIterations = uint(-1);
ssRayInput.maxIterations = uint(-1);
ssRayInput.proxyData = envLightData;
ssRayInput.proxyData = envLightData;
// Perform ray query
ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
// Perform ray query
ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
// Debug screen space tracing
// Debug screen space tracing
if (_DebugLightingMode == debugMode
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
{
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
if (_DebugLightingMode == debugMode
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
{
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
lighting.specularTransmitted = hit.debugOutput;
lighting.specularTransmitted = hit.debugOutput;
return lighting;
}
return lighting;
}
if (!hitSuccessful)
return lighting;
if (!hitSuccessful)
return lighting;
weightNDC = weightNDC * weightNDC * (3 - 2 * weightNDC);
float weight = weightNDC.x * weightNDC.y;
weightNDC = weightNDC * weightNDC * (3 - 2 * weightNDC);
float weight = weightNDC.x * weightNDC.y;
float hitDeviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, hit.positionSS, 0).r;
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);
float hitDeviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, hit.positionSS, 0).r;
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);
// Exit if texel is out of color buffer
// Or if the texel is from an object in front of the object
if (hitLinearDepth < posInput.linearDepth
|| weight == 0)
{
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
}
// Exit if texel is out of color buffer
// Or if the texel is from an object in front of the object
if (hitLinearDepth < posInput.linearDepth
|| weight == 0)
{
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
}
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hierarchy priority
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hierarchy priority
float3 preLD = SAMPLE_TEXTURE2D_LOD(
_ColorPyramidTexture,
s_trilinear_clamp_sampler,
hit.positionNDC * _ColorPyramidScale.xy,
float3 preLD = SAMPLE_TEXTURE2D_LOD(
_ColorPyramidTexture,
s_trilinear_clamp_sampler,
hit.positionNDC * _ColorPyramidScale.xy,
).rgb;
).rgb;
float3 F = preLightData.specularFGD;
float3 F = preLightData.specularFGD;
lighting.specularTransmitted = (1.0 - F) * preLD.rgb * preLightData.transparentTransmittance * weight;
lighting.specularTransmitted = (1.0 - F) * preLD.rgb * preLightData.transparentTransmittance * weight;
else if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = F * preLD.rgb * weight;
#endif

#undef SSRAY_QUERY
#undef SSRAY_MODEL
return lighting;
return lighting;
}
//-----------------------------------------------------------------------------

#else
// TODO: factor this code in common, so other material authoring don't require to rewrite everything,
// TODO: test the strech from Tomasz
// float roughness = PerceptualRoughnessToRoughness(preLightData.IblPerceptualRoughness);
// float shrunkRoughness = AnisotropicStrechAtGrazingAngle(roughness, roughness, NdotV);
// Guideline for reflection volume: In HDRenderPipeline we separate the projection volume (the proxy of the scene) from the influence volume (what pixel on the screen is affected)
// However we add the constrain that the shape of the projection and influence volume is the same (i.e if we have a sphere shape projection volume, we have a shape influence).
// It allow to have more coherence for the dynamic if in shader code.
// Users can also chose to not have any projection, in this case we use the property minProjectionDistance to minimize code change. minProjectionDistance is set to huge number
// that simulate effect of no shape projection
float3 coatR = preLightData.coatIblR;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{

// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.
float3x3 worldToIS = WorldToInfluenceSpace(lightData);
float3 positionIS = WorldToInfluencePosition(lightData, worldToIS, positionWS);
float3 dirIS = mul(R, worldToIS);
float3x3 worldToPS = WorldToProxySpace(lightData);
float3 positionPS = WorldToProxyPosition(lightData, worldToPS, positionWS);
float3 dirPS = mul(R, worldToPS);
float projectionDistance = 0;
// 1. First process the projection
if (influenceShapeType == ENVSHAPETYPE_SPHERE)
{
projectionDistance = IntersectSphereProxy(lightData, dirPS, positionPS);
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);
// Test again for clear coat
// Don't do clear coating for refraction
float3 coatR = preLightData.coatIblR;
dirPS = mul(coatR, worldToPS);
projectionDistance = IntersectSphereProxy(lightData, dirPS, positionPS);
coatR = (positionWS + projectionDistance * coatR) - capturePositionWS;
float unusedWeight = 0.0;
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, coatR, unusedWeight);
weight = InfluenceSphereWeight(lightData, bsdfData, positionWS, positionIS, dirIS);
}
else if (influenceShapeType == ENVSHAPETYPE_BOX)
{
projectionDistance = IntersectBoxProxy(lightData, dirPS, positionPS);
// No need to normalize for fetching cubemap
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
// TODO: add distance based roughness
// Test again for clear coat
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirPS = mul(coatR, worldToPS);
projectionDistance = IntersectBoxProxy(lightData, dirPS, positionPS);
coatR = (positionWS + projectionDistance * coatR) - capturePositionWS;
}
weight = InfluenceBoxWeight(lightData, bsdfData, positionWS, positionIS, dirIS);
}
#ifdef DEBUG_DISPLAY
float3 radiusToProxy = R;
#endif
// When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume
// Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection.

float3 sampleDirectionDiscardWS = lightData.sampleDirectionDiscardWS;
if (dot(sampleDirectionDiscardWS, R) < 0)
if (dot(sampleDirectionDiscardWS, R) < 0) // Use by planar reflection to early reject opposite plan reflection, neutral for reflection probe
weight *= preLD.a;
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_ENVIRONMENT_PROXY_VOLUME)
preLD = ApplyDebugProjectionVolume(preLD, radiusToProxy, _DebugEnvironmentProxyDepthScale);
#endif
// Smooth weighting
weight = Smoothstep01(weight);
weight *= preLD.a; // Used by planar reflection to discard pixel
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
{

#endif // LIT_DISPLAY_REFERENCE_IBL
weight *= lightData.weight;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
envLighting *= weight * lightData.multiplier;

{
float3 bakeDiffuseLighting = bakeLightingData.bakeDiffuseLighting;
AmbientOcclusionFactor aoFactor;
#define GTAO_MULTIBOUNCE_APPROX 1
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.positionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
#if 0
GetScreenSpaceAmbientOcclusion(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.specularOcclusion, aoFactor);
float indirectAmbientOcclusion = 1.0;
float directAmbientOcclusion = 1.0;
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
#if GTAO_MULTIBOUNCE_APPROX
bakeDiffuseLighting *= GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
#else
bakeDiffuseLighting *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), indirectAmbientOcclusion);
#endif
bakeDiffuseLighting *= aoFactor.indirectAmbientOcclusion;
lighting.indirect.specularReflected *= aoFactor.indirectSpecularOcclusion;
lighting.direct.diffuse *= aoFactor.directAmbientOcclusion;
float roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(preLightData.NdotV), indirectAmbientOcclusion, roughness);
// Try to mimic multibounce with specular color. Not the point of the original formula but ok result.
// Take the min of screenspace specular occlusion and visibility cone specular occlusion
#if GTAO_MULTIBOUNCE_APPROX
lighting.indirect.specularReflected *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
#else
lighting.indirect.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
#endif
lighting.direct.diffuse *=
#if GTAO_MULTIBOUNCE_APPROX
GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
#else
lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
#endif
// Subsurface scattering mdoe
uint texturingMode = (bsdfData.materialFeatures >> MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET) & 3;
float3 modifiedDiffuseColor = ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor);

// If refraction is enable we use the transmittanceMask to lerp between current diffuse lighting and refraction value
// Physically speaking, it should be transmittanceMask should be 1, but for artistic reasons, we let the value vary
// Physically speaking, transmittanceMask should be 1, but for artistic reasons, we let the value vary
#if HAS_REFRACTION
diffuseLighting = lerp(diffuseLighting, lighting.indirect.specularTransmitted, bsdfData.transmittanceMask);
#endif

if (_DebugLightingMode != 0)
{
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
switch (_DebugLightingMode)
{
case DEBUGLIGHTINGMODE_LUX_METER:

case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO:
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO:
diffuseLighting = specularOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
#if GTAO_MULTIBOUNCE_APPROX
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO:
diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION:
diffuseLighting = aoFactor.indirectAmbientOcclusion;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO:
diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION:
diffuseLighting = aoFactor.indirectSpecularOcclusion;
#endif
{
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
break;
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitData.hlsl


float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
ApplyDepthOffsetPositionInput(V, depthOffset, GetViewForwardDir(), GetWorldToHClipMatrix(), posInput);
#endif
// We perform the conversion to world of the normalTS outside of the GetSurfaceData

52
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl


#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER)
{
diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting;
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)
{
// NEWLITTODO
//diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO)
{
// NEWLITTODO
//diffuseLighting = specularOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#if GTAO_MULTIBOUNCE_APPROX
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO)
if (_DebugLightingMode != 0)
// NEWLITTODO
//diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO)
{
// NEWLITTODO
//diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
switch (_DebugLightingMode)
{
case DEBUGLIGHTINGMODE_LUX_METER:
//diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting;
break;
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION:
//diffuseLighting = indirectAmbientOcclusion;
break;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION:
//diffuseLighting = specularOcclusion;
break;
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION:
//if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
// diffuseLighting = lighting.indirect.specularTransmitted;
break;
}
#endif
// NEWLITTODO
//diffuseLighting = bsdfData.diffuseColor;
diffuseLighting = bsdfData.diffuseColor;
#endif
}

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs


cmd.ClearRandomWriteTargets();
}
// TODO: Remove this once fix, see comment inside the function
hdCamera.SetupComputeShader(m_SubsurfaceScatteringCS, cmd);
unsafe
{
// Warning: Unity is not able to losslessly transfer integers larger than 2^24 to the shader system.

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/CameraMotionVectors.shader


{
float depth = LOAD_TEXTURE2D(_MainDepthTexture, input.positionCS.xy).x;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
float4 worldPos = float4(posInput.positionWS, 1.0);
float4 prevPos = worldPos;

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/CopyStencilBuffer.shader


#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "../ShaderVariables.hlsl"
#include "../Lighting/LightDefinition.cs.hlsl"
int _StencilRef;
RW_TEXTURE2D(float, _HTile); // DXGI_FORMAT_R8_UINT is not supported by Unity

SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Name "Pass 0 - Copy stencilRef to output"

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassDBuffer.hlsl


FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
float depth = LOAD_TEXTURE2D(_MainDepthTexture, input.positionSS.xy).x;
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
// Transform from world space to decal space (DS) to clip the decal.
// For this we must use absolute position.

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/VaryingMesh.hlsl


output.isFrontFace = IS_FRONT_VFACE(input.cullFace, true, false);
// Handle handness of the view matrix (In Unity view matrix default to a determinant of -1)
// when we render a cubemap the view matrix handness is flipped (due to convention used for cubemap) we have a determinant of +1
output.isFrontFace = _ViewParam.x < 0.0 ? output.isFrontFace : !output.isFrontFace;
output.isFrontFace = _DetViewMatrix < 0.0 ? output.isFrontFace : !output.isFrontFace;
#endif
return output;

175
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


// ----------------------------------------------------------------------------
CBUFFER_START(UnityPerCamera)
// Time (t = time since current level load) values from Unity
float4 _Time; // (t/20, t, t*2, t*3)
float4 _LastTime; // Last frame time (t/20, t, t*2, t*3)
float4 _SinTime; // sin(t/8), sin(t/4), sin(t/2), sin(t)
float4 _CosTime; // cos(t/8), cos(t/4), cos(t/2), cos(t)
float4 unity_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt
#if !defined(USING_STEREO_MATRICES)
float3 _WorldSpaceCameraPos;
#endif
// x = 1 or -1 (-1 if projection is flipped)
// y = near plane
// z = far plane
// w = 1/far plane
float4 _ProjectionParams;
// x = width
// y = height
// z = 1 + 1.0/width
// w = 1 + 1.0/height
float4 _ScreenParams;
// x = camera.pixelWidth / RTHandle.maxWidth
// y = camera.pixelHeight / RTHandle.maxHeight
float4 _ScreenToTargetScale;
// Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
// x = 1-far/near
// y = far/near
// z = x/far
// w = y/far
// or in case of a reversed depth buffer (UNITY_REVERSED_Z is 1)
// x = -1+far/near
// y = 1
// z = x/far
// w = 1/far
float4 _ZBufferParams;
// x = orthographic camera's width
// y = orthographic camera's height
// z = unused
// w = 1.0 if camera is ortho, 0.0 if perspective
float4 unity_OrthoParams;
CBUFFER_END
// *********************************************************
// * *
// * UnityPerCameraRare has been deprecated. Do NOT use! *
// * Please refer to UnityPerView instead. *
// * *
// *********************************************************
// DEPRECATED: use _FrustumPlanes
float4 unity_CameraWorldClipPlanes[6];
#if !defined(USING_STEREO_MATRICES)

// DEPRECATED: use _ProjMatrix, _InvProjMatrix, _ViewMatrix, _InvViewMatrix
float4x4 unity_CameraProjection;
float4x4 unity_CameraInvProjection;
float4x4 unity_WorldToCamera;

#endif
float4 unity_ShadowColor;
float2 _TaaFrameRotation; // {x = sin(_TaaFrameIndex * PI/2), y = cos(_TaaFrameIndex * PI/2), z = unused}
uint _TaaFrameIndex; // [0, 7]
// Volumetric lighting.
float4 _AmbientProbeCoeffs[7]; // 3 bands of SH, packed, rescaled and convolved with the phase function
float _GlobalAsymmetry;
float3 _GlobalScattering;
float _GlobalExtinction;
float4 _VBufferResolution; // { w, h, 1/w, 1/h }
float4 _VBufferSliceCount; // { count, 1/count, 0, 0 }
float4 _VBufferDepthEncodingParams; // See the call site for description
float4 _VBufferDepthDecodingParams; // See the call site for description
CBUFFER_END
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// TODO: all affine matrices should be 3x4.
// TODO: sort these vars by the frequency of use (descending), and put commonly used vars together.
CBUFFER_START(UnityPerPass)
float4x4 _PrevViewProjMatrix; // non-jittered
float4x4 _ViewProjMatrix;
float4x4 _NonJitteredViewProjMatrix;
float4x4 _ViewMatrix;
float4x4 _ProjMatrix;
float4x4 _InvViewProjMatrix;
float4x4 _InvViewMatrix;
float4x4 _InvProjMatrix;
float4 _ViewParam; // .x = ViewMatrix determinant
float4 _InvProjParam;
float4 _ScreenSize; // {w, h, 1/w, 1/h}
float4 _FrustumPlanes[6]; // {(a, b, c) = N, d = -dot(N, P)} [L, R, T, B, N, F]
CBUFFER_START(UnityPerView)
float4x4 _ViewMatrix;
float4x4 _InvViewMatrix;
float4x4 _ProjMatrix;
float4x4 _InvProjMatrix;
float4x4 _ViewProjMatrix;
float4x4 _InvViewProjMatrix;
float4x4 _NonJitteredViewProjMatrix;
float4x4 _PrevViewProjMatrix; // non-jittered
// TODO: put commonly used vars together (below), and then sort them by the frequency of use (descending).
// Note: a matrix is 4 * 4 * 4 = 64 bytes (1x cache line), so no need to sort those.
#if defined(USING_STEREO_MATRICES)
float3 _Align16;
#else
float3 _WorldSpaceCameraPos;
#endif
float _DetViewMatrix; // determinant(_ViewMatrix)
float4 _ScreenSize; // { w, h, 1 / w, 1 / h }
float4 _ScreenToTargetScale; // { w / RTHandle.maxWidth, h / RTHandle.maxHeight, 0, 0 }
// Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
// x = 1 - f/n
// y = f/n
// z = 1/f - 1/n
// w = 1/n
// or in case of a reversed depth buffer (UNITY_REVERSED_Z is 1)
// x = -1 + f/n
// y = 1
// z = -1/n + -1/f
// w = 1/f
float4 _ZBufferParams;
// x = 1 or -1 (-1 if projection is flipped)
// y = near plane
// z = far plane
// w = 1/far plane
float4 _ProjectionParams;
// x = orthographic camera's width
// y = orthographic camera's height
// z = unused
// w = 1.0 if camera is ortho, 0.0 if perspective
float4 unity_OrthoParams;
// x = width
// y = height
// z = 1 + 1.0/width
// w = 1 + 1.0/height
float4 _ScreenParams;
float4 _FrustumPlanes[6]; // { (a, b, c) = N, d = -dot(N, P) } [L, R, T, B, N, F]
// TAA Frame Index ranges from 0 to 7. This gives you two rotations per cycle.
float4 _TaaFrameRotation; // { sin(taaFrame * PI/2), cos(taaFrame * PI/2), 0, 0 }
// t = animateMaterials ? Time.realtimeSinceStartup : 0.
float4 _Time; // { t/20, t, t*2, t*3 }
float4 _LastTime; // { t/20, t, t*2, t*3 }
float4 _SinTime; // { sin(t/8), sin(t/4), sin(t/2), sin(t) }
float4 _CosTime; // { cos(t/8), cos(t/4), cos(t/2), cos(t) }
float4 unity_DeltaTime; // { dt, 1/dt, smoothdt, 1/smoothdt }
// Volumetric lighting.
float4 _AmbientProbeCoeffs[7]; // 3 bands of SH, packed, rescaled and convolved with the phase function
float _GlobalAsymmetry;
float3 _GlobalScattering;
float _GlobalExtinction;
float4 _VBufferResolution; // { w, h, 1/w, 1/h }
float4 _VBufferSliceCount; // { count, 1/count, 0, 0 }
float4 _VBufferDepthEncodingParams; // See the call site for description
float4 _VBufferDepthDecodingParams; // See the call site for description
CBUFFER_END
CBUFFER_START(UnityLightingParameters)
// Buffer pyramid
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
// Screen space lighting
float _SSRefractionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
float _SSReflectionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
// Ambiant occlusion
float4 _AmbientOcclusionParam; // xyz occlusion color, w directLightStrenght
// Rough refraction texture
// Color pyramid (width, height, lodcount, Unused)
TEXTURE2D(_ColorPyramidTexture);
// Depth pyramid (width, height, lodcount, Unused)
TEXTURE2D(_DepthPyramidTexture);
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
// Custom generated by HDRP, not from Unity Engine (passed in via HDCamera)
#if defined(USING_STEREO_MATRICES)

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl


return positionWS;
}
// Note: '_WorldSpaceCameraPos' is set by the legacy Unity code.
float3 GetPrimaryCameraPosition()
{
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)

return GetPrimaryCameraPosition();
#else
// This is a generic solution.
// However, for the primary camera, using '_WorldSpaceCameraPos' is better for cache locality,
// However, using '_WorldSpaceCameraPos' is better for cache locality,
// and in case we enable camera-relative rendering, we can statically set the position is 0.
return UNITY_MATRIX_I_V._14_24_34;
#endif

#if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS)
return (unity_OrthoParams.w == 0);
#else
// This is a generic solution.
// However, using 'unity_OrthoParams' is better for cache locality.
// TODO: set 'unity_OrthoParams' during the shadow pass.
return UNITY_MATRIX_P[3][3] == 0;
#endif

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/OpaqueAtmosphericScattering.shader


float4 Frag(Varyings input) : SV_Target
{
float depth = LOAD_TEXTURE2D(_MainDepthTexture, input.positionCS.xy).x;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
if (depth == UNITY_RAW_FAR_CLIP_VALUE)
{

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Wind/ShaderWindSettings.cs


void ApplySettings()
{
Shader.SetGlobalTexture("WIND_SETTINGS_TexNoise", NoiseTexture);
Shader.SetGlobalTexture("WIND_SETTINGS_TexGust", GustMaskTexture);
Shader.SetGlobalTexture("_WIND_SETTINGS_TexNoise", NoiseTexture);
Shader.SetGlobalTexture("_WIND_SETTINGS_TexGust", GustMaskTexture);
Shader.SetGlobalVector("WIND_SETTINGS_WorldDirectionAndSpeed", GetDirectionAndSpeed());
Shader.SetGlobalFloat("WIND_SETTINGS_FlexNoiseScale", 1.0f / Mathf.Max(0.01f, FlexNoiseWorldSize));
Shader.SetGlobalFloat("WIND_SETTINGS_ShiverNoiseScale", 1.0f / Mathf.Max(0.01f, ShiverNoiseWorldSize));

100
ScriptableRenderPipeline/LightweightPipeline/CHANGELOG.md


# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [1.1.4-preview]
### Improvements
- Terrain and grass shaders ported
- Updated materials and shader default albedo and specular color to midgrey.
- Exposed _ScaledScreenParams to shader. It works the same as _ScreenParams but takes pipeline RenderScale into consideration
- Performance Improvements in mobile
### Bugfixes
- Fixed SRP Shader library issue that was causing all constants to be highp in mobile
- Fixed shader error that prevented LWRP to build to UWP
- Fixed shader compilation errors in Linux due to case sensitive includes
- Fixed Rendering Texture flipping issue
- Fixed Standard Particles shader cutout and blending modes
- Fixed crash caused by using projectors
- Fixed issue that was causing Shadow Strength to not be computed on mobile
- Fixed Material Upgrader issue that caused editor to SoftLocks
- Fixed GI in Unlit shader
- Fixed null reference in the Unlit material shader GUI
## [0.1.6] - 2018-xx-yy
## [1.1.2-preview]
### Improvements
- Performance improvements in mobile
### Bugfixes
- Fixed shadows on GLES 2.0
- Fixed CPU performance regression in shadow rendering
- Fixed alpha clip shadow issues
- Fixed unmatched command buffer error message
- Fixed null reference exception caused by missing resource in LWRP
- Fixed issue that was causing Camera clear flags was being ignored in mobile
### Changelog starting
## [1.1.1-preview]
### Improvements
- Added Cascade Split selection UI
- Shadowmap uses 16bit format instead of 32bit.
- Added SHADER_HINT_NICE_QUALITY. If user defines this to 1 in the shader Lightweight pipeline will favor quality even on mobile platforms.
- Small shader performance improvements
Started Changelog
### Bugfixes
- Fixed Subtractive Mode
- Shadow Distance does not accept negative values anymore
## [0.1.24]
### Improvements
- Refactored lightweight standard shaders and shader library to improve ease of use.
- Added Light abstraction layer on lightweight shader library.
- HDR RT now uses what format is configured in Tier settings.
- Optimized tile LOAD op on mobile.
- Added HDR global setting on pipeline asset.
- Added Soft Particles settings on pipeline asset.
- Ported particles shaders to SRP library
- Reduced GC pressure
- Reduced shader variant count by ~56% by improving fog and lightmap keywords
- Converted LW shader library files to use real/half when necessary.
### Bugfixes
- Fixed realtime shadows on OpenGL
- Fixed shader compiler errors in GLES 2.0
- Fixed issue sorting issues when BeforeTransparent custom fx was enabled.
- Fixed VR single pass rendering.
- Fixed viewport rendering issues when rendering to backbuffer.
- Fixed viewport rendering issues when rendering to with MSAA turned off.
- Fixed multi-camera rendering.
## [0.1.23]
### Improvements
- Shaders ported to the new SRP shader library.
- Constant Buffer Refactor to use new Batcher
- Shadow filtering and bias improved.
- Pipeline now updates color constants in gamma when in Gamma colorspace.
- UI Improvements (Rendering features not supported by LW are hidden)
- Optimized ALU and CB usage on Shadows.
- Reduced shader variant count by ~33% by improving shadow and light classification keywords
- Default resources were removed from the pipeline asset.
### Bugfixes
- Fixed shader include path when using SRP from package manager.
- Fixed spot light attenuation to match Unity Built-in pipeline.
- Fixed depth pre-pass clearing issue.
## [0.1.12]
### Improvements
- Realtime shadow filtering was improved.
- Standard Unlit shader now has an option to sample GI.
- Added Material Upgrader for stock Unity Mobile and Legacy Shaders.
- UI improvements
### Bugfixes
- Fixed an issue that was including unreferenced shaders in the build.
- Fixed a null reference caused by Particle System component lights.
## [0.1.11]
Initial Release.

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


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

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

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

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

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

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

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

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

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

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


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

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


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

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


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

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

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

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

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

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

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

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

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


using System;
using UnityEditor;
using UnityEngine;

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

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

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

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

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


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

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

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

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

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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


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

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

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

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


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

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

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


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

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

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

20
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightConstantBuffer.cs


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

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

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

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

160
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs


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

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

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

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShaderUtils.cs


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

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


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

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

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


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

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

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


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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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


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

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

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


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

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


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

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LTCAreaLight/LtcData.DisneyDiffuse.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public partial class Lit : RenderPipelineMaterial
public partial class LTCAreaLight
//-------------------------------------------------------------------------------------------
// LTC area light Look up table (fit for Disney Diffuse)
//-------------------------------------------------------------------------------------------
public static double[,] s_LtcDisneyDiffuseMatrixData = new double[k_LtcLUTResolution * k_LtcLUTResolution, k_LtcLUTMatrixDim * k_LtcLUTMatrixDim]
{
{1.018309, 0, 0.000000, 0, 1.018309, 0, 0.000000, 0, 1},

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LTCAreaLight/LtcData.GGX.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public partial class Lit : RenderPipelineMaterial
public partial class LTCAreaLight
{
//-------------------------------------------------------------------------------------------
// LTC area light Look up table (fit for GGX with height-correlated Smith's visibility term)

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LTCAreaLight.meta


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

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/PreIntegratedFGD.meta


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

631
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存