浏览代码

Merge branch 'master' into lowendmobile

/vr_sandbox
Felipe Lira 8 年前
当前提交
05e84b23
共有 239 个文件被更改,包括 1437 次插入1024 次删除
  1. 1
      Assets/BasicRenderLoopTutorial/BasicRenderLoop.cs
  2. 3
      Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs
  3. 2
      Assets/Editor/Tests/ShaderGeneratorTests/ShaderGeneratorTests.cs
  4. 10
      Assets/ScriptableRenderLoop/AdditionalLightData.cs
  5. 5
      Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs
  6. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/DebugViewMaterial.cs
  7. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/DebugViewMaterial.cs.hlsl
  8. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader
  9. 10
      Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
  10. 8
      Assets/ScriptableRenderLoop/HDRenderPipeline/Editor/UpgradeStandardShaderMaterials.cs
  11. 32
      Assets/ScriptableRenderLoop/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  12. 10
      Assets/ScriptableRenderLoop/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  13. 137
      Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs
  14. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting.meta
  15. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightDefinition.cs
  16. 32
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  17. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightLoop.cs
  18. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/Resources/Deferred.shader
  19. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass.meta
  20. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
  21. 31
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  22. 14
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  23. 17
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  24. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material.meta
  25. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Builtin/BuiltinData.cs
  26. 8
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Builtin/BuiltinData.cs.hlsl
  27. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit.meta
  28. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/Editor.meta
  29. 175
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  30. 112
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  31. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit.meta
  32. 138
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  33. 51
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  34. 7
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs
  35. 10
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs
  36. 5
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.cs
  37. 12
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  38. 151
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.hlsl
  39. 73
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.shader
  40. 195
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl
  41. 31
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  42. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs
  43. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LtcData.GGX.cs
  44. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/PreIntegratedFGD.shader
  45. 92
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  46. 8
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/MaterialUtilities.hlsl
  47. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  48. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs
  49. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.cs
  50. 8
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.cs.hlsl
  51. 98
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.shader
  52. 27
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/UnlitData.hlsl
  53. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/UnlitSharePass.hlsl
  54. 207
      Assets/ScriptableRenderLoop/HDRenderPipeline/PostProcess/Resources/FinalPass.shader
  55. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/CommonSettings.cs
  56. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/Editor/CommonSettingsEditor.cs
  57. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderConfig.cs
  58. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderConfig.cs.hlsl
  59. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPass.cs
  60. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl
  61. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl
  62. 11
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
  63. 8
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassGBuffer.hlsl
  64. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassLightTransport.hlsl
  65. 32
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl
  66. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Shadow/FixedSizePCF/FixedSizePCF.cs
  67. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky.meta
  68. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Editor/HDRISkyEditor.cs
  69. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/HDRISkyParameters.cs
  70. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs
  71. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader
  72. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs
  73. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyParameters.cs
  74. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  75. 10
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader
  76. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader
  77. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyManager.cs
  78. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyManager.cs.hlsl
  79. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyParameters.cs
  80. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyRenderer.cs
  81. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Utilities.cs
  82. 2
      Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs
  83. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl
  84. 37
      Assets/ScriptableRenderLoop/ShaderLibrary/BSDF.hlsl
  85. 62
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  86. 25
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl
  87. 15
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl
  88. 62
      Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl
  89. 4
      Assets/ScriptableRenderLoop/ShaderLibrary/Fibonacci.hlsl
  90. 260
      Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl
  91. 51
      Assets/ScriptableRenderLoop/ShaderLibrary/Packing.hlsl
  92. 2
      Assets/ScriptableRenderLoop/common/TextureCache.cs
  93. 2
      Assets/ScriptableRenderLoop/common/TextureSettings.cs
  94. 4
      Assets/ScriptableRenderLoop/core/RenderPipeline.cs
  95. 4
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  96. 2
      Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs
  97. 5
      Assets/ShaderGenerator/Editor/CSharpToHLSL.cs
  98. 2
      Assets/ShaderGenerator/Editor/ShaderGeneratorMenu.cs
  99. 4
      Assets/ShaderGenerator/Editor/ShaderTypeGeneration.cs
  100. 2
      Assets/ShaderGenerator/ShaderGeneratorAttributes.cs

1
Assets/BasicRenderLoopTutorial/BasicRenderLoop.cs


using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.ScriptableRenderPipeline;
// Very basic scriptable rendering loop example:
// - Use with BasicRenderLoopShader.shader (the loop expects "BasicPass" pass type to exist)

3
Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs


using System;
using System.Collections.Generic;
using UnityEngine.ScriptableRenderPipeline;
[ExecuteInEditMode]
public class RenderLoopTestFixture : RenderPipelineAsset

2
Assets/Editor/Tests/ShaderGeneratorTests/ShaderGeneratorTests.cs


using UnityEngine;
using UnityEditor;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.ScriptableRenderLoop;
using UnityEditor.Experimental.Rendering;
[TestFixture]
public class ShaderGeneratorTests

10
Assets/ScriptableRenderLoop/AdditionalLightData.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering
{
public enum LightArchetype {Punctual, Rectangle, Line};

return DefaultShadowResolution;
}
[RangeAttribute(0.0F, 100.0F)]
[Range(0.0F, 100.0F)]
private float m_innerSpotPercent = 0.0F;
public float GetInnerSpotPercent01()

[RangeAttribute(0.0F, 1.0F)]
[Range(0.0F, 1.0F)]
public float shadowDimmer = 1.0f;
public bool affectDiffuse = true;

public bool isDoubleSided = false;
[RangeAttribute(0.0f, 20.0f)]
[Range(0.0f, 20.0f)]
[RangeAttribute(0.0f, 20.0f)]
[Range(0.0f, 20.0f)]
public float areaLightWidth = 0.0f;
}
}

5
Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering
{
public class MaterialUpgrader
{

6
Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/DebugViewMaterial.cs


using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Attributes
{

BakeDiffuseLighting,
}
}
} // namespace UnityEngine.Experimental.ScriptableRenderLoop
}

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/DebugViewMaterial.cs.hlsl


#ifndef DEBUGVIEWMATERIAL_CS_HLSL
#define DEBUGVIEWMATERIAL_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.Attributes.DebugViewVarying: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Attributes.DebugViewVarying: static fields
//
#define DEBUGVIEWVARYING_TEXCOORD0 (1)
#define DEBUGVIEWVARYING_TEXCOORD1 (2)

#define DEBUGVIEWVARYING_VERTEX_COLOR_ALPHA (9)
//
// UnityEngine.Experimental.ScriptableRenderLoop.Attributes.DebugViewGbuffer: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Attributes.DebugViewGbuffer: static fields
//
#define DEBUGVIEWGBUFFER_DEPTH (10)
#define DEBUGVIEWGBUFFER_BAKE_DIFFUSE_LIGHTING (11)

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader


HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4// TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag

10
Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader


HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4// TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag

float depthMouse = LOAD_TEXTURE2D(_CameraDepthTexture, mousePosInput.unPositionSS).x;
UpdatePositionInput(depthMouse, _InvViewProjMatrix, _ViewProjMatrix, mousePosInput);
int category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;
int start;
int count;
uint category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;
uint start;
uint count;
GetCountAndStart(mousePosInput, category, start, count);
float4 result2 = float4(.1,.1,.1,.9);

}
}
Fallback Off
}
}

8
Assets/ScriptableRenderLoop/HDRenderPipeline/Editor/UpgradeStandardShaderMaterials.cs


using System.Collections;
using UnityEditor;
using System;
using NUnit.Framework;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
public class UpgradeStandardShaderMaterials
public class UpgradeStandardShaderMaterials
{
static List<MaterialUpgrader> GetHDUpgraders()
{

32
Assets/ScriptableRenderLoop/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
[UnityEditor.MenuItem("HDRenderPipeline/Create Scene Settings")]
[MenuItem("HDRenderPipeline/Create Scene Settings")]
CommonSettings[] settings = Object.FindObjectsOfType(typeof(CommonSettings)) as CommonSettings[];
CommonSettings[] settings = Object.FindObjectsOfType<CommonSettings>();
if(settings.Length == 0)
if (settings.Length == 0)
GameObject go = new GameObject();
go.name = "SceneSettings";
go.AddComponent(typeof(CommonSettings));
GameObject go = new GameObject { name = "SceneSettings" };
go.AddComponent<CommonSettings>();
go.AddComponent<PostProcessing>();
}
}
[MenuItem("HDRenderPipeline/Synchronize all Layered materials")]
static void SynchronizeAllLayeredMaterial()
{
Object[] materials = Resources.FindObjectsOfTypeAll<Material>();
foreach (Object obj in materials)
{
Material mat = obj as Material;
if(mat.shader.name == "HDRenderLoop/LayeredLit")
{
LayeredLitGUI.SynchronizeAllLayers(mat);
}
}
}
}

10
Assets/ScriptableRenderLoop/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


//using EditorGUIUtility=UnityEditor.EditorGUIUtility;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(HDRenderPipeline))]
public class HDRenderPipelineInspector : Editor

public readonly GUIContent displayOpaqueObjects = new GUIContent("Display Opaque Objects", "Toggle opaque objects rendering on and off.");
public readonly GUIContent displayTransparentObjects = new GUIContent("Display Transparent Objects", "Toggle transparent objects rendering on and off.");
public readonly GUIContent enableTonemap = new GUIContent("Enable Tonemap");
public readonly GUIContent exposure = new GUIContent("Exposure");
public readonly GUIContent useForwardRenderingOnly = new GUIContent("Use Forward Rendering Only");
public readonly GUIContent useDepthPrepass = new GUIContent("Use Depth Prepass");

debugParameters.debugViewMaterial = EditorGUILayout.IntPopup(styles.debugViewMaterial, (int)debugParameters.debugViewMaterial, styles.debugViewMaterialStrings, styles.debugViewMaterialValues);
EditorGUILayout.Space();
debugParameters.enableTonemap = EditorGUILayout.Toggle(styles.enableTonemap, debugParameters.enableTonemap);
debugParameters.exposure = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.exposure, debugParameters.exposure), k_MaxExposure), -k_MaxExposure);
EditorGUILayout.Space();
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderContext); // Repaint

137
Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.ScriptableRenderPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class HDRenderPipelineInstance : RenderPipeline
{

if (m_Owner != null)
m_Owner.Build();
}
public override void Dispose()
{
base.Dispose();

public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
{

{
return new HDRenderPipelineInstance(this);
}
SkyManager m_SkyManager = new SkyManager();
public SkyManager skyManager
{

public bool useDepthPrepass = false;
public bool useDistortion = true;
public bool enableTonemap = true;
public float exposure = 0;
// we have to fallback to forward-only rendering when scene view is using wireframe rendering mode --
// as rendering everything in wireframe + deferred do not play well together
public bool ShouldUseForwardRenderingOnly () { return useForwardRenderingOnly || GL.wireframe; }
}
DebugParameters m_DebugParameters = new DebugParameters();

}
// Various set of material use in render loop
Material m_FinalPassMaterial;
Material m_DebugViewMaterialGBuffer;
// Various buffer

m_SkyManager.Build();
m_FinalPassMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/FinalPass");
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DebugViewMaterialGBuffer");
m_ShadowPass = new ShadowRenderPass(m_ShadowSettings);

{
m_lightLoop.Cleanup();
m_LitRenderLoop.Cleanup();
Utilities.Destroy(m_FinalPassMaterial);
Utilities.Destroy(m_DebugViewMaterialGBuffer);
m_SkyManager.Cleanup();

cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
if (!debugParameters.useForwardRenderingOnly)
if (!debugParameters.ShouldUseForwardRenderingOnly())
{
m_gbufferManager.InitGBuffers(w, h, cmd);
}

void RenderGBuffer(CullResults cull, Camera camera, ScriptableRenderContext renderContext)
{
if (debugParameters.useForwardRenderingOnly)
if (debugParameters.ShouldUseForwardRenderingOnly())
{
return ;
}

}
// This pass is use in case of forward opaque and deferred rendering. We need to render forward objects before tile lighting pass
void RenderForwardOnlyDepthPrepass(CullResults cull, Camera camera, ScriptableRenderContext renderContext)
void RenderForwardOnlyOpaqueDepthPrepass(CullResults cull, Camera camera, ScriptableRenderContext renderContext)
// If we are forward only we don't need to render ForwardOpaqueDepth object
// If we are forward only we don't need to render ForwardOnlyOpaqueDepthOnly object
if (debugParameters.useForwardRenderingOnly && !debugParameters.useDepthPrepass)
if (debugParameters.ShouldUseForwardRenderingOnly() && !debugParameters.useDepthPrepass)
RenderOpaqueRenderList(cull, camera, renderContext, "ForwardOnlyDepthOnly");
RenderOpaqueRenderList(cull, camera, renderContext, "ForwardOnlyOpaqueDepthOnly");
}
}

}
// Render GBuffer opaque
if (!debugParameters.useForwardRenderingOnly)
if (!debugParameters.ShouldUseForwardRenderingOnly())
{
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewMaterialGBuffer);
m_DebugViewMaterialGBuffer.SetFloat("_DebugViewMaterial", (float)debugParameters.debugViewMaterial);

void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext)
{
if (debugParameters.useForwardRenderingOnly)
if (debugParameters.ShouldUseForwardRenderingOnly())
{
return ;
}

{
m_SkyManager.RenderSky(hdCamera, m_lightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthBufferRT, renderContext);
}
if (!debugParameters.useForwardRenderingOnly && renderOpaque)
if (!debugParameters.ShouldUseForwardRenderingOnly() && renderOpaque)
return;
using (new Utilities.ProfilingSample("Forward Pass", renderContext))

}
}
// Render material that are forward opaque only (like eye)
// TODO: Think about hair that could be render both as opaque and transparent...
void RenderForwardOnly(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext)
// Render material that are forward opaque only (like eye), this include unlit material
void RenderForwardOnlyOpaque(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext)
{
using (new Utilities.ProfilingSample("Forward Only Pass", renderContext))
{

Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT);
m_lightLoop.RenderForward(camera, renderContext, true);
RenderOpaqueRenderList(cullResults, camera, renderContext, "ForwardOnly");
}
}
void RenderForwardUnlit(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext)
{
using (new Utilities.ProfilingSample("Forward Unlit Pass", renderContext))
{
// Bind material data
m_LitRenderLoop.Bind();
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT);
RenderOpaqueRenderList(cullResults, camera, renderContext, "ForwardUnlit");
RenderTransparentRenderList(cullResults, camera, renderContext, "ForwardUnlit");
RenderOpaqueRenderList(cullResults, camera, renderContext, "ForwardOnlyOpaque");
}
}

{
// If opaque velocity have been render during GBuffer no need to render it here
if ((ShaderConfig.s_VelocityInGbuffer == 0) || debugParameters.useForwardRenderingOnly)
if ((ShaderConfig.s_VelocityInGbuffer == 0) || debugParameters.ShouldUseForwardRenderingOnly())
return ;
int w = camera.pixelWidth;

}
}
void FinalPass(ScriptableRenderContext renderContext)
void FinalPass(Camera camera, ScriptableRenderContext renderContext)
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float blackIn = 0.02f;
const float whiteIn = 10.0f;
const float blackOut = 0.0f;
const float whiteOut = 10.0f;
const float whiteLevel = 5.3f;
const float whiteClip = 10.0f;
const float dialUnits = 20.0f;
const float halfDialUnits = dialUnits * 0.5f;
// All of this is temporary, sub-optimal and quickly hacked together but is necessary
// for artists to do lighting work until the fully-featured framework is ready
// converting from artist dial units to easy shader-lerps (0-1)
var tonemapCoeff1 = new Vector4((blackIn * dialUnits) + 1.0f, (blackOut * halfDialUnits) + 1.0f, (whiteIn / dialUnits), (1.0f - (whiteOut / dialUnits)));
var tonemapCoeff2 = new Vector4(0.0f, 0.0f, whiteLevel, whiteClip / halfDialUnits);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2);
var localPostProcess = camera.GetComponent<PostProcessing>();
var globalPostProcess = commonSettings == null
? null
: commonSettings.GetComponent<PostProcessing>();
m_FinalPassMaterial.SetFloat("_EnableToneMap", debugParameters.enableTonemap ? 1.0f : 0.0f);
m_FinalPassMaterial.SetFloat("_Exposure", debugParameters.exposure);
bool localActive = localPostProcess != null && localPostProcess.enabled;
bool globalActive = globalPostProcess != null && globalPostProcess.enabled;
var cmd = new CommandBuffer { name = "" };
if (!localActive && !globalActive)
{
var cmd = new CommandBuffer { name = "" };
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
return;
}
// Resolve our HDR texture to CameraTarget.
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
var target = localActive ? localPostProcess : globalPostProcess;
target.Render(camera, renderContext, m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget);
}
}

m_ShadowSettings.maxShadowDistance = m_CommonSettings.shadowMaxDistance;
}
}
public void Render(ScriptableRenderContext renderContext, IEnumerable<Camera> cameras)
{
if (!m_LitRenderLoop.isInit)

// Forward opaque with deferred/cluster tile require that we fill the depth buffer
// correctly to build the light list.
// TODO: avoid double lighting by tagging stencil or gbuffer that we must not lit.
RenderForwardOnlyDepthPrepass(cullResults, camera, renderContext);
RenderForwardOnlyOpaqueDepthPrepass(cullResults, camera, renderContext);
RenderGBuffer(cullResults, camera, renderContext);
if (debugParameters.debugViewMaterial != 0)

using (new Utilities.ProfilingSample("Shadow Pass", renderContext))
{
m_ShadowPass.Render(renderContext, cullResults, out shadows);
}
}
m_lightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthBufferRT);
m_lightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthBufferRT); // TODO: Use async compute here to run light culling during shadow
}
UpdateSkyEnvironment(hdCamera, renderContext);
}
// Caution: We require sun light here as some sky use the sun light to render, mean UpdateSkyEnvironment
// must be call after BuildGPULightLists.
// TODO: Try to arrange code so we can trigger this call earlier and use async compute here to run sky convolution during other passes (once we move convolution shader to compute).
UpdateSkyEnvironment(hdCamera, renderContext);
RenderForward(cullResults, camera, renderContext, true);
RenderForwardOnly(cullResults, camera, renderContext);
// For opaque forward we have split rendering in two categories
// Material that are always forward and material that can be deferred or forward depends on render pipeline options (like switch to rendering forward only mode)
// Material that are always forward are unlit and complex (Like Hair) and don't require sorting, so it is ok to split them.
RenderForward(cullResults, camera, renderContext, true); // Render deferred or forward opaque
RenderForwardOnlyOpaque(cullResults, camera, renderContext);
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForwardUnlit(cullResults, camera, renderContext);
RenderVelocity(cullResults, camera, renderContext); // Note we may have to render velocity earlier if we do temporalAO, temporal volumetric etc... Mean we will not take into account forward opaque in case of deferred rendering ?

// Instead we chose to apply distortion at the end after we cumulate distortion vector and desired blurriness. This
RenderDistortion(cullResults, camera, renderContext);
FinalPass(renderContext);
FinalPass(camera, renderContext);
}
// bind depth surface for editor grid/gizmo/selection rendering

renderContext.Submit();
}
// Post effects
}
}
}

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting.meta


fileFormatVersion: 2
guid: 7dc18395c5211d44bbe417b8b8b2e81a
guid: 1c14e71d397fce047b1675fc26d0bb48
folderAsset: yes
timeCreated: 1474297943
licenseType: Pro

6
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightDefinition.cs


using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
//-----------------------------------------------------------------------------
// structure definition

// Include scale and bias for shadow atlas if any
public Matrix4x4 worldToShadow;
public GPULightType lightType;
public float unused2;
public Vector4 invResolution;
};

public Vector3 offsetLS;
public float unused2;
};
} // namespace UnityEngine.Experimental.ScriptableRenderLoop
}

32
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


#ifndef LIGHTDEFINITION_CS_HLSL
#define LIGHTDEFINITION_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.GPULightType: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.GPULightType: static fields
//
#define GPULIGHTTYPE_DIRECTIONAL (0)
#define GPULIGHTTYPE_SPOT (1)

#define GPULIGHTTYPE_CYLINDER (10)
//
// UnityEngine.Experimental.ScriptableRenderLoop.EnvShapeType: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.EnvShapeType: static fields
//
#define ENVSHAPETYPE_NONE (0)
#define ENVSHAPETYPE_BOX (1)

//
// UnityEngine.Experimental.ScriptableRenderLoop.EnvConstants: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.EnvConstants: static fields
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.LightData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.LightData
// PackingRules = Exact
struct LightData
{

bool twoSided;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.DirectionalLightData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData
// PackingRules = Exact
struct DirectionalLightData
{

int cookieIndex;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.ShadowData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowData
int lightType;
float unused2;
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.EnvLightData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData
// PackingRules = Exact
struct EnvLightData
{

};
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.LightData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.LightData
//
float3 GetPositionWS(LightData value)
{

}
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.DirectionalLightData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.DirectionalLightData
//
float3 GetForward(DirectionalLightData value)
{

}
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.ShadowData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ShadowData
int GetLightType(ShadowData value)
{
return value.lightType;
}
float GetBias(ShadowData value)
{
return value.bias;

{
return value.unused;
}
float GetUnused2(ShadowData value)
{
return value.unused2;
}
float4 GetInvResolution(ShadowData value)
{
return value.invResolution;

// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.EnvLightData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData
//
float3 GetPositionWS(EnvLightData value)
{

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightLoop.cs


using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class BaseLightLoop
{

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/Resources/Deferred.shader


HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4// TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass.meta


fileFormatVersion: 2
guid: ef8815a81d7dd9147b37093f06d9977c
guid: 8a355c056864a5d4cb26d9c3168ae0bb
folderAsset: yes
timeCreated: 1479218330
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute


#include "common.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
#if !defined(SHADER_API_XBOXONE)
#include "../SortingComputeUtils.hlsl"
#endif

31
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace TilePass
{

{
m_lightList.Clear();
if (cullResults.visibleLights.Length == 0)
if (cullResults.visibleLights.Length == 0 && cullResults.visibleReflectionProbes.Length == 0)
return;
// 1. Count the number of lights and sort all light by category, type and volume

cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "uavOutput", cameraColorBufferRT);
cmd.DispatchCompute(shadeOpaqueShader, kernel, numTilesX, numTilesY, 1);
}
else
{
// Pixel shader evaluation
if (enableSplitLightEvaluation)
}
else
// Pixel shader evaluation
if (enableSplitLightEvaluation)
{
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredDirectMaterial);
m_DeferredDirectMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredDirectMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);

m_DeferredIndirectMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredIndirectMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
cmd.Blit(null, cameraColorBufferRT, m_DeferredDirectMaterial, 0);
cmd.Blit(null, cameraColorBufferRT, m_DeferredIndirectMaterial, 0);
}
else
{
cmd.Blit(null, cameraColorBufferRT, m_DeferredDirectMaterial, 0);
cmd.Blit(null, cameraColorBufferRT, m_DeferredIndirectMaterial, 0);
}
else
{
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredAllMaterial);
m_DeferredAllMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredAllMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);

cmd.Blit(null, cameraColorBufferRT, m_DeferredAllMaterial, 0);
}
cmd.Blit(null, cameraColorBufferRT, m_DeferredAllMaterial, 0);
}
}
// Draw tile debugging

}
SetGlobalPropertyRedirect(null, 0, null);
//}
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

14
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl


#ifndef TILEPASS_CS_HLSL
#define TILEPASS_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.TilePass.LightVolumeType: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightVolumeType: static fields
//
#define LIGHTVOLUMETYPE_CONE (0)
#define LIGHTVOLUMETYPE_SPHERE (1)

//
// UnityEngine.Experimental.ScriptableRenderLoop.TilePass.LightCategory: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightCategory: static fields
//
#define LIGHTCATEGORY_PUNCTUAL (0)
#define LIGHTCATEGORY_AREA (1)

//
// UnityEngine.Experimental.ScriptableRenderLoop.TilePass.LightDefinitions: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightDefinitions: static fields
//
#define MAX_NR_LIGHTS_PER_CAMERA (1024)
#define MAX_NR_BIGTILE_LIGHTS_PLUSONE (512)

#define IS_BOX_PROJECTED (4)
#define HAS_SHADOW (8)
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.TilePass.SFiniteLightBound
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.TilePass.SFiniteLightBound
// PackingRules = Exact
struct SFiniteLightBound
{

float radius;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.TilePass.LightVolumeData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightVolumeData
// PackingRules = Exact
struct LightVolumeData
{

};
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.TilePass.SFiniteLightBound
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.TilePass.SFiniteLightBound
//
float3 GetBoxAxisX(SFiniteLightBound value)
{

}
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.TilePass.LightVolumeData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightVolumeData
//
float3 GetLightPos(LightVolumeData value)
{

17
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


TEXTURECUBE_ARRAY(_CookieCubeTextures);
SAMPLERCUBE(sampler_CookieCubeTextures);
// Use texture array for reflection
// Use texture array for reflection (or LatLong 2D array for mobile)
#ifdef CUBE_ARRAY_NOT_SUPPORTED
TEXTURE2D_ARRAY(_EnvTextures);
SAMPLER2D(sampler_EnvTextures);
#else
#endif
TEXTURECUBE(_SkyTexture);
SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...

// Shadow sampling function
// ----------------------------------------------------------------------------
float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, uint lightType, float3 positionWS, int index, float3 L, float2 unPositionSS)
if (_ShadowDatas[index].lightType == GPULIGHTTYPE_POINT)
if (lightType == GPULIGHTTYPE_POINT)
{
GetCubeFaceID(L, faceIndex);
}

// EnvIndex can also be use to fetch in another array of struct (to atlas information etc...).
float4 SampleEnv(LightLoopContext lightLoopContext, int index, float3 texCoord, float lod)
{
lod = min(lod, UNITY_SPECCUBE_LOD_STEPS);
#ifdef CUBE_ARRAY_NOT_SUPPORTED
return SAMPLE_TEXTURE2D_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, DirectionToLatLongCoordinate(texCoord), index, lod);
#else
#endif
}
else // SINGLE_PASS_SAMPLE_SKY
{

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material.meta


fileFormatVersion: 2
guid: 752ba4c5a264906428ff58cb5973e10a
guid: 96af336cb096f854ea18990a1c0a4e19
folderAsset: yes
timeCreated: 1474297943
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Builtin/BuiltinData.cs


//-----------------------------------------------------------------------------
// structure definition
//-----------------------------------------------------------------------------
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Builtin
{

8
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Builtin/BuiltinData.cs.hlsl


#ifndef BUILTINDATA_CS_HLSL
#define BUILTINDATA_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.Builtin.BuiltinData: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Builtin.BuiltinData: static fields
//
#define DEBUGVIEW_BUILTIN_BUILTINDATA_OPACITY (100)
#define DEBUGVIEW_BUILTIN_BUILTINDATA_BAKE_DIFFUSE_LIGHTING (101)

#define DEBUGVIEW_BUILTIN_BUILTINDATA_DEPTH_OFFSET (107)
//
// UnityEngine.Experimental.ScriptableRenderLoop.Builtin.LighTransportData: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Builtin.LighTransportData: static fields
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Builtin.BuiltinData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Builtin.BuiltinData
// PackingRules = Exact
struct BuiltinData
{

float depthOffset;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Builtin.LighTransportData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Builtin.LighTransportData
// PackingRules = Exact
struct LighTransportData
{

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit.meta


fileFormatVersion: 2
guid: d43c06a2afd9f2f4ab88a7a94c43e1a6
guid: e173dfe6cd75d954b95306237244f6de
folderAsset: yes
timeCreated: 1476653183
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/Editor.meta


fileFormatVersion: 2
guid: 4e53b0488682a1c4c8fa2b548ae0c25c
guid: 007fa1ca3307f1c4daa3a6efa6bba7e1
folderAsset: yes
timeCreated: 1479127283
licenseType: Pro

175
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs


using System.Linq;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
internal class LayeredLitGUI : LitGUI
{

{
public readonly GUIContent[] layerLabels =
{
new GUIContent("Layer 0"),
new GUIContent("Base Layer"),
public readonly GUIStyle[] layerLabelColors =
{
new GUIStyle(EditorStyles.label),
new GUIStyle(EditorStyles.label),
new GUIStyle(EditorStyles.label),
new GUIStyle(EditorStyles.label)
};
public readonly GUIContent layerMapVertexColorText = new GUIContent("Use Vertex Color", "Layer mask (multiplied by layer mask if enabled)");
public readonly GUIContent layerMapVertexColorText = new GUIContent("Use Vertex Color", "If no layer mask is set, vertex color values between 0 and 1.0 are used as final mask.\nIf a layer mask is set, vertex color values are remapped between -1 and 1 and added to the mask (neutral at 0.5 vertex color).");
public readonly GUIContent vertexColorHeightMultiplierText = new GUIContent("Vertex Height Scale", "Scale applied to the vertex color height.");
public readonly GUIContent heightOffsetText = new GUIContent("HeightOffset", "Height offset from the previous layer.");
public readonly GUIContent heightOffsetText = new GUIContent("Height Offset", "Height offset from the previous layer.");
public readonly GUIContent inheritBaseLayerText = new GUIContent("Inherit Base Layer Normal", "Inherit the normal from the base layer.");
public StylesLayer()
{
layerLabelColors[1].normal.textColor = Color.red;
layerLabelColors[2].normal.textColor = Color.green;
layerLabelColors[3].normal.textColor = Color.blue;
}
}
static StylesLayer s_Styles = null;

MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
const string kUseHeightBasedBlend = "_UseHeightBasedBlend";
MaterialProperty[] useHeightBasedBlend = new MaterialProperty[kMaxLayerCount-1];
MaterialProperty useHeightBasedBlend = null;
const string kInheritBaseLayer = "_InheritBaseLayer";
MaterialProperty[] inheritBaseLayer = new MaterialProperty[kMaxLayerCount - 1];
const string kVertexColorHeightFactor = "_VertexColorHeightFactor";
MaterialProperty vertexColorHeightFactor = null;
MaterialProperty layerEmissiveColor = null;
MaterialProperty layerEmissiveColorMap = null;

layerMaskMap = FindProperty(kLayerMaskMap, props);
layerMaskVertexColor = FindProperty(kLayerMaskVertexColor, props);
vertexColorHeightFactor = FindProperty(kVertexColorHeightFactor, props);
for (int i = 0; i < numLayer; ++i)
useHeightBasedBlend = FindProperty(kUseHeightBasedBlend, props);
for (int i = 0; i < kMaxLayerCount; ++i)
{
layerTexWorldScale[i] = FindProperty(string.Format("{0}{1}", kTexWorldScale, i), props);
layerUVBase[i] = FindProperty(string.Format("{0}{1}", kUVBase, i), props);

if(i != 0)
{
useHeightBasedBlend[i-1] = FindProperty(string.Format("{0}{1}", kUseHeightBasedBlend, i), props);
inheritBaseLayer[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseLayer, i), props);
heightOffset[i-1] = FindProperty(string.Format("{0}{1}", kHeightOffset, i), props);
heightFactor[i-1] = FindProperty(string.Format("{0}{1}", kHeightFactor, i), props);
blendSize[i-1] = FindProperty(string.Format("{0}{1}", kBlendSize, i), props);

get { return (int)layerCount.floatValue; }
}
public static void SynchronizeAllLayers(Material material)
{
int layerCount = (int)material.GetFloat("_LayerCount");
AssetImporter materialImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material.GetInstanceID()));
Material[] layers = null;
InitializeMaterialLayers(materialImporter, ref layers);
for (int i = 0 ; i < layerCount ; ++i)
{
SynchronizeLayerProperties(material, layers, i);
}
}
SynchronizeLayerProperties(i);
SynchronizeLayerProperties(m_MaterialEditor.target as Material, m_MaterialLayers, i);
void SynchronizeLayerProperties(int layerIndex)
static void SynchronizeLayerProperties(Material material, Material[] layers, int layerIndex)
Material material = m_MaterialEditor.target as Material;
Material layerMaterial = m_MaterialLayers[layerIndex];
Material layerMaterial = layers[layerIndex];
if (layerMaterial != null)
{

}
}
void InitializeMaterialLayers(AssetImporter materialImporter)
static void InitializeMaterialLayers(AssetImporter materialImporter, ref Material[] layers)
{
if (materialImporter.userData != string.Empty)
{

m_MaterialLayers = new Material[layersGUID.GUIDArray.Length];
layers = new Material[layersGUID.GUIDArray.Length];
m_MaterialLayers[i] = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(layersGUID.GUIDArray[i]), typeof(Material)) as Material;
layers[i] = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(layersGUID.GUIDArray[i]), typeof(Material)) as Material;
}
}
}

return result;
}
bool CheckInputFloatOptionConsistency(string optionName, ref string outValueNames)
{
bool result = true;
outValueNames = "";
for (int i = 0; i < numLayer; ++i)
{
Material layer = m_MaterialLayers[i];
if (layer != null)
{
float currentValue = layer.GetFloat(optionName);
for (int j = i + 1; j < numLayer; ++j)
{
Material otherLayer = m_MaterialLayers[j];
if (otherLayer != null)
{
if (currentValue != otherLayer.GetFloat(optionName))
{
result = false;
}
}
}
}
else
{
outValueNames += "X ";
}
}
return result;
}
bool CheckInputMapConsistency(string mapName, ref string outValueNames)
{
bool result = true;

// Input options consistency
string[] smoothnessSourceShortNames = { "Mask", "Albedo" };
string[] normalMapShortNames = { "Tan", "Obj" };
string[] heightMapShortNames = { "Parallax", "Disp" };
string[] detailModeShortNames = { "DNormal", "DAOHeight" };
string warningInputOptions = "";

{
warningInputOptions += "Normal Map Space: " + optionValueNames + "\n";
}
if (!CheckInputOptionConsistency(kHeightMapMode, heightMapShortNames, ref optionValueNames))
if (!CheckInputFloatOptionConsistency(kEnablePerPixelDisplacement, ref optionValueNames))
warningInputOptions += "Height Map Mode: " + optionValueNames + "\n";
warningInputOptions += "Per pixel displacement: " + optionValueNames + "\n";
}
if (!CheckInputOptionConsistency(kDetailMapMode, detailModeShortNames, ref optionValueNames))
{

{
material.SetFloat(kSmoothnessTextureChannel, firstLayer.GetFloat(kSmoothnessTextureChannel));
material.SetFloat(kNormalMapSpace, firstLayer.GetFloat(kNormalMapSpace));
material.SetFloat(kHeightMapMode, firstLayer.GetFloat(kHeightMapMode));
material.SetFloat(kEnablePerPixelDisplacement, firstLayer.GetFloat(kEnablePerPixelDisplacement));
// Force emissive to be emissive color
material.SetFloat(kEmissiveColorMode, (float)EmissiveColorMode.UseEmissiveColor);
}

{
bool result = false;
EditorGUILayout.LabelField(styles.layerLabels[layerIndex]);
Material material = m_MaterialEditor.target as Material;
EditorGUILayout.LabelField(styles.layerLabels[layerIndex], styles.layerLabelColors[layerIndex]);
EditorGUI.indentLevel++;

{
Undo.RecordObject(materialImporter, "Change layer material");
SynchronizeLayerProperties(layerIndex);
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex);
result = true;
}

{
SynchronizeLayerProperties(layerIndex);
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex);
result = true;
}
if (((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Planar) ||

m_MaterialEditor.ShaderProperty(layerUVDetail[layerIndex], styles.UVDetailText);
if (EditorGUI.EndChangeCheck())
{
SynchronizeLayerProperties(layerIndex);
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex);
result = true;
}
}

int heightParamIndex = layerIndex - 1;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = useHeightBasedBlend[heightParamIndex].hasMixedValue;
bool enabled = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend[heightParamIndex].floatValue > 0.0f);
if(EditorGUI.EndChangeCheck())
if (!useHeightBasedBlend.hasMixedValue && useHeightBasedBlend.floatValue != 0.0f)
useHeightBasedBlend[heightParamIndex].floatValue = enabled ? 1.0f : 0.0f;
}
int heightParamIndex = layerIndex - 1;
if(enabled)
{
m_MaterialEditor.ShaderProperty(inheritBaseLayer[heightParamIndex], styles.inheritBaseLayerText);
m_MaterialEditor.ShaderProperty(heightOffset[heightParamIndex], styles.heightOffsetText);
m_MaterialEditor.ShaderProperty(heightFactor[heightParamIndex], styles.heightFactorText);
m_MaterialEditor.ShaderProperty(blendSize[heightParamIndex], styles.blendSizeText);

EditorGUI.indentLevel--;
if(layerIndex == 0)
EditorGUILayout.Space();
return result;
}

EditorGUI.indentLevel++;
GUILayout.Label(styles.layersText, EditorStyles.boldLabel);
EditorGUI.showMixedValue = layerCount.hasMixedValue;
EditorGUI.BeginChangeCheck();
int newLayerCount = EditorGUILayout.IntSlider(styles.layerCountText, (int)layerCount.floatValue, 2, 4);
if (EditorGUI.EndChangeCheck())

layerChanged = true;
}
m_MaterialEditor.ShaderProperty(layerMaskVertexColor, styles.layerMapVertexColorText);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = useHeightBasedBlend.hasMixedValue;
bool enabled = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend.floatValue > 0.0f);
if (EditorGUI.EndChangeCheck())
{
useHeightBasedBlend.floatValue = enabled ? 1.0f : 0.0f;
}
if (enabled)
{
m_MaterialEditor.ShaderProperty(vertexColorHeightFactor, styles.vertexColorHeightMultiplierText);
}
else
{
m_MaterialEditor.ShaderProperty(layerMaskVertexColor, styles.layerMapVertexColorText);
}
EditorGUILayout.Space();
for (int i = 0; i < numLayer; i++)

SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap + i));
SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", ((DetailMapMode)material.GetFloat(kDetailMapMode)) == DetailMapMode.DetailWithNormal);
SetKeyword(material, "_HEIGHTMAP_AS_DISPLACEMENT", ((HeightmapMode)material.GetFloat(kHeightMapMode)) == HeightmapMode.Displacement);
bool perPixelDisplacement = material.GetFloat(kEnablePerPixelDisplacement) == 1.0;
SetKeyword(material, "_PER_PIXEL_DISPLACEMENT", perPixelDisplacement);
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR", material.GetFloat(kLayerMaskVertexColor) != 0.0f);
bool useHeightBasedBlend = material.GetFloat(kUseHeightBasedBlend) != 0.0f;
if(useHeightBasedBlend)
{
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR_ADD", false);
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR_MUL", false);
SetKeyword(material, "_HEIGHT_BASED_BLEND", true);
}
else
{
if (material.GetTexture(kLayerMaskMap) != null)
{
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR_ADD", material.GetFloat(kLayerMaskVertexColor) != 0.0f);
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR_MUL", false);
}
else
{
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR_MUL", material.GetFloat(kLayerMaskVertexColor) != 0.0f);
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR_ADD", false);
}
SetKeyword(material, "_HEIGHT_BASED_BLEND", false);
}
// We have to check for each layer if the UV2 or UV3 is needed.
bool UV2orUV3needed = false;

Material material = m_MaterialEditor.target as Material;
AssetImporter materialImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material.GetInstanceID()));
InitializeMaterialLayers(materialImporter);
InitializeMaterialLayers(materialImporter, ref m_MaterialLayers);
bool optionsChanged = false;
EditorGUI.BeginChangeCheck();

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


_NormalMap2("NormalMap2", 2D) = "bump" {}
_NormalMap3("NormalMap3", 2D) = "bump" {}
_NormalScale0("_NormalScale0", Range(0.0, 2.0)) = 1
_NormalScale1("_NormalScale1", Range(0.0, 2.0)) = 1
_NormalScale2("_NormalScale2", Range(0.0, 2.0)) = 1
_NormalScale3("_NormalScale3", Range(0.0, 2.0)) = 1
_HeightScale0("Height Scale0", Float) = 1
_HeightScale1("Height Scale1", Float) = 1
_HeightScale2("Height Scale2", Float) = 1
_HeightScale3("Height Scale3", Float) = 1
_HeightAmplitude0("Height Scale0", Float) = 1
_HeightAmplitude1("Height Scale1", Float) = 1
_HeightAmplitude2("Height Scale2", Float) = 1
_HeightAmplitude3("Height Scale3", Float) = 1
_HeightBias0("Height Bias0", Float) = 0
_HeightBias1("Height Bias1", Float) = 0
_HeightBias2("Height Bias2", Float) = 0
_HeightBias3("Height Bias3", Float) = 0
_HeightCenter0("Height Bias0", Float) = 0
_HeightCenter1("Height Bias1", Float) = 0
_HeightCenter2("Height Bias2", Float) = 0
_HeightCenter3("Height Bias3", Float) = 0
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}

_TexWorldScale2("TexWorldScale2", Float) = 1.0
_TexWorldScale3("TexWorldScale3", Float) = 1.0
// Blend mask between layer
// Layer blending options
// Height based blend (layer 0 does not need it)
_UseHeightBasedBlend1("UseHeightBasedBlend1", Float) = 0.0
_UseHeightBasedBlend2("UseHeightBasedBlend2", Float) = 0.0
_UseHeightBasedBlend3("UseHeightBasedBlend3", Float) = 0.0
[ToggleOff] _UseHeightBasedBlend("UseHeightBasedBlend", Float) = 0.0
_HeightOffset1("_HeightOffset1", Range(-0.3, 0.3)) = 0.0
_HeightOffset2("_HeightOffset2", Range(-0.3, 0.3)) = 0.0

_HeightFactor2("_HeightFactor2", Range(0, 5)) = 1
_HeightFactor3("_HeightFactor3", Range(0, 5)) = 1
_BlendSize1("_BlendSize1", Range(0, 0.05)) = 0.0
_BlendSize2("_BlendSize2", Range(0, 0.05)) = 0.0
_BlendSize3("_BlendSize3", Range(0, 0.05)) = 0.0
_BlendSize1("_BlendSize1", Range(0, 0.30)) = 0.0
_BlendSize2("_BlendSize2", Range(0, 0.30)) = 0.0
_BlendSize3("_BlendSize3", Range(0, 0.30)) = 0.0
_InheritBaseLayer1("_InheritBaseLayer1", Range(0, 1.0)) = 0.0
_InheritBaseLayer2("_InheritBaseLayer2", Range(0, 1.0)) = 0.0
_InheritBaseLayer3("_InheritBaseLayer3", Range(0, 1.0)) = 0.0
_VertexColorHeightFactor("_VertexColorHeightFactor", Float) = 0.3
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}

[Enum(Mask Alpha, 0, BaseColor Alpha, 1)] _SmoothnessTextureChannel("Smoothness texture channel", Float) = 1
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1

HLSLINCLUDE
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4// TEMP: unitl we go futher in dev
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON

#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_3
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV2_OR_UV3
#pragma shader_feature _EMISSIVE_COLOR

#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _HEIGHTMAP
#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _LAYER_MASK_VERTEX_COLOR
#pragma shader_feature _ _LAYER_MASK_VERTEX_COLOR_MUL _LAYER_MASK_VERTEX_COLOR_ADD
#pragma shader_feature _HEIGHT_BASED_BLEND
#pragma shader_feature _ _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON

#include "Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
SubShader

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassDebugViewMaterial.hlsl"

// DYNAMICLIGHTMAP_ON is used when we have an "enlighten lightmap" ie a lightmap updated at runtime by enlighten.This lightmap contain indirect lighting from realtime lights and realtime emissive material.Offline baked lighting(from baked material / light,
// both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON.
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitMetaPass.hlsl"
#include "../Lit/LitMetaPass.hlsl"
#include "../../ShaderPass/ShaderPassLightTransport.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitVelocityPass.hlsl"
#include "../Lit/LitVelocityPass.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "../Lit/LitDepthPass.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "../Lit/LitDepthPass.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDistortionPass.hlsl"
#include "../Lit/LitDistortionPass.hlsl"
#include "../../ShaderPass/ShaderPassDistortion.hlsl"

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#define SHADERPASS SHADERPASS_FORWARD
// TEMP until pragma work in include
// #include "../../Lighting/Forward.hlsl"

#include "../../Lighting/Lighting.hlsl"
#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"

CustomEditor "Experimental.ScriptableRenderLoop.LayeredLitGUI"
CustomEditor "Experimental.Rendering.HDPipeline.LayeredLitGUI"
}

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit.meta


fileFormatVersion: 2
guid: 24406b9cf8c7f2543b7d20ead11e37d5
guid: d6cadd3aaf3ad6641b86e85a0929b245
folderAsset: yes
timeCreated: 1476653183
licenseType: Pro

138
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
public static string OptionText = "Options";
public static string SurfaceTypeText = "Surface Type";
public static string BlendModeText = "Blend Mode";
public static string optionText = "Options";
public static string surfaceTypeText = "Surface Type";
public static string blendModeText = "Blend Mode";
public static string detailText = "Inputs Detail";
public static string lightingText = "Inputs Lighting";

public static GUIContent texWorldScaleText = new GUIContent("Tiling", "Tiling factor applied to Planar/Trilinear mapping");
public static GUIContent UVBaseDetailMappingText = new GUIContent("UV set for Base and Detail", "");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", "");
public static GUIContent enablePerPixelDisplacementText = new GUIContent("Enable Per Pixel Displacement", "");
public static GUIContent detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height");
public static GUIContent UVDetailMappingText = new GUIContent("UV set for Detail", "");
public static GUIContent emissiveColorModeText = new GUIContent("Emissive Color Usage", "Use emissive color or emissive mask");

public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5");
public static GUIContent heightMapText = new GUIContent("Height Map (R)", "Height Map");
public static GUIContent heightMapAmplitudeText = new GUIContent("Height Map Amplitude", "Height Map amplitude in world units.");
public static GUIContent heightMapCenterText = new GUIContent("Height Map Center", "Center of the heightmap in the texture (between 0 and 1)");
public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC5) - DXT5 for test");
public static GUIContent anisotropyText = new GUIContent("Anisotropy", "Anisotropy scale factor");

public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive.");
public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect.");
public static string tessellationModeText = "Tessellation Mode";
public static readonly string[] tessellationModeNames = Enum.GetNames(typeof(TessellationMode));
public static GUIContent tessellationText = new GUIContent("Tessellation options", "Tessellation options");
public static GUIContent tessellationFactorFixedText = new GUIContent("Fixed tessellation factor", "If non negative, this value is a fixed tessellation factor use for tessellation");
public static GUIContent tessellationFactorMaxDistanceText = new GUIContent("Max Distance", "Maximun distance to the camera where triangle are tesselated");
public static GUIContent tessellationFactorTriangleSizeText = new GUIContent("Triangle size", "Desired screen space sized of triangle. Smaller value mean smaller triangle.");
public static GUIContent tessellationShapeFactorText = new GUIContent("Shape factor", "Strength of Phong tessellation shape (lerp factor)");
public static GUIContent tessellationBackFaceCullEpsilonText = new GUIContent("Triangle culling Epsilon", "If non zero, backface culling is enabled for tessellation, smaller number mean more aggressive culling and better performance");
public static GUIContent tessellationObjectScaleText = new GUIContent("Enable object scale", "Scale displacement taking into account the object scale");
}
public enum SurfaceType

}
public enum BlendMode
{
Lerp,

Premultiply
}
public enum DoubleSidedMode
{
None,

}
public enum TessellationMode
{
Phong,
Displacement,
DisplacementPhong,
}
void SurfaceTypePopup()
{
EditorGUI.showMixedValue = surfaceType.hasMixedValue;

mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
mode = (SurfaceType)EditorGUILayout.Popup(Styles.surfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");

EditorGUI.showMixedValue = false;
}
void TessellationModePopup()
{
EditorGUI.showMixedValue = tessellationMode.hasMixedValue;
var mode = (TessellationMode)tessellationMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (TessellationMode)EditorGUILayout.Popup(Styles.tessellationModeText, (int)mode, Styles.tessellationModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Tessellation Mode");
tessellationMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
GUILayout.Label(Styles.optionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{

m_MaterialEditor.ShaderProperty(depthOffsetEnable, Styles.depthOffsetEnableText.text);
EditorGUI.indentLevel--;
if (tessellationMode != null)
{
GUILayout.Label(Styles.tessellationText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
TessellationModePopup();
m_MaterialEditor.ShaderProperty(tessellationFactorFixed, Styles.tessellationFactorFixedText);
m_MaterialEditor.ShaderProperty(tessellationFactorMaxDistance, Styles.tessellationFactorMaxDistanceText);
m_MaterialEditor.ShaderProperty(tessellationFactorTriangleSize, Styles.tessellationFactorTriangleSizeText);
if ((TessellationMode)tessellationMode.floatValue == TessellationMode.Phong ||
(TessellationMode)tessellationMode.floatValue == TessellationMode.DisplacementPhong)
{
m_MaterialEditor.ShaderProperty(tessellationShapeFactor, Styles.tessellationShapeFactorText);
}
m_MaterialEditor.ShaderProperty(tessellationBackFaceCullEpsilon, Styles.tessellationBackFaceCullEpsilonText);
m_MaterialEditor.ShaderProperty(tessellationObjectScale, Styles.tessellationObjectScaleText);
EditorGUI.indentLevel--;
}
}
private void BlendModePopup()

EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
mode = (BlendMode)EditorGUILayout.Popup(Styles.blendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");

distortionOnly = FindProperty(kDistortionOnly, props);
distortionDepthTest = FindProperty(kDistortionDepthTest, props);
depthOffsetEnable = FindProperty(kDepthOffsetEnable, props);
// tessellation specific, silent if not found
tessellationMode = FindProperty(kTessellationMode, props, false);
tessellationFactorFixed = FindProperty(kTessellationFactorFixed, props, false);
tessellationFactorMaxDistance = FindProperty(kTessellationFactorMaxDistance, props, false);
tessellationFactorTriangleSize = FindProperty(kTessellationFactorTriangleSize, props, false);
tessellationShapeFactor = FindProperty(kTessellationShapeFactor, props, false);
tessellationBackFaceCullEpsilon = FindProperty(kTessellationBackFaceCullEpsilon, props, false);
tessellationObjectScale = FindProperty(kTessellationObjectScale, props, false);
}
protected void SetupCommonOptionsKeywords(Material material)

BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");

SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable);
SetupEmissionGIFlags(material);
if (tessellationMode != null)
{
TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode);
if (tessMode == TessellationMode.Phong)
{
material.DisableKeyword("_TESSELLATION_DISPLACEMENT");
material.DisableKeyword("_TESSELLATION_DISPLACEMENT_PHONG");
}
else if (tessMode == TessellationMode.Displacement)
{
material.EnableKeyword("_TESSELLATION_DISPLACEMENT");
material.DisableKeyword("_TESSELLATION_DISPLACEMENT_PHONG");
}
else
{
material.DisableKeyword("_TESSELLATION_DISPLACEMENT");
material.EnableKeyword("_TESSELLATION_DISPLACEMENT_PHONG");
}
}
}
protected void SetKeyword(Material m, string keyword, bool state)

protected MaterialEditor m_MaterialEditor;
MaterialProperty surfaceType = null;
const string kSurfaceType = "_SurfaceType";
const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
const string kBlendMode = "_BlendMode";
const string kAlphaCutoff = "_AlphaCutoff";
const string kDoubleSidedMode = "_DoubleSidedMode";
const string kDistortionEnable = "_DistortionEnable";
const string kDistortionOnly = "_DistortionOnly";
MaterialProperty depthOffsetEnable = null;
const string kSurfaceType = "_SurfaceType";
const string kBlendMode = "_BlendMode";
const string kAlphaCutoff = "_AlphaCutoff";
const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
const string kDoubleSidedMode = "_DoubleSidedMode";
const string kDistortionEnable = "_DistortionEnable";
const string kDistortionOnly = "_DistortionOnly";
MaterialProperty depthOffsetEnable = null;
// tessellation params
MaterialProperty tessellationMode = null;
const string kTessellationMode = "_TessellationMode";
MaterialProperty tessellationFactorFixed = null;
const string kTessellationFactorFixed = "_TessellationFactorFixed";
MaterialProperty tessellationFactorMaxDistance = null;
const string kTessellationFactorMaxDistance = "_TessellationFactorMaxDistance";
MaterialProperty tessellationFactorTriangleSize = null;
const string kTessellationFactorTriangleSize = "_TessellationFactorTriangleSize";
MaterialProperty tessellationShapeFactor = null;
const string kTessellationShapeFactor = "_TessellationShapeFactor";
MaterialProperty tessellationBackFaceCullEpsilon = null;
const string kTessellationBackFaceCullEpsilon = "_TessellationBackFaceCullEpsilon";
MaterialProperty tessellationObjectScale = null;
const string kTessellationObjectScale = "_TessellationObjectScale";
protected static string[] reservedProperties = new string[] { kSurfaceType, kBlendMode, kAlphaCutoff, kAlphaCutoffEnabled, kDoubleSidedMode };
protected abstract void FindMaterialProperties(MaterialProperty[] props);

51
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
class LitGUI : BaseLitGUI
{

protected const string kUVMappingPlanar = "_UVMappingPlanar";
protected MaterialProperty normalMapSpace = null;
protected const string kNormalMapSpace = "_NormalMapSpace";
protected MaterialProperty heightMapMode = null;
protected const string kHeightMapMode = "_HeightMapMode";
protected MaterialProperty enablePerPixelDisplacement = null;
protected const string kEnablePerPixelDisplacement = "_EnablePerPixelDisplacement";
protected MaterialProperty detailMapMode = null;
protected const string kDetailMapMode = "_DetailMapMode";
protected MaterialProperty UVDetail = null;

protected const string kSpecularOcclusionMap = "_SpecularOcclusionMap";
protected MaterialProperty normalMap = null;
protected const string kNormalMap = "_NormalMap";
protected MaterialProperty normalScale = null;
protected const string kNormalScale = "_NormalScale";
protected MaterialProperty heightScale = null;
protected const string kHeightScale = "_HeightScale";
protected MaterialProperty heightBias = null;
protected const string kHeightBias= "_HeightBias";
protected MaterialProperty heightAmplitude = null;
protected const string kHeightAmplitude = "_HeightAmplitude";
protected MaterialProperty heightCenter = null;
protected const string kHeightCenter = "_HeightCenter";
protected MaterialProperty tangentMap = null;
protected const string kTangentMap = "_TangentMap";
protected MaterialProperty anisotropy = null;

protected MaterialProperty emissiveIntensity = null;
protected const string kEmissiveIntensity = "_EmissiveIntensity";
// These are options that are shared with the LayeredLit shader. Don't put anything that can't be shared here:
// For instance, properties like BaseColor and such don't exist in the LayeredLit so don't put them here.
protected void FindMaterialOptionProperties(MaterialProperty[] props)

heightMapMode = FindProperty(kHeightMapMode, props);
enablePerPixelDisplacement = FindProperty(kEnablePerPixelDisplacement, props);
detailMapMode = FindProperty(kDetailMapMode, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
}

maskMap = FindProperty(kMaskMap, props);
specularOcclusionMap = FindProperty(kSpecularOcclusionMap, props);
normalMap = FindProperty(kNormalMap, props);
normalScale = FindProperty(kNormalScale, props);
heightScale = FindProperty(kHeightScale, props);
heightBias = FindProperty(kHeightBias, props);
heightAmplitude = FindProperty(kHeightAmplitude, props);
heightCenter = FindProperty(kHeightCenter, props);
tangentMap = FindProperty(kTangentMap, props);
anisotropy = FindProperty(kAnisotropy, props);
anisotropyMap = FindProperty(kAnisotropyMap, props);

W = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
UVDetailsMappingMask.colorValue = new Color(X, Y, Z, W);
m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(normalMapSpace, Styles.normalMapSpaceText.text);
m_MaterialEditor.ShaderProperty(heightMapMode, Styles.heightMapModeText.text);
//m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(normalMapSpace, Styles.normalMapSpaceText.text);
m_MaterialEditor.ShaderProperty(enablePerPixelDisplacement, Styles.enablePerPixelDisplacementText.text);
EditorGUI.indentLevel--;
}

m_MaterialEditor.TexturePropertySingleLine(Styles.specularOcclusionMapText, specularOcclusionMap);
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap);
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap, heightScale, heightBias);
m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap);
if(!heightMap.hasMixedValue && heightMap.textureValue != null)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightAmplitude, Styles.heightMapAmplitudeText);
m_MaterialEditor.ShaderProperty(heightCenter, Styles.heightMapCenterText);
EditorGUI.showMixedValue = false;
EditorGUI.indentLevel--;
}
m_MaterialEditor.TexturePropertySingleLine(Styles.tangentMapText, tangentMap);

m_MaterialEditor.ShaderProperty(detailAlbedoScale, Styles.detailAlbedoScaleText);
m_MaterialEditor.ShaderProperty(detailNormalScale, Styles.detailNormalScaleText);
m_MaterialEditor.ShaderProperty(detailSmoothnessScale, Styles.detailSmoothnessScaleText);
m_MaterialEditor.ShaderProperty(detailHeightScale, Styles.detailHeightScaleText);
m_MaterialEditor.ShaderProperty(detailAOScale, Styles.detailAOScaleText);
//m_MaterialEditor.ShaderProperty(detailHeightScale, Styles.detailHeightScaleText);
//m_MaterialEditor.ShaderProperty(detailAOScale, Styles.detailAOScaleText);
EditorGUI.indentLevel--;
EditorGUILayout.Space();

m_MaterialEditor.LightmapEmissionProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)

SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannel)) == SmoothnessMapChannel.AlbedoAlpha);
SetKeyword(material, "_MAPPING_TRIPLANAR", ((UVBaseMapping)material.GetFloat(kUVBase)) == UVBaseMapping.Triplanar);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", ((NormalMapSpace)material.GetFloat(kNormalMapSpace)) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_HEIGHTMAP_AS_DISPLACEMENT", ((HeightmapMode)material.GetFloat(kHeightMapMode)) == HeightmapMode.Displacement);
bool perPixelDisplacement = material.GetFloat(kEnablePerPixelDisplacement) == 1.0;
SetKeyword(material, "_PER_PIXEL_DISPLACEMENT", perPixelDisplacement);
SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", ((DetailMapMode)material.GetFloat(kDetailMapMode)) == DetailMapMode.DetailWithNormal);
SetKeyword(material, "_EMISSIVE_COLOR", ((EmissiveColorMode)material.GetFloat(kEmissiveColorMode)) == EmissiveColorMode.UseEmissiveColor);

7
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs


using System;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
class StandardSpecularToHDLitMaterialUpgrader : MaterialUpgrader
{

RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameFloat("_BumpScale", "_NormalScale");
//@Seb: Bumpmap scale doesn't exist in new shader
//_BumpScale("Scale", Float) = 1.0
// Anything reasonable that can be done here?
//RenameFloat("_SpecColor", ...);

10
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs


using System;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
class StandardToHDLitMaterialUpgrader : MaterialUpgrader
class StandardToHDLitMaterialUpgrader : MaterialUpgrader
{
public StandardToHDLitMaterialUpgrader()
{

RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameFloat("_BumpScale", "_NormalScale");
RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");

RenameTexture("_DetailNormalMap", "_DetailMap");
//@Seb: Bumpmap scale doesn't exist in new shader
//_BumpScale("Scale", Float) = 1.0
// Metallic uses [Gamma] attribute in standard shader but not in Lit.
// @Seb: Should we convert?

5
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.cs


using UnityEngine;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Lit
{

public void Build()
{
m_InitPreFGD = CreateEngineMaterial("Hidden/HDRenderPipeline/PreIntegratedFGD");
// TODO: switch to RGBA64 when it becomes available.
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGBHalf);
m_LtcGGXMatrix = LoadLUT(TextureFormat.RGBAHalf, s_LtcGGXMatrixData);

12
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.cs.hlsl


#ifndef LIT_CS_HLSL
#define LIT_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.Lit.MaterialId: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.MaterialId: static fields
//
#define MATERIALID_LIT_STANDARD (0)
#define MATERIALID_LIT_SSS (1)

//
// UnityEngine.Experimental.ScriptableRenderLoop.Lit.SurfaceData: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.SurfaceData: static fields
//
#define DEBUGVIEW_LIT_SURFACEDATA_BASE_COLOR (1000)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_OCCLUSION (1001)

#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_COLOR (1015)
//
// UnityEngine.Experimental.ScriptableRenderLoop.Lit.BSDFData: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.BSDFData: static fields
//
#define DEBUGVIEW_LIT_BSDFDATA_DIFFUSE_COLOR (1030)
#define DEBUGVIEW_LIT_BSDFDATA_FRESNEL0 (1031)

#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1046)
//
// UnityEngine.Experimental.ScriptableRenderLoop.Lit.GBufferMaterial: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.GBufferMaterial: static fields
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Lit.SurfaceData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Lit.SurfaceData
// PackingRules = Exact
struct SurfaceData
{

float3 specularColor;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Lit.BSDFData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Lit.BSDFData
// PackingRules = Exact
struct BSDFData
{

151
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.hlsl


bsdfData.diffuseColor = surfaceData.baseColor * (1.0 - surfaceData.metallic);
bsdfData.fresnel0 = lerp(float3(surfaceData.specular, surfaceData.specular, surfaceData.specular), surfaceData.baseColor, surfaceData.metallic);
bsdfData.tangentWS = surfaceData.tangentWS;
bsdfData.bitangentWS = cross(surfaceData.normalWS, surfaceData.tangentWS);
bsdfData.tangentWS = surfaceData.tangentWS;
bsdfData.bitangentWS = cross(surfaceData.normalWS, surfaceData.tangentWS);
ConvertAnisotropyToRoughness(bsdfData.roughness, surfaceData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
bsdfData.anisotropy = surfaceData.anisotropy;

bsdfData.fresnel0 = lerp(float3(specular, specular, specular), baseColor, metallic);
bsdfData.tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0));
// TODO: Do we need to orthonormalize here, IIRC Eric say that we should
bsdfData.bitangentWS = cross(bsdfData.normalWS, bsdfData.tangentWS);
ConvertAnisotropyToRoughness(bsdfData.roughness, anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
bsdfData.anisotropy = anisotropy;

float anisoGGXLambdaV;
float3 iblDirWS; // Dominant specular direction, used for IBL in EvaluateBSDF_Env()
float iblMipLevel;
// TODO: if we want we can store ambient occlusion here from SSAO pass for example that can be use for IBL specular occlusion
// float ambientOcclusion; // Feed from an ambient occlusion buffer
// area light
float3x3 ltcXformGGX; // TODO: make sure the compiler not wasting VGPRs on constants

float ltcDisneyDiffuseMagnitude;
// Shadow (sampling rotation disc)
float2 unPositionSS;
};
PreLightData GetPreLightData(float3 V, PositionInputs posInput, BSDFData bsdfData)

// TODO: check Eric idea about doing that when writting into the GBuffer (with our forward decal)
preLightData.NdotV = GetShiftedNdotV(bsdfData.normalWS, V, false);
// We have handle the case of NdotV being negative in GetData() function with GetShiftedNdotV.
// So we don't need to saturate or take the abs here.
// In case a material use negative normal for double sided lighting like speedtree this will be handle in the GetData() code too.
preLightData.NdotV = dot(bsdfData.normalWS, V);
preLightData.ggxLambdaV = GetSmithJointGGXLambdaV(preLightData.NdotV, bsdfData.roughness);

// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NDotV) and use iblNormalWS
// into function like GetSpecularDominantDir(). However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here.
// With this in mind and for performance reasons we chose to only use modified normal to calculate R.
// iblNdotV = GetShiftedNdotV(iblNormalWS, V), false);
}
GetPreIntegratedFGD(iblNdotV, bsdfData.perceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD);

preLightData.iblDirWS = GetSpecularDominantDir(bsdfData.normalWS, iblR, bsdfData.roughness);
preLightData.iblDirWS = GetSpecularDominantDir(bsdfData.normalWS, iblR, bsdfData.roughness, preLightData.NdotV);
// #if SHADERPASS == SHADERPASS_GBUFFER
// preLightData.ambientOcclusion = LOAD_TEXTURE2D(_AmbientOcclusion, posInput.unPositionSS).x;
// #endif
preLightData.iblMipLevel = perceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
float theta = FastACos(dot(bsdfData.normalWS, V));
float theta = FastACos(preLightData.NdotV);
// Scale and bias for the current precomputed table - the constant use here are the one that have been use when the table in LtcData.DisneyDiffuse.cs and LtcData.GGX.cs was use
float2 uv = 0.0078125 + 0.984375 * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);

preLightData.ltcGGXFresnelMagnitudeDiff = ltcMagnitude.r;
preLightData.ltcGGXFresnelMagnitude = ltcMagnitude.g;
preLightData.ltcDisneyDiffuseMagnitude = ltcMagnitude.b;
// Shadow
preLightData.unPositionSS = posInput.unPositionSS;
return preLightData;
}

// Maybe always using aniso maybe a win ?
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{
float TdotL = saturate(dot(bsdfData.tangentWS, L));
float BdotL = saturate(dot(bsdfData.bitangentWS, L));
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float TdotL = dot(bsdfData.tangentWS, L);
float BdotH = dot(bsdfData.bitangentWS, H);
float BdotL = dot(bsdfData.bitangentWS, L);
bsdfData.roughnessT = ClampRoughnessForAnalyticalLights(bsdfData.roughnessT);
bsdfData.roughnessB = ClampRoughnessForAnalyticalLights(bsdfData.roughnessB);
#ifdef LIT_USE_BSDF_PRE_LAMBDAV
Vis = V_SmithJointGGXAnisoLambdaV( preLightData.TdotV, preLightData.BdotV, preLightData.NdotV, TdotL, BdotL, NdotL,

bsdfData.roughnessT, bsdfData.roughnessB);
#endif
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float BdotH = dot(bsdfData.bitangentWS, H);
bsdfData.roughness = ClampRoughnessForAnalyticalLights(bsdfData.roughness);
#ifdef LIT_USE_BSDF_PRE_LAMBDAV
Vis = V_SmithJointGGX(NdotL, preLightData.NdotV, bsdfData.roughness, preLightData.ggxLambdaV);
#else

[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0f)
{
float shadowAttenuation = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, preLightData.unPositionSS);
float shadowAttenuation = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
illuminance *= shadowAttenuation;
}

// TODO: measure impact of having all these dynamic branch here and the gain (or not) of testing illuminace > 0
[branch] if (lightData.IESIndex >= 0 && illuminance > 0.0)
{
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float2 sphericalCoord = GetIESTextureCoordinate(lightToWorld, L);
illuminance *= SampleIES(lightLoopContext, lightData.IESIndex, sphericalCoord, 0).r;
}
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
{
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float shadowAttenuation = GetPunctualShadowAttenuation(lightLoopContext, lightData.lightType, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
shadowAttenuation = lerp(1.0, shadowAttenuation, lightData.shadowDimmer);
illuminance *= shadowAttenuation;
}
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
{
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);

illuminance *= cookie.a;
}
[branch] if (lightData.IESIndex >= 0 && illuminance > 0.0)
{
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float2 sphericalCoord = GetIESTextureCoordinate(lightToWorld, L);
illuminance *= SampleIES(lightLoopContext, lightData.IESIndex, sphericalCoord, 0).r;
}
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
{
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float shadowAttenuation = GetPunctualShadowAttenuation(lightLoopContext, positionWS + offset, lightData.shadowIndex, L, preLightData.unPositionSS);
shadowAttenuation = lerp(1.0, shadowAttenuation, lightData.shadowDimmer);
illuminance *= shadowAttenuation;
}
[branch] if (illuminance > 0.0)
{
BSDF(V, L, positionWS, preLightData, bsdfData, diffuseLighting, specularLighting);

P1 -= positionWS;
P2 -= positionWS;
// Construct an orthonormal basis (local coordinate system) around N.
// TODO: it could be stored in PreLightData. All LTC lights compute it more than once!
// Also consider using 'bsdfData.tangentWS', 'bsdfData.bitangentWS', 'bsdfData.normalWS'.
// Construct a view-dependent orthonormal basis around N.
// TODO: it could be stored in PreLightData, since all LTC lights compute it more than once.
float3x3 basis;
basis[0] = normalize(V - bsdfData.normalWS * preLightData.NdotV);
basis[1] = normalize(cross(bsdfData.normalWS, basis[0]));

float lightPdf = 0.0; // Pdf of the light sample
float2 u = Hammersley2d(i, sampleCount);
u = frac(u + randNum + 0.5);
u = frac(u + randNum);
float4x4 localToWorld = float4x4(float4(lightData.right, 0.0), float4(lightData.up, 0.0), float4(lightData.forward, 0.0), float4(lightData.positionWS, 1.0));

// ----------------------------------------------------------------------------
// Ref: Moving Frostbite to PBR (Appendix A)
float3 IntegrateLambertIBLRef( LightLoopContext lightLoopContext,
EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 2048)
float3 IntegrateLambertIBLRef(LightLoopContext lightLoopContext,
float3 V, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 4096)
float3 N = bsdfData.normalWS;
float3 tangentX = bsdfData.tangentWS;
float3x3 localToWorld = GetLocalFrame(N, tangentX);
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
float2 randNum = InitRandom(N.xy * 0.5 + 0.5);
float2 randNum = InitRandom(V.xy * 0.5 + 0.5);
u = frac(u + randNum + 0.5);
u = frac(u + randNum);
float3 L;
float NdotL;

}
float3 IntegrateDisneyDiffuseIBLRef(LightLoopContext lightLoopContext,
float3 V, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 2048)
float3 V, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 4096)
float3 N = bsdfData.normalWS;
float3 tangentX = bsdfData.tangentWS;
float3x3 localToWorld = GetLocalFrame(N, tangentX);
float NdotV = GetShiftedNdotV(N, V, false);
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
float2 randNum = InitRandom(N.xy * 0.5 + 0.5);
float2 randNum = InitRandom(V.xy * 0.5 + 0.5);
u = frac(u + randNum + 0.5);
u = frac(u + randNum);
float3 L;
float NdotL;

float LdotH = dot(L, H);
// Note: we call DisneyDiffuse that require to multiply by Albedo / PI. Divide by PI is already taken into account
// in weightOverPdf of ImportanceSampleLambert call.
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
float disneyDiffuse = DisneyDiffuse(preLightData.NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function
float4 val = SampleEnv(lightLoopContext, lightData.envIndex, L, 0);

}
// Ref: Moving Frostbite to PBR (Appendix A)
float3 IntegrateSpecularGGXIBLRef( LightLoopContext lightLoopContext,
float3 V, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 2048)
float3 IntegrateSpecularGGXIBLRef(LightLoopContext lightLoopContext,
float3 V, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 4096)
float3 N = bsdfData.normalWS;
float3 tangentX = bsdfData.tangentWS;
float3 tangentY = bsdfData.bitangentWS;
float3x3 localToWorld = GetLocalFrame(N, tangentX);
float NdotV = GetShiftedNdotV(N, V, false);
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
float3 acc = float3(0.0, 0.0, 0.0);
// Add some jittering on Hammersley2d

{
float2 u = Hammersley2d(i, sampleCount);
u = frac(u + randNum + 0.5);
u = frac(u + randNum);
float VdotH;
float NdotL;

// GGX BRDF
if (bsdfData.materialId = MATERIALID_LIT_ANISO)
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
ImportanceSampleAnisoGGX(u, V, N, tangentX, tangentY, bsdfData.roughnessT, bsdfData.roughnessB, NdotV, L, VdotH, NdotL, weightOverPdf);
ImportanceSampleAnisoGGX(u, V, localToWorld, bsdfData.roughnessT, bsdfData.roughnessB, preLightData.NdotV, L, VdotH, NdotL, weightOverPdf);
ImportanceSampleGGX(u, V, localToWorld, bsdfData.roughness, NdotV, L, VdotH, NdotL, weightOverPdf);
ImportanceSampleGGX(u, V, localToWorld, bsdfData.roughness, preLightData.NdotV, L, VdotH, NdotL, weightOverPdf);
}

#ifdef LIT_DISPLAY_REFERENCE_IBL
specularLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, lightData, bsdfData);
specularLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
diffuseLighting = IntegrateLambertIBLRef(lightData, bsdfData);
diffuseLighting = IntegrateLambertIBLRef(lightData, V, bsdfData);
diffuseLighting = IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, lightData, bsdfData);
diffuseLighting = IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
#endif
*/
diffuseLighting = float3(0.0, 0.0, 0.0);

// TODO: we must always perform a weight calculation as due to tiled rendering we need to smooth out cubemap at boundaries.
// So goal is to split into two category and have an option to say if we parallax correct or not.
// TODO: compare current Morten version: offline cubemap with a particular remap + the bias in perceptualRoughnessToMipmapLevel
// to classic remap like unreal/Frobiste. The function GetSpecularDominantDir can result in a better matching in this case
// We let GetSpecularDominantDir currently as it still an improvement but not as good as it could be
float mip = perceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, mip);
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, preLightData.iblMipLevel);
specularLighting = preLD.rgb * preLightData.specularFGD;
// Apply specular occlusion on it

#endif
#endif

73
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.shader


_SpecularOcclusionMap("SpecularOcclusion", 2D) = "white" {}
_NormalMap("NormalMap", 2D) = "bump" {}
_NormalScale("_NormalScale", Range(0.0, 2.0)) = 1
_HeightScale("Height Scale", Float) = 0.01
_HeightBias("Height Bias", Float) = 0
_HeightAmplitude("Height Amplitude", Float) = 0.01 // In world units
_HeightCenter("Height Center", Float) = 0.5 // In texture space
_TangentMap("TangentMap", 2D) = "bump" {}
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0

[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1,0,0,0)
[HideInInspector] _UVMappingPlanar("_UVMappingPlanar", Float) = 0
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1,0,0,0)

HLSLINCLUDE
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4// TEMP: unitl we go futher in dev
//-------------------------------------------------------------------------------------
// Variant

#pragma shader_feature _MAPPING_TRIPLANAR
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV2_OR_UV3
#pragma shader_feature _EMISSIVE_COLOR

#include "Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
SubShader

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitSharePass.hlsl"
#include "LitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitSharePass.hlsl"
#include "LitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassDebugViewMaterial.hlsl"

// DYNAMICLIGHTMAP_ON is used when we have an "enlighten lightmap" ie a lightmap updated at runtime by enlighten.This lightmap contain indirect lighting from realtime lights and realtime emissive material.Offline baked lighting(from baked material / light,
// both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON.
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitMetaPass.hlsl"
#include "LitMetaPass.hlsl"
#include "../../ShaderPass/ShaderPassLightTransport.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitDepthPass.hlsl"
#include "LitDepthPass.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

ZWrite On
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitDepthPass.hlsl"
#include "LitDepthPass.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitVelocityPass.hlsl"
#include "LitVelocityPass.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitDistortionPass.hlsl"
#include "LitDistortionPass.hlsl"
#include "../../ShaderPass/ShaderPassDistortion.hlsl"

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#define SHADERPASS SHADERPASS_FORWARD
// TEMP until pragma work in include

#include "../../Lighting/Lighting.hlsl"
#include "../../Lighting/Lighting.hlsl"
#include "ShaderPass/LitSharePass.hlsl"
#include "LitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"

CustomEditor "Experimental.ScriptableRenderLoop.LitGUI"
CustomEditor "Experimental.Rendering.HDPipeline.LitGUI"
}

195
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl


// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float3 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float3 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{

val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ), scale);
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX), scale);
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY), scale);
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv));
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv), scale);
float3 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float3 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv), scale);
}
}
// This version is for normalmap with RGB encoding only, i.e non encoding. It is necessary to use this abstraction to handle correctly triplanar
// plus consistent with the normal scale parameter
float3 SampleNormalLayerRGB(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{

val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
val += weights.x * UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ), scale);
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
val += weights.y * UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX), scale);
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
val += weights.z * UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY), scale);
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv));
return UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv), scale);
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord) SampleNormalLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord) SampleNormalLayerAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale) SampleNormalLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale) SampleNormalLayerAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleNormalLayerRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)

#define LAYER_INDEX 0
#define ADD_IDX(Name) Name
#define ADD_ZERO_IDX(Name) Name
#include "LitSurfaceData.hlsl"
#include "LitDataInternal.hlsl"
#ifdef TESSELLATION_ON
#include "LitTessellation.hlsl"
#endif
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{

float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, builtinData.depthOffset, posInput);
ApplyDepthOffsetPositionInput(V, depthOffset, posInput);
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData);
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData, normalTS);
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
// NdotV should not be negative for visible pixels, but it can happen due to the
// perspective projection and the normal mapping + decals. In that case, the normal
// should be modified to become valid (i.e facing the camera) to avoid weird artifacts.
// Note: certain applications (e.g. SpeedTree) make use of double-sided lighting.
// This will potentially reduce the length of the normal at edges of geometry.
bool twoSided = false;
GetShiftedNdotV(surfaceData.normalWS, V, twoSided);
// Orthonormalize the basis vectors using the Gram-Schmidt process.
// We assume that the length of the surface normal is sufficiently close to 1.
surfaceData.tangentWS = normalize(surfaceData.tangentWS - dot(surfaceData.tangentWS, surfaceData.normalWS));
// Caution: surfaceData must be fully initialize before calling GetBuiltinData
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);
}

// Generate function for all layer
#define LAYER_INDEX 0
#define ADD_IDX(Name) Name##0
#include "LitSurfaceData.hlsl"
#include "LitDataInternal.hlsl"
#ifdef TESSELLATION_ON
#include "LitTessellation.hlsl" // Include only one time for layer 0
#endif
#include "LitSurfaceData.hlsl"
#include "LitDataInternal.hlsl"
#include "LitSurfaceData.hlsl"
#include "LitDataInternal.hlsl"
#include "LitSurfaceData.hlsl"
#include "LitDataInternal.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX

outWeights[0] = left;
}
float3 BlendLayeredColor(float3 rgb0, float3 rgb1, float3 rgb2, float3 rgb3, float weight[4])
float3 BlendLayeredFloat3(float3 x0, float3 x1, float3 x2, float3 x3, float weight[4])
result = rgb0 * weight[0] + rgb1 * weight[1];
result = x0 * weight[0] + x1 * weight[1];
result += (rgb2 * weight[2]);
result += (x2 * weight[2]);
result += rgb3 * weight[3];
result += x3 * weight[3];
float3 BlendLayeredNormal(float3 normal0, float3 normal1, float3 normal2, float3 normal3, float weight[4])
{
float3 result = float3(0.0, 0.0, 0.0);
result = normal0 * weight[0] + normal1 * weight[1];
#if _LAYER_COUNT >= 3
result += normal2 * weight[2];
#endif
#if _LAYER_COUNT >= 4
result += normal3 * weight[3];
#endif
return normalize(result);
}
float BlendLayeredScalar(float x0, float x1, float x2, float x3, float weight[4])
{
float result = 0.0;

return result;
}
float ApplyHeightBasedBlend(inout float inputFactor, float previousLayerHeight, float layerHeight, float heightOffset, float heightFactor, float edgeBlendStrength)
float ApplyHeightBasedBlend(inout float inputFactor, float previousLayerHeight, float layerHeight, float heightOffset, float heightFactor, float edgeBlendStrength, float vertexColor)
float finalLayerHeight = layerHeight * heightFactor + heightOffset;
float finalLayerHeight = heightFactor * layerHeight + heightOffset + _VertexColorHeightFactor * (vertexColor * 2.0 - 1.0);
edgeBlendStrength = max(0.001, edgeBlendStrength);
float heightThreshold = previousLayerHeight + edgeBlendStrength;
edgeBlendStrength = max(0.00001, edgeBlendStrength);
if (previousLayerHeight >= finalLayerHeight)
{

}
#define SURFACEDATA_BLEND_COLOR(surfaceData, name, mask) BlendLayeredColor(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_NORMAL(surfaceData, name, mask) BlendLayeredNormal(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_COLOR(surfaceData, name, mask) BlendLayeredFloat3(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_SCALAR(surfaceData, name, mask) BlendLayeredScalar(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define PROP_BLEND_SCALAR(name, mask) BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);

float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, builtinData.depthOffset, posInput);
ApplyDepthOffsetPositionInput(V, depthOffset, posInput);
ApplyDepthOffsetAttribute(depthOffset, input);
#endif

SurfaceData surfaceData3;
float alpha0 = GetSurfaceData0(input, layerTexCoord, surfaceData0);
float alpha1 = GetSurfaceData1(input, layerTexCoord, surfaceData1);
float alpha2 = GetSurfaceData2(input, layerTexCoord, surfaceData2);
float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3);
float3 normalTS0;
float3 normalTS1;
float3 normalTS2;
float3 normalTS3;
float alpha0 = GetSurfaceData0(input, layerTexCoord, surfaceData0, normalTS0);
float alpha1 = GetSurfaceData1(input, layerTexCoord, surfaceData1, normalTS1);
float alpha2 = GetSurfaceData2(input, layerTexCoord, surfaceData2, normalTS2);
float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3, normalTS3);
#if defined(_LAYER_MASK_VERTEX_COLOR)
// Mutually exclusive with _HEIGHT_BASED_BLEND
#if defined(_LAYER_MASK_VERTEX_COLOR_MUL) // Used when no layer mask is set
#elif defined(_LAYER_MASK_VERTEX_COLOR_ADD) // When layer mask is set, color is additive to enable user to override it.
maskValues = saturate(maskValues + input.vertexColor.rgb * 2.0 - 1.0);
#if defined(_HEIGHT_BASED_BLEND)
if (_UseHeightBasedBlend1 > 0.0f)
{
baseLayerHeight = ApplyHeightBasedBlend(maskValues.r, baseLayerHeight, height1, _HeightOffset1, _HeightFactor1, _BlendSize1);
}
if (_UseHeightBasedBlend2 > 0.0f)
{
baseLayerHeight = ApplyHeightBasedBlend(maskValues.g, baseLayerHeight, height2, _HeightOffset2 + _HeightOffset1, _HeightFactor2, _BlendSize2);
}
if (_UseHeightBasedBlend3 > 0.0f)
{
ApplyHeightBasedBlend(maskValues.b, baseLayerHeight, height3, _HeightOffset3 + _HeightOffset2 + _HeightOffset1, _HeightFactor3, _BlendSize3);
}
baseLayerHeight = ApplyHeightBasedBlend(maskValues.r, baseLayerHeight, height1, _HeightOffset1, _HeightFactor1, _BlendSize1, input.vertexColor.r);
baseLayerHeight = ApplyHeightBasedBlend(maskValues.g, baseLayerHeight, height2, _HeightOffset2 + _HeightOffset1, _HeightFactor2, _BlendSize2, input.vertexColor.g);
ApplyHeightBasedBlend(maskValues.b, baseLayerHeight, height3, _HeightOffset3 + _HeightOffset2 + _HeightOffset1, _HeightFactor3, _BlendSize3, input.vertexColor.b);
#endif
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);

// Note: for normal map (in tangent space) it is possible to have better performance
// by blending in tangent space then transform to world and apply flip.
// Sadly this require a specific path (without taking into account that there is detail normal map)
// mean it add an extra cost of maintenance. We chose to not do this optimization in favor
// of simpler code and in the future will rely on shader graph to create optimize code.
surfaceData.normalWS = SURFACEDATA_BLEND_NORMAL(surfaceData, normalWS, weights);
float3 normalTS;
#if defined(_HEIGHT_BASED_BLEND)
float _InheritBaseLayer0 = 1.0f; // Default value for lerp when all weights but base layer are zero.
// Compute the combined inheritance factor of layers 1,2 and 3
float inheritFactor = PROP_BLEND_SCALAR(_InheritBaseLayer, weights);
float3 vertexNormalTS = float3(0.0, 0.0, 1.0);
// The idea here is to lerp toward vertex normal. This way when we don't want to inherit, we will combine layer 1/2/3 normal with a vertex normal which is neutral.
float3 baseLayerNormalTS = normalize(lerp(vertexNormalTS, normalTS0, inheritFactor));
// Blend layer 1/2/3 normals before combining to the base layer. Again we need to have a neutral value for base layer (vertex normal) in case all weights are zero.
float3 layersNormalTS = BlendLayeredFloat3(vertexNormalTS, normalTS1, normalTS2, normalTS3, weights);
normalTS = BlendNormalRNM(baseLayerNormalTS, layersNormalTS);
#else
normalTS = BlendLayeredFloat3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
#endif
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
// NdotV should not be negative for visible pixels, but it can happen due to the
// perspective projection and the normal mapping + decals. In that case, the normal
// should be modified to become valid (i.e facing the camera) to avoid weird artifacts.
// Note: certain applications (e.g. SpeedTree) make use of double-sided lighting.
// This will potentially reduce the length of the normal at edges of geometry.
bool twoSided = false;
GetShiftedNdotV(surfaceData.normalWS, V, twoSided);
// Orthonormalize the basis vectors using the Gram-Schmidt process.
// We assume that the length of the surface normal is sufficiently close to 1.
surfaceData.tangentWS = normalize(surfaceData.tangentWS - dot(surfaceData.tangentWS, surfaceData.normalWS));
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;
surfaceData.subSurfaceRadius = 1.0;

31
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl


TEXTURE2D(_NormalMap);
SAMPLER2D(sampler_NormalMap);
float _NormalScale;
TEXTURE2D(_DetailMask);
SAMPLER2D(sampler_DetailMask);

TEXTURE2D(_HeightMap);
SAMPLER2D(sampler_HeightMap);
float _HeightScale;
float _HeightBias;
float _HeightAmplitude;
float _HeightCenter;
TEXTURE2D(_TangentMap);
SAMPLER2D(sampler_TangentMap);

PROP_DECL_TEX2D(_SpecularOcclusionMap);
PROP_DECL_TEX2D(_NormalMap);
PROP_DECL(float, _NormalScale);
PROP_DECL_TEX2D(_HeightMap);
PROP_DECL_TEX2D(_DetailMask);

PROP_DECL(float, _DetailHeightScale);
PROP_DECL(float, _DetailAOScale);
PROP_DECL(float, _HeightScale);
PROP_DECL(float, _HeightBias);
PROP_DECL(float, _HeightAmplitude);
PROP_DECL(float, _HeightCenter);
TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);

TEXTURE2D(_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
float _UseHeightBasedBlend1;
float _UseHeightBasedBlend2;
float _UseHeightBasedBlend3;
float _HeightOffset1;
float _HeightOffset2;
float _HeightOffset3;

float _BlendSize1;
float _BlendSize2;
float _BlendSize3;
float _VertexColorHeightFactor;
float _InheritBaseLayer1;
float _InheritBaseLayer2;
float _InheritBaseLayer3;
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);

PROP_DECL(float, _TexWorldScale);
PROP_DECL(float, _UVMappingPlanar);
PROP_DECL(float, _UVMappingPlanar);
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);

// Tessellation specific
#ifdef TESSELLATION_ON
float _TessellationFactorFixed;
float _TessellationFactorMaxDistance;
float _TessellationFactorTriangleSize;
float _TessellationShapeFactor;
float _TessellationBackFaceCullEpsilon;
float _TessellationObjectScale;
#endif

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs


using UnityEngine.Rendering;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Lit
{

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LtcData.GGX.cs


using UnityEngine.Rendering;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Lit
{

6
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/PreIntegratedFGD.shader


#pragma vertex Vert
#pragma fragment Frag
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4// TEMP: unitl we go futher in dev
#include "Common.hlsl"
#include "ImageBasedLighting.hlsl"

float3 V = float3(sqrt(1 - NdotV * NdotV), 0, NdotV);
float3 N = float3(0.0, 0.0, 1.0);
const int numSamples = 2048;
float4 preFGD = IntegrateGGXAndDisneyFGD(V, N, PerceptualRoughnessToRoughness(perceptualRoughness), numSamples);
float4 preFGD = IntegrateGGXAndDisneyFGD(V, N, PerceptualRoughnessToRoughness(perceptualRoughness));
return float4(preFGD.xyz, 1.0);
}

92
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


float height = 0.0f;
#ifdef _HEIGHTMAP
height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
height = (SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r - ADD_IDX(_HeightCenter)) * ADD_IDX(_HeightAmplitude);
//#ifndef _HEIGHTMAP_AS_DISPLACEMENT
// //height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
// float2 offset = ParallaxOffset(viewDirTS, height);
//#ifdef _PER_PIXEL_DISPLACEMENT
// //height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
// float2 offset = ParallaxOffset(viewDirTS, height);
// ADD_IDX(layerTexCoord.base).uv += offset;
// ADD_IDX(layerTexCoord.base).uvYZ += offset;
// ADD_IDX(layerTexCoord.base).uvZX += offset;
// ADD_IDX(layerTexCoord.base).uvXY += offset;
// ADD_IDX(layerTexCoord.base).uv += offset;
// ADD_IDX(layerTexCoord.base).uvYZ += offset;
// ADD_IDX(layerTexCoord.base).uvZX += offset;
// ADD_IDX(layerTexCoord.base).uvXY += offset;
// ADD_IDX(layerTexCoord.details).uv += offset;
// ADD_IDX(layerTexCoord.details).uvYZ += offset;
// ADD_IDX(layerTexCoord.details).uvZX += offset;
// ADD_IDX(layerTexCoord.details).uvXY += offset;
// ADD_IDX(layerTexCoord.details).uv += offset;
// ADD_IDX(layerTexCoord.details).uvYZ += offset;
// ADD_IDX(layerTexCoord.details).uvZX += offset;
// ADD_IDX(layerTexCoord.details).uvXY += offset;
// // Only modify texcoord for first layer, this will be use by for builtin data (like lightmap)
// if (LAYER_INDEX == 0)
// {
// input.texCoord0 += offset;
// input.texCoord1 += offset;
// input.texCoord2 += offset;
// input.texCoord3 += offset;
// }
// // Only modify texcoord for first layer, this will be use by for builtin data (like lightmap)
// if (LAYER_INDEX == 0)
// {
// input.texCoord0 += offset;
// input.texCoord1 += offset;
// input.texCoord2 += offset;
// input.texCoord3 += offset;
// }
// // Need to refetch for the right parallaxed height for layer blending to behave correctly...
// height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
// // Need to refetch for the right parallaxed height for layer blending to behave correctly...
// height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
// #endif
// #endif
#endif
return height;

float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData)
float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData, out float3 normalTS)
{
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
float alpha = ADD_IDX(_BaseColor).a;

#ifdef _DETAIL_MAP_WITH_NORMAL
// Resample the detail map but this time for the normal map. This call should be optimize by the compiler
// We split both call due to trilinear mapping
float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details));
float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details), ADD_ZERO_IDX(_DetailNormalScale));
//float detailAO = 0.0;
#else
// TODO: Use heightmap as a derivative with Morten Mikklesen approach, how this work with our abstraction and triplanar ?

//surfaceData.specularOcclusion *= surfaceData.specularOcclusion;
surfaceData.specularOcclusion = 1.0;
#endif
surfaceData.normalWS = float3(0.0, 0.0, 0.0); // Need to init this so that the compiler leaves us alone.
float3 vertexNormalWS = normalize(input.tangentToWorld[2].xyz);
float3 normalTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base));
#ifdef _DETAIL_MAP
normalTS = lerp(normalTS, BlendNormal(normalTS, detailNormalTS), detailMask);
#endif
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
normalTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base), ADD_ZERO_IDX(_NormalScale));
// TODO: We are suppose to do * 2 - 1 here. how to deal with triplanar...
float3 normalOS = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base)).rgb;
surfaceData.normalWS = TransformObjectToWorldDir(normalOS);
float3 normalOS = SAMPLE_LAYER_NORMALMAP_RGB(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base), ADD_ZERO_IDX(_NormalScale)).rgb;
normalTS = TransformObjectToTangent(normalOS, input.tangentToWorld);
#endif
float3 detailNormalWS = TransformTangentToWorld(detailNormalTS, input.tangentToWorld);
surfaceData.normalWS = lerp(surfaceData.normalWS, BlendNormal(surfaceData.normalWS, detailNormalWS), detailMask);
normalTS = lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask);
#endif
surfaceData.normalWS = vertexNormalWS;
normalTS = float3(0.0, 0.0, 1.0);
float3 oppositeNormalWS = -surfaceData.normalWS;
float3 oppositeNormalTS = -normalTS;
float3 oppositeNormalWS = reflect(surfaceData.normalWS, vertexNormalWS);
float3 oppositeNormalTS = reflect(normalTS, float3(0.0, 0.0, 1.0)); // Reflect around vertex normal (in tangent space this is z)
// TODO : Test if GetOdddNegativeScale() is necessary here in case of normal map, as GetOdddNegativeScale is take into account in CreateTangentToWorld();
surfaceData.normalWS = input.isFrontFace ?
(GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS) :
(-GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS);
// TODO : Test if GetOddNegativeScale() is necessary here in case of normal map, as GetOddNegativeScale is take into account in CreateTangentToWorld();
normalTS = input.isFrontFace ?
(GetOddNegativeScale() >= 0.0 ? normalTS : oppositeNormalTS) :
(-GetOddNegativeScale() >= 0.0 ? normalTS : oppositeNormalTS);
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

// TODO: think about using BC5
#ifdef _TANGENTMAP
#ifdef _NORMALMAP_TANGENT_SPACE // Normal and tangent use same space
float3 tangentTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base));
float3 tangentTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base), 1.0);
#else // Object space (TODO: We need to apply the world rotation here! - Require to pass world transform)
surfaceData.tangentWS = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base)).rgb;
#else // Object space
float3 tangentOS = SAMPLE_LAYER_NORMALMAP_RGB(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base), 1.0).rgb;
surfaceData.tangentWS = TransformObjectToWorldDir(tangentOS);
#endif
#else
surfaceData.tangentWS = normalize(input.tangentToWorld[0].xyz);

8
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/MaterialUtilities.hlsl


#ifdef DIRLIGHTMAP_COMBINED
bakeDiffuseLighting += SampleDirectionalLightmap(TEXTURE2D_PARAM(unity_Lightmap, samplerunity_Lightmap),
TEXTURE2D_PARAM(unity_LightmapInd, samplerunity_Lightmap),
uvStaticLightmap, unity_LightmapST, normalWS);
uvStaticLightmap, unity_LightmapST, normalWS, true);
bakeDiffuseLighting += SampleSingleLightmap(TEXTURE2D_PARAM(unity_Lightmap, samplerunity_Lightmap), uvStaticLightmap, unity_LightmapST);
bakeDiffuseLighting += SampleSingleLightmap(TEXTURE2D_PARAM(unity_Lightmap, samplerunity_Lightmap), uvStaticLightmap, unity_LightmapST, true);
#endif
#endif

TEXTURE2D_PARAM(unity_DynamicDirectionality, samplerunity_DynamicLightmap),
uvDynamicLightmap, unity_DynamicLightmapST, normalWS);
uvDynamicLightmap, unity_DynamicLightmapST, normalWS, false);
bakeDiffuseLighting += SampleSingleLightmap(TEXTURE2D_PARAM(unity_DynamicLightmap, samplerunity_DynamicLightmap), uvDynamicLightmap, unity_DynamicLightmapST);
bakeDiffuseLighting += SampleSingleLightmap(TEXTURE2D_PARAM(unity_DynamicLightmap, samplerunity_DynamicLightmap), uvDynamicLightmap, unity_DynamicLightmapST, false);
#endif
#endif

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public abstract class BaseUnlitGUI : ShaderGUI
{

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
class UnlitGUI : BaseUnlitGUI
{

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Unlit
{

8
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.cs.hlsl


#ifndef UNLIT_CS_HLSL
#define UNLIT_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.Unlit.SurfaceData: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Unlit.SurfaceData: static fields
// UnityEngine.Experimental.ScriptableRenderLoop.Unlit.BSDFData: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Unlit.BSDFData: static fields
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Unlit.SurfaceData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Unlit.SurfaceData
// PackingRules = Exact
struct SurfaceData
{

// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Unlit.BSDFData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Unlit.BSDFData
// PackingRules = Exact
struct BSDFData
{

98
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.shader


_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}
_EmissiveIntensity("EmissiveIntensity", Float) = 0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Only", Float) = 0.0
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 0.0
[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5

[HideInInspector] _BlendMode ("__blendmode", Float) = 0.0
[HideInInspector] _SrcBlend ("__src", Float) = 1.0
[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _BlendMode("__blendmode", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[Enum(None, 0, DoubleSided, 1)] _DoubleSidedMode("Double sided mode", Float) = 0
}

#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 // TEMP: unitl we go futher in dev
//-------------------------------------------------------------------------------------
// Variant

#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _EMISSIVE_COLOR_MAP
//-------------------------------------------------------------------------------------

float _EmissiveIntensity;
float _AlphaCutoff;
// All our shaders use same name for entry point
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL

HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#include "UnlitData.hlsl"
#include "UnlitSharePass.hlsl"
#include "UnlitSharePass.hlsl"
#include "UnlitData.hlsl"
// ------------------------------------------------------------------
// forward opaque pass
// Material opaque that are always forward (i.e can't render in deferred) need to implement ForwardOnlyOpaque pass
// (Code is exactly the same as "Forward", it simply allow our system to filter objects correctly
// TODO: can we do this another way ? Like relying on QueueIndex ? But it will be require anyway for material with two forward pass like hair
Pass
{
Name "ForwardUnlit"
Tags { "LightMode" = "ForwardOnlyOpaque" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
Cull [_CullMode]
HLSLPROGRAM
#define SHADERPASS SHADERPASS_FORWARD_UNLIT
#include "../../Material/Material.hlsl"
#include "UnlitSharePass.hlsl"
#include "UnlitData.hlsl"
#include "../../ShaderPass/ShaderPassForwardUnlit.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// forward pass

Tags { "LightMode" = "ForwardUnlit" }
Tags { "LightMode" = "Forward" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]

#pragma vertex VertDefault
#pragma fragment Frag
#include "UnlitSharePass.hlsl"
#include "UnlitSharePass.hlsl"
#include "../../ShaderPass/ShaderPassForwardUnlit.hlsl"

// Lightmap memo
// DYNAMICLIGHTMAP_ON is used when we have an "enlighten lightmap" ie a lightmap updated at runtime by enlighten.This lightmap contain indirect lighting from realtime lights and realtime emissive material.Offline baked lighting(from baked material / light,
// both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON.
#pragma vertex Vert
#pragma fragment Frag
#include "../../Material/Material.hlsl"
#include "../../Material/Material.hlsl"
CBUFFER_START(UnityMetaPass)
// x = use uv1 as raster position

CBUFFER_END
// This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency
float unity_OneOverOutputBoost;
// This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency
float unity_OneOverOutputBoost;
float unity_MaxOutputValue;
struct Attributes

ENDHLSL
}
Pass
{
Name "Distortion" // Name is not used
Tags { "LightMode" = "DistortionVectors" } // This will be only for transparent object based on the RenderQueue index
Blend One One
ZTest [_ZTestMode]
ZWrite off
Cull [_CullMode]
HLSLPROGRAM
#define SHADERPASS SHADERPASS_DISTORTION
#include "../../Material/Material.hlsl"
#include "UnlitSharePass.hlsl"
#include "UnlitData.hlsl"
#include "../../ShaderPass/ShaderPassDistortion.hlsl"
ENDHLSL
}
CustomEditor "Experimental.ScriptableRenderLoop.UnlitGUI"
CustomEditor "Experimental.Rendering.HDPipeline.UnlitGUI"
}

27
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/UnlitData.hlsl


builtinData.velocity = float2(0.0, 0.0);
#ifdef _DISTORTION_ON
float3 distortion = SAMPLE_TEXTURE2D(_DistortionVectorMap, sampler_DistortionVectorMap, input.texCoord0).rgb;
builtinData.distortion = distortion.rg;
builtinData.distortionBlur = distortion.b;
#else
#endif
#ifdef TESSELLATION_ON
float4 TessellationEdge(float3 p0, float3 p1, float3 p2, float3 n0, float3 n1, float3 n2)
{
return DistanceBasedTess(p0, p1, p2, 0.0, _TessellationFactorMaxDistance, unity_ObjectToWorld, _WorldSpaceCameraPos) * _TessellationFactorFixed.xxxx;
}
void Displacement(inout Attributes v)
{
#ifdef _HEIGHTMAP
float height = (SAMPLE_TEXTURE2D_LOD(ADD_ZERO_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), v.uv0, 0).r - ADD_ZERO_IDX(_HeightCenter)) * ADD_IDX(_HeightAmplitude);
#else
float height = 0.0;
#endif
#if (SHADERPASS != SHADERPASS_VELOCITY) && (SHADERPASS != SHADERPASS_DISTORTION)
v.positionOS.xyz += height * v.normalOS;
#endif
}
#endif

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/UnlitSharePass.hlsl


// Vertex shader
//-------------------------------------------------------------------------------------
PackedVaryings VertDefault(Attributes input)
PackedVaryings Vert(Attributes input)
{
Varyings output;

207
Assets/ScriptableRenderLoop/HDRenderPipeline/PostProcess/Resources/FinalPass.shader


// Final compositing pass, just does gamma correction for now.
_ToneMapCoeffs1("Parameters for neutral tonemap", Vector) = (0.0, 0.0, 0.0, 0.0)
_ToneMapCoeffs2("Parameters for neutral tonemap", Vector) = (0.0, 0.0, 0.0, 0.0)
_Exposure("Exposure", Range(-32.0, 32.0)) = 0
[ToggleOff] _EnableToneMap("Enable Tone Map", Float) = 0
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
HLSLINCLUDE
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma target 5.0
#pragma target 5.0
#include "Common.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl"
#include "ColorGrading.hlsl"
#include "Common.hlsl"
#include "Color.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl"
TEXTURE2D(_MainTex);
SAMPLER2D(sampler_MainTex);
TEXTURE2D(_MainTex);
SAMPLER2D(sampler_MainTex);
TEXTURE2D(_AutoExposure);
SAMPLER2D(sampler_AutoExposure);
float4 _ToneMapCoeffs1;
float4 _ToneMapCoeffs2;
TEXTURE2D(_LogLut);
SAMPLER2D(sampler_LogLut);
#define InBlack _ToneMapCoeffs1.x
#define OutBlack _ToneMapCoeffs1.y
#define InWhite _ToneMapCoeffs1.z
#define OutWhite _ToneMapCoeffs1.w
#define WhiteLevel _ToneMapCoeffs2.z
#define WhiteClip _ToneMapCoeffs2.w
float4 _LogLut_Params;
float _Exposure;
float _EnableToneMap;
float _Exposure;
struct Attributes
{
float3 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
float4 _NeutralTonemapperParams1;
float4 _NeutralTonemapperParams2;
struct Varyings
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
struct Attributes
{
float3 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.vertex = TransformWorldToHClip(input.vertex);
output.texcoord = input.texcoord.xy;
return output;
}
struct Varyings
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
float3 evalCurve(float3 x, float A, float B, float C, float D, float E, float F)
{
return ((x*(A*x + C*B) + D*E) / (x*(A*x + B) + D*F)) - E / F;
}
Varyings Vert(Attributes input)
{
Varyings output;
output.vertex = TransformWorldToHClip(input.vertex);
output.texcoord = input.texcoord.xy;
return output;
}
float3 applyTonemapFilmicAD(float3 linearColor)
{
float blackRatio = InBlack / OutBlack;
float whiteRatio = InWhite / OutWhite;
// Neutral tonemapping (Hable/Hejl/Frostbite)
// Input is linear RGB
float3 NeutralCurve(float3 x, float a, float b, float c, float d, float e, float f)
{
return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
}
float3 NeutralTonemap(float3 x, float4 params1, float4 params2)
{
// ACES supports negative color values and WILL output negative values when coming from ACES or ACEScg
// Make sure negative channels are clamped to 0.0 as this neutral tonemapper can't deal with them properly
x = max((0.0).xxx, x);
// Tonemap
float a = params1.x;
float b = params1.y;
float c = params1.z;
float d = params1.w;
float e = params2.x;
float f = params2.y;
float whiteLevel = params2.z;
float whiteClip = params2.w;
// blend tunable coefficients
float B = lerp(0.57, 0.37, blackRatio);
float C = lerp(0.01, 0.24, whiteRatio);
float D = lerp(0.02, 0.20, blackRatio);
float3 whiteScale = (1.0).xxx / NeutralCurve(whiteLevel, a, b, c, d, e, f);
x = NeutralCurve(x * whiteScale, a, b, c, d, e, f);
x *= whiteScale;
// constants
float A = 0.2;
float E = 0.02;
float F = 0.30;
// Post-curve white point adjustment
x /= whiteClip.xxx;
// eval and correct for white point
float3 whiteScale = 1.0f / evalCurve(WhiteLevel, A, B, C, D, E, F);
float3 curr = evalCurve(linearColor * whiteScale, A, B, C, D, E, F);
return x;
}
return curr * whiteScale;
}
float4 Frag(Varyings input) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.texcoord);
float3 remapWhite(float3 inPixel, float whitePt)
#if EYE_ADAPTATION
// var breakout for readability
const float inBlack = 0;
const float outBlack = 0;
float inWhite = whitePt;
const float outWhite = 1;
// remap input range to output range
float3 outPixel = ((inPixel.rgb) - inBlack.xxx) / (inWhite.xxx - inBlack.xxx) * (outWhite.xxx - outBlack.xxx) + outBlack.xxx;
return (outPixel.rgb);
float autoExposure = SAMPLE_TEXTURE2D(_AutoExposure, sampler_AutoExposure, input.texcoord).r;
color *= autoExposure;
#endif
float3 NeutralTonemap(float3 x)
color.rgb *= _Exposure; // Exposure is in ev units (or 'stops'), precomputed CPU-side
#if NEUTRAL_GRADING
float3 finalColor = applyTonemapFilmicAD(x); // curve (dynamic coeffs differ per level)
finalColor = remapWhite(finalColor, WhiteClip); // post-curve white point adjustment
finalColor = saturate(finalColor);
return finalColor;
color.rgb = NeutralTonemap(color.rgb, _NeutralTonemapperParams1, _NeutralTonemapperParams2);
#elif CUSTOM_GRADING
{
float3 uvw = saturate(LinearToLogC(color));
float3 ApplyToneMap(float3 color)
// Strip lut format where `height = sqrt(width)`
uvw.z *= _LogLut_Params.z;
half shift = floor(uvw.z);
uvw.xy = uvw.xy * _LogLut_Params.z * _LogLut_Params.xy + _LogLut_Params.xy * 0.5;
uvw.x += shift * _LogLut_Params.y;
uvw.xyz = lerp(
SAMPLE_TEXTURE2D(_LogLut, sampler_LogLut, uvw.xy).rgb,
SAMPLE_TEXTURE2D(_LogLut, sampler_LogLut, uvw.xy + half2(_LogLut_Params.y, 0)).rgb,
uvw.z - shift
);
color.rgb = uvw;
}
#else
if (_EnableToneMap > 0.0)
{
return NeutralTonemap(color);
}
else
{
return saturate(color);
}
color = saturate(color);
#endif
float4 Frag(Varyings input) : SV_Target
{
float4 c = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.texcoord);
// Gamma correction
return color;
}
// TODO: Currenlt in the editor there a an additional pass were the result is copyed in a render target RGBA8_sRGB.
// So we must not correct the sRGB here else it will be done two time.
// To fix!
ENDHLSL
c.rgb = ApplyToneMap(c.rgb * exp2(_Exposure));
SubShader
{
Cull Off ZWrite Off ZTest Always
// return LinearToSRGB(c);
return c;
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma multi_compile __ NEUTRAL_GRADING CUSTOM_GRADING
#pragma multi_compile __ EYE_ADAPTATION
}
Fallback Off
}

2
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/CommonSettings.cs


using System.Linq;
using System.Reflection;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[ExecuteInEditMode]
[DisallowMultipleComponent]

2
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/Editor/CommonSettingsEditor.cs


using System.Linq;
using System.Reflection;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(CommonSettings))]
[CanEditMultipleObjects]

2
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderConfig.cs


// Configuration
//-----------------------------------------------------------------------------
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL(PackingRules.Exact)]
public enum ShaderOptions

2
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderConfig.cs.hlsl


#ifndef SHADERCONFIG_CS_HLSL
#define SHADERCONFIG_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.ShaderOptions: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.ShaderOptions: static fields
//
#define SHADEROPTIONS_VELOCITY_IN_GBUFFER (0)
#define SHADEROPTIONS_PACK_GBUFFER_IN_U16 (0)

4
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPass.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL(PackingRules.Exact)]
public enum ShaderPass

2
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl


#ifndef SHADERPASS_CS_HLSL
#define SHADERPASS_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.ShaderPass: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.ShaderPass: static fields
//
#define SHADERPASS_GBUFFER (0)
#define SHADERPASS_FORWARD (1)

2
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl


outColor = float4(0.0, 0.0, 0.0, 0.0);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.rawDepth;
outputDepth = posInput.depthRaw;
#endif
}

11
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
SurfaceData surfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
SurfaceData surfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;

outColor = float4(diffuseLighting + specularLighting, builtinData.opacity);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.rawDepth;
outputDepth = posInput.depthRaw;
#endif
}

8
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassGBuffer.hlsl


OUTPUT_GBUFFER(outGBuffer)
OUTPUT_GBUFFER_VELOCITY(outVelocityBuffer)
#ifdef _DEPTHOFFSET_ON
, float outputDepth : SV_Depth
, out float outputDepth : SV_Depth
#endif
)
{

BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
float3 bakeDiffuseLighting = GetBakedDiffuseLigthing(surfaceData, builtinData, bsdfData, preLightData);
ENCODE_INTO_GBUFFER(surfaceData, bakeDiffuseLighting, outGBuffer);

outputDepth = posInput.rawDepth;
outputDepth = posInput.depthRaw;
#endif
}

6
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassLightTransport.hlsl


#include "Color.hlsl"
// TODO: This is the max value allowed for emissive (bad name - but keep for now to retrieve it) (It is 8^2.2 (gamma) and 8 is the limit of punctual light slider...), comme from UnityCg.cginc. Fix it!
// Ask Jesper if this can be change for HDRenderPipeline
#define EMISSIVE_RGBM_SCALE 97.0
float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInputs input = UnpackVaryings(packedInput);

{
// TODO: THIS LIMIT MUST BE REMOVE, IT IS NOT HDR, change when RGB9e5 is here.
// Do we assume here that emission is [0..1] ?
res = PackRGBM(lightTransportData.emissiveColor, EMISSIVE_RGBM_SCALE);
res = PackEmissiveRGBM(lightTransportData.emissiveColor);
}
return res;

32
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl


return glstate_matrix_inv_projection;
}
float GetOdddNegativeScale()
float GetOddNegativeScale()
{
return unity_WorldTransformParams.w;
}

float3x3 CreateTangentToWorld(float3 normal, float3 tangent, float tangentSign)
{
// For odd-negative scale transforms we need to flip the sign
float sign = tangentSign * GetOdddNegativeScale();
float3 bitangent = cross(normal, tangent) * sign;
float sgn = tangentSign * GetOddNegativeScale();
float3 bitangent = cross(normal, tangent) * sgn;
return float3x3(tangent, bitangent, normal);
}

{
return normalize(_WorldSpaceCameraPos.xyz - positionWS);
float3 V = _WorldSpaceCameraPos.xyz - positionWS;
// Uncomment this once the compiler bug is fixed.
// if (unity_OrthoParams.w == 1.0)
// {
// float4x4 M = GetWorldToViewMatrix();
// V = M[1].xyz;
// }
return normalize(V);
}
float3 TransformTangentToWorld(float3 dirTS, float3 tangentToWorld[3])

return normalize(mul(float3x3(tangentToWorld[0].xyz, tangentToWorld[1].xyz, tangentToWorld[2].xyz), dirWS));
}
float3 TransformTangentToObject(float3 dirTS, float3 worldToTangent[3])
{
// TODO check: do we need to normalize ?
// worldToTangent is orthonormal so inverse <==> transpose
float3x3 mWorldToTangent = float3x3(worldToTangent[0].xyz, worldToTangent[1].xyz, worldToTangent[2].xyz);
float3 normalWS = mul(dirTS, mWorldToTangent);
return normalize(mul((float3x3)unity_WorldToObject, normalWS));
}
// Assume TBN is orthonormal.
float3 TransformObjectToTangent(float3 dirOS, float3 worldToTangent[3])
{
// TODO check: do we need to normalize ?
return normalize(mul(float3x3(worldToTangent[0].xyz, worldToTangent[1].xyz, worldToTangent[2].xyz), mul((float3x3)unity_ObjectToWorld, dirOS)));
}
#endif // UNITY_SHADER_VARIABLES_INCLUDED

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Shadow/FixedSizePCF/FixedSizePCF.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class ShadowFilteringFixedSizePCF
{

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky.meta


fileFormatVersion: 2
guid: d7469c05ebee66f4886264af0ab8bf2a
guid: 066ab4d03bd03384f81c9d82b479f8dd
folderAsset: yes
timeCreated: 1479239906
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Editor/HDRISkyEditor.cs


using UnityEngine;
using UnityEditor;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CanEditMultipleObjects]
[CustomEditor(typeof(HDRISkyParameters))]

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/HDRISkyParameters.cs


using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[DisallowMultipleComponent]
public class HDRISkyParameters

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class HDRISkyRenderer
: SkyRenderer<HDRISkyParameters>

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader


HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 // TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs


using UnityEngine;
using UnityEditor;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
//[CanEditMultipleObjects]
//[CustomEditor(typeof(ProceduralSkyParameters))]

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyParameters.cs


using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[ExecuteInEditMode]
[DisallowMultipleComponent]

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class ProceduralSkyRenderer
: SkyRenderer<ProceduralSkyParameters>

10
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader


HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 // TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag

#ifdef PERFORM_SKY_OCCLUSION_TEST
// Determine whether the sky is occluded by the scene geometry.
// Do not perform blending with the environment map if the sky is occluded.
float rawDepth = max(skyDepth, LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r);
float skyTexWeight = (rawDepth > skyDepth) ? 0.0 : 1.0;
float depthRaw = max(skyDepth, LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r);
float skyTexWeight = (depthRaw > skyDepth) ? 0.0 : 1.0;
float rawDepth = skyDepth;
float depthRaw = skyDepth;
UpdatePositionInput(rawDepth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
UpdatePositionInput(depthRaw, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float4 c1, c2, c3;
VolundTransferScatter(posInput.positionWS, c1, c2, c3);

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader


HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 // TEMP: unitl we go futher in dev
#pragma multi_compile _ USE_MIS

6
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyManager.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public enum SkyResolution

{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap(m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT);
// Note that m_SkyboxCubemapRT is created with auto-generate mipmap, it mean that here we have also our mipmap correctly box filtered for importance sampling.
// Convolve downsampled cubemap
RenderCubemapGGXConvolution(renderContext, m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT);

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyManager.cs.hlsl


#ifndef SKYMANAGER_CS_HLSL
#define SKYMANAGER_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.LightSamplingParameters: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.LightSamplingParameters: static fields
//
#define LIGHTSAMPLINGPARAMETERS_TEXTURE_HEIGHT (256)
#define LIGHTSAMPLINGPARAMETERS_TEXTURE_WIDTH (512)

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyParameters.cs


using System.Reflection;
using System.Linq;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[ExecuteInEditMode]
public class SkyParameters : MonoBehaviour

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyRenderer.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
abstract public class SkyRenderer
{

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Utilities.cs


using System;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Flags]
public enum ClearFlag

2
Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs


using System.Collections.Generic;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering
{
[System.Serializable]
public class ShadowSettings

9
Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl


{
// 1. ClipQuadToHorizon
// detect clipping config
// detect clipping config
uint config = 0;
if (L[0].z > 0) config += 1;
if (L[1].z > 0) config += 2;

// For polygonal lights.
float LTCEvaluate(float4x3 L, float3 V, float3 N, float NdotV, bool twoSided, float3x3 invM)
{
// Construct local orthonormal basis around N, aligned with N
// TODO: it could be stored in PreLightData. All LTC lights compute it more than once!
// Also consider using 'bsdfData.tangentWS', 'bsdfData.bitangentWS', 'bsdfData.normalWS'.
// Construct a view-dependent orthonormal basis around N.
// TODO: it could be stored in PreLightData, since all LTC lights compute it more than once.
float3x3 basis;
basis[0] = normalize(V - N * NdotV);
basis[1] = normalize(cross(N, basis[0]));

// 'normal' is the direction orthogonal to the tangent. It is the shortest vector between
// the shaded point and the line, pointing away from the shaded point.
float LineIrradiance(float l1, float l2, float3 normal, float3 tangent)
{
{
float d = length(normal);
float l1rcpD = l1 * rcp(d);
float l2rcpD = l2 * rcp(d);

37
Assets/ScriptableRenderLoop/ShaderLibrary/BSDF.hlsl


// With analytical light (not image based light) we clamp the minimun roughness in the NDF to avoid numerical instability.
#define UNITY_MIN_ROUGHNESS 0.002
float ClampRoughnessForAnalyticalLights(float roughness)
{
return max(roughness, UNITY_MIN_ROUGHNESS);
}
roughness = max(roughness, UNITY_MIN_ROUGHNESS);
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
return a2 / (f * f);

float D_GGX_Inverse(float NdotH, float roughness)
{
roughness = max(roughness, UNITY_MIN_ROUGHNESS);
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
float g = (f * f) / a2;

// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 19, 29.
float G_MaskingSmithGGX(float NdotV, float VdotH, float roughness)
{
// G1(V, H) = HeavisideStep(VdotH) / (1 + Λ(V)).
// Λ(V) = -0.5 + 0.5 * sqrt(1 + 1 / a²).
// a = 1 / (roughness * tan(theta)).
// 1 + Λ(V) = 0.5 + 0.5 * sqrt(1 + roughness² * tan²(theta)).
// tan²(theta) = (1 - cos²(theta)) / cos²(theta) = 1 / cos²(theta) - 1.
float hs = VdotH > 0.0 ? 1.0 : 0.0;
float a2 = roughness * roughness;
float z2 = NdotV * NdotV;
return hs / (0.5 + 0.5 * sqrt(1.0 + a2 * (1.0 / z2 - 1.0)));
}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 12.
float D_GGX_Visible(float NdotH, float NdotV, float VdotH, float roughness)
{
// Note that we pass 1.0 instead of 'VdotH' since the multiplication will already clamp.
return D_GGX(NdotH, roughness) * G_MaskingSmithGGX(NdotV, 1.0, roughness) * VdotH / NdotV;
}
// Ref: http://jcgt.org/published/0003/02/03/paper.pdf
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
{

// G = 1 / (1 + lambda_v + lambda_l);
float a = roughness;
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
float lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);

// roughnessB -> roughness in bitangent direction
float D_GGXAnisoNoPI(float TdotH, float BdotH, float NdotH, float roughnessT, float roughnessB)
{
roughnessT = max(roughnessT, UNITY_MIN_ROUGHNESS);
roughnessB = max(roughnessB, UNITY_MIN_ROUGHNESS);
float f = TdotH * TdotH / (roughnessT * roughnessT) + BdotH * BdotH / (roughnessB * roughnessB) + NdotH * NdotH;
return 1.0 / (roughnessT * roughnessB * f * f);
}

62
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


// Include language header
#if defined(SHADER_API_D3D11)
#include "API/D3D11.hlsl"
#elif defined(SHADER_API_PSSL)
#include "API/PSSL.hlsl"
#elif defined(SHADER_API_XBOXONE)
#include "API/D3D11_1.hlsl"
#else

float4 t = a; a = b; b = t;
}
#define CUBEMAPFACE_POSITIVE_X 0
#define CUBEMAPFACE_NEGATIVE_X 1
#define CUBEMAPFACE_POSITIVE_Y 2
#define CUBEMAPFACE_NEGATIVE_Y 3
#define CUBEMAPFACE_POSITIVE_Z 4
#define CUBEMAPFACE_NEGATIVE_Z 5
#ifndef INTRINSIC_CUBEMAP_FACE_ID
// TODO: implement this. Is the reference implementation of cubemapID provide by AMD the reverse of our ?
/*

return faceID;
}
*/
#endif // INTRINSIC_CUBEMAP_FACE_ID
#define CUBEMAPFACE_POSITIVE_X 0
#define CUBEMAPFACE_NEGATIVE_X 1
#define CUBEMAPFACE_POSITIVE_Y 2
#define CUBEMAPFACE_NEGATIVE_Y 3
#define CUBEMAPFACE_POSITIVE_Z 4
#define CUBEMAPFACE_NEGATIVE_Z 5
void GetCubeFaceID(float3 dir, out int faceIndex)
{

faceIndex = dir.y > 0.0 ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y;
}
}
#endif // INTRINSIC_CUBEMAP_FACE_ID
// ----------------------------------------------------------------------------
// Common math definition and fastmath function

}
// ----------------------------------------------------------------------------
// Texture format sampling
// ----------------------------------------------------------------------------
float2 DirectionToLatLongCoordinate(float3 dir)
{
// coordinate frame is (-Z, X) meaning negative Z is primary axis and X is secondary axis.
return float2(1.0 - 0.5 * INV_PI * atan2(dir.x, -dir.z), asin(dir.y) * INV_PI + 0.5);
}
// ----------------------------------------------------------------------------
// Z buffer to linear 0..1 depth
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane)
float Linear01DepthFromNear(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.x + zBufferParam.y / depth);
}
// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane)
float Linear01Depth(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.x * depth + zBufferParam.y);

}
// depthOffsetVS is always in the direction of the view vector (V)
void ApplyDepthOffsetPositionInput(float V, float depthOffsetVS, inout PositionInputs posInput)
void ApplyDepthOffsetPositionInput(float3 V, float depthOffsetVS, inout PositionInputs posInput)
{
posInput.depthVS += depthOffsetVS;
// TODO: it is an approx, need a correct value where we use projection matrix to reproject the depth from VS

posInput.positionCS = float4(posInput.positionSS.xy * 2.0 - 1.0, posInput.depthRaw, 1.0) * posInput.depthVS;
// Just add the offset along the view vector is sufficiant for world position
posInput.positionWS += V * depthOffsetVS;
}
//-----------------------------------------------------------------------------
// various helper
//-----------------------------------------------------------------------------
// NdotV should not be negative for visible pixels, but it can happen due to the
// perspective projection and the normal mapping + decals. In that case, the normal
// should be modified to become valid (i.e facing the camera) to avoid weird artifacts.
// Note: certain applications (e.g. SpeedTree) make use of two-sided lighting.
float GetShiftedNdotV(inout float3 N, float3 V, bool twoSided)
{
float NdotV = dot(N, V);
float limit = 1e-4;
if (!twoSided && NdotV < limit)
{
// We do not renormalize the normal because { abs(length(N) - 1.0) < limit }.
N += (-NdotV + limit) * V;
NdotV = limit;
}
return NdotV;
}
#endif // UNITY_COMMON_INCLUDED

25
Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl


}
//-----------------------------------------------------------------------------
// Get local frame
// Helper functions
// Generates an orthonormal basis from two orthogonal unit vectors.
float3x3 GetLocalFrame(float3 localZ, float3 localX)
// NdotV should not be negative for visible pixels, but it can happen due to the
// perspective projection and the normal mapping + decals. In that case, the normal
// should be modified to become valid (i.e facing the camera) to avoid weird artifacts.
// Note: certain applications (e.g. SpeedTree) make use of double-sided lighting.
// This will potentially reduce the length of the normal at edges of geometry.
float GetShiftedNdotV(inout float3 N, float3 V, bool twoSided)
float3 localY = cross(localZ, localX);
float NdotV = dot(N, V);
float limit = rcp(256.0); // Determined mostly by the quality of the G-buffer normal encoding
if (!twoSided && NdotV < limit)
{
// We do not renormalize the normal because { abs(length(N) - 1.0) < limit }.
N += (-NdotV + limit) * V;
NdotV = limit;
}
return float3x3(localX, localY, localZ);
return NdotV;
}
// Generates an orthonormal basis from a unit vector.

float3 localX = normalize(cross(upVector, localZ));
float3 localY = cross(localZ, localX);
return GetLocalFrame(localZ, localX);
return float3x3(localX, localY, localZ);
}
// TODO: test

15
Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl


return viewDirTS.xy * height;
}
// ref https://www.gamedev.net/topic/678043-how-to-blend-world-space-normals/#entry5287707
// assume compositing in world space
// Note: Using vtxNormal = float3(0, 0, 1) give the BlendNormalRNM formulation.
// TODO: Untested
float3 BlendNormalWorldspaceRNM(float3 n1, float3 n2, float3 vtxNormal)
{
// Build the shortest-arc quaternion
float4 q = float4(cross(vtxNormal, n2), dot(vtxNormal, n2) + 1.0) / sqrt(2.0 * (dot(vtxNormal, n2) + 1));
// Rotate the normal
return n1 * (q.w * q.w - dot(q.xyz, q.xyz)) + 2 * q.xyz * dot(q.xyz, n1) + 2 * q.w * cross(q.xyz, n1);
}
// assume compositing in tangent space
float3 BlendNormalRNM(float3 n1, float3 n2)
{
float3 t = n1.xyz + float3(0.0, 0.0, 1.0);

}
// assume compositing in tangent space
float3 BlendNormal(float3 n1, float3 n2)
{
return normalize(float3(n1.xy * n2.z + n2.xy * n1.z, n1.z * n2.z));

62
Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl


}
// Following functions are to sample enlighten lightmaps (or lightmaps encoded the same way as our
// enlighten implementation). They assume use of RGB9E5 for illuminance map.
// enlighten implementation). They assume use of RGB9E5 for dynamic illuminance map and RGBM for baked ones.
float3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), float2 uv, float4 transform)
#define LIGHTMAP_RGBM_RANGE 5.0
// TODO: This is the max value allowed for emissive (bad name - but keep for now to retrieve it) (It is 8^2.2 (gamma) and 8 is the limit of punctual light slider...), comme from UnityCg.cginc. Fix it!
// Ask Jesper if this can be change for HDRenderPipeline
#define EMISSIVE_RGBM_SCALE 97.0
// RGBM stuff is temporary. For now baked lightmap are in RGBM and the RGBM range for lightmaps is specific so we can't use the generic method.
// In the end baked lightmaps are going to be BC6H so the code will be the same as dynamic lightmaps.
// Same goes for emissive packed as an input for Enlighten with another hard coded multiplier.
// TODO: This function is used with the LightTransport pass to encode lightmap or emissive
float4 PackEmissiveRGBM(float3 rgb)
{
float kOneOverRGBMMaxRange = 1.0 / EMISSIVE_RGBM_SCALE;
const float kMinMultiplier = 2.0 * 1e-2;
float4 rgbm = float4(rgb * kOneOverRGBMMaxRange, 1.0);
rgbm.a = max(max(rgbm.r, rgbm.g), max(rgbm.b, kMinMultiplier));
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;
// Division-by-zero warning from d3d9, so make compiler happy.
rgbm.a = max(rgbm.a, kMinMultiplier);
rgbm.rgb /= rgbm.a;
return rgbm;
}
float3 UnpackLightmapRGBM(float4 rgbmInput)
{
return rgbmInput.rgb * rgbmInput.a * LIGHTMAP_RGBM_RANGE;
}
float3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), float2 uv, float4 transform, bool lightmapRGBM)
// Remark: Lightmap is RGB9E5
float3 illuminance = float3(0.0, 0.0, 0.0);
// Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5
if (lightmapRGBM)
{
illuminance = UnpackLightmapRGBM(SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba);
}
else
{
illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
}
float3 SampleDirectionalLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_ARGS(lightmapDirTex, lightmapDirSampler), float2 uv, float4 transform, float3 normalWS)
float3 SampleDirectionalLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_ARGS(lightmapDirTex, lightmapDirSampler), float2 uv, float4 transform, float3 normalWS, bool lightmapRGBM)
{
// In directional mode Enlighten bakes dominant light direction
// in a way, that using it for half Lambert and then dividing by a "rebalancing coefficient"

uv = uv * transform.xy + transform.zw;
float4 direction = SAMPLE_TEXTURE2D(lightmapDirTex, lightmapDirSampler, uv);
// Remark: Lightmap is RGB9E5
float3 illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
// Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5
float3 illuminance = float3(0.0, 0.0, 0.0);
if (lightmapRGBM)
{
illuminance = UnpackLightmapRGBM(SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba);
}
else
{
illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
}
#endif // UNITY_ENTITY_LIGHTING_INCLUDED
#endif // UNITY_ENTITY_LIGHTING_INCLUDED

4
Assets/ScriptableRenderLoop/ShaderLibrary/Fibonacci.hlsl


}
static const int k_FibonacciSeq[] = {
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181
};
static const float2 k_Fibonacci2dSeq21[] = {

int fibN2 = sampleCount;
// These are all constants, so this loop will be optimized away.
for (int j = 1; j < 16; j++)
for (int j = 1; j < 20; j++)
{
if (k_FibonacciSeq[j] == fibN1)
{

260
Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl


// Util image based lighting
//-----------------------------------------------------------------------------
// The *approximated* version of the non-linear remapping. It works by
// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution.
// TODO: Clean a bit this code
// CAUTION: remap from Morten may work only with offline convolution, see impact with runtime convolution!
perceptualRoughness = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness);
return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
}
// The *accurate* version of the non-linear remapping. It works by
// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution and adds reflection (contact) hardening.
// TODO: optimize!
float perceptualRoughnessToMipmapLevel(float perceptualRoughness, float NdotR)
{
float m = PerceptualRoughnessToRoughness(perceptualRoughness);
// For now disabled
#if 0
float m = PerceptualRoughnessToRoughness(perceptualRoughness); // m is the real roughness parameter
float n = (2.0 / max(FLT_EPSILON, m*m)) - 2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
// Remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
float n = (2.0 / max(FLT_EPSILON, m * m)) - 2.0;
n /= 4.0; // remap from n_dot_h formulatino to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
// Remap from n_dot_h formulation to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
n /= (4.0 * max(NdotR, FLT_EPSILON));
perceptualRoughness = pow(2.0 / (n + 2.0), 0.25); // remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)
#else
// MM: came up with a surprisingly close approximation to what the #if 0'ed out code above does.
perceptualRoughness = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness);
#endif
// remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)
perceptualRoughness = pow(2.0 / (n + 2.0), 0.25);
// The inverse of the *approximated* version of perceptualRoughnessToMipmapLevel().
return saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);
float perceptualRoughness = saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);
return saturate(1.7 / 1.4 - sqrt(2.89 - 2.8 * perceptualRoughness) / 1.4);
}
// Ref: "Moving Frostbite to PBR", p. 69.
float3 GetSpecularDominantDir(float3 N, float3 R, float roughness, float NdotV)
{
float a = 1.0 - roughness;
float s = sqrt(a);
#ifdef USE_FB_DSD
// This is the original formulation.
float lerpFactor = (s + roughness) * a;
#else
// TODO: tweak this further to achieve a closer match to the reference.
float lerpFactor = (s + roughness) * saturate(a * a + lerp(0.0, a, NdotV * NdotV));
#endif
// The result is not normalized as we fetch in a cubemap
return lerp(N, R, lerpFactor);
}
//-----------------------------------------------------------------------------
// Anisotropic image based lighting
//-----------------------------------------------------------------------------
// 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
float AnisotropicStrechAtGrazingAngle(float roughness, float perceptualRoughness, float NdotV)
{
return roughness * lerp(saturate(NdotV * 2.0), 1.0, perceptualRoughness);
}
//-----------------------------------------------------------------------------

// Transforms the unit vector from the spherical to the Cartesian (right-handed, Z up) coordinate.
float3 SphericalToCartesian(float phi, float sinTheta, float cosTheta)
float3 SphericalToCartesian(float phi, float cosTheta)
float sinTheta = sqrt(saturate(1.0 - cosTheta * cosTheta));
return float3(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta);
}

// coordinate system with Y pointing up and Z facing forward (DirectX style).
float3 TransformGLtoDX(float x, float y, float z)
{
return float3(x, z, y);
}
float3 TransformGLtoDX(float3 v)
{
return v.xzy;

float3 ConvertEquiarealToCubemap(float u, float v)
{
// The equiareal mapping is defined as follows:
// phi = TWO_PI * (1.0 - u)
// cos(theta) = 1.0 - 2.0 * v
// sin(theta) = sqrt(1.0 - cos^2(theta)) = 2.0 * sqrt(v - v * v)
float sinTheta = 2.0 * sqrt(v - v * v);
return TransformGLtoDX(SphericalToCartesian(phi, sinTheta, cosTheta));
}
// Ref: See "Moving Frostbite to PBR" Listing 22
// This formulation is for GGX only (with smith joint visibility or regular)
float3 GetSpecularDominantDir(float3 N, float3 R, float roughness)
{
float a = 1.0 - roughness;
float lerpFactor = a * (sqrt(a) + roughness);
// The result is not normalized as we fetch in a cubemap
return lerp(N, R, lerpFactor);
}
//-----------------------------------------------------------------------------
// Anisotropic image based lighting
//-----------------------------------------------------------------------------
// 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
float AnisotropicStrechAtGrazingAngle(float roughness, float perceptualRoughness, float NdotV)
{
return roughness * lerp(saturate(NdotV * 2.0), 1.0, perceptualRoughness);
return TransformGLtoDX(SphericalToCartesian(phi, cosTheta));
}
// ----------------------------------------------------------------------------

void ImportanceSampleCosDir(float2 u,
float3x3 localToWorld,
out float3 L)
// Performs uniform sampling of the unit disk.
// Ref: PBRT v3, p. 777.
float2 SampleDiskUniform(float2 u)
// Cosine sampling - ref: http://www.rorydriscoll.com/2009/01/07/better-sampling/
float cosTheta = sqrt(saturate(1.0 - u.x));
float sinTheta = sqrt(u.x);
float phi = TWO_PI * u.y;
float r = sqrt(u.x);
float phi = TWO_PI * u.y;
L = SphericalToCartesian(phi, sinTheta, cosTheta);
L = mul(L, localToWorld);
float sinPhi, cosPhi;
sincos(phi, sinPhi, cosPhi);
return r * float2(cosPhi, sinPhi);
void ImportanceSampleGGXDir(float2 u,
float3 V,
// Performs cosine-weighted sampling of the hemisphere.
// Ref: PBRT v3, p. 780.
void SampleHemisphereCosine(float2 u,
float roughness,
out float NdotH,
out float VdotH,
bool VeqN = false)
out float NdotL)
{
float3 localL;
// Since we don't really care about the area distortion,
// we substitute uniform disk sampling for the concentric one.
localL.xy = SampleDiskUniform(u);
// Project the point from the disk onto the hemisphere.
localL.z = sqrt(1.0 - u.x);
NdotL = localL.z;
L = mul(localL, localToWorld);
}
void SampleGGXDir(float2 u,
float3 V,
float3x3 localToWorld,
float roughness,
out float3 L,
out float NdotL,
out float NdotH,
out float VdotH,
bool VeqN = false)
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
float3 localH = SphericalToCartesian(phi, sinTheta, cosTheta);
float3 localH = SphericalToCartesian(phi, cosTheta);
NdotH = cosTheta;

VdotH = saturate(dot(localV, localH));
}
// Compute { L = reflect(-localV, localH) }
L = -localV + 2.0 * VdotH * localH;
// Compute { localL = reflect(-localV, localH) }
float3 localL = -localV + 2.0 * VdotH * localH;
L = mul(L, localToWorld);
NdotL = localL.z;
L = mul(localL, localToWorld);
void ImportanceSampleAnisoGGXDir( float2 u,
float3 V,
float3 N,
float3 tangentX,
float3 tangentY,
float roughnessT,
float roughnessB,
out float3 H,
out float3 L)
void SampleAnisoGGXDir(float2 u,
float3 V,
float3 N,
float3 tangentX,
float3 tangentY,
float roughnessT,
float roughnessB,
out float3 H,
out float3 L)
// Local to world
// H = tangentX * H.x + tangentY * H.y + N * H.z;
// Convert sample from half angle to incident angle
L = 2.0 * saturate(dot(V, H)) * H - V;

out float NdotL,
out float weightOverPdf)
{
ImportanceSampleCosDir(u, localToWorld, L);
NdotL = saturate(dot(localToWorld[2], L));
SampleHemisphereCosine(u, localToWorld, L, NdotL);
// Importance sampling weight for each sample
// pdf = N.L / PI

out float NdotL,
out float weightOverPdf)
{
float3 H;
float NdotH;
ImportanceSampleGGXDir(u, V, localToWorld, roughness, L, NdotH, VdotH);
NdotL = saturate(dot(localToWorld[2], L));
float NdotH;
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH);
// Importance sampling weight for each sample
// pdf = D(H) * (N.H) / (4 * (L.H))

}
// weightOverPdf return the weight (without the Fresnel term) over pdf. Fresnel term must be apply by the caller.
void ImportanceSampleAnisoGGX(
float2 u,
float3 V,
float3 N,
float3 tangentX,
float3 tangentY,
float roughnessT,
float roughnessB,
float NdotV,
out float3 L,
out float VdotH,
out float NdotL,
out float weightOverPdf)
void ImportanceSampleAnisoGGX(float2 u,
float3 V,
float3x3 localToWorld,
float roughnessT,
float roughnessB,
float NdotV,
out float3 L,
out float VdotH,
out float NdotL,
out float weightOverPdf)
float3 tangentX = localToWorld[0];
float3 tangentY = localToWorld[1];
float3 N = localToWorld[2];
ImportanceSampleAnisoGGXDir(u, V, N, tangentX, tangentY, roughnessT, roughnessB, H, L);
SampleAnisoGGXDir(u, V, N, tangentX, tangentY, roughnessT, roughnessB, H, L);
float NdotH = saturate(dot(N, H));
// Note: since L and V are symmetric around H, LdotH == VdotH

// weightOverPdf = F(H) * 4 * (N.L) * V(V, L) * (L.H) / (N.H) with V(V, L) = G(V, L) / (4 * (N.L) * (N.V))
// Remind (L.H) == (V.H)
// F is apply outside the function
// For anisotropy we must not saturate these values
float TdotL = saturate(dot(tangentX, L));
float BdotL = saturate(dot(tangentY, L));
float TdotL = dot(tangentX, L);
float BdotL = dot(tangentY, L);
float Vis = V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB);
weightOverPdf = 4.0 * Vis * NdotL * VdotH / NdotH;

// ----------------------------------------------------------------------------
// Ref: Listing 18 in "Moving Frostbite to PBR" + https://knarkowicz.wordpress.com/2014/12/27/analytical-dfg-term-for-ibl/
float4 IntegrateGGXAndDisneyFGD(float3 V, float3 N, float roughness, uint sampleCount)
float4 IntegrateGGXAndDisneyFGD(float3 V, float3 N, float roughness, uint sampleCount = 4096)
float NdotV = GetShiftedNdotV(N, V, false);
float NdotV = saturate(dot(N, V));
float4 acc = float4(0.0, 0.0, 0.0, 0.0);
// Add some jittering on Hammersley2d
float2 randNum = InitRandom(V.xy * 0.5 + 0.5);

// Bias samples towards the mirror direction to reduce variance.
// This will have a side effect of making the reflection sharper.
// Ref: Stochastic Screen-Space Reflections, p. 67.
const float bias = 0.2;
const float bias = 0.1 + 0.2 * roughness;
float NdotH, VdotH;
ImportanceSampleGGXDir(u, V, localToWorld, roughness, L, NdotH, VdotH, true);
float NdotL = saturate(dot(N, L));
float NdotL, NdotH, VdotH;
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH, true);
float mipLevel;

float omegaS = rcp(sampleCount) * invPdf;
// invOmegaP is precomputed on CPU and provide as a parameter of the function
// float omegaP = FOUR_PI / (6.0f * cubemapWidth * cubemapWidth);
mipLevel = 0.5 * log2(omegaS * invOmegaP);
mipLevel = 0.5 * log2(omegaS * invOmegaP + 1.0);
// TODO: There is a bug currently where autogenerate mipmap for the cubemap seems to clamp the mipLevel to 6. correct it! Then remove this clamp
// All MIP map levels beyond UNITY_SPECCUBE_LOD_STEPS contain invalid data.
mipLevel = min(mipLevel, UNITY_SPECCUBE_LOD_STEPS);
}
if (NdotL > 0.0)

// *********************************************************************************
// Our goal is to use Monte-Carlo integration with importance sampling to evaluate
// X(V) = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// CBSDF = F * D * G * NdotL / (4 * NdotL * NdotV) = F * D * G / (4 * NdotV).

// (LdotH == NdotH) && (NdotV == 1) && (Weight == F * G).
// We use the approximation of Brian Karis from "Real Shading in Unreal Engine 4":
// Weight ≈ NdotL, which produces nearly identical results in practice.
// *********************************************************************************
lightInt += NdotL * val;
cbsdfInt += NdotL;
}

51
Assets/ScriptableRenderLoop/ShaderLibrary/Packing.hlsl


return normalize(n);
}
float3 UnpackNormalRGB(float4 packedNormal, float scale = 1.0)
{
float3 normal;
normal.xyz = packedNormal.rgb * 2.0 - 1.0;
normal.xy *= scale;
return normalize(normal);
}
float3 UnpackNormalAG(float4 packedNormal, float scale = 1.0)
{
float3 normal;

}
// Unpack normal as DXT5nm (1, y, 0, x) or BC5 (x, y, 0, 1)
float3 UnpackNormalmapRGorAG(float4 packedNormal)
float3 UnpackNormalmapRGorAG(float4 packedNormal, float scale = 1.0)
{
// This do the trick
packedNormal.x *= packedNormal.w;

normal.xy *= scale;
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
return normal;
}

Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;
float3 vRGB = mul(Xp_Y_XYZp, InverseM);
return max(vRGB, float3(0.0, 0.0, 0.0));
}
// TODO: This function is used with the LightTransport pass to encode lightmap or emissive
float4 PackRGBM(float3 rgb, float maxRGBM)
{
float kOneOverRGBMMaxRange = 1.0 / maxRGBM;
const float kMinMultiplier = 2.0 * 1e-2;
float4 rgbm = float4(rgb * kOneOverRGBMMaxRange, 1.0);
rgbm.a = max(max(rgbm.r, rgbm.g), max(rgbm.b, kMinMultiplier));
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;
// Division-by-zero warning from d3d9, so make compiler happy.
rgbm.a = max(rgbm.a, kMinMultiplier);
rgbm.rgb /= rgbm.a;
return rgbm;
}
// Alternative...
#define RGBMRANGE (8.0)
float4 PackRGBM(float3 color)
{
float4 rgbm;
color *= (1.0 / RGBMRANGE);
rgbm.a = saturate(max(max(color.r, color.g), max(color.b, 1e-6)));
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;
rgbm.rgb = color / rgbm.a;
return rgbm;
}
float3 UnpackRGBM(float4 rgbm)
{
return RGBMRANGE * rgbm.rgb * rgbm.a;
}
// The standard 32-bit HDR color format

return PackFloatInt(f, i, maxi, 255.0);
}
float UnpackFloatInt8bit(float val, float maxi, out float f, out int i)
void UnpackFloatInt8bit(float val, float maxi, out float f, out int i)
{
UnpackFloatInt(val, maxi, 255.0, f, i);
}

return PackFloatInt(f, i, maxi, 1024.0);
}
float UnpackFloatInt10bit(float val, float maxi, out float f, out int i)
void UnpackFloatInt10bit(float val, float maxi, out float f, out int i)
{
UnpackFloatInt(val, maxi, 1024.0, f, i);
}

return PackFloatInt(f, i, maxi, 65536.0);
}
float UnpackFloatInt16bit(float val, float maxi, out float f, out int i)
void UnpackFloatInt16bit(float val, float maxi, out float f, out int i)
{
UnpackFloatInt(val, maxi, 65536.0, f, i);
}

2
Assets/ScriptableRenderLoop/common/TextureCache.cs


}
public abstract class TextureCache : Object
public abstract class TextureCache
{
protected int m_NumMipLevels;

2
Assets/ScriptableRenderLoop/common/TextureSettings.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering
{
[System.Serializable]
public struct TextureSettings

4
Assets/ScriptableRenderLoop/core/RenderPipeline.cs


using System;
using System.Collections.Generic;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.ScriptableRenderPipeline
namespace UnityEngine.Experimental.Rendering
{
public abstract class RenderPipeline : IRenderPipeline
{

4
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.ScriptableRenderPipeline;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering.Fptl
{
public class FptlLightingInstance : RenderPipeline
{

2
Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs


using UnityEngine;
using UnityEngine.Experimental.ScriptableRenderLoop;
using UnityEngine.Experimental.Rendering;
[GenerateHLSL]
public struct SFiniteLightData

5
Assets/ShaderGenerator/Editor/CSharpToHLSL.cs


using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering
{
public class CSharpToHLSL
{

2
Assets/ShaderGenerator/Editor/ShaderGeneratorMenu.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering
{
public class ShaderGeneratorMenu
{

4
Assets/ShaderGenerator/Editor/ShaderTypeGeneration.cs


using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEditor.Experimental.Rendering
{
internal class ShaderTypeGenerator
{

2
Assets/ShaderGenerator/ShaderGeneratorAttributes.cs


using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
namespace UnityEngine.Experimental.Rendering
{
public enum PackingRules
{

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

正在加载...
取消
保存