浏览代码

Merge remote-tracking branch 'upstream/master'

/main
Evgenii Golubev 8 年前
当前提交
8bbe4289
共有 151 个文件被更改,包括 2542 次插入1634 次删除
  1. 2
      Assets/BasicRenderLoopTutorial/BasicRenderLoop.cs
  2. 4
      Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs
  3. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/DebugViewMaterial.cs
  4. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/DebugViewMaterial.cs.hlsl
  5. 15
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewMaterialGBuffer.shader
  6. 87
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader
  7. 34
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
  8. 7
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
  9. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta
  10. 205
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  11. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  12. 5
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl
  13. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs
  14. 20
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Resources/Deferred.shader
  15. 130
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  16. 36
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl
  17. 64
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
  18. 25
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Attributes.hlsl
  19. 7
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.cs
  20. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.cs.hlsl
  21. 10
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.hlsl
  22. 73
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
  23. 83
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  24. 96
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs
  25. 79
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs
  26. 10
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.cs
  27. 29
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl
  28. 55
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader
  29. 49
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl
  30. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDepthPass.hlsl
  31. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitMetaPass.hlsl
  32. 37
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl
  33. 60
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl
  34. 49
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitVelocityPass.hlsl
  35. 25
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs
  36. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/UnlitUI.cs
  37. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Unlit.shader
  38. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/UnlitData.hlsl
  39. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/UnlitSharePass.hlsl
  40. 13
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderConfig.cs
  41. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDebugViewMaterial.hlsl
  42. 22
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDepthOnly.hlsl
  43. 29
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassForward.hlsl
  44. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassForwardUnlit.hlsl
  45. 23
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassGBuffer.hlsl
  46. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassLightTransport.hlsl
  47. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassVelocity.hlsl
  48. 166
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl
  49. 312
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
  50. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs.meta
  51. 41
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
  52. 93
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  53. 30
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  54. 89
      Assets/TestScenes/HDTest/GlobalIlluminationTest.unity
  55. 914
      Assets/TestScenes/HDTest/LayeredLitTest.unity
  56. 20
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Planar.mat
  57. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Planar.mat.meta
  58. 16
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Triplanar.mat
  59. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Triplanar.mat.meta
  60. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV0.mat.meta
  61. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV1.mat.meta
  62. 31
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV3.mat
  63. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV3.mat.meta
  64. 22
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Planar.mat
  65. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Planar.mat.meta
  66. 15
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Triplanar.mat
  67. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Triplanar.mat.meta
  68. 23
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_UV3.mat
  69. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_UV3.mat.meta
  70. 22
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Planar.mat
  71. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Planar.mat.meta
  72. 15
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Triplanar.mat
  73. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Triplanar.mat.meta
  74. 23
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_UV3.mat
  75. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_UV3.mat.meta
  76. 22
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Planar.mat
  77. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Planar.mat.meta
  78. 16
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Triplanar.mat
  79. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Triplanar.mat.meta
  80. 33
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_UV3.mat
  81. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_UV3.mat.meta
  82. 7
      README.md
  83. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader
  84. 14
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader
  85. 27
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs
  86. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs.meta
  87. 94
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDistortionPass.hlsl
  88. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDistortionPass.hlsl.meta
  89. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings.meta
  90. 23
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDistortion.hlsl
  91. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDistortion.hlsl.meta
  92. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky.meta
  93. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky.meta
  94. 437
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs
  95. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs.meta
  96. 71
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs
  97. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs.meta

2
Assets/BasicRenderLoopTutorial/BasicRenderLoop.cs


}
#endif
private ShaderPassName shaderPassBasic;
public override void Build()
{
}

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


var sceneCamera = Camera.main;
var camObject = sceneCamera.gameObject;
GraphicsSettings.SetRenderPipeline(m_Instance);
GraphicsSettings.renderPipeline = m_Instance;
s_Callback = renderCallback;
Transform t = camObject.transform;

SceneView.lastActiveSceneView.LookAtDirect(t.position + t.forward * camDist, t.rotation, size);
sceneCamera.Render();
GraphicsSettings.SetRenderPipeline(null);
GraphicsSettings.renderPipeline = null;
}
}

3
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/DebugViewMaterial.cs


VertexNormalWS,
VertexColor,
VertexColorAlpha,
// caution if you add something here, it must start below
};
// Number must be contiguous

Depth = DebugViewVarying.VertexColor + 1,
Depth = DebugViewVarying.VertexColorAlpha + 1,
BakeDiffuseLighting,
}
}

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


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

15
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewMaterialGBuffer.shader


#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Debug/DebugViewMaterial.cs.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Material/Material.hlsl"
SAMPLER2D(sampler_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
int _DebugViewMaterial;
struct Attributes

float4 Frag(Varyings input) : SV_Target
{
float4 unPositionSS = input.positionCS; // as input we have the vpos
Coordinate coord = GetCoordinate(unPositionSS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).x;
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
FETCH_GBUFFER(gbuffer, _GBufferTexture, coord.unPositionSS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, bsdfData, bakeDiffuseLighting);

if (_DebugViewMaterial == DEBUGVIEWGBUFFER_DEPTH)
{
float linearDepth = frac(LinearEyeDepth(depth, _ZBufferParams) * 0.1);
float linearDepth = frac(posInput.depthVS * 0.1);
result = linearDepth.xxx;
}
else if (_DebugViewMaterial == DEBUGVIEWGBUFFER_BAKE_DIFFUSE_LIGHTING)

87
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader


// variable declaration
//-------------------------------------------------------------------------------------
uint _ViewTilesFlags;
float4x4 _InvViewProjMatrix;
uint _ViewTilesFlags;
float2 _MousePixelCoord;
}
float4 AlphaBlend(float4 c0, float4 c1) // c1 over c0
{
return float4(lerp(c0.rgb, c1.rgb, c1.a), c0.a + c1.a - c0.a * c1.a);
}
float4 OverlayHeatMap(uint2 pixCoord, uint numLights)

int2 coord = pixCoord - int2(1, 1);
float4 color = float4(pow(col.xyz, 2.2), 0.3*col.w);
float4 color = float4(PositivePow(col.xyz, 2.2), 0.3 * col.w);
if (numLights > 0)
{
if (SampleDebugFontNumber(coord, numLights)) // Shadow

float4 Frag(float4 positionCS : SV_POSITION) : SV_Target
{
Coordinate coord = GetCoordinate(positionCS.xy, _ScreenSize.zw);
#ifdef USE_CLUSTERED_LIGHTLIST
// Perform same calculation than in deferred.shader
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).x;
float3 positionWS = UnprojectToWorld(depth, coord.positionSS, _InvViewProjMatrix);
float linearDepth = TransformWorldToView(positionWS).z; // View space linear depth
#else
float linearDepth = 0.0; // unused
#endif
// positionCS is SV_Position
PositionInputs posInput = GetPositionInput(positionCS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
int2 pixelCoord = posInput.unPositionSS.xy;
int2 tileCoord = (float2)pixelCoord / TILE_SIZE;
int2 mouseTileCoord = _MousePixelCoord / TILE_SIZE;
int2 offsetInTile = pixelCoord - tileCoord * TILE_SIZE;
int n = 0;
for (int category = 0; category < LIGHTCATEGORY_COUNT; category++)

{
uint start;
uint count;
GetCountAndStart(coord, category, linearDepth, start, count);
GetCountAndStart(posInput, category, start, count);
float4 result = float4(0.0, 0.0, 0.0, 0.0);
// Tile overlap counter
return OverlayHeatMap(int2(coord.unPositionSS.xy) & 15, n);
result = OverlayHeatMap(int2(posInput.unPositionSS.xy) & (TILE_SIZE - 1), n);
}
// Highlight selected tile
if (all(mouseTileCoord == tileCoord))
{
bool border = any(offsetInTile == 0 || offsetInTile == TILE_SIZE - 1);
float4 result2 = float4(1.0, 1.0, 1.0, border ? 1.0 : 0.5);
result = AlphaBlend(result, result2);
else
// Print light lists for selected tile at the bottom of the screen
int maxLights = 32;
if (tileCoord.y < LIGHTCATEGORY_COUNT && tileCoord.x < maxLights + 3)
return 0.0;
PositionInputs mousePosInput = GetPositionInput(_MousePixelCoord, _ScreenSize.zw);
float depthMouse = LOAD_TEXTURE2D(_CameraDepthTexture, mousePosInput.unPositionSS).x;
UpdatePositionInput(depthMouse, _InvViewProjMatrix, _ViewProjMatrix, mousePosInput);
int category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;
int start;
int count;
GetCountAndStart(mousePosInput, category, start, count);
float4 result2 = float4(.1,.1,.1,.9);
int2 fontCoord = int2(pixelCoord.x, offsetInTile.y);
int lightListIndex = tileCoord.x - 2;
int n = -1;
if(tileCoord.x == 0)
{
n = count;
}
else if(lightListIndex >= 0 && lightListIndex < count)
{
n = FetchIndex(start, lightListIndex);
}
if (n >= 0)
{
if (SampleDebugFontNumber(offsetInTile, n))
result2 = float4(0.0, 0.0, 0.0, 1.0);
if (SampleDebugFontNumber(offsetInTile + 1, n))
result2 = float4(1.0, 1.0, 1.0, 1.0);
}
result = AlphaBlend(result, result2);
return result;
}
ENDHLSL

34
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs


public readonly GUIContent useForwardRenderingOnly = new GUIContent("Use Forward Rendering Only");
public readonly GUIContent useDepthPrepass = new GUIContent("Use Depth Prepass");
public readonly GUIContent useDistortion = new GUIContent("Use Distortion");
public readonly GUIContent skyParameters = new GUIContent("Sky Parameters");
public readonly GUIContent skyResolution = new GUIContent("Sky Resolution");
public readonly GUIContent skyExposure = new GUIContent("Sky Exposure");
public readonly GUIContent skyRotation = new GUIContent("Sky Rotation");
public readonly GUIContent skyMultiplier = new GUIContent("Sky Multiplier");
public readonly GUIContent shadowSettings = new GUIContent("Shadow Settings");

debugParameters.displayTransparentObjects = EditorGUILayout.Toggle(styles.displayTransparentObjects, debugParameters.displayTransparentObjects);
debugParameters.useForwardRenderingOnly = EditorGUILayout.Toggle(styles.useForwardRenderingOnly, debugParameters.useForwardRenderingOnly);
debugParameters.useDepthPrepass = EditorGUILayout.Toggle(styles.useDepthPrepass, debugParameters.useDepthPrepass);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint
}
EditorGUI.indentLevel--;
}
private void SkyParametersUI(HDRenderLoop renderLoop)
{
EditorGUILayout.Space();
var skyParameters = renderLoop.skyParameters;
EditorGUILayout.LabelField(styles.skyParameters);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
skyParameters.skyHDRI = (Texture)EditorGUILayout.ObjectField("Cubemap", skyParameters.skyHDRI, typeof(Cubemap), false);
skyParameters.skyResolution = (SkyResolution)EditorGUILayout.EnumPopup(styles.skyResolution, skyParameters.skyResolution);
skyParameters.exposure = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyExposure, skyParameters.exposure), 32), -32);
skyParameters.multiplier = Mathf.Max(EditorGUILayout.FloatField(styles.skyMultiplier, skyParameters.multiplier), 0);
skyParameters.rotation = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyRotation, skyParameters.rotation), 360), -360);
debugParameters.useDistortion = EditorGUILayout.Toggle(styles.useDistortion, debugParameters.useDistortion);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint

return;
DebugParametersUI(renderLoop);
SkyParametersUI(renderLoop);
ShadowParametersUI(renderLoop);
TextureParametersUI(renderLoop);
TilePassUI(renderLoop);

7
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset


m_Script: {fileID: 11500000, guid: 558064ecdbf6b6742892d699acb39aed, type: 3}
m_Name: HDRenderLoop
m_EditorClassIdentifier:
m_SkyParameters:
skyHDRI: {fileID: 0}
rotation: 0
exposure: 0
multiplier: 1
skyResolution: 256
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096

spotCookieSize: 128
pointCookieSize: 512
reflectionCubemapSize: 128
m_Dirty: 0

2
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta


fileFormatVersion: 2
guid: 2400b74f5ce370c4481e5dc417d03703
timeCreated: 1481084818
timeCreated: 1481618742
licenseType: Pro
NativeFormatImporter:
userData:

205
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


}
#endif
SkyRenderer m_SkyRenderer = null;
[SerializeField]
SkyParameters m_SkyParameters = new SkyParameters();
SkyManager m_SkyManager = new SkyManager();
public SkyManager skyManager
{
get { return m_SkyManager; }
}
public SkyParameters skyParameters
public void InstantiateSkyRenderer(Type skyRendererType)
get { return m_SkyParameters; }
m_SkyManager.InstantiateSkyRenderer(skyRendererType);
}
public class DebugParameters

public bool useForwardRenderingOnly = false; // TODO: Currently there is no way to strip the extra forward shaders generated by the shaders compiler, so we can switch dynamically.
public bool useDepthPrepass = false;
public bool useDistortion = true;
public bool enableTonemap = true;
public float exposure = 0;

RenderTargetIdentifier m_DistortionBufferRT;
// Detect when windows size is changing
int m_WidthOnRecord;
int m_HeightOnRecord;
int m_currentWidth;
int m_currentHeight;
// Keep these settings safe to recover when leaving the render pipeline
bool previousLightsUseLinearIntensity;
bool previousLightsUseCCT;
// This must be allocate outside of Rebuild() else the option in the class can't be set in the inspector (as it will in this case recreate the class with default value)
// This must be allocate outside of Build() else the option in the class can't be set in the inspector (as it will in this case recreate the class with default value)
BaseLightLoop m_lightLoop = new TilePass.LightLoop();
public BaseLightLoop lightLoop

// TODO: Find a way to automatically create/iterate through deferred material
// TODO TO CHECK: SebL I move allocation from Rebuild() to here, but there was a comment "// Our object can be garbage collected, so need to be allocate here", it is still true ?
// TODO TO CHECK: SebL I move allocation from Build() to here, but there was a comment "// Our object can be garbage collected, so need to be allocate here", it is still true ?
public struct HDCamera
{
public Camera camera;
public Vector4 screenSize;
public Matrix4x4 viewProjectionMatrix;
public Matrix4x4 invViewProjectionMatrix;
}
public override void Build()
{
#if UNITY_EDITOR

};
#endif
previousLightsUseLinearIntensity = UnityEngine.Rendering.GraphicsSettings.lightsUseLinearIntensity;
previousLightsUseCCT = UnityEngine.Rendering.GraphicsSettings.lightsUseCCT;
UnityEngine.Rendering.GraphicsSettings.lightsUseLinearIntensity = true;
UnityEngine.Rendering.GraphicsSettings.lightsUseCCT = true;
m_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
m_CameraDepthBuffer = Shader.PropertyToID("_CameraDepthTexture");

m_SkyRenderer = new SkyRenderer();
m_SkyRenderer.Rebuild();
m_SkyManager.Build();
m_FinalPassMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/FinalPass");
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewMaterialGBuffer");

m_gbufferManager.SetBufferDescription(gbufferIndex, "_GBufferTexture" + gbufferIndex, RTFormat[gbufferIndex], RTReadWrite[gbufferIndex]);
}
#pragma warning disable 162 // warning CS0162: Unreachable code detected
if (ShaderConfig.VelocityInGbuffer == 1)
if (ShaderConfig.s_VelocityInGbuffer == 1)
{
// If velocity is in GBuffer then it is in the last RT. Assign a different name to it.
m_gbufferManager.SetBufferDescription(m_gbufferManager.gbufferCount, "_VelocityTexture", Builtin.RenderLoop.GetVelocityBufferFormat(), Builtin.RenderLoop.GetVelocityBufferReadWrite());

#pragma warning restore 162
m_LitRenderLoop.Rebuild();
m_lightLoop.Rebuild(m_TextureSettings);
m_LitRenderLoop.Build();
m_lightLoop.Build(m_TextureSettings);
m_lightLoop.Cleanup();
m_lightLoop.Cleanup();
if (m_SkyRenderer != null)
{
m_SkyRenderer.Cleanup();
}
m_SkyManager.Cleanup();
UnityEngine.Rendering.GraphicsSettings.lightsUseLinearIntensity = previousLightsUseLinearIntensity;
UnityEngine.Rendering.GraphicsSettings.lightsUseCCT = previousLightsUseCCT;
}
void InitAndClearBuffer(Camera camera, RenderLoop renderLoop)

}
// This pass is use in case of forward opaque and deferred rendering. We need to render forward objects before tile lighting pass
void RenderForwardOpaqueDepth(CullResults cull, Camera camera, RenderLoop renderLoop)
void RenderForwardOnlyDepthPrepass(CullResults cull, Camera camera, RenderLoop renderLoop)
// If we have render a depth prepass, no need for this pass
if (debugParameters.useDepthPrepass)
// If we are forward only we don't need to render ForwardOpaqueDepth object
// But in case we request a prepass we render it
if (debugParameters.useForwardRenderingOnly && !debugParameters.useDepthPrepass)
// TODO: Use the render queue index to only send the forward opaque!
// or use the new MAterial.SetPassEnable ?
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
RenderOpaqueRenderList(cull, camera, renderLoop, "ForwardOnlyDepthOnly");
void RenderDebugViewMaterial(CullResults cull, Camera camera, RenderLoop renderLoop)
void RenderDebugViewMaterial(CullResults cull, HDCamera hdCamera, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("DebugView Material Mode Pass", renderLoop))
// Render Opaque forward

Shader.SetGlobalInt("_DebugViewMaterial", (int)debugParameters.debugViewMaterial);
RenderOpaqueRenderList(cull, camera, renderLoop, "DebugViewMaterial");
RenderOpaqueRenderList(cull, hdCamera.camera, renderLoop, "DebugViewMaterial");
Vector4 screenSize = Utilities.ComputeScreenSize(camera);
m_DebugViewMaterialGBuffer.SetVector("_ScreenSize", screenSize);
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewMaterialGBuffer);
m_DebugViewMaterialGBuffer.SetFloat("_DebugViewMaterial", (float)debugParameters.debugViewMaterial);
// m_gbufferManager.BindBuffers(m_DebugViewMaterialGBuffer);

// Render forward transparent
{
RenderTransparentRenderList(cull, camera, renderLoop, "DebugViewMaterial");
RenderTransparentRenderList(cull, hdCamera.camera, renderLoop, "DebugViewMaterial");
}
// Last blit

}
}
void RenderDeferredLighting(Camera camera, RenderLoop renderLoop)
void RenderDeferredLighting(HDCamera hdCamera, RenderLoop renderLoop)
{
if (debugParameters.useForwardRenderingOnly)
{

// Bind material data
m_LitRenderLoop.Bind();
m_lightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
m_lightLoop.RenderDeferredLighting(hdCamera, renderLoop, m_CameraColorBuffer);
}
void UpdateSkyEnvironment(HDCamera hdCamera, RenderLoop renderLoop)
{
m_SkyManager.UpdateEnvironment(hdCamera, m_lightLoop.GetCurrentSunLight(), renderLoop);
void RenderSky(Camera camera, RenderLoop renderLoop)
void RenderSky(HDCamera hdCamera, RenderLoop renderLoop)
m_SkyRenderer.RenderSky(camera, m_SkyParameters, m_CameraColorBufferRT, m_CameraDepthBufferRT, renderLoop);
m_SkyManager.RenderSky(hdCamera, m_lightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthBufferRT, renderLoop);
}
void RenderForward(CullResults cullResults, Camera camera, RenderLoop renderLoop, bool renderOpaque)

}
}
// 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, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Forward Only Pass", renderLoop))
{
// Bind material data
m_LitRenderLoop.Bind();
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT);
m_lightLoop.RenderForward(camera, renderLoop, true);
RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardOnly");
}
}
void RenderForwardUnlit(CullResults cullResults, Camera camera, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Forward Unlit Pass", renderLoop))

{
using (new Utilities.ProfilingSample("Velocity Pass", renderLoop))
{
// warning CS0162: Unreachable code detected // warning CS0429: Unreachable expression code detected
#pragma warning disable 162, 429
if ((ShaderConfig.VelocityInGbuffer == 0) || debugParameters.useForwardRenderingOnly)
if ((ShaderConfig.s_VelocityInGbuffer == 0) || debugParameters.useForwardRenderingOnly)
return ;
int w = camera.pixelWidth;

cmd.Dispose();
RenderOpaqueRenderList(cullResults, camera, renderLoop, "MotionVectors");
#pragma warning restore 162, 429
if (!debugParameters.useDistortion)
return ;
using (new Utilities.ProfilingSample("Distortion Pass", renderLoop))
{
int w = camera.pixelWidth;

cmd.GetTemporaryRT(m_DistortionBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetDistortionBufferFormat(), Builtin.RenderLoop.GetDistortionBufferReadWrite());
cmd.SetRenderTarget(m_DistortionBufferRT, m_CameraDepthBufferRT);
cmd.ClearRenderTarget(false, true, Color.black); // TODO: can we avoid this clear for performance ?
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

}
#if UNITY_EDITOR
public override void RenderSceneView(Camera camera, RenderLoop renderLoop)
{
base.RenderSceneView(camera, renderLoop);
renderLoop.PrepareForEditorRendering(camera, m_CameraDepthBufferRT);
renderLoop.Submit();
}
#endif
void FinalPass(RenderLoop renderLoop)
{

// Function to prepare light structure for GPU lighting
void PrepareLightsForGPU(CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
m_lightLoop.PrepareLightsForGPU(cullResults, camera, ref shadowOutput);
m_lightLoop.PrepareLightsForGPU(shadowSettings, cullResults, camera, ref shadowOutput);
}
void Resize(Camera camera)

// TODO: This is the wrong way to handle resize/allocation. We can have several different camera here, mean that the loop on camera will allocate and deallocate
// the below buffer which is bad. Best is to have a set of buffer for each camera that is persistent and reallocate resource if need
// For now consider we have only one camera that go to this code, the main one.
m_SkyRenderer.Resize(m_SkyParameters); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
m_SkyManager.Resize(); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
if (camera.pixelWidth != m_WidthOnRecord || camera.pixelHeight != m_HeightOnRecord || m_lightLoop.NeedResize())
if (camera.pixelWidth != m_currentWidth || camera.pixelHeight != m_currentHeight || m_lightLoop.NeedResize())
if (m_WidthOnRecord > 0 && m_HeightOnRecord > 0)
if (m_currentWidth > 0 && m_currentHeight > 0)
{
m_lightLoop.ReleaseResolutionDependentBuffers();
}

// update recorded window resolution
m_WidthOnRecord = camera.pixelWidth;
m_HeightOnRecord = camera.pixelHeight;
m_currentWidth = camera.pixelWidth;
m_currentHeight = camera.pixelHeight;
public void PushGlobalParams(Camera camera, RenderLoop renderLoop)
public void PushGlobalParams(HDCamera hdCamera, RenderLoop renderLoop)
if (m_SkyRenderer.IsSkyValid(m_SkyParameters))
if (m_SkyManager.IsSkyValid())
m_SkyRenderer.SetGlobalSkyTexture();
m_SkyManager.SetGlobalSkyTexture();
Shader.SetGlobalInt("_EnvLightSkyEnabled", 1);
}
else

m_lightLoop.PushGlobalParams(camera, renderLoop);
var cmd = new CommandBuffer { name = "Push Global Parameters" };
cmd.SetGlobalVector("_ScreenSize", hdCamera.screenSize);
cmd.SetGlobalMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
cmd.SetGlobalMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
m_lightLoop.PushGlobalParams(hdCamera.camera, renderLoop);
}
public override void Render(Camera[] cameras, RenderLoop renderLoop)

renderLoop.SetupCameraProperties(camera);
HDCamera hdCamera = Utilities.GetHDCamera(camera);
RenderGBuffer(cullResults, camera, renderLoop);
// Forward opaque with deferred tile require that we fill the depth buffer
// Forward opaque with deferred/cluster tile require that we fill the depth buffer
// TODO: ask Morten why this pass is not before GBuffer ? Will make more sense and avoid
// to do gbuffer pass on unseen mesh.
// TODO: how do we select only the object that must be render forward ?
// this is all object with gbuffer pass disabled ?
//RenderForwardOpaqueDepth(cullResults, camera, renderLoop);
RenderForwardOnlyDepthPrepass(cullResults, camera, renderLoop);
RenderGBuffer(cullResults, camera, renderLoop);
RenderDebugViewMaterial(cullResults, camera, renderLoop);
RenderDebugViewMaterial(cullResults, hdCamera, renderLoop);
}
else
{

m_ShadowPass.Render(renderLoop, cullResults, out shadows);
}
}
m_lightLoop.PrepareLightsForGPU(cullResults, camera, ref shadows);
m_lightLoop.PrepareLightsForGPU(m_ShadowSettings, cullResults, camera, ref shadows);
PushGlobalParams(camera, renderLoop);
}
RenderDeferredLighting(camera, renderLoop);
PushGlobalParams(hdCamera, renderLoop);
}
UpdateSkyEnvironment(hdCamera, renderLoop);
RenderDeferredLighting(hdCamera, renderLoop);
// TODO: enable this for tile forward opaque
// RenderForward(cullResults, camera, renderLoop, true);
RenderForward(cullResults, camera, renderLoop, true);
RenderForwardOnly(cullResults, camera, renderLoop);
RenderSky(camera, renderLoop);
RenderSky(hdCamera, renderLoop);
RenderForward(cullResults, camera, renderLoop, false);

// Rendering distortion here have off course lot of artifact.
// But resolving at each objects that write in distortion is not possible (need to sort transparent, render those that do not distort, then resolve, then etc...)
// Instead we chose to apply distortion at the end after we cumulate distortion vector and desired blurriness. This
// RenderDistortion(cullResults, camera, renderLoop);
RenderDistortion(cullResults, camera, renderLoop);
}
// bind depth surface for editor grid/gizmo/selection rendering
if (camera.cameraType == CameraType.SceneView)
{
var cmd = new CommandBuffer();
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, m_CameraDepthBufferRT);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
renderLoop.Submit();

1
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs


public float bias;
public float quality;
public float unused;
public Vector4 invResolution;
};
[GenerateHLSL]

5
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl


float bias;
float quality;
float unused;
float4 invResolution;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.EnvLightData

float GetUnused(ShadowData value)
{
return value.unused;
}
float4 GetInvResolution(ShadowData value)
{
return value.invResolution;
}
//

12
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs


{
public class BaseLightLoop
{
protected Light m_CurrentSunLight = null;
public virtual void Rebuild(TextureSettings textureSettings) {}
public virtual void Build(TextureSettings textureSettings) {}
public virtual void Cleanup() {}

public virtual void NewFrame() {}
public virtual void PrepareLightsForGPU(CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput) { }
public virtual void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput) { }
// TODO: this should not be aprt of the interface but for now make something working
// TODO: this should not be part of the interface but for now make something working
public virtual void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT) {}
public virtual void RenderDeferredLighting(HDRenderLoop.HDCamera hdCamera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT) {}
public Light GetCurrentSunLight() { return m_CurrentSunLight; }
}
}

20
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Resources/Deferred.shader


TEXTURE2D(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
float4x4 _InvViewProjMatrix;
struct Attributes
{
float3 positionOS : POSITION;

float4 Frag(Varyings input) : SV_Target
{
float4 unPositionSS = input.positionCS; // as input we have the vpos
Coordinate coord = GetCoordinate(unPositionSS.xy, _ScreenSize.zw);
// No need to manage inverse depth, this is handled by the projection matrix
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).x;
float3 positionWS = UnprojectToWorld(depth, coord.positionSS, _InvViewProjMatrix);
float3 V = GetWorldSpaceNormalizeViewDir(positionWS);
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, coord.unPositionSS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
LightLoop(V, positionWS, coord, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
return float4(diffuseLighting + specularLighting, 1.0);
}

130
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs


public class LightLoop : BaseLightLoop
{
public const int k_MaxDirectionalLightsOnSCreen = 10;
public const int k_MaxPunctualLightsOnSCreen = 512;
public const int k_MaxDirectionalLightsOnScreen = 10;
public const int k_MaxPunctualLightsOnScreen = 512;
public const int k_MaxLightsOnSCreen = k_MaxDirectionalLightsOnSCreen + k_MaxPunctualLightsOnSCreen + k_MaxAreaLightsOnSCreen;
public const int k_MaxEnvLightsOnSCreen = 64;
public const int k_MaxLightsOnScreen = k_MaxDirectionalLightsOnScreen + k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnSCreen;
public const int k_MaxEnvLightsOnScreen = 64;
public const int k_MaxShadowOnScreen = 16;
public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;

public int debugViewTilesFlags = 0;
public bool enableClustered = false;
public bool disableFptlWhenClustered = true; // still useful on opaques. Should be false by default to force tile on opaque.
public bool enableBigTilePrepass = true;
public bool enableBigTilePrepass = false;
const bool k_UseDepthBuffer = true; // only has an impact when EnableClustered is true (requires a depth-prepass)
const bool k_UseAsyncCompute = true; // should not use on mobile

return (camera.pixelHeight + (k_TileSize - 1)) / k_TileSize;
}
public override void Rebuild(TextureSettings textureSettings)
public override void Build(TextureSettings textureSettings)
s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnSCreen + k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_shadowDatas = new ComputeBuffer(k_MaxCascadeCount + k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
m_CookieTexArray = new TextureCache2D();

s_GenAABBKernel = buildScreenAABBShader.FindKernel("ScreenBoundsAABB");
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(enableBigTilePrepass ? "TileLightListGen_SrcBigTile" : "TileLightListGen");
s_AABBBoundsBuffer = new ComputeBuffer(2 * k_MaxLightsOnSCreen, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(k_MaxLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
s_LightVolumeDataBuffer = new ComputeBuffer(k_MaxLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightVolumeData)));
s_AABBBoundsBuffer = new ComputeBuffer(2 * k_MaxLightsOnScreen, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
s_LightVolumeDataBuffer = new ComputeBuffer(k_MaxLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightVolumeData)));
buildScreenAABBShader.SetBuffer(s_GenAABBKernel, "g_data", s_ConvexBoundsBuffer);
buildPerTileLightListShader.SetBuffer(s_GenListPerTileKernel, "g_vBoundsBuffer", s_AABBBoundsBuffer);

m_SingleDeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_SingleDeferredMaterial.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
#if UNITY_EDITOR
UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
UnityEditor.SceneView.onSceneGUIDelegate += OnSceneGUI;
#endif
#if UNITY_EDITOR
UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
#endif
Utilities.SafeRelease(s_DirectionalLightDatas);
Utilities.SafeRelease(s_LightDatas);
Utilities.SafeRelease(s_EnvLightDatas);

public Vector3 GetLightColor(VisibleLight light)
{
// Linear intensity calculation (different from legacy Unity - match LinearLighting new option in 5.6)
var lightColorR = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.r);
var lightColorG = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.g);
var lightColorB = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.b);
return new Vector3(lightColorR, lightColorG, lightColorB);
return new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
public int GetShadows(VisibleLight light, int lightIndex, ref ShadowOutput shadowOutput)
public int GetShadows(VisibleLight light, int lightIndex, ref ShadowOutput shadowOutput, ShadowSettings shadowSettings)
{
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{

shadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
shadowData.bias = light.light.shadowBias;
shadowData.invResolution = new Vector4(1.0f / shadowSettings.shadowAtlasWidth, 1.0f / shadowSettings.shadowAtlasHeight, 0.0f, 0.0f);
m_lightList.shadows.Add(shadowData);
}

public void GetDirectionalLightData(GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int directionalShadowcount)
public void GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int directionalShadowcount)
{
var directionalLightData = new DirectionalLightData();

bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = directionalShadowcount == 0; // Only one cascade shadow allowed
// If we have not found a directional shadow casting light yet, we register the last directional anyway as "sun".
if (directionalShadowcount == 0)
{
m_CurrentSunLight = light.light;
}
// Always choose the directional shadow casting light if it exists.
m_CurrentSunLight = light.light;
directionalShadowcount += GetShadows(light, lightIndex, ref shadowOutput);
directionalShadowcount += GetShadows(light, lightIndex, ref shadowOutput, shadowSettings);
// Fill split information for shaders
for (int s = 0; s < k_MaxCascadeCount; ++s)

m_lightList.directionalLights.Add(directionalLightData);
}
public void GetLightData(GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int shadowCount)
public void GetLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int shadowCount)
{
var lightData = new LightData();

{
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
lightData.shadowIndex = m_lightList.shadows.Count;
shadowCount += GetShadows(light, lightIndex, ref shadowOutput);
shadowCount += GetShadows(light, lightIndex, ref shadowOutput, shadowSettings);
}
if (additionalData.archetype != LightArchetype.Punctual)

var mat = probe.localToWorld;
Vector3 vx = mat.GetColumn(0);
Vector3 vy = mat.GetColumn(1);
Vector3 vz = mat.GetColumn(2);
Vector3 vw = mat.GetColumn(3);
vx.Normalize(); // Scale shouldn't affect the probe or its bounds
vy.Normalize();
vz.Normalize();
//Vector3 C = bnds.center; // P + boxOffset;
var C = mat.MultiplyPoint(boxOffset); // same as commented out line above when rot is identity
var C = vx * boxOffset.x + vy * boxOffset.y + vz * boxOffset.z + vw;
Vector3 vx = mat.GetColumn(0);
Vector3 vy = mat.GetColumn(1);
Vector3 vz = mat.GetColumn(2);
// transform to camera space (becomes a left hand coordinate frame in Unity since Determinant(worldToView)<0)
vx = worldToView.MultiplyVector(vx);

m_lightList.lightVolumes.Add(ligthVolumeData);
}
public override void PrepareLightsForGPU(CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
{
m_lightList.Clear();

int punctualLightcount = 0;
int areaLightCount = 0;
var sortKeys = new uint[Math.Min(cullResults.visibleLights.Length, k_MaxLightsOnSCreen)];
var sortKeys = new uint[Math.Min(cullResults.visibleLights.Length, k_MaxLightsOnScreen)];
int sortCount = 0;
for (int lightIndex = 0, numLights = cullResults.visibleLights.Length; lightIndex < numLights; ++lightIndex)

switch (light.lightType)
{
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnSCreen)
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Point;

case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnSCreen)
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Spot;

case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnSCreen)
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Directional;

// Directional rendering side, it is separated as it is always visible so no volume to handle here
if (gpuLightType == GPULightType.Directional)
{
GetDirectionalLightData(gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref directionalShadowcount);
GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref directionalShadowcount);
GetLightData(gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref shadowCount);
GetLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref shadowCount);
// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], worldToView);
}

// Redo everything but this time with envLights
int envLightCount = 0;
sortKeys = new uint[Math.Min(cullResults.visibleReflectionProbes.Length, k_MaxEnvLightsOnSCreen)];
sortKeys = new uint[Math.Min(cullResults.visibleReflectionProbes.Length, k_MaxEnvLightsOnScreen)];
sortCount = 0;
for (int probeIndex = 0, numProbes = cullResults.visibleReflectionProbes.Length; probeIndex < numProbes; probeIndex++)

if (envLightCount >= k_MaxEnvLightsOnSCreen)
if (envLightCount >= k_MaxEnvLightsOnScreen)
continue;
// TODO: Support LightVolumeType.Sphere, currently in UI there is no way to specify a sphere influence volume

cmd.Dispose();
}
public override void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT)
#if UNITY_EDITOR
private Vector2 m_mousePosition = Vector2.zero;
private void OnSceneGUI(UnityEditor.SceneView sceneview)
{
m_mousePosition = Event.current.mousePosition;
}
#endif
public override void RenderDeferredLighting(HDRenderLoop.HDCamera hdCamera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT)
var invViewProj = Utilities.GetViewProjectionMatrix(camera).inverse;
var screenSize = Utilities.ComputeScreenSize(camera);
Vector2 mousePixelCoord = Input.mousePosition;
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
{
mousePixelCoord = m_mousePosition;
mousePixelCoord.y = (hdCamera.screenSize.y - 1.0f) - mousePixelCoord.y;
}
#endif
m_DeferredDirectMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DeferredDirectMaterial.SetVector("_ScreenSize", screenSize);
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredDirectMaterial);
m_DeferredIndirectMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DeferredIndirectMaterial.SetVector("_ScreenSize", screenSize);
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredIndirectMaterial);
m_DeferredAllMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DeferredAllMaterial.SetVector("_ScreenSize", screenSize);
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredAllMaterial);
m_DebugViewTilesMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DebugViewTilesMaterial.SetVector("_ScreenSize", screenSize);
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewTilesMaterial);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_SingleDeferredMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_SingleDeferredMaterial.SetVector("_ScreenSize", screenSize);
Utilities.SetupMaterialHDCamera(hdCamera, m_SingleDeferredMaterial);
m_SingleDeferredMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_SingleDeferredMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);

36
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl


positionTXS.z = 1.0 - positionTXS.z;
#endif
float4 vShadow3x3PCFTerms0;
float4 vShadow3x3PCFTerms1;
float4 vShadow3x3PCFTerms2;
float4 vShadow3x3PCFTerms3;
float flTexelEpsilonX = shadowData.invResolution.x;
float flTexelEpsilonY = shadowData.invResolution.y;
vShadow3x3PCFTerms0 = float4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
vShadow3x3PCFTerms1 = float4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
vShadow3x3PCFTerms2 = float4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
vShadow3x3PCFTerms3 = float4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
//return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
float4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.xy, positionTXS.z)).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.zy, positionTXS.z)).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.xw, positionTXS.z)).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.zw, positionTXS.z)).x; // -1 -1
float flSum = dot(v20Taps.xyzw, float4(0.25, 0.25, 0.25, 0.25));
if ((flSum == 0.0) || (flSum == 1.0))
return flSum;
flSum *= vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms2.xz, positionTXS.z)).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms3.xz, positionTXS.z)).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms3.zy, positionTXS.z)).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms2.zy, positionTXS.z)).x; // 0 1
flSum += dot(v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy);
flSum += SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS).x * vShadow3x3PCFTerms0.z;
return flSum;
}
//-----------------------------------------------------------------------------

64
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl


#ifdef LIGHTLOOP_TILE_PASS
// Calculate the offset in global light index light for current light category
int GetTileOffset(Coordinate coord, uint lightCategory)
int GetTileOffset(PositionInputs posInput, uint lightCategory)
uint2 tileIndex = coord.unPositionSS / TILE_SIZE;
uint2 tileIndex = posInput.unPositionSS / TILE_SIZE;
void GetCountAndStartTile(Coordinate coord, uint lightCategory, float linearDepth, out uint start, out uint lightCount)
void GetCountAndStartTile(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
const int tileOffset = GetTileOffset(coord, lightCategory);
const int tileOffset = GetTileOffset(posInput, lightCategory);
// The first entry inside a tile is the number of light for lightCategory (thus the +0)
lightCount = g_vLightListGlobal[DWORD_PER_TILE * tileOffset + 0] & 0xffff;

#ifdef USE_FPTL_LIGHTLIST
void GetCountAndStart(Coordinate coord, uint lightCategory, float linearDepth, out uint start, out uint lightCount)
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
GetCountAndStartTile(coord, lightCategory, linearDepth, start, lightCount);
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)

#include "ClusteredUtils.hlsl"
void GetCountAndStartCluster(Coordinate coord, uint lightCategory, float linearDepth, out uint start, out uint lightCount)
void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
uint2 tileIndex = coord.unPositionSS / TILE_SIZE;
uint2 tileIndex = posInput.unPositionSS / TILE_SIZE;
float logBase = g_fClustBase;
if (g_isLogBaseBufferEnabled)

int clustIdx = SnapToClusterIdxFlex(linearDepth, logBase, g_isLogBaseBufferEnabled != 0);
int clustIdx = SnapToClusterIdxFlex(posInput.depthVS, logBase, g_isLogBaseBufferEnabled != 0);
int nrClusters = (1 << g_iLog2NumClusters);
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileY + tileIndex.y) * _NumTileX + tileIndex.x;

return g_vLightListGlobal[tileOffset + lightIndex];
}
void GetCountAndStart(Coordinate coord, uint lightCategory, float linearDepth, out uint start, out uint lightCount)
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
GetCountAndStartTile(coord, lightCategory, linearDepth, start, lightCount);
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
GetCountAndStartCluster(coord, lightCategory, linearDepth, start, lightCount);
GetCountAndStartCluster(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)

#endif
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, float3 positionWS, Coordinate coord, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
#ifdef USE_CLUSTERED_LIGHTLIST
float linearDepth = TransformWorldToView(positionWS).z; // View space linear depth
#else
float linearDepth = 0.0; // unused
#endif
LightLoopContext context;
ZERO_INITIALIZE(LightLoopContext, context);

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, positionWS, prelightData, _DirectionalLightDatas[i], bsdfData,
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;

// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(coord, LIGHTCATEGORY_PUNCTUAL, linearDepth, punctualLightStart, punctualLightCount);
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, punctualLightStart, punctualLightCount);
EvaluateBSDF_Punctual( context, V, positionWS, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;

// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(coord, LIGHTCATEGORY_AREA, linearDepth, areaLightStart, areaLightCount);
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
for (i = 0; i < areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;

if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, positionWS, prelightData, _LightDatas[areaIndex], bsdfData,
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
EvaluateBSDF_Area( context, V, positionWS, prelightData, _LightDatas[areaIndex], bsdfData,
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}

// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
EvaluateBSDF_Env(context, V, positionWS, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}

GetCountAndStart(coord, LIGHTCATEGORY_ENV, linearDepth, envLightStart, envLightCount);
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
for (i = 0; i < envLightCount; ++i)
{

EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightDatas[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}

#else // LIGHTLOOP_SINGLE_PASS
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, float3 positionWS, Coordinate coord, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, positionWS, prelightData, _DirectionalLightDatas[i], bsdfData,
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, positionWS, prelightData, _LightDatas[i], bsdfData,
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;

if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, positionWS, prelightData, _LightDatas[i], bsdfData,
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
EvaluateBSDF_Area( context, V, positionWS, prelightData, _LightDatas[i], bsdfData,
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}

// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
EvaluateBSDF_Env(context, V, positionWS, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}

float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightDatas[i], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[i], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}

25
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Attributes.hlsl


//-------------------------------------------------------------------------------------
// FragInput
// FragInputs
struct FragInput
struct FragInputs
float4 unPositionSS; // This is the position return by VPOS (That is name positionCS in PackedVarying), only xy is use
// Contain value return by SV_POSITION (That is name positionCS in PackedVarying).
// xy: unormalized screen position (offset by 0.5), z: device depth, w: depth in view space
// Note: SV_POSITION is the result of the clip space position provide to the vertex shaders that is transform by the viewport
float4 unPositionSS; // In case depth offset is use, positionWS.w is equal to depth offset
float3 positionWS;
float2 texCoord0;
float2 texCoord1;

float4 vertexColor;
// For velocity
// Note: Z component is not use
float4 positionCS; // This is the clip spae position. Warning, do not confuse with the value of positionCS in PackedVarying which is VPOS and store in unPositionSS
// CAUTION: Only use with velocity currently, null else
// Note: Z component is not use currently
// This is the clip space position. Warning, do not confuse with the value of positionCS in PackedVarying which is SV_POSITION and store in unPositionSS
float4 positionCS;
// end velocity specific
void GetVaryingsDataDebug(uint paramId, FragInput input, inout float3 result, inout bool needLinearToSRGB)
void ApplyDepthOffsetAttribute(float depthOffsetVS, inout FragInputs fragInput)
{
fragInput.positionCS.w += depthOffsetVS;
fragInput.previousPositionCS.w += depthOffsetVS;
}
void GetVaryingsDataDebug(uint paramId, FragInputs input, inout float3 result, inout bool needLinearToSRGB)
{
switch (paramId)
{

7
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.cs


public Vector2 distortion;
[SurfaceDataAttributes("Distortion Blur")]
public float distortionBlur; // Define the color buffer mipmap level to use
// Depth
[SurfaceDataAttributes("Depth Offset")]
public float depthOffset; // define the depth in unity unit to add in Z forward direction
};
//-----------------------------------------------------------------------------

public static RenderTextureFormat GetDistortionBufferFormat()
{
return RenderTextureFormat.ARGBHalf; // This format need to be blendable and include distortionBlur
// TODO: // This format need to be additive blendable and include distortionBlur, blend mode different for alpha value
return RenderTextureFormat.ARGBHalf;
}
public static RenderTextureReadWrite GetDistortionBufferReadWrite()

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.cs.hlsl


#define DEBUGVIEW_BUILTIN_BUILTINDATA_VELOCITY (104)
#define DEBUGVIEW_BUILTIN_BUILTINDATA_DISTORTION (105)
#define DEBUGVIEW_BUILTIN_BUILTINDATA_DISTORTION_BLUR (106)
#define DEBUGVIEW_BUILTIN_BUILTINDATA_DEPTH_OFFSET (107)
//
// UnityEngine.Experimental.ScriptableRenderLoop.Builtin.LighTransportData: static fields

float2 velocity;
float2 distortion;
float distortionBlur;
float depthOffset;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.Builtin.LighTransportData

10
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.hlsl


void EncodeDistortion(float2 distortion, float distortionBlur, out float4 outBuffer)
{
// RT - 16:16 float
outBuffer = float4(distortion, distortionBlur, 0.0);
// RT - 16:16:16:16 float
// distortionBlur in alpha for a different blend mode
outBuffer = float4(distortion, 0.0, distortionBlur);
distortionBlur = inBuffer.z;
distortionBlur = inBuffer.a;
}
void GetBuiltinDataDebug(uint paramId, BuiltinData builtinData, inout float3 result, inout bool needLinearToSRGB)

break;
case DEBUGVIEW_BUILTIN_BUILTINDATA_DISTORTION_BLUR:
result = builtinData.distortionBlur.xxx;
break;
case DEBUGVIEW_BUILTIN_BUILTINDATA_DEPTH_OFFSET:
result = builtinData.depthOffset.xxx * 10.0; // * 10 assuming 1 unity unity is 1m
break;
}
}

73
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs


{
UV0,
UV1,
UV2,
}
public enum LayerUVDetailMapping
{
UV0,
UV1,
UV3
}
private class StylesLayer

MaterialProperty[] layerTexWorldScale = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVBase = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVMappingMask = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVMappingPlanar = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVDetail = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];

private void FindLayerProperties(MaterialProperty[] props)
override protected void FindMaterialProperties(MaterialProperty[] props)
FindMaterialOptionProperties(props);
layerMaskMap = FindProperty(kLayerMaskMap, props);
layerMaskVertexColor = FindProperty(kLayerMaskVertexColor, props);
layerCount = FindProperty(kLayerCount, props);

layerUVBase[i] = FindProperty(string.Format("{0}{1}", kUVBase, i), props);
layerUVMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVMappingMask, i), props);
layerUVMappingPlanar[i] = FindProperty(string.Format("{0}{1}", kUVMappingPlanar, i), props);
layerUVDetail[i] = FindProperty(string.Format("{0}{1}", kUVDetail, i), props);
layerUVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVDetailsMappingMask, i), props);
}

return layerChanged;
}
protected override void SetupKeywordsForInputMaps(Material material)
protected override void SetupMaterialKeywords(Material material)
SetupCommonOptionsKeywords(material);
SetupLayersKeywords(material);
// Find first non null layer
int i = 0;
while (i < numLayer && (m_MaterialLayers[i] == null)) ++i;

SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR", material.GetFloat(kLayerMaskVertexColor) != 0.0f);
// We have to check for each layer if the UV2 or UV3 is needed.
bool UV2orUV3needed = false;
for (int layer = 0; layer < numLayer; ++layer)
{
string uvBase = string.Format("{0}{1}", kUVBase, layer);
string uvDetail = string.Format("{0}{1}", kUVDetail, layer);
if (
((UVDetailMapping)material.GetFloat(uvDetail) == UVDetailMapping.UV2) ||
((LayerUVBaseMapping)material.GetFloat(uvBase) == LayerUVBaseMapping.UV2) ||
((UVDetailMapping)material.GetFloat(uvDetail) == UVDetailMapping.UV3) ||
((LayerUVBaseMapping)material.GetFloat(uvBase) == LayerUVBaseMapping.UV3)
)
{
UV2orUV3needed = true;
break;
}
}
SetKeyword(material, "_REQUIRE_UV2_OR_UV3", UV2orUV3needed);
void SetupMaterialForLayers(Material material)
void SetupLayersKeywords(Material material)
{
if (numLayer == 4)
{

string layerUVBaseParam = string.Format("{0}{1}", kUVBase, i);
LayerUVBaseMapping layerUVBaseMapping = (LayerUVBaseMapping)material.GetFloat(layerUVBaseParam);
string layerUVDetailParam = string.Format("{0}{1}", kUVDetail, i);
LayerUVDetailMapping layerUVDetailMapping = (LayerUVDetailMapping)material.GetFloat(layerUVDetailParam);
UVDetailMapping layerUVDetailMapping = (UVDetailMapping)material.GetFloat(layerUVDetailParam);
Z = (layerUVBaseMapping == LayerUVBaseMapping.UV3) ? 1.0f : 0.0f;
W = (layerUVBaseMapping == LayerUVBaseMapping.Planar) ? 1.0f : 0.0f;
Z = (layerUVBaseMapping == LayerUVBaseMapping.UV2) ? 1.0f : 0.0f;
W = (layerUVBaseMapping == LayerUVBaseMapping.UV3) ? 1.0f : 0.0f;
layerUVMappingPlanar[i].floatValue = (layerUVBaseMapping == LayerUVBaseMapping.Planar) ? 1.0f : 0.0f;
// If base is planar mode, detail is planar too
if (W > 0.0f)
{
X = Y = Z = 0.0f;
}
else
{
X = (layerUVDetailMapping == LayerUVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == LayerUVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == LayerUVDetailMapping.UV3) ? 1.0f : 0.0f;
}
layerUVDetailsMappingMask[i].colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
X = (layerUVDetailMapping == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == UVDetailMapping.UV2) ? 1.0f : 0.0f;
W = (layerUVDetailMapping == UVDetailMapping.UV3) ? 1.0f : 0.0f;
layerUVDetailsMappingMask[i].colorValue = new Color(X, Y, Z, W);
FindOptionProperties(props);
FindLayerProperties(props);
FindCommonOptionProperties(props);
FindMaterialProperties(props);
m_MaterialEditor = materialEditor;

foreach (var obj in m_MaterialEditor.targets)
{
SetupMaterial((Material)obj);
SetupMaterialForLayers((Material)obj);
SetupMaterialKeywords((Material)obj);
}
SaveMaterialLayers(materialImporter);

83
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader


_LayerMaskMap("LayerMaskMap", 2D) = "white" {}
[ToggleOff] _LayerMaskVertexColor("Use Vertex Color Mask", Float) = 0.0
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 0.0
[ToggleOff] _DepthOffsetEnable("Depth Offset View space", Float) = 0.0
[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5

[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0

_TexWorldScale2("Tiling", Float) = 1.0
_TexWorldScale3("Tiling", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase3("UV Set for base3", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase3("UV Set for base3", Float) = 0
[HideInInspector] _UVMappingMask0("_UVMappingMask0", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask1("_UVMappingMask1", Color) = (1, 0, 0, 0)

[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail0("UV Set for detail0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail1("UV Set for detail1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail2("UV Set for detail2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail3("UV Set for detail3", Float) = 0
[HideInInspector] _UVMappingPlanar0("_UVMappingPlanar0", Float) = 0.0
[HideInInspector] _UVMappingPlanar1("_UVMappingPlanar1", Float) = 0.0
[HideInInspector] _UVMappingPlanar2("_UVMappingPlanar2", Float) = 0.0
[HideInInspector] _UVMappingPlanar3("_UVMappingPlanar3", Float) = 0.0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail0("UV Set for detail0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail1("UV Set for detail1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail2("UV Set for detail2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail3("UV Set for detail3", Float) = 0
// Unused but to be able to share litUI.Sahder and layeredUI.Shader
[HideInInspector] _UVBase("UV Set for base", Float) = 0
[HideInInspector] _UVDetail("UV Set for base", Float) = 0
[HideInInspector] _TexWorldScale("Tiling", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)
}
HLSLINCLUDE

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _REQUIRE_UV2_OR_UV3
#pragma shader_feature _EMISSIVE_COLOR
#pragma shader_feature _NORMALMAP

// Set of users variables
PROP_DECL(float4, _BaseColor);
PROP_DECL_TEX2D(_BaseColorMap);
float4 _BaseColorMap0_ST;
float4 _BaseColorMap1_ST;
float4 _BaseColorMap2_ST;
float4 _BaseColorMap3_ST;
PROP_DECL(float, _Metallic);
PROP_DECL(float, _Smoothness);

TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
TEXTURE2D(_DistortionVectorMap);
SAMPLER2D(sampler_DistortionVectorMap);
TEXTURE2D(_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);

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

Cull[_CullMode]
ZTest LEqual
ZWrite Off // TODO: Test Z equal here.
HLSLPROGRAM

Cull[_CullMode]
ZWrite On ZTest LEqual
ZWrite On
ZTest LEqual
HLSLPROGRAM

Cull[_CullMode]
ZWrite On ZTest LEqual
ZWrite On
HLSLPROGRAM

#include "../Lit/LitDepthPass.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
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
#pragma vertex Vert
#pragma fragment Frag
#define SHADERPASS SHADERPASS_DISTORTION
#define LAYERED_LIT_SHADER
#include "../../Material/Material.hlsl"
#include "../Lit/LitData.hlsl"
#include "../Lit/LitDistortionPass.hlsl"
#include "../../ShaderPass/ShaderPassDistortion.hlsl"
ENDHLSL
}

96
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs


public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)");
public static GUIContent distortionEnableText = new GUIContent("Distortion", "Enable distortion on this shader");
public static GUIContent distortionOnlyText = new GUIContent("Distortion Only", "This shader will only be use to render distortion");
public static GUIContent distortionDepthTestText = new GUIContent("Distortion Depth Test", "Enable the depth test for distortion");
public static GUIContent depthOffsetEnableText = new GUIContent("DepthOffset", "EnableDepthOffset on this shader (Use with heightmap)");
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));

if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
m_MaterialEditor.ShaderProperty(distortionEnable, Styles.distortionEnableText.text);
if (distortionEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(distortionOnly, Styles.distortionOnlyText.text);
m_MaterialEditor.ShaderProperty(distortionDepthTest, Styles.distortionDepthTestText.text);
}
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)

m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
m_MaterialEditor.ShaderProperty(depthOffsetEnable, Styles.depthOffsetEnableText.text);
EditorGUI.indentLevel--;
}

EditorGUI.showMixedValue = false;
}
protected void FindOptionProperties(MaterialProperty[] props)
protected void FindCommonOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);

FindInputOptionProperties(props);
distortionEnable = FindProperty(kDistortionEnable, props);
distortionOnly = FindProperty(kDistortionOnly, props);
distortionDepthTest = FindProperty(kDistortionDepthTest, props);
depthOffsetEnable = FindProperty(kDepthOffsetEnable, props);
protected void SetupMaterial(Material material)
protected void SetupCommonOptionsKeywords(Material material)
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");

}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetupInputMaterial(material);
bool distortionEnable = material.GetFloat(kDistortionEnable) == 1.0;
bool distortionOnly = material.GetFloat(kDistortionOnly) == 1.0;
bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) == 1.0;
bool depthOffsetEnable = material.GetFloat(kDepthOffsetEnable) == 1.0;
if (distortionEnable)
{
material.SetShaderPassEnabled("DistortionVectors", true);
}
else
{
material.SetShaderPassEnabled("DistortionVectors", false);
}
if (distortionEnable && distortionOnly)
{
// Disable all passes except dbug material
material.SetShaderPassEnabled("GBuffer", false);
material.SetShaderPassEnabled("DebugViewMaterial", true);
material.SetShaderPassEnabled("Meta", false);
material.SetShaderPassEnabled("ShadowCaster", false);
material.SetShaderPassEnabled("DepthOnly", false);
material.SetShaderPassEnabled("MotionVectors", false);
material.SetShaderPassEnabled("Forward", false);
}
else
{
material.SetShaderPassEnabled("GBuffer", true);
material.SetShaderPassEnabled("DebugViewMaterial", true);
material.SetShaderPassEnabled("Meta", true);
material.SetShaderPassEnabled("ShadowCaster", true);
material.SetShaderPassEnabled("DepthOnly", true);
material.SetShaderPassEnabled("MotionVectors", true);
material.SetShaderPassEnabled("Forward", true);
}
if (distortionDepthTest)
{
material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.LessEqual);
}
else
{
material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.Always);
}
SetKeyword(material, "_DISTORTION_ON", distortionEnable);
SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable);
SetupEmissionGIFlags(material);
}

if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
SetupMaterialKeywords((Material)obj);
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
FindCommonOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindMaterialProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;

MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty doubleSidedMode = null;
MaterialProperty distortionEnable = null;
MaterialProperty distortionOnly = null;
MaterialProperty distortionDepthTest = null;
MaterialProperty depthOffsetEnable = null;
const string kDistortionEnable = "_DistortionEnable";
const string kDistortionOnly = "_DistortionOnly";
const string kDistortionDepthTest = "_DistortionDepthTest";
const string kDepthOffsetEnable = "_DepthOffsetEnable";
protected abstract void FindInputProperties(MaterialProperty[] props);
protected abstract void ShaderInputGUI();
protected abstract void FindMaterialProperties(MaterialProperty[] props);
protected abstract void ShaderInputGUI();
protected abstract void FindInputOptionProperties(MaterialProperty[] props);
protected abstract void SetupInputMaterial(Material material);
protected abstract void SetupMaterialKeywords(Material material);
protected abstract bool ShouldEmissionBeEnabled(Material material);
}
} // namespace UnityEditor

79
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs


{
UV0,
UV1,
UV2,
UV3
}

protected const string kTexWorldScale = "_TexWorldScale";
protected MaterialProperty UVMappingMask = null;
protected const string kUVMappingMask = "_UVMappingMask";
protected MaterialProperty UVMappingPlanar = null;
protected const string kUVMappingPlanar = "_UVMappingPlanar";
protected MaterialProperty normalMapSpace = null;
protected const string kNormalMapSpace = "_NormalMapSpace";
protected MaterialProperty heightMapMode = null;

protected MaterialProperty emissiveIntensity = null;
protected const string kEmissiveIntensity = "_EmissiveIntensity";
override protected void FindInputOptionProperties(MaterialProperty[] props)
// 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)
UVBase = FindProperty(kUVBase, props);
TexWorldScale = FindProperty(kTexWorldScale, props);
UVMappingMask = FindProperty(kUVMappingMask, props);
UVDetail = FindProperty(kUVDetail, props);
UVDetailsMappingMask = FindProperty(kUVDetailsMappingMask, props);
override protected void FindInputProperties(MaterialProperty[] props)
override protected void FindMaterialProperties(MaterialProperty[] props)
FindMaterialOptionProperties(props);
baseColor = FindProperty(kBaseColor, props);
baseColorMap = FindProperty(kBaseColorMap, props);
metallic = FindProperty(kMetallic, props);

anisotropy = FindProperty(kAnisotropy, props);
anisotropyMap = FindProperty(kAnisotropyMap, props);
UVBase = FindProperty(kUVBase, props);
UVDetail = FindProperty(kUVDetail, props);
TexWorldScale = FindProperty(kTexWorldScale, props);
UVMappingMask = FindProperty(kUVMappingMask, props);
UVMappingPlanar = FindProperty(kUVMappingPlanar, props);
UVDetailsMappingMask = FindProperty(kUVDetailsMappingMask, props);
detailMap = FindProperty(kDetailMap, props);
detailMask = FindProperty(kDetailMask, props);
detailAlbedoScale = FindProperty(kDetailAlbedoScale, props);

float X, Y, Z, W;
X = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0) ? 1.0f : 0.0f;
W = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) ? 1.0f : 0.0f;
UVMappingMask.colorValue = new Color(X, 0.0f, 0.0f, W);
UVMappingMask.colorValue = new Color(X, 0.0f, 0.0f, 0.0f);
UVMappingPlanar.floatValue = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) ? 1.0f : 0.0f;
if (((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) || ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Triplanar))
{
EditorGUI.indentLevel++;

m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText.text);
}
// If base is planar mode, detail is planar too
if (W > 0.0f)
{
X = Y = Z = 0.0f;
}
else
{
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
}
UVDetailsMappingMask.colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV2) ? 1.0f : 0.0f;
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.TexturePropertySingleLine(Styles.anisotropyMapText, anisotropyMap);
m_MaterialEditor.TextureScaleOffsetProperty(baseColorMap);
EditorGUILayout.Space();
GUILayout.Label(Styles.detailText, EditorStyles.boldLabel);

base.AssignNewShaderToMaterial(material, oldShader, newShader);
}
protected virtual void SetupKeywordsForInputMaps(Material material)
{
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap) || material.GetTexture(kDetailMap)); // With details map, we always use a normal map and Unity provide a default (0, 0, 1) normal map for ir
SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kSpecularOcclusionMap));
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_HEIGHTMAP", material.GetTexture(kHeightMap));
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMap));
SetKeyword(material, "_ANISOTROPYMAP", material.GetTexture(kAnisotropyMap));
SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));
}
protected override bool ShouldEmissionBeEnabled(Material mat)
{
float emissiveIntensity = mat.GetFloat(kEmissiveIntensity);

override protected void SetupInputMaterial(Material material)
override protected void SetupMaterialKeywords(Material material)
SetupCommonOptionsKeywords(material);
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannel)) == SmoothnessMapChannel.AlbedoAlpha);

SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", ((DetailMapMode)material.GetFloat(kDetailMapMode)) == DetailMapMode.DetailWithNormal);
SetKeyword(material, "_REQUIRE_UV3", ((UVDetailMapping)material.GetFloat(kUVDetail)) == UVDetailMapping.UV3 && (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV0);
SetupKeywordsForInputMaps(material);
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap) || material.GetTexture(kDetailMap)); // With details map, we always use a normal map and Unity provide a default (0, 0, 1) normal map for ir
SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kSpecularOcclusionMap));
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_HEIGHTMAP", material.GetTexture(kHeightMap));
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMap));
SetKeyword(material, "_ANISOTROPYMAP", material.GetTexture(kAnisotropyMap));
SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));
SetKeyword(material, "_REQUIRE_UV2_OR_UV3", (
((UVDetailMapping)material.GetFloat(kUVDetail) == UVDetailMapping.UV2 || (UVDetailMapping)material.GetFloat(kUVDetail) == UVDetailMapping.UV3)
&& (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV0)
);
}
}
} // namespace UnityEditor

10
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.cs


public enum GBufferMaterial
{
// Note: This count doesn't include the velocity buffer. On shader and csharp side the velocity buffer will be added by the framework
Count = (ShaderConfig.PackgbufferInU16 == 1) ? 2 : 4
Count = (ShaderConfig.k_PackgbufferInU16 == 1) ? 2 : 4
};
public partial class RenderLoop : Object

RTFormat = new RenderTextureFormat[(int)GBufferMaterial.Count];
RTReadWrite = new RenderTextureReadWrite[(int)GBufferMaterial.Count];
#pragma warning disable 162 // warning CS0162: Unreachable code detected
if (ShaderConfig.PackgbufferInU16 == 1)
if (ShaderConfig.s_PackgbufferInU16 == 1)
{
// TODO: Just discovered that Unity doesn't support unsigned 16 RT format.
RTFormat[0] = RenderTextureFormat.ARGBInt; RTReadWrite[0] = RenderTextureReadWrite.Linear;

RTFormat[2] = RenderTextureFormat.ARGB32; RTReadWrite[2] = RenderTextureReadWrite.Linear;
RTFormat[3] = RenderTextureFormat.RGB111110Float; RTReadWrite[3] = RenderTextureReadWrite.Linear;
}
#pragma warning restore 162
}
//-----------------------------------------------------------------------------

return CreateLUT(k_LtcLUTResolution, k_LtcLUTResolution, format, pixels);
}
public void Rebuild()
public void Build()
{
m_InitPreFGD = CreateEngineMaterial("Hidden/HDRenderLoop/PreIntegratedFGD");
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGBHalf);

{
Utilities.Destroy(m_InitPreFGD);
// TODO: how to delete RenderTexture ?
// TODO: how to delete RenderTexture ? or do we need to do it ?
isInit = false;
}

29
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl


float2 unPositionSS;
};
PreLightData GetPreLightData(float3 V, float3 positionWS, Coordinate coord, BSDFData bsdfData)
PreLightData GetPreLightData(float3 V, PositionInputs posInput, BSDFData bsdfData)
{
PreLightData preLightData;

preLightData.iblDirWS = GetSpecularDominantDir(bsdfData.normalWS, iblR, bsdfData.roughness);
// #if SHADERPASS == SHADERPASS_GBUFFER
// preLightData.ambientOcclusion = LOAD_TEXTURE2D(_AmbientOcclusion, coord.unPositionSS).x;
// preLightData.ambientOcclusion = LOAD_TEXTURE2D(_AmbientOcclusion, posInput.unPositionSS).x;
// #endif
// Area light specific

preLightData.ltcDisneyDiffuseMagnitude = ltcMagnitude.b;
// Shadow
preLightData.unPositionSS = coord.unPositionSS;
preLightData.unPositionSS = posInput.unPositionSS;
return preLightData;
}

//-----------------------------------------------------------------------------
void EvaluateBSDF_Directional( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData preLightData, DirectionalLightData lightData, BSDFData bsdfData,
float3 V, PositionInputs posInput, PreLightData preLightData, DirectionalLightData lightData, BSDFData bsdfData,
float3 positionWS = posInput.positionWS;
float3 L = -lightData.forward; // Lights are pointing backward in Unity
float illuminance = saturate(dot(bsdfData.normalWS, L));

coord = coord * 0.5 + 0.5;
// Tile the texture if the 'repeat' wrap mode is enabled.
if (lightData.tileCookie) coord = frac(coord);
if (lightData.tileCookie)
coord = frac(coord);
float4 cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);

//-----------------------------------------------------------------------------
void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData preLightData, LightData lightData, BSDFData bsdfData,
float3 V, PositionInputs posInput, PreLightData preLightData, LightData lightData, BSDFData bsdfData,
float3 positionWS = posInput.positionWS;
// All punctual light type in the same formula, attenuation is neutral depends on light type.
// light.positionWS is the normalize light direction in case of directional light and invSqrAttenuationRadius is 0
// mean dot(unL, unL) = 1 and mean GetDistanceAttenuation() will return 1

//-----------------------------------------------------------------------------
void EvaluateBSDF_Line(LightLoopContext lightLoopContext,
float3 V, float3 positionWS,
float3 V, PositionInputs posInput,
float3 positionWS = posInput.positionWS;
#ifdef LIT_DISPLAY_REFERENCE_AREA
IntegrateBSDF_LineRef(V, positionWS, preLightData, lightData, bsdfData,
diffuseLighting, specularLighting);

// #define ELLIPSOIDAL_ATTENUATION
void EvaluateBSDF_Area(LightLoopContext lightLoopContext,
float3 V, float3 positionWS,
float3 V, PositionInputs posInput,
float3 positionWS = posInput.positionWS;
#ifdef LIT_DISPLAY_REFERENCE_AREA
IntegrateBSDF_AreaRef(V, positionWS, preLightData, lightData, bsdfData,
diffuseLighting, specularLighting);

// _preIntegratedFGD and _CubemapLD are unique for each BRDF
void EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
float3 V, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
float3 positionWS = posInput.positionWS;
#ifdef LIT_DISPLAY_REFERENCE_IBL
specularLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, lightData, bsdfData);

55
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader


//_CoatRoughness("CoatRoughness", Range(0.0, 1.0)) = 0
//_CoatRoughnessMap("CoatRoughnessMap", 2D) = "white" {}
// _DistortionVectorMap("DistortionVectorMap", 2D) = "white" {}
// _DistortionBlur("DistortionBlur", Range(0.0, 1.0)) = 0
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
// Following options are for the GUI inspector and different from the input parameters above
// These option below will cause different compilation flag.

_EmissiveIntensity("EmissiveIntensity", Float) = 0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 0.0
[ToggleOff] _DepthOffsetEnable("Depth Offset View space", Float) = 0.0
[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5

[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
// Material Id
[HideInInspector] _MaterialId("_MaterialId", FLoat) = 0

[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _UVBase("UV Set for base", Float) = 0
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1,0,0,0)
[HideInInspector] _UVMappingPlanar("_UVMappingPlanar", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail("UV Set for detail", 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)
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
}

//-------------------------------------------------------------------------------------
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _REQUIRE_UV2_OR_UV3
#pragma shader_feature _EMISSIVE_COLOR
#pragma shader_feature _NORMALMAP

float4 _BaseColor;
TEXTURE2D(_BaseColorMap);
SAMPLER2D(sampler_BaseColorMap);
float4 _BaseColorMap_ST;
float _Metallic;
float _Smoothness;

TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
TEXTURE2D(_DistortionVectorMap);
SAMPLER2D(sampler_DistortionVectorMap);
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);

float _AlphaCutoff;
float _TexWorldScale;
float _UVMappingPlanar;
float4 _UVMappingMask;
float4 _UVDetailsMappingMask;

Cull[_CullMode]
ZWrite On ZTest LEqual
ZWrite On
ZTest LEqual
HLSLPROGRAM

Cull[_CullMode]
ZWrite On ZTest LEqual
ZWrite On
HLSLPROGRAM
#pragma vertex Vert

Cull[_CullMode]
ZTest LEqual
ZWrite Off // TODO: Test Z equal here.
HLSLPROGRAM

#include "LitVelocityPass.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"
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
#pragma vertex Vert
#pragma fragment Frag
#define SHADERPASS SHADERPASS_DISTORTION
#include "../../Material/Material.hlsl"
#include "LitData.hlsl"
#include "LitDistortionPass.hlsl"
#include "../../ShaderPass/ShaderPassDistortion.hlsl"
ENDHLSL
}

49
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl


//-------------------------------------------------------------------------------------
#include "../MaterialUtilities.hlsl"
void GetBuiltinData(FragInput input, SurfaceData surfaceData, float alpha, out BuiltinData builtinData)
void GetBuiltinData(FragInputs input, SurfaceData surfaceData, float alpha, float depthOffset, out BuiltinData builtinData)
{
// Builtin Data
builtinData.opacity = alpha;

builtinData.velocity = CalculateVelocity(input.positionCS, input.previousPositionCS);
#ifdef _DISTORTION_ON
float3 distortion = SAMPLE_TEXTURE2D(_DistortionVectorMap, sampler_DistortionVectorMap, input.texCoord0).rgb;
builtinData.distortion = distortion.rg;
builtinData.distortionBlur = distortion.b;
#else
#endif
builtinData.depthOffset = depthOffset;
}
// Gather all kind of mapping in one struct, allow to improve code readability

#define ADD_ZERO_IDX(Name) Name
#include "LitSurfaceData.hlsl"
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);

layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz);
#endif
// Be sure that the compiler is aware that we don't touch UV1 and UV3 for base layer in case of non layer shader
// Be sure that the compiler is aware that we don't touch UV1 to UV3 for base layer in case of non layer shader
_UVMappingMask.yz = float2(0.0, 0.0);
_UVMappingMask.yzw = float3(0.0, 0.0, 0.0);
ApplyDisplacement(input, layerTexCoord);
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
ApplyDisplacement(input, viewDirTS, layerTexCoord);
float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, builtinData.depthOffset, posInput);
ApplyDepthOffsetAttribute(depthOffset, input);
#endif
GetBuiltinData(input, surfaceData, alpha, builtinData);
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);
}
#else

#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);
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);

isTriplanar = true;
#endif
ComputeLayerTexCoord3(input, isTriplanar, layerTexCoord);
ApplyDisplacement0(input, layerTexCoord);
ApplyDisplacement1(input, layerTexCoord);
ApplyDisplacement2(input, layerTexCoord);
ApplyDisplacement3(input, layerTexCoord);
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
ApplyDisplacement0(input, viewDirTS, layerTexCoord);
ApplyDisplacement1(input, viewDirTS, layerTexCoord);
ApplyDisplacement2(input, viewDirTS, layerTexCoord);
ApplyDisplacement3(input, viewDirTS, layerTexCoord);
float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, builtinData.depthOffset, posInput);
ApplyDepthOffsetAttribute(depthOffset, input);
#endif
SurfaceData surfaceData0;
SurfaceData surfaceData1;

surfaceData.specularColor = float3(0.0, 0.0, 0.0);
float alpha = PROP_BLEND_SCALAR(alpha, weights);
GetBuiltinData(input, surfaceData, alpha, builtinData);
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);
}
#endif // #ifndef LAYERED_LIT_SHADER

8
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDepthPass.hlsl


return output;
}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS; // as input we have the vpos
output.unPositionSS = input.positionCS; // input.positionCS is SV_Position
#if NEED_TANGENT_TO_WORLD
output.positionWS.xyz = input.interpolators[0].xyz;

8
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitMetaPass.hlsl


return output;
}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS; // as input we have the vpos
output.unPositionSS = input.positionCS; // input.positionCS is SV_Position
output.texCoord0 = input.interpolators[0].xy;
output.texCoord1 = input.interpolators[0].zw;

37
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl


// Attribute/Varying
//-------------------------------------------------------------------------------------
#define WANT_UV2 (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV2_OR_UV3)
#define WANT_UV3 (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV2_OR_UV3)
struct Attributes
{
float3 positionOS : POSITION;

#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if WANT_UV2
#ifdef _REQUIRE_UV3
#if WANT_UV3
float2 uv3 : TEXCOORD3;
#endif
float4 tangentOS : TANGENT; // Always present as we require it also in case of anisotropic lighting

float3 positionWS;
float2 texCoord0;
float2 texCoord1;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if WANT_UV2
#ifdef _REQUIRE_UV3
#if WANT_UV3
float2 texCoord3;
#endif
float3 tangentToWorld[3];

struct PackedVaryings
{
float4 positionCS : SV_Position;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV3)
#if (WANT_UV2) || (WANT_UV3)
float4 interpolators[6] : TEXCOORD0;
#else
float4 interpolators[5] : TEXCOORD0;

output.interpolators[4] = input.color;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV3)
#if (WANT_UV2) || (WANT_UV3)
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if WANT_UV2
#ifdef _REQUIRE_UV3
#if WANT_UV3
output.interpolators[5].zw = input.texCoord3.xy;
#endif

}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS; // as input we have the vpos
output.unPositionSS = input.positionCS; // input.positionCS is SV_Position
output.positionWS.xyz = input.interpolators[0].xyz;
output.tangentToWorld[0] = input.interpolators[1].xyz;
output.tangentToWorld[1] = input.interpolators[2].xyz;

output.vertexColor = input.interpolators[4];
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if WANT_UV2
#ifdef _REQUIRE_UV3
#if WANT_UV3
output.texCoord3 = input.interpolators[5].zw;
#endif

output.texCoord0 = input.uv0;
output.texCoord1 = input.uv1;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if WANT_UV2
#endif
#if WANT_UV3
output.texCoord3 = input.uv3;
#endif
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);

60
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl


void ADD_IDX(ComputeLayerTexCoord)(FragInput input, bool isTriplanar, inout LayerTexCoord layerTexCoord)
void ADD_IDX(ComputeLayerTexCoord)(FragInputs input, bool isTriplanar, inout LayerTexCoord layerTexCoord)
// Handle uv0, uv1, uv2, uv3 based on _UVMappingMask weight (exclusif 0..1)
float2 uvBase = ADD_IDX(_UVMappingMask).x * input.texCoord0 +
ADD_IDX(_UVMappingMask).y * input.texCoord1 +
ADD_IDX(_UVMappingMask).z * input.texCoord2 +
ADD_IDX(_UVMappingMask).w * input.texCoord3;
float2 uvDetails = ADD_IDX(_UVDetailsMappingMask).x * input.texCoord0 +
ADD_IDX(_UVDetailsMappingMask).y * input.texCoord1 +
ADD_IDX(_UVDetailsMappingMask).z * input.texCoord2 +
ADD_IDX(_UVDetailsMappingMask).w * input.texCoord3;
// Note that if base is planar/triplanar, detail map is too
// planar
// Handle uv0, uv1 and plnar XZ coordinate based on _CoordWeight weight (exclusif 0..1)
ADD_IDX(layerTexCoord.base).uv = ADD_IDX(_UVMappingMask).x * input.texCoord0 +
ADD_IDX(_UVMappingMask).y * input.texCoord1 +
ADD_IDX(_UVMappingMask).z * input.texCoord3 +
ADD_IDX(_UVMappingMask).w * -position.xz;
float2 uvDetails = ADD_IDX(_UVDetailsMappingMask).x * input.texCoord0 +
ADD_IDX(_UVDetailsMappingMask).y * input.texCoord1 +
ADD_IDX(_UVDetailsMappingMask).z * input.texCoord3 +
// Note that if base is planar, detail map is planar
ADD_IDX(_UVMappingMask).w * -position.xz;
if (ADD_IDX(_UVMappingPlanar) > 0.0)
{
uvBase = -position.xz;
uvDetails = -position.xz;
}
ADD_IDX(layerTexCoord.base).uv = TRANSFORM_TEX(uvBase, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.details).uv = TRANSFORM_TEX(uvDetails, ADD_IDX(_DetailMap));
// triplanar

// In triplanar, if we are facing away from the world axis, a different axis will be flipped for each direction.
// This is particularly problematic for tangent space normal maps which need to be in the right direction.
// So we multiplying the offending coordinate by the sign of the normal.
ADD_IDX(layerTexCoord.base).uvYZ = float2(direction.x * position.z, position.y);
ADD_IDX(layerTexCoord.base).uvZX = -float2(position.x, direction.y * position.z);
ADD_IDX(layerTexCoord.base).uvXY = float2(-position.x, direction.z * position.y);
float2 uvYZ = float2(direction.x * position.z, position.y);
float2 uvZX = -float2(position.x, direction.y * position.z);
float2 uvXY = float2(-position.x, direction.z * position.y);
ADD_IDX(layerTexCoord.base).uvYZ = TRANSFORM_TEX(uvYZ, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.base).uvZX = TRANSFORM_TEX(uvZX, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.base).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.details).uvYZ = TRANSFORM_TEX(ADD_IDX(layerTexCoord.base).uvYZ, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZX = TRANSFORM_TEX(ADD_IDX(layerTexCoord.base).uvZX, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(ADD_IDX(layerTexCoord.base).uvXY, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvYZ = TRANSFORM_TEX(uvYZ, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZX = TRANSFORM_TEX(uvZX, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_DetailMap));
void ADD_IDX(ApplyDisplacement)(inout FragInput input, inout LayerTexCoord layerTexCoord)
void ADD_IDX(ApplyDisplacement)(inout FragInputs input, float3 viewDirTS, inout LayerTexCoord layerTexCoord)
// Transform view vector in tangent space
// Hope the compiler can optimize this in case of multiple layer
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
float 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.details).uvZX += offset;
ADD_IDX(layerTexCoord.details).uvXY += offset;
// Only modify tex coord for first layer, this will be use by for builtin data (like lightmap)
// Only modify texcoord for first layer, this will be use by for builtin data (like lightmap)
if (LAYER_INDEX == 0)
{
input.texCoord0 += offset;

}
// Return opacity
float ADD_IDX(GetSurfaceData)(FragInput input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData)
float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData)
{
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
float alpha = ADD_IDX(_BaseColor).a;

49
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitVelocityPass.hlsl


struct Varyings
{
float4 positionCS;
float3 positionWS;
// Note: Z component is not use
float4 transferPositionCS;
float4 transferPreviousPositionCS;

#if NEED_TANGENT_TO_WORLD
float3 positionWS;
float3 tangentToWorld[3];
#endif
};

#if NEED_TANGENT_TO_WORLD
float4 interpolators[5] : TEXCOORD0;
#elif NEED_TEXCOORD0
float4 interpolators[2] : TEXCOORD0;
float4 interpolators[3] : TEXCOORD0;
float4 interpolators[2] : TEXCOORD0;
float4 interpolators[3] : TEXCOORD0;
#endif
};

PackedVaryings output;
output.positionCS = input.positionCS;
output.interpolators[0] = float4(input.transferPositionCS.xyw, 0.0);
output.interpolators[1] = float4(input.transferPreviousPositionCS.xyw, 0.0);
output.interpolators[0] = float4(input.positionWS, 0.0);
output.interpolators[1] = float4(input.transferPositionCS.xyw, 0.0);
output.interpolators[2] = float4(input.transferPreviousPositionCS.xyw, 0.0);
output.interpolators[2].xyz = input.tangentToWorld[0];
output.interpolators[3].xyz = input.tangentToWorld[1];
output.interpolators[4].xyz = input.tangentToWorld[2];
output.interpolators[3].xyz = input.tangentToWorld[0];
output.interpolators[4].xyz = input.tangentToWorld[1];
output.interpolators[2].w = input.positionWS.x;
output.interpolators[3].w = input.positionWS.y;
output.interpolators[4].w = input.positionWS.z;
output.interpolators[2].w = input.tangentToWorld[2].x;
output.interpolators[3].w = input.tangentToWorld[2].y;
output.interpolators[4].w = input.tangentToWorld[2].z;
#elif NEED_TEXCOORD0
output.interpolators[0].w = input.texCoord0.x;
output.interpolators[1].w = input.texCoord0.y;

}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS; // as input we have the vpos
output.positionCS = float4(input.interpolators[0].xy, 0.0, input.interpolators[0].z);
output.previousPositionCS = float4(input.interpolators[1].xy, 0.0, input.interpolators[1].z);
output.unPositionSS = input.positionCS; // input.positionCS is SV_Position
output.positionWS = input.interpolators[0].xyz;
output.positionCS = float4(input.interpolators[1].xy, 0.0, input.interpolators[1].z);
output.previousPositionCS = float4(input.interpolators[1].xy, 0.0, input.interpolators[2].z);
output.positionWS.xyz = float2(input.interpolators[2].w, input.interpolators[3].w, input.interpolators[4].w);
output.tangentToWorld[0] = input.interpolators[2].xyz;
output.tangentToWorld[1] = input.interpolators[3].xyz;
output.tangentToWorld[2] = input.interpolators[4].xyz;
output.tangentToWorld[0] = input.interpolators[3].xyz;
output.tangentToWorld[1] = input.interpolators[4].xyz;
output.tangentToWorld[2] = float3(input.interpolators[2].w, input.interpolators[3].w, input.interpolators[4].w);
#elif NEED_TEXCOORD0
output.texCoord0.xy = float2(input.interpolators[0].w, input.interpolators[1].w);
#endif

{
Varyings output;
float3 positionWS = TransformObjectToWorld(input.positionOS);
output.positionCS = TransformWorldToHClip(positionWS);
output.positionWS = TransformObjectToWorld(input.positionOS);
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow steps transform to clip space + instancing matrix)
output.positionCS = TransformWorldToHClip(output.positionWS);
// TODO: Clean this code, put in function ?
output.transferPositionCS = mul(_NonJitteredVP, mul(unity_ObjectToWorld, float4(input.positionOS, 1.0)));

#endif
#if NEED_TANGENT_TO_WORLD
output.positionWS = positionWS;
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);

25
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs


protected MaterialEditor m_MaterialEditor;
public void FindOptionProperties(MaterialProperty[] props)
public void FindCommonOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);

FindInputOptionProperties(props);
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
FindCommonOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindMaterialProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;

if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
SetupMaterialKeywords((Material)obj);
}
}

EditorGUI.showMixedValue = false;
}
protected void SetupMaterial(Material material)
{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
protected void SetupCommonOptionsKeywords(Material material)
{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;

}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetupInputMaterial(material);
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;

material.globalIlluminationFlags = flags;
}
}
}
bool HasValidEmissiveKeyword(Material material)
{

m.DisableKeyword(keyword);
}
protected abstract void FindInputProperties(MaterialProperty[] props);
protected abstract void FindMaterialProperties(MaterialProperty[] props);
protected abstract void FindInputOptionProperties(MaterialProperty[] props);
protected abstract void SetupInputMaterial(Material material);
protected abstract void SetupMaterialKeywords(Material material);
}
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/UnlitUI.cs


protected const string kEmissiveColorMap = "_EmissiveColorMap";
protected const string kEmissiveIntensity = "_EmissiveIntensity";
override protected void FindInputProperties(MaterialProperty[] props)
override protected void FindMaterialProperties(MaterialProperty[] props)
{
color = FindProperty("_Color", props);
colorMap = FindProperty("_ColorMap", props);

{
}
protected override void FindInputOptionProperties(MaterialProperty[] props)
protected override void SetupMaterialKeywords(Material material)
}
protected override void SetupInputMaterial(Material material)
{
SetupCommonOptionsKeywords(material);
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
}

6
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Unlit.shader


return output;
}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS;
output.texCoord0 = input.interpolators[0].xy;

4
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/UnlitData.hlsl


// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
surfaceData.color = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, input.texCoord0).rgb * _Color.rgb;
float alpha = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, input.texCoord0).a * _Color.a;

builtinData.distortion = float2(0.0, 0.0);
builtinData.distortionBlur = 0.0;
builtinData.depthOffset = 0.0;
}

6
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/UnlitSharePass.hlsl


return output;
}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS;
output.texCoord0.xy = input.interpolators[0].xy;

13
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderConfig.cs


// Changing a value in this enum Config here require to regenerate the hlsl include and recompile C# and shaders
public class ShaderConfig
{
public const int VelocityInGbuffer = (int)ShaderOptions.VelocityInGBuffer;
public const int PackgbufferInU16 = (int)ShaderOptions.PackGBufferInU16;
// const variable produce warning like this one: warning CS0162: Unreachable code detected
// If we want to avoid them we can add #pragma warning disable 162, however doing that make the debugger shift his line count when debugging which is really annoying
// so here we decalare two kind of variable, one const that can be use in enum init and one static so the compiler doesn't complain. It mean that the conditional code will stay
// but it is usually small, so we are fine with it (until someone at microsoft fix the debuggger).
public const int k_VelocityInGbuffer = (int)ShaderOptions.VelocityInGBuffer;
public static int s_VelocityInGbuffer = (int)ShaderOptions.VelocityInGBuffer;
public const int k_PackgbufferInU16 = (int)ShaderOptions.PackGBufferInU16;
public static int s_PackgbufferInU16 = (int)ShaderOptions.PackGBufferInU16;
//#define VELOCITY_IN_GBUFFER

9
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDebugViewMaterial.hlsl


float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInput input = UnpackVaryings(packedInput);
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);

22
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDepthOnly.hlsl


#error SHADERPASS_is_not_correctly_define
#endif
float4 Frag(PackedVaryings packedInput) : SV_Target
void Frag( PackedVaryings packedInput,
out float4 outColor : SV_Target
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
FragInput input = UnpackVaryings(packedInput);
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
return float4(0.0, 0.0, 0.0, 0.0);
outColor = float4(0.0, 0.0, 0.0, 0.0);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.rawDepth;
#endif
}

29
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassForward.hlsl


#error SHADERPASS_is_not_correctly_define
#endif
float4 Frag(PackedVaryings packedInput) : SV_Target
void Frag( PackedVaryings packedInput,
out float4 outColor : SV_Target
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
FragInput input = UnpackVaryings(packedInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 positionWS = input.positionWS;
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
Coordinate coord = GetCoordinate(input.unPositionSS.xy, _ScreenSize.zw);
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
LightLoop(V, positionWS, coord, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
return float4(diffuseLighting + specularLighting, builtinData.opacity);
outColor = float4(diffuseLighting + specularLighting, builtinData.opacity);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.rawDepth;
#endif
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassForwardUnlit.hlsl


float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInput input = UnpackVaryings(packedInput);
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
// Not lit here (but emissive is allowed)

23
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassGBuffer.hlsl


void Frag( PackedVaryings packedInput,
OUTPUT_GBUFFER(outGBuffer)
OUTPUT_GBUFFER_VELOCITY(outVelocityBuffer)
#ifdef _DEPTHOFFSET_ON
, float outputDepth : SV_Depth
#endif
FragInput input = UnpackVaryings(packedInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 positionWS = input.positionWS;
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
Coordinate coord = GetCoordinate(input.unPositionSS.xy, _ScreenSize.zw);
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
ENCODE_INTO_GBUFFER(surfaceData, bakeDiffuseLighting, outGBuffer);
ENCODE_INTO_GBUFFER(surfaceData, bakeDiffuseLighting, outGBuffer);
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.rawDepth;
#endif
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassLightTransport.hlsl


float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInput input = UnpackVaryings(packedInput);
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
// No position and depth in case of light transport
float3 V = float3(0, 0, 1); // No vector view in case of light transport
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
LighTransportData lightTransportData = GetLightTransportData(surfaceData, builtinData, bsdfData);

9
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassVelocity.hlsl


float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInput input = UnpackVaryings(packedInput);
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
float4 outBuffer;
EncodeVelocity(builtinData.velocity, outBuffer);

166
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl


CBUFFER_START(UnityPerCamera)
// Time (t = time since current level load) values from Unity
float4 _Time; // (t/20, t, t*2, t*3)
float4 _SinTime; // sin(t/8), sin(t/4), sin(t/2), sin(t)
float4 _CosTime; // cos(t/8), cos(t/4), cos(t/2), cos(t)
float4 unity_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt
// Time (t = time since current level load) values from Unity
float4 _Time; // (t/20, t, t*2, t*3)
float4 _SinTime; // sin(t/8), sin(t/4), sin(t/2), sin(t)
float4 _CosTime; // cos(t/8), cos(t/4), cos(t/2), cos(t)
float4 unity_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt
#ifndef UNITY_SINGLE_PASS_STEREO
float3 _WorldSpaceCameraPos;
#if !defined(USING_STEREO_MATRICES)
float3 _WorldSpaceCameraPos;
// x = 1 or -1 (-1 if projection is flipped)
// y = near plane
// z = far plane
// w = 1/far plane
float4 _ProjectionParams;
// x = 1 or -1 (-1 if projection is flipped)
// y = near plane
// z = far plane
// w = 1/far plane
float4 _ProjectionParams;
// x = width
// y = height
// z = 1 + 1.0/width
// w = 1 + 1.0/height
float4 _ScreenParams;
// x = width
// y = height
// z = 1 + 1.0/width
// w = 1 + 1.0/height
float4 _ScreenParams;
// Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
// x = 1-far/near
// y = far/near
// z = x/far
// w = y/far
float4 _ZBufferParams;
// Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
// x = 1-far/near
// y = far/near
// z = x/far
// w = y/far
float4 _ZBufferParams;
// x = orthographic camera's width
// y = orthographic camera's height
// z = unused
// w = 1.0 if camera is ortho, 0.0 if perspective
float4 unity_OrthoParams;
// x = orthographic camera's width
// y = orthographic camera's height
// z = unused
// w = 1.0 if camera is ortho, 0.0 if perspective
float4 unity_OrthoParams;
float4 unity_CameraWorldClipPlanes[6];
float4 unity_CameraWorldClipPlanes[6];
// Projection matrices of the camera. Note that this might be different from projection matrix
// that is set right now, e.g. while rendering shadows the matrices below are still the projection
// of original camera.
float4x4 unity_CameraProjection;
float4x4 unity_CameraInvProjection;
#ifndef UNITY_SINGLE_PASS_STEREO
float4x4 unity_WorldToCamera;
float4x4 unity_CameraToWorld;
#if !defined(USING_STEREO_MATRICES)
// Projection matrices of the camera. Note that this might be different from projection matrix
// that is set right now, e.g. while rendering shadows the matrices below are still the projection
// of original camera.
float4x4 unity_CameraProjection;
float4x4 unity_CameraInvProjection;
float4x4 unity_WorldToCamera;
float4x4 unity_CameraToWorld;
#endif
CBUFFER_END

#ifndef UNITY_SINGLE_PASS_STEREO
float4x4 glstate_matrix_mvp;
#ifdef UNITY_USE_PREMULTIPLIED_MATRICES
float4x4 glstate_matrix_mvp;
float4x4 glstate_matrix_modelview0;
float4x4 glstate_matrix_invtrans_modelview0;
// Use center position for stereo rendering
float4x4 glstate_matrix_modelview0;
float4x4 glstate_matrix_invtrans_modelview0;
float4x4 unity_ObjectToWorld;
float4x4 unity_WorldToObject;
float4 unity_LODFade; // x is the fade value ranging within [0,1]. y is x quantized into 16 levels
float4 unity_WorldTransformParams; // w is usually 1.0, or -1.0 for odd-negative scale transforms
float4x4 unity_ObjectToWorld;
float4x4 unity_WorldToObject;
float4 unity_LODFade; // x is the fade value ranging within [0,1]. y is x quantized into 16 levels
float4 unity_WorldTransformParams; // w is usually 1.0, or -1.0 for odd-negative scale transforms
#ifdef UNITY_SINGLE_PASS_STEREO
CBUFFER_START(UnityPerEye)
float3 _WorldSpaceCameraPos;
float4x4 glstate_matrix_projection;
#if defined(USING_STEREO_MATRICES)
CBUFFER_START(UnityStereoGlobals)
float4x4 unity_StereoMatrixP[2];
float4x4 unity_StereoMatrixV[2];
float4x4 unity_StereoMatrixInvV[2];
float4x4 unity_StereoMatrixVP[2];
float4x4 unity_MatrixV;
float4x4 unity_MatrixVP;
float4x4 unity_StereoCameraProjection[2];
float4x4 unity_StereoCameraInvProjection[2];
float4x4 unity_StereoWorldToCamera[2];
float4x4 unity_StereoCameraToWorld[2];
float3 unity_StereoWorldSpaceCameraPos[2];
float4 unity_StereoScaleOffset[2];
CBUFFER_END
float4x4 unity_WorldToCamera;
float4x4 unity_CameraToWorld;
#ifdef UNITY_SUPPORT_MULTIVIEW
#define unity_StereoEyeIndex UNITY_VIEWID
UNITY_DECLARE_MULTIVIEW(2);
#else
CBUFFER_START(UnityStereoEyeIndex)
int unity_StereoEyeIndex;
#endif
float4x4 glstate_matrix_transpose_modelview0;
#ifdef UNITY_SINGLE_PASS_STEREO
float4x4 glstate_matrix_mvp;
#endif
float4x4 glstate_matrix_transpose_modelview0;
CBUFFER_END

#ifndef UNITY_SINGLE_PASS_STEREO
float4x4 glstate_matrix_projection;
float4x4 unity_MatrixV;
float4x4 unity_MatrixVP;
float4 glstate_lightmodel_ambient;
float4 unity_AmbientSky;
float4 unity_AmbientEquator;
float4 unity_AmbientGround;
float4 unity_IndirectSpecColor;
#if !defined(USING_STEREO_MATRICES)
float4x4 glstate_matrix_projection;
float4x4 unity_MatrixV;
float4x4 unity_MatrixInvV;
float4x4 unity_MatrixVP;
int unity_StereoEyeIndex;
float4 glstate_lightmodel_ambient;
float4 unity_AmbientSky;
float4 unity_AmbientEquator;
float4 unity_AmbientGround;
float4 unity_IndirectSpecColor;
float4 unity_ShadowColor;
CBUFFER_END

// ----------------------------------------------------------------------------
// TODO: move this to constant buffer by Pass
float4x4 _InvViewProjMatrix;
float4x4 _ViewProjMatrix; // Looks like using UNITY_MATRIX_VP in pixel shader doesn't work ??? need to setup my own...
return unity_MatrixV;
return UNITY_MATRIX_V;
}
float4x4 GetObjectToWorldMatrix()

// Transform to homogenous clip space
float4x4 GetWorldToHClipMatrix()
{
return unity_MatrixVP;
return UNITY_MATRIX_VP;
}
// Transform from clip space to homogenous world space

return unity_WorldTransformParams.w;
}
float4x4 GetObjectToWorldViewMatrix()
{
return glstate_matrix_modelview0;
}
float3 TransformWorldToView(float3 positionWS)
{
return mul(GetWorldToViewMatrix(), float4(positionWS, 1.0)).xyz;

float3 TransformWorldToObject(float3 positionWS)
{
return mul(GetWorldToObjectMatrix(), float4(positionWS, 1.0)).xyz;
}
float3 TransformObjectToView(float3 positionOS)
{
return mul(GetObjectToWorldViewMatrix(), float4(positionOS, 1.0)).xyz;
}
float3 TransformObjectToWorldDir(float3 dirOS)

312
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Serializable]
public enum SkyResolution
abstract public class SkyRenderer
SkyResolution128 = 128,
SkyResolution256 = 256,
SkyResolution512 = 512,
SkyResolution1024 = 1024,
// TODO: Anything above 1024 cause a crash in Unity...
//SkyResolution2048 = 2048,
//SkyResolution4096 = 4096
}
abstract public void Build();
abstract public void Cleanup();
abstract public void RenderSky(BuiltinSkyParameters builtinParams, SkyParameters skyParameters);
abstract public bool IsSkyValid(SkyParameters skyParameters);
[Serializable]
public class SkyParameters
{
public Texture skyHDRI;
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;
public SkyResolution skyResolution = SkyResolution.SkyResolution256;
virtual public bool IsParameterValid(SkyParameters skyParameters) { return false; }
virtual public Type GetSkyParameterType() { return typeof(SkyParameters); }
public class SkyRenderer
abstract public class SkyRenderer<ParameterType> : SkyRenderer
where ParameterType : SkyParameters
RenderTexture m_SkyboxCubemapRT = null;
RenderTexture m_SkyboxGGXCubemapRT = null;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_SkyHDRIMaterial = null; // Renders a cubemap into a render texture (can be cube or 2D)
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
SkyParameters m_bakedSkyParameters = new SkyParameters(); // This is the SkyParam used when baking and convolving the sky.
MaterialPropertyBlock m_RenderSkyPropertyBlock = null;
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];
Mesh BuildSkyMesh(Vector3 cameraPosition, Matrix4x4 cameraInvViewProjectionMatrix, bool forceUVBottom)
{
Vector4 vertData0 = new Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData1 = new Vector4(1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData2 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 vertData3 = new Vector4(-1.0f, 1.0f, 1.0f, 1.0f);
Vector3[] vertData = new Vector3[4];
vertData[0] = new Vector3(vertData0.x, vertData0.y, vertData0.z);
vertData[1] = new Vector3(vertData1.x, vertData1.y, vertData1.z);
vertData[2] = new Vector3(vertData2.x, vertData2.y, vertData2.z);
vertData[3] = new Vector3(vertData3.x, vertData3.y, vertData3.z);
// Get view vector based on the frustum, i.e (invert transform frustum get position etc...)
Vector3[] eyeVectorData = new Vector3[4];
Matrix4x4 transformMatrix = cameraInvViewProjectionMatrix;
Vector4 posWorldSpace0 = transformMatrix * vertData0;
Vector4 posWorldSpace1 = transformMatrix * vertData1;
Vector4 posWorldSpace2 = transformMatrix * vertData2;
Vector4 posWorldSpace3 = transformMatrix * vertData3;
Vector4 cameraPos = new Vector4(cameraPosition.x, cameraPosition.y, cameraPosition.z, 0.0f);
Vector4 direction0 = (posWorldSpace0 / posWorldSpace0.w - cameraPos);
Vector4 direction1 = (posWorldSpace1 / posWorldSpace1.w - cameraPos);
Vector4 direction2 = (posWorldSpace2 / posWorldSpace2.w - cameraPos);
Vector4 direction3 = (posWorldSpace3 / posWorldSpace3.w - cameraPos);
if (SystemInfo.graphicsUVStartsAtTop && !forceUVBottom)
{
eyeVectorData[3] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[2] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[1] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[0] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
else
{
eyeVectorData[0] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[1] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[2] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[3] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
// Write out the mesh
var triangles = new int[6] { 0, 1, 2, 2, 3, 0 };
return new Mesh
{
vertices = vertData,
normals = eyeVectorData,
triangles = triangles
};
}
void RebuildTextures(SkyParameters skyParameters)
{
if ((m_SkyboxCubemapRT != null) && (m_SkyboxCubemapRT.width != (int)skyParameters.skyResolution))
{
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
}
if (m_SkyboxCubemapRT == null)
{
m_SkyboxCubemapRT = new RenderTexture((int)skyParameters.skyResolution, (int)skyParameters.skyResolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true; // Generate regular mipmap for filtered importance sampling
m_SkyboxCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxCubemapRT.Create();
m_SkyboxGGXCubemapRT = new RenderTexture((int)skyParameters.skyResolution, (int)skyParameters.skyResolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxGGXCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxGGXCubemapRT.useMipMap = true;
m_SkyboxGGXCubemapRT.autoGenerateMips = false;
m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT.Create();
}
}
// Sets the global MIP-mapped cubemap '_SkyTexture' in the shader.
// The texture being set is the sky (environment) map pre-convolved with GGX.
public void SetGlobalSkyTexture()
{
Shader.SetGlobalTexture("_SkyTexture", m_SkyboxGGXCubemapRT);
}
public void Resize(SkyParameters skyParameters)
{
// When loading RenderDoc, RenderTextures will go null
RebuildTextures(skyParameters);
}
public void Rebuild()
{
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_SkyHDRIMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/SkyHDRI");
m_GGXConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/GGXConvolve");
m_RenderSkyPropertyBlock = new MaterialPropertyBlock();
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, 0.1f, 1.0f);
Vector3[] lookAtList = {
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] UpVectorList = {
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
for (int i = 0; i < 6; ++i)
{
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], UpVectorList[i]);
m_faceCameraInvViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj).inverse;
// When rendering into a texture the render will be flip (due to legacy unity openGL behavior), so we need to flip UV here...
m_CubemapFaceMesh[i] = BuildSkyMesh(Vector3.zero, m_faceCameraInvViewProjectionMatrix[i], true);
}
}
public void Cleanup()
{
Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_SkyHDRIMaterial);
Utilities.Destroy(m_GGXConvolveMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
}
public bool IsSkyValid(SkyParameters parameters)
{
// Later we will also test shader for procedural skies.
return parameters.skyHDRI != null;
}
private void RenderSky(Matrix4x4 invViewProjectionMatrix, SkyParameters skyParameters, Mesh skyMesh, RenderLoop renderLoop)
{
m_RenderSkyPropertyBlock.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_RenderSkyPropertyBlock.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
m_RenderSkyPropertyBlock.SetMatrix("_InvViewProjMatrix", invViewProjectionMatrix);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, 0, m_RenderSkyPropertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
private void RenderSkyToCubemap(SkyParameters skyParameters, RenderTexture target, RenderLoop renderLoop)
override public bool IsParameterValid(SkyParameters skyParameters)
for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(renderLoop, target, 0, (CubemapFace)i);
RenderSky(m_faceCameraInvViewProjectionMatrix[i], skyParameters, m_CubemapFaceMesh[i], renderLoop);
}
return GetParameters(skyParameters) != null;
private void RenderCubemapGGXConvolution(Texture input, RenderTexture target, RenderLoop renderLoop)
override public Type GetSkyParameterType()
using (new Utilities.ProfilingSample("Sky Pass: GGX Convolution", renderLoop))
{
int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f);
if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1))
{
Debug.LogWarning("RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ((int)EnvConstants.SpecCubeLodStep + 1) + " mip levels");
return;
}
// Copy the first mip.
// TEMP code until CopyTexture is implemented for command buffer
// All parameters are neutral because exposure/multiplier have already been applied in the first copy.
SkyParameters skyParams = new SkyParameters();
skyParams.exposure = 0.0f;
skyParams.multiplier = 1.0f;
skyParams.rotation = 0.0f;
skyParams.skyHDRI = input;
RenderSkyToCubemap(skyParams, target, renderLoop);
// End temp
//for (int f = 0; f < 6; f++)
// Graphics.CopyTexture(input, f, 0, target, f, 0);
// Do the convolution on remaining mipmaps
float invOmegaP = (6.0f * input.width * input.width) / (4.0f * Mathf.PI); // Solid angle associated to a pixel of the cubemap;
m_GGXConvolveMaterial.SetTexture("_MainTex", input);
m_GGXConvolveMaterial.SetFloat("_MipMapCount", mipCount);
m_GGXConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
{
Utilities.SetRenderTarget(renderLoop, target, mip, (CubemapFace)face);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(m_CubemapFaceMesh[face], Matrix4x4.identity, m_GGXConvolveMaterial, 0, 0, propertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}
return typeof(ParameterType);
public void RenderSky(Camera camera, SkyParameters skyParameters, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
protected ParameterType GetParameters(SkyParameters parameters)
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
{
if (IsSkyValid(skyParameters))
{
// Trigger a rebuild of cubemap / convolution
// TODO: can we have some kind of hash value here ? +> use or override GetHashCode() + include a refresh rate value in parameters
// TODO: we could apply multiplier/exposure and rotation on the final result (i.e on the sky ibl and on lightprobe / lightmap, but can be tricky as Unity seems to merge sky information with
// other lighting into SH / lightmap.
if (skyParameters.skyResolution != m_bakedSkyParameters.skyResolution ||
skyParameters.exposure != m_bakedSkyParameters.exposure ||
skyParameters.rotation != m_bakedSkyParameters.rotation ||
skyParameters.multiplier != m_bakedSkyParameters.multiplier ||
skyParameters.skyHDRI != m_bakedSkyParameters.skyHDRI)
{
using (new Utilities.ProfilingSample("Sky Pass: Render Cubemap", renderLoop))
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap(skyParameters, m_SkyboxCubemapRT, renderLoop);
// Convolve downsampled cubemap
RenderCubemapGGXConvolution(m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT, renderLoop);
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
RenderSettings.customReflection = null;
DynamicGI.UpdateEnvironment();
}
// Cleanup all this...
m_bakedSkyParameters.skyHDRI = skyParameters.skyHDRI;
m_bakedSkyParameters.skyResolution = skyParameters.skyResolution;
m_bakedSkyParameters.exposure = skyParameters.exposure;
m_bakedSkyParameters.rotation = skyParameters.rotation;
m_bakedSkyParameters.multiplier = skyParameters.multiplier;
}
// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
Matrix4x4 invViewProjectionMatrix = Utilities.GetViewProjectionMatrix(camera).inverse;
RenderSky(invViewProjectionMatrix, skyParameters, BuildSkyMesh(camera.GetComponent<Transform>().position, invViewProjectionMatrix, false), renderLoop);
}
}
return parameters as ParameterType;
}
}
}

4
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs.meta


fileFormatVersion: 2
guid: cf8a015aab8d3b643aa3ef3816f85447
timeCreated: 1479314393
guid: 0dc07ece20cf92244bb1f9c889f3cea5
timeCreated: 1481626426
licenseType: Pro
MonoImporter:
serializedVersion: 2

41
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs


// Render Target Management.
public const ClearFlag kClearAll = ClearFlag.ClearDepth | ClearFlag.ClearColor;
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier buffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.ClearNone, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
var cmd = new CommandBuffer();
cmd.name = "";

disposed = true;
}
}
var gpuVP = gpuProj * worldToViewMatrix;
var gpuVP = gpuProj * worldToViewMatrix * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API.
public static Matrix4x4 GetViewProjectionMatrix(Camera camera)
public static HDRenderLoop.HDCamera GetHDCamera(Camera camera)
return GetViewProjectionMatrix(camera.worldToCameraMatrix, camera.projectionMatrix);
HDRenderLoop.HDCamera hdCamera = new HDRenderLoop.HDCamera();
hdCamera.camera = camera;
hdCamera.screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
var gpuVP = gpuProj * camera.worldToCameraMatrix;
hdCamera.viewProjectionMatrix = gpuVP;
hdCamera.invViewProjectionMatrix = gpuVP.inverse;
return hdCamera;
public static Vector4 ComputeScreenSize(Camera camera)
public static void SetupMaterialHDCamera(HDRenderLoop.HDCamera hdCamera, Material material)
return new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
material.SetVector("_ScreenSize", hdCamera.screenSize);
material.SetMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
material.SetMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
}
// TEMP: These functions should be implemented C++ side, for now do it in C#

m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public static HDRenderLoop GetHDRenderLoop()
{
HDRenderLoop renderLoop = UnityEngine.Rendering.GraphicsSettings.renderPipeline as HDRenderLoop;
if (renderLoop == null)
{
Debug.LogWarning("SkyParameters component can only be used with HDRenderLoop custom RenderPipeline.");
return null;
}
return renderLoop;
}
}
}

93
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


// World position reconstruction / transformation
// ----------------------------------------------------------------------------
struct Coordinate
// Z buffer to linear 0..1 depth
float Linear01Depth(float depth, float4 zBufferParam)
// Normalize coordinates
float2 positionSS;
// Unormalize coordinates
uint2 unPositionSS;
return 1.0 / (zBufferParam.x * depth + zBufferParam.y);
}
// Z buffer to linear depth
float LinearEyeDepth(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.z * depth + zBufferParam.w);
}
struct PositionInputs
{
// Normalize screen position (offset by 0.5)
float2 positionSS;
// Unormalize screen position (offset by 0.5)
uint2 unPositionSS;
float depthRaw; // raw depth from depth buffer
float depthVS;
float4 positionCS;
float3 positionWS;
// else it is current unormalized screen coordinate like return by VPOS
Coordinate GetCoordinate(float2 unPositionSS, float2 invScreenSize)
// else it is current unormalized screen coordinate like return by SV_Position
PositionInputs GetPositionInput(float2 unPositionSS, float2 invScreenSize)
Coordinate coord;
coord.positionSS = unPositionSS;
PositionInputs posInput;
ZERO_INITIALIZE(PositionInputs, posInput);
posInput.positionSS = unPositionSS;
coord.positionSS.xy += float2(0.5, 0.5);
posInput.positionSS.xy += float2(0.5, 0.5);
coord.positionSS *= invScreenSize;
posInput.positionSS *= invScreenSize;
posInput.unPositionSS = uint2(unPositionSS);
return posInput;
}
coord.unPositionSS = uint2(unPositionSS);
// From forward
// depthRaw and depthVS come directly form .zw of SV_Position
void UpdatePositionInput(float depthRaw, float depthVS, float3 positionWS, inout PositionInputs posInput)
{
posInput.depthRaw = depthRaw;
posInput.depthVS = depthVS;
return coord;
// TODO: We revert for DX but maybe it is not the case of OGL ? Test the define ?
posInput.positionCS = float4((posInput.positionSS - 0.5) * float2(2.0, -2.0), depthRaw, 1.0) * depthVS; // depthVS is SV_Position.w
posInput.positionWS = positionWS;
// screenPos is screen coordinate in [0..1] (return by Coordinate.positionSS)
// From deferred or compute shader
float3 UnprojectToWorld(float depth, float2 screenPos, float4x4 invViewProjectionMatrix)
void UpdatePositionInput(float depth, float4x4 invViewProjectionMatrix, float4x4 ViewProjectionMatrix, inout PositionInputs posInput)
float4 positionCS = float4(screenPos.xy * 2.0 - 1.0, depth, 1.0);
float4 hpositionWS = mul(invViewProjectionMatrix, positionCS);
posInput.depthRaw = depth;
return hpositionWS.xyz / hpositionWS.w;
}
// TODO: Do we need to flip Y axis here on OGL ?
posInput.positionCS = float4(posInput.positionSS.xy * 2.0 - 1.0, depth, 1.0);
float4 hpositionWS = mul(invViewProjectionMatrix, posInput.positionCS);
posInput.positionWS = hpositionWS.xyz / hpositionWS.w;
// Z buffer to linear 0..1 depth
float Linear01Depth(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.x * depth + zBufferParam.y);
// The compiler should optimize this (less expensive than reconstruct depth VS from depth buffer)
posInput.depthVS = mul(ViewProjectionMatrix, float4(posInput.positionWS, 1.0)).w;
posInput.positionCS *= posInput.depthVS;
// Z buffer to linear depth
float LinearEyeDepth(float depth, float4 zBufferParam)
// depthOffsetVS is always in the direction of the view vector (V)
void ApplyDepthOffsetPositionInput(float V, float depthOffsetVS, inout PositionInputs posInput)
return 1.0 / (zBufferParam.z * depth + zBufferParam.w);
posInput.depthVS += depthOffsetVS;
// TODO: it is an approx, need a correct value where we use projection matrix to reproject the depth from VS
posInput.depthRaw = posInput.positionCS.z / posInput.depthVS;
// TODO: Do we need to flip Y axis here on OGL ?
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;
}
//-----------------------------------------------------------------------------

30
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


cmd.GetTemporaryRT(s_GBufferZ, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(s_CameraDepthTexture, width, height, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(s_CameraTarget, width, height, 0, FilterMode.Point, formatHDR, RenderTextureReadWrite.Default, 1, true); // rtv/uav
var colorMRTs = new RenderTargetIdentifier[4] { s_GBufferAlbedo, s_GBufferSpecRough, s_GBufferNormal, s_GBufferEmission };
cmd.SetRenderTarget(colorMRTs, new RenderTargetIdentifier(s_GBufferZ));
cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0));

return !disableFptl;
}
}
static void CopyDepthAfterGBuffer(RenderLoop loop)
{
var cmd = new CommandBuffer { name = "Copy depth" };

}
else
{
cmd.Blit(0, s_CameraTarget, m_DeferredMaterial, 0);
cmd.Blit(0, s_CameraTarget, m_DeferredReflectionMaterial, 0);
cmd.Blit(BuiltinRenderTextureType.CameraTarget, s_CameraTarget, m_DeferredMaterial, 0);
cmd.Blit(BuiltinRenderTextureType.CameraTarget, s_CameraTarget, m_DeferredReflectionMaterial, 0);
}

return numLightsOut + numProbesOut;
}
#if UNITY_EDITOR
public override void RenderSceneView(Camera camera, RenderLoop renderLoop)
{
base.RenderSceneView(camera, renderLoop);
renderLoop.PrepareForEditorRendering(camera, new RenderTargetIdentifier(s_CameraDepthTexture));
renderLoop.Submit();
}
#endif
public override void Render(Camera[] cameras, RenderLoop renderLoop)
{
foreach (var camera in cameras)

// debug views.
if (enableDrawLightBoundsDebug) DrawLightBoundsDebug(loop, cullResults.visibleLights.Length);
// bind depth surface for editor grid/gizmo/selection rendering
if (camera.cameraType == CameraType.SceneView)
{
var cmd = new CommandBuffer();
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, new RenderTargetIdentifier(s_CameraDepthTexture));
loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
loop.Submit();
}
void DrawLightBoundsDebug(RenderLoop loop, int numLights)

89
Assets/TestScenes/HDTest/GlobalIlluminationTest.unity


--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 7
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3

m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1

m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.6238628, g: 0.56322443, b: 0.5425187, a: 1}
m_IndirectSpecularColor: {r: 0.5456157, g: 0.39781958, b: 0.24038762, a: 1}
serializedVersion: 7
m_GIWorkflowMode: 0
serializedVersion: 9
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1

m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 4
serializedVersion: 6
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024

m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_DirectLightInLightProbes: 1
m_StationaryBakeMode: 1
m_ShadowMaskMode: 2
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2

minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &20738779

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 565152814}
m_Enabled: 1
serializedVersion: 7
serializedVersion: 8
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 3

m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_CCT: 6570
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!114 &565152817

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1108908831}
m_Enabled: 1
serializedVersion: 7
serializedVersion: 8
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 100

m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_CCT: 6570
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!114 &1108908834

m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1879932837}
m_LocalRotation: {x: 0.07759436, y: -0.72047704, z: 0.08170084, w: 0.6842638}
m_LocalPosition: {x: 7.3, y: 1.41, z: -4.72}
m_LocalRotation: {x: 0.120674305, y: -0, z: -0, w: 0.9926922}
m_LocalPosition: {x: -0.56, y: 2.81, z: -12.59}
m_LocalEulerAnglesHint: {x: 12.939001, y: -92.953, z: 0}
m_LocalEulerAnglesHint: {x: 13.862, y: 0, z: 0}
--- !u!114 &1879932843
MonoBehaviour:
m_ObjectHideFlags: 0

m_Script: {fileID: 11500000, guid: 92bb16b4ee20841929b24d6bd771738d, type: 3}
m_Name:
m_EditorClassIdentifier:
m_RenderLoop: {fileID: 11400000, guid: 2400b74f5ce370c4481e5dc417d03703, type: 2}
--- !u!1 &1910068096
GameObject:
m_ObjectHideFlags: 0

- {x: -1, y: 1, z: -1}
- {x: -1, y: -1, z: 1}
- {x: -1, y: -1, z: -1}
--- !u!1 &1944423445
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1944423448}
- component: {fileID: 1944423447}
- component: {fileID: 1944423446}
m_Layer: 0
m_Name: SceneSettings
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1944423446
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1944423445}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name:
m_EditorClassIdentifier:
rotation: 0
exposure: 0
multiplier: 1
resolution: 256
updateMode: 1
updatePeriod: 0
skyHDRI: {fileID: 8900000, guid: 9b513842339ef704ca63ef696691bc34, type: 3}
--- !u!114 &1944423447
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1944423445}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bc357c46587fc9d4cb8f311794d7d2f3, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SkyRendererTypeName: UnityEngine.Experimental.ScriptableRenderLoop.HDRISkyRenderer
--- !u!4 &1944423448
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1944423445}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

914
Assets/TestScenes/HDTest/LayeredLitTest.unity
文件差异内容过多而无法显示
查看文件

20
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Planar.mat


m_Name: Layered_Layer0_Planar
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYER_MASK_VERTEX_COLOR _NORMALMAP_TANGENT_SPACE
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYER_MAPPING_TRIPLANAR_0 _LAYER_MASK_VERTEX_COLOR
_NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _TexWorldScale2: 1
- _TexWorldScale3: 1
- _UVBase: 0
- _UVBase0: 3
- _UVBase0: 4
- _UVBase1: 0
- _UVBase2: 0
- _UVBase3: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 0, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask0: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask0: {r: 0, g: 0, b: 0, a: 0}
- _UVMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Planar.mat.meta


fileFormatVersion: 2
guid: 91a8197de5f6d074c8dac4416c16cbb2
timeCreated: 1480934271
timeCreated: 1481879942
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["a02ccd7b5946da643a654ccea743375b","686eb5593c0e94f4eb86ca1d3cfef7fa","",""]}'

16
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Triplanar.mat


m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 0
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 1
- _DstBlend: 0

- _TexWorldScale2: 1
- _TexWorldScale3: 1
- _UVBase: 0
- _UVBase0: 4
- _UVBase0: 5
- _UVBase1: 0
- _UVBase2: 0
- _UVBase3: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_Triplanar.mat.meta


fileFormatVersion: 2
guid: b8805bd8838bdf34996bedcee9ebbf10
timeCreated: 1480934285
timeCreated: 1481881655
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["a02ccd7b5946da643a654ccea743375b","686eb5593c0e94f4eb86ca1d3cfef7fa","",""]}'

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV0.mat.meta


fileFormatVersion: 2
guid: ea0f1f2983d72874084abf3a8d75bf04
timeCreated: 1480933657
timeCreated: 1481819419
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["a02ccd7b5946da643a654ccea743375b","686eb5593c0e94f4eb86ca1d3cfef7fa","",""]}'

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV1.mat.meta


fileFormatVersion: 2
guid: dde88fa6f8dc19a4eb2d828bf0f4d91c
timeCreated: 1480934261
timeCreated: 1481819429
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["a02ccd7b5946da643a654ccea743375b","686eb5593c0e94f4eb86ca1d3cfef7fa","",""]}'

31
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV3.mat


m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYER_MASK_VERTEX_COLOR _NORMALMAP_TANGENT_SPACE
_REQUIRE_UV2_OR_UV3 _REQUIRE_UV3
disabledShaderPasses: []
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _TexWorldScale2: 1
- _TexWorldScale3: 1
- _UVBase: 0
- _UVBase0: 2
- _UVBase1: 0
- _UVBase0: 3
- _UVBase1: 3
- _UVDetail0: 2
- _UVDetail1: 2
- _UVDetail0: 3
- _UVDetail1: 3
- _UVDetail2: 0
- _UVDetail3: 0
- _UVDetailsMappingMask0: 0

- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 0, g: 0, b: 1, a: 0}
- _UVDetailsMappingMask1: {r: 0, g: 0, b: 1, a: 0}
- _UVDetailsMappingMask0: {r: 0, g: 0, b: 0, a: 1}
- _UVDetailsMappingMask1: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask0: {r: 0, g: 0, b: 1, a: 0}
- _UVMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask0: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask1: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer0_UV3.mat.meta


fileFormatVersion: 2
guid: 3e3a7e6d5f3b8164eb7c110dd465185d
timeCreated: 1480934266
timeCreated: 1481881392
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["a02ccd7b5946da643a654ccea743375b","686eb5593c0e94f4eb86ca1d3cfef7fa","",""]}'

22
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Planar.mat


m_Name: Layered_Layer1_Planar
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYER_MASK_VERTEX_COLOR _NORMALMAP_TANGENT_SPACE
_REQUIRE_UV3
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYER_MAPPING_TRIPLANAR_1 _LAYER_MASK_VERTEX_COLOR
_NORMALMAP_TANGENT_SPACE
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _TexWorldScale3: 1
- _UVBase: 0
- _UVBase0: 0
- _UVBase1: 3
- _UVBase1: 4
- _UVBase2: 0
- _UVBase3: 0
- _UVDetail: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 0, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask1: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask1: {r: 0, g: 0, b: 0, a: 0}
- _UVMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Planar.mat.meta


fileFormatVersion: 2
guid: fd9a6b078b486c8408e9c7ed638a47ec
timeCreated: 1480680901
timeCreated: 1481879952
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","609b27a9e3e537048b26ff65f31946e8","",""]}'

15
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Triplanar.mat


m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 0
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 1
- _DstBlend: 0

- _TexWorldScale3: 1
- _UVBase: 0
- _UVBase0: 0
- _UVBase1: 4
- _UVBase1: 5
- _UVBase2: 0
- _UVBase3: 0
- _UVDetail: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_Triplanar.mat.meta


fileFormatVersion: 2
guid: 74b98b46b0cf6f4408b920728d5945eb
timeCreated: 1480680915
timeCreated: 1481881644
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","609b27a9e3e537048b26ff65f31946e8","",""]}'

23
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_UV3.mat


m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYER_MASK_VERTEX_COLOR _NORMALMAP_TANGENT_SPACE
_REQUIRE_UV3
_REQUIRE_UV2_OR_UV3 _REQUIRE_UV3
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _TexWorldScale3: 1
- _UVBase: 0
- _UVBase0: 0
- _UVBase1: 2
- _UVBase1: 3
- _UVDetail1: 2
- _UVDetail1: 3
- _UVDetail2: 0
- _UVDetail3: 0
- _UVDetailsMappingMask0: 0

- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 0, g: 0, b: 1, a: 0}
- _UVDetailsMappingMask1: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask1: {r: 0, g: 0, b: 1, a: 0}
- _UVMappingMask1: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer1_UV3.mat.meta


fileFormatVersion: 2
guid: aa6171e055287cb4f9fea8ce6733e050
timeCreated: 1480680809
timeCreated: 1481881398
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","609b27a9e3e537048b26ff65f31946e8","",""]}'

22
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Planar.mat


m_Name: Layered_Layer2_Planar
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYEREDLIT_3_LAYERS _LAYER_MASK_VERTEX_COLOR
_NORMALMAP_TANGENT_SPACE _REQUIRE_UV3
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYEREDLIT_3_LAYERS _LAYER_MAPPING_TRIPLANAR_2
_LAYER_MASK_VERTEX_COLOR _NORMALMAP_TANGENT_SPACE
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _UVBase: 0
- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 3
- _UVBase2: 4
- _UVBase3: 0
- _UVDetail: 0
- _UVDetail0: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask2: {r: 0, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask2: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask2: {r: 0, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Planar.mat.meta


fileFormatVersion: 2
guid: cd6fab12a4d34f841a5d2e59188f981c
timeCreated: 1480680992
timeCreated: 1481879997
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","b1bac0266a49a1040a9365f40c7b6ddd",""]}'

15
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Triplanar.mat


m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 0
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 1
- _DstBlend: 0

- _UVBase: 0
- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 4
- _UVBase2: 5
- _UVBase3: 0
- _UVDetail: 0
- _UVDetail0: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_Triplanar.mat.meta


fileFormatVersion: 2
guid: 4e173a4bed5c8ba4b930247d61ca57ec
timeCreated: 1480681000
timeCreated: 1481881627
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","b1bac0266a49a1040a9365f40c7b6ddd",""]}'

23
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_UV3.mat


m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYEREDLIT_3_LAYERS _LAYER_MASK_VERTEX_COLOR
_NORMALMAP_TANGENT_SPACE _REQUIRE_UV3
_NORMALMAP_TANGENT_SPACE _REQUIRE_UV2_OR_UV3 _REQUIRE_UV3
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _UVBase: 0
- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 2
- _UVBase2: 3
- _UVDetail2: 2
- _UVDetail2: 3
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask2: {r: 0, g: 0, b: 1, a: 0}
- _UVDetailsMappingMask2: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask2: {r: 0, g: 0, b: 1, a: 0}
- _UVMappingMask2: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer2_UV3.mat.meta


fileFormatVersion: 2
guid: ee3e0f05e742ad246855fc1151154c01
timeCreated: 1480680986
timeCreated: 1481881437
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","b1bac0266a49a1040a9365f40c7b6ddd",""]}'

22
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Planar.mat


m_Name: Layered_Layer3_Planar
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYEREDLIT_4_LAYERS _LAYER_MASK_VERTEX_COLOR
_NORMALMAP_TANGENT_SPACE _REQUIRE_UV3
_DISTORTIONONLY_OFF _EMISSION _EMISSIVE_COLOR _LAYEREDLIT_4_LAYERS _LAYER_MAPPING_TRIPLANAR_3
_LAYER_MASK_VERTEX_COLOR _NORMALMAP_TANGENT_SPACE
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 0
- _UVBase3: 3
- _UVBase3: 4
- _UVDetail: 0
- _UVDetail0: 0
- _UVDetail1: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask3: {r: 0, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask3: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask3: {r: 0, g: 0, b: 0, a: 0}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Planar.mat.meta


fileFormatVersion: 2
guid: 32ddfc45781832a4f94eb0efa3b88571
timeCreated: 1480682190
timeCreated: 1481880057
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","6c40a6ba55a62fc4c92fdc1cdee2f85a"]}'

16
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Triplanar.mat


m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _BumpScale: 1
- _CullMode: 0
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 1
- _DstBlend: 0

- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 0
- _UVBase3: 4
- _UVBase3: 5
- _UVDetail: 0
- _UVDetail0: 0
- _UVDetail1: 0

- _UVDetailsMappingMask1: 0
- _UVDetailsMappingMask2: 0
- _UVDetailsMappingMask3: 0
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_Triplanar.mat.meta


fileFormatVersion: 2
guid: 0284c7765797bfe42b104f08550600a8
timeCreated: 1480935617
timeCreated: 1481881618
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","6c40a6ba55a62fc4c92fdc1cdee2f85a"]}'

33
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_UV3.mat


m_PrefabInternal: {fileID: 0}
m_Name: Layered_Layer3_UV3
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_NORMALMAP_TANGENT_SPACE _REQUIRE_UV3
_NORMALMAP_TANGENT_SPACE _REQUIRE_UV2_OR_UV3 _REQUIRE_UV3
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap0:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 21bed8c058c65f84e92fd4e28dd6ec51, type: 3}
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 21bed8c058c65f84e92fd4e28dd6ec51, type: 3}
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 21bed8c058c65f84e92fd4e28dd6ec51, type: 3}
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 21bed8c058c65f84e92fd4e28dd6ec51, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAOScale0: 1
- _DetailAOScale1: 1
- _DetailAOScale2: 1

- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0

- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 0
- _UVBase3: 2
- _UVBase3: 3
- _UVDetail3: 2
- _UVDetail3: 3
- _UVMappingPlanar0: 0
- _UVMappingPlanar1: 0
- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}

- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask3: {r: 0, g: 0, b: 1, a: 0}
- _UVDetailsMappingMask3: {r: 0, g: 0, b: 0, a: 1}
- _UVMappingMask3: {r: 0, g: 0, b: 1, a: 0}
- _UVMappingMask3: {r: 0, g: 0, b: 0, a: 1}

2
Assets/TestScenes/HDTest/LayeredLitTest/Material/Layered_Layer3_UV3.mat.meta


fileFormatVersion: 2
guid: b5dde76940778384c891440343094268
timeCreated: 1480681119
timeCreated: 1481881474
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","686eb5593c0e94f4eb86ca1d3cfef7fa","6c40a6ba55a62fc4c92fdc1cdee2f85a"]}'

7
README.md


# Unity Scriptable Render Loop testbed
**NOTE**: this is a testbed for a Unity feature that has not shipped yet! The project will not work with any public
**NOTE**: this is a testbed for a Unity feature that has not shipped yet! The project does not work with any public
Unity version, and things in it might and will be broken.
"Scriptable Render Loops" is a potential future Unity feature, think "Command Buffers, take two". We plan to ship the feature, and a

There's a more detailed overview document here: [ScriptableRenderLoop google doc](https://docs.google.com/document/d/1e2jkr_-v5iaZRuHdnMrSv978LuJKYZhsIYnrDkNAuvQ/edit?usp=sharing)
Did we mention it's a very WIP, no promises, may or might not ship feature, anything and everything in it can change? It totally is.
## For Unity 5.6 beta users
* Unity 5.6 beta 1 should use an older revision of this project, [tagged unity-5.6.0b1](../../releases/tag/unity-5.6.0b1) (commit `acc230b` on 2016 Nov 23). "BasicRenderLoopScene" scene is the basic example, with the scriptable render loop defaulting to off; enable it by enabling the component on the camera. All the other scenes may or might not work. Use of Windows/DX11 is preferred.

3
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader


Shader "Hidden/HDRenderLoop/SkyHDRI"
Shader "Hidden/HDRenderLoop/Sky/SkyHDRI"
{
SubShader
{

TEXTURECUBE(_Cubemap);
SAMPLERCUBE(sampler_Cubemap);
float4x4 _InvViewProjMatrix;
float4 _SkyParam; // x exposure, y multiplier, z rotation
struct Attributes

14
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader


Shader "Hidden/HDRenderLoop/SkyProcedural"
Shader "Hidden/HDRenderLoop/Sky/SkyProcedural"
{
SubShader
{

TEXTURECUBE(_Cubemap);
SAMPLERCUBE(sampler_Cubemap);
float4x4 _InvViewProjMatrix;
float4 _SkyParam; // x exposure, y multiplier, z rotation
struct Attributes

float3 rotDirY = float3(sinPhi, 0, cosPhi);
dir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
Coordinate coord = GetCoordinate(input.positionCS.xy, _ScreenSize.zw);
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
// If the sky box is too far away (depth set to 0), the resulting look is too foggy.
const float skyDepth = 0.01;

float rawDepth = max(skyDepth, LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).r);
float rawDepth = max(skyDepth, LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r);
float skyTexWeight = (rawDepth > skyDepth) ? 0.0 : 1.0;
#else
float rawDepth = skyDepth;

float3 positionWS = UnprojectToWorld(rawDepth, coord.positionSS, _InvViewProjMatrix);
UpdatePositionInput(rawDepth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
VolundTransferScatter(positionWS, c1, c2, c3);
VolundTransferScatter(posInput.positionWS, c1, c2, c3);
float4 coord1 = float4(c1.rgb + c3.rgb, max(0.f, 1.f - c1.a - c3.a));
float3 coord2 = c2.rgb;

27
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class HDRenderLoopMenuItems
{
[UnityEditor.MenuItem("HDRenderLoop/Create Scene Settings")]
static void CreateSceneSettings()
{
CommonSettings[] settings = Object.FindObjectsOfType(typeof(CommonSettings)) as CommonSettings[];
if(settings.Length == 0)
{
GameObject go = new GameObject();
go.name = "SceneSettings";
go.AddComponent(typeof(CommonSettings));
}
else
{
Debug.LogWarning("SceneSettings has already been created.");
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs.meta


fileFormatVersion: 2
guid: 19042aef0dcb65e4496d778558fefad9
timeCreated: 1481793704
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

94
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDistortionPass.hlsl


#ifndef SHADERPASS
#error Undefine_SHADERPASS
#endif
#define NEED_TANGENT_TO_WORLD NEED_TEXCOORD0 && (defined(_HEIGHTMAP) && !defined(_HEIGHTMAP_AS_DISPLACEMENT))
struct Attributes
{
float3 positionOS : POSITION;
float2 uv0 : TEXCOORD0;
#if NEED_TANGENT_TO_WORLD
float4 tangentOS : TANGENT;
#endif
};
struct Varyings
{
float4 positionCS;
float3 positionWS;
float2 texCoord0;
#if NEED_TANGENT_TO_WORLD
float3 tangentToWorld[3];
#endif
};
struct PackedVaryings
{
float4 positionCS : SV_Position;
#if NEED_TANGENT_TO_WORLD
float4 interpolators[4] : TEXCOORD0;
#else
float4 interpolators[2] : TEXCOORD0;
#endif
};
// Function to pack data to use as few interpolator as possible, the ShaderGraph should generate these functions
PackedVaryings PackVaryings(Varyings input)
{
PackedVaryings output;
output.positionCS = input.positionCS;
output.interpolators[0] = float4(input.positionWS, 0.0);
output.interpolators[0].w = input.texCoord0.x;
output.interpolators[1] = float4(0.0, 0.0, 0.0, input.texCoord0.y);
#if NEED_TANGENT_TO_WORLD
output.interpolators[1].xyz = input.tangentToWorld[0];
output.interpolators[2].xyz = input.tangentToWorld[1];
output.interpolators[3].xyz = input.tangentToWorld[2];
#endif
return output;
}
FragInputs UnpackVaryings(PackedVaryings input)
{
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS; // input.positionCS is SV_Position
output.positionWS = input.interpolators[0].xyz;
#if NEED_TANGENT_TO_WORLD
output.texCoord0.xy = float2(input.interpolators[0].w, input.interpolators[1].w);
output.tangentToWorld[0] = input.interpolators[1].xyz;
output.tangentToWorld[1] = input.interpolators[2].xyz;
output.tangentToWorld[2] = input.interpolators[3].xyz;
#endif
return output;
}
PackedVaryings Vert(Attributes input)
{
Varyings output;
output.positionWS = TransformObjectToWorld(input.positionOS);
// TODO deal with camera center rendering and instancing (This is the reason why we always perform tow steps transform to clip space + instancing matrix)
output.positionCS = TransformWorldToHClip(output.positionWS);
output.texCoord0 = input.uv0;
#if NEED_TANGENT_TO_WORLD
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
float3x3 tangentToWorld = CreateTangentToWorld(normalWS, tangentWS.xyz, tangentWS.w);
output.tangentToWorld[0] = tangentToWorld[0];
output.tangentToWorld[1] = tangentToWorld[1];
output.tangentToWorld[2] = tangentToWorld[2];
#endif
return PackVaryings(output);
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDistortionPass.hlsl.meta


fileFormatVersion: 2
guid: a89db0bb66712eb4287e14bbafacfa15
timeCreated: 1481762668
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings.meta


fileFormatVersion: 2
guid: 1b5e87e98ef1994498478f60a6dcdd65
folderAsset: yes
timeCreated: 1481725797
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

23
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDistortion.hlsl


#if SHADERPASS != SHADERPASS_DISTORTION
#error SHADERPASS_is_not_correctly_define
#endif
float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
// Perform alpha testing + get distortion
SurfaceData surfaceData;
BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
float4 outBuffer;
EncodeDistortion(builtinData.distortion, builtinData.distortionBlur, outBuffer);
return outBuffer;
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDistortion.hlsl.meta


fileFormatVersion: 2
guid: b6e11447d75c89a4e99bee65db7c78f5
timeCreated: 1481762668
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky.meta


fileFormatVersion: 2
guid: 3dc75ec23ead9c94fa152d2c7c33aee4
folderAsset: yes
timeCreated: 1481626018
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky.meta


fileFormatVersion: 2
guid: 65f9231eb40b6914eb24ea0b555778f0
folderAsset: yes
timeCreated: 1481646017
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

437
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Serializable]
public enum SkyResolution
{
SkyResolution128 = 128,
SkyResolution256 = 256,
SkyResolution512 = 512,
SkyResolution1024 = 1024,
// TODO: Anything above 1024 cause a crash in Unity...
//SkyResolution2048 = 2048,
//SkyResolution4096 = 4096
}
public enum EnvironementUpdateMode
{
OnChanged = 0,
OnDemand,
Realtime
}
public class BuiltinSkyParameters
{
public Matrix4x4 viewProjMatrix;
public Matrix4x4 invViewProjMatrix;
public Vector4 screenSize;
public Mesh skyMesh;
public RenderLoop renderLoop;
public Light sunLight;
}
public class SkyManager
{
RenderTexture m_SkyboxCubemapRT = null;
RenderTexture m_SkyboxGGXCubemapRT = null;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceCameraViewProjectionMatrix = new Matrix4x4[6];
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];
BuiltinSkyParameters m_BuiltinParameters = new BuiltinSkyParameters();
SkyRenderer m_Renderer = null;
int m_SkyParametersHash = 0;
bool m_NeedLowLevelUpdateEnvironment = false;
bool m_UpdateRequired = true;
float m_CurrentUpdateTime = 0.0f;
SkyParameters m_SkyParameters = null;
public SkyParameters skyParameters
{
set
{
if(m_Renderer != null)
{
if (value == null || IsSkyParameterValid(value))
{
m_SkyParametersHash = 0;
m_SkyParameters = value;
m_UpdateRequired = true;
}
else
{
Debug.LogWarning("Sky renderer needs an instance of " + GetSkyParameterType().ToString() + " to be able to render.");
}
}
}
get { return m_SkyParameters; }
}
public void InstantiateSkyRenderer(Type skyRendererType)
{
if(skyRendererType == null)
{
m_Renderer = null;
}
else if (m_Renderer == null || m_Renderer.GetType() != skyRendererType)
{
m_Renderer = Activator.CreateInstance(skyRendererType) as SkyRenderer;
m_Renderer.Build();
}
}
protected Mesh BuildSkyMesh(Vector3 cameraPosition, Matrix4x4 cameraInvViewProjectionMatrix, bool forceUVBottom)
{
Vector4 vertData0 = new Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData1 = new Vector4(1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData2 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 vertData3 = new Vector4(-1.0f, 1.0f, 1.0f, 1.0f);
Vector3[] vertData = new Vector3[4];
vertData[0] = new Vector3(vertData0.x, vertData0.y, vertData0.z);
vertData[1] = new Vector3(vertData1.x, vertData1.y, vertData1.z);
vertData[2] = new Vector3(vertData2.x, vertData2.y, vertData2.z);
vertData[3] = new Vector3(vertData3.x, vertData3.y, vertData3.z);
// Get view vector based on the frustum, i.e (invert transform frustum get position etc...)
Vector3[] eyeVectorData = new Vector3[4];
Matrix4x4 transformMatrix = cameraInvViewProjectionMatrix;
Vector4 posWorldSpace0 = transformMatrix * vertData0;
Vector4 posWorldSpace1 = transformMatrix * vertData1;
Vector4 posWorldSpace2 = transformMatrix * vertData2;
Vector4 posWorldSpace3 = transformMatrix * vertData3;
Vector4 cameraPos = new Vector4(cameraPosition.x, cameraPosition.y, cameraPosition.z, 0.0f);
Vector4 direction0 = (posWorldSpace0 / posWorldSpace0.w - cameraPos);
Vector4 direction1 = (posWorldSpace1 / posWorldSpace1.w - cameraPos);
Vector4 direction2 = (posWorldSpace2 / posWorldSpace2.w - cameraPos);
Vector4 direction3 = (posWorldSpace3 / posWorldSpace3.w - cameraPos);
if (SystemInfo.graphicsUVStartsAtTop && !forceUVBottom)
{
eyeVectorData[3] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[2] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[1] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[0] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
else
{
eyeVectorData[0] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[1] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[2] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[3] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
// Write out the mesh
var triangles = new int[6] { 0, 1, 2, 2, 3, 0 };
return new Mesh
{
vertices = vertData,
normals = eyeVectorData,
triangles = triangles
};
}
void RebuildTextures(SkyParameters skyParameters)
{
int resolution = 256;
// Parameters not set yet. We need them for the resolution.
if (skyParameters != null)
resolution = (int)skyParameters.resolution;
if ((m_SkyboxCubemapRT != null) && (m_SkyboxCubemapRT.width != resolution))
{
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
m_UpdateRequired = true; // Special case. Even if update mode is set to OnDemand, we need to regenerate the environment after destroying the texture.
}
if (m_SkyboxCubemapRT == null)
{
m_SkyboxCubemapRT = new RenderTexture(resolution, resolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true; // Generate regular mipmap for filtered importance sampling
m_SkyboxCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxCubemapRT.Create();
m_SkyboxGGXCubemapRT = new RenderTexture(resolution, resolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxGGXCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxGGXCubemapRT.useMipMap = true;
m_SkyboxGGXCubemapRT.autoGenerateMips = false;
m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT.Create();
}
m_CubemapScreenSize = new Vector4((float)resolution, (float)resolution, 1.0f / (float)resolution, 1.0f / (float)resolution);
}
void RebuildSkyMeshes()
{
if(m_CubemapFaceMesh[0] == null)
{
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, 0.1f, 1.0f);
Vector3[] lookAtList = {
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] UpVectorList = {
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
for (int i = 0; i < 6; ++i)
{
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], UpVectorList[i]);
m_faceCameraViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj);
m_faceCameraInvViewProjectionMatrix[i] = m_faceCameraViewProjectionMatrix[i].inverse;
// When rendering into a texture the render will be flip (due to legacy unity openGL behavior), so we need to flip UV here...
m_CubemapFaceMesh[i] = BuildSkyMesh(Vector3.zero, m_faceCameraInvViewProjectionMatrix[i], true);
}
}
}
// Sets the global MIP-mapped cubemap '_SkyTexture' in the shader.
// The texture being set is the sky (environment) map pre-convolved with GGX.
public void SetGlobalSkyTexture()
{
Shader.SetGlobalTexture("_SkyTexture", m_SkyboxGGXCubemapRT);
}
public void Resize()
{
// When loading RenderDoc, RenderTextures will go null
RebuildTextures(skyParameters);
RebuildSkyMeshes();
}
public void Build()
{
if (m_Renderer != null)
m_Renderer.Build();
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_GGXConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/GGXConvolve");
m_CurrentUpdateTime = 0.0f;
}
public void Cleanup()
{
Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_GGXConvolveMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
if(m_Renderer != null)
m_Renderer.Cleanup();
}
public bool IsSkyValid()
{
return m_Renderer != null && m_Renderer.IsParameterValid(skyParameters) && m_Renderer.IsSkyValid(skyParameters);
}
private void RenderSkyToCubemap(BuiltinSkyParameters builtinParams, SkyParameters skyParameters, RenderTexture target)
{
for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(builtinParams.renderLoop, target, ClearFlag.ClearNone, 0, (CubemapFace)i);
builtinParams.invViewProjMatrix = m_faceCameraInvViewProjectionMatrix[i];
builtinParams.viewProjMatrix = m_faceCameraViewProjectionMatrix[i];
builtinParams.screenSize = m_CubemapScreenSize;
builtinParams.skyMesh = m_CubemapFaceMesh[i];
m_Renderer.RenderSky(builtinParams, skyParameters);
}
}
private void RenderCubemapGGXConvolution(RenderLoop renderLoop, BuiltinSkyParameters builtinParams, SkyParameters skyParams, Texture input, RenderTexture target)
{
using (new Utilities.ProfilingSample("Sky Pass: GGX Convolution", renderLoop))
{
int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f);
if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1))
{
Debug.LogWarning("RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ((int)EnvConstants.SpecCubeLodStep + 1) + " mip levels");
return;
}
// Copy the first mip.
// WARNING:
// Since we can't instanciate the parameters anymore (we don't know the final type here)
// we can't make sure that exposure/multiplier etc are at neutral values
// This will be solved with proper CopyTexture
// TEMP code until CopyTexture is implemented for command buffer
// All parameters are neutral because exposure/multiplier have already been applied in the first copy.
//SkyParameters skyParams = new SkyParameters();
//skyParams.exposure = 0.0f;
//skyParams.multiplier = 1.0f;
//skyParams.rotation = 0.0f;
//skyParams.skyHDRI = input;
RenderSkyToCubemap(builtinParams, skyParams, target);
// End temp
//for (int f = 0; f < 6; f++)
// Graphics.CopyTexture(input, f, 0, target, f, 0);
// Do the convolution on remaining mipmaps
float invOmegaP = (6.0f * input.width * input.width) / (4.0f * Mathf.PI); // Solid angle associated to a pixel of the cubemap;
m_GGXConvolveMaterial.SetTexture("_MainTex", input);
m_GGXConvolveMaterial.SetFloat("_MipMapCount", mipCount);
m_GGXConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
{
Utilities.SetRenderTarget(renderLoop, target, ClearFlag.ClearNone, mip, (CubemapFace)face);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(m_CubemapFaceMesh[face], Matrix4x4.identity, m_GGXConvolveMaterial, 0, 0, propertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}
}
public bool IsSkyParameterValid(SkyParameters parameters)
{
return m_Renderer != null && m_Renderer.IsParameterValid(parameters);
}
public Type GetSkyParameterType()
{
return (m_Renderer == null) ? null : m_Renderer.GetSkyParameterType();
}
public void RequestEnvironmentUpdate()
{
m_UpdateRequired = true;
}
public void UpdateEnvironment(HDRenderLoop.HDCamera camera, Light sunLight, RenderLoop renderLoop)
{
{
using (new Utilities.ProfilingSample("Sky Environment Pass", renderLoop))
{
if (IsSkyValid())
{
m_CurrentUpdateTime += Time.deltaTime;
m_BuiltinParameters.renderLoop = renderLoop;
m_BuiltinParameters.sunLight = sunLight;
// We need one frame delay for this update to work since DynamicGI.UpdateEnvironment is executed direclty but the renderloop is not (so we need to wait for the sky texture to be rendered first)
if (m_NeedLowLevelUpdateEnvironment)
{
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
RenderSettings.customReflection = null;
DynamicGI.UpdateEnvironment();
m_NeedLowLevelUpdateEnvironment = false;
}
if (
(skyParameters.updateMode == EnvironementUpdateMode.OnDemand && m_UpdateRequired) ||
(skyParameters.updateMode == EnvironementUpdateMode.OnChanged && skyParameters.GetHash() != m_SkyParametersHash) ||
(skyParameters.updateMode == EnvironementUpdateMode.Realtime && m_CurrentUpdateTime > skyParameters.updatePeriod)
)
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap(m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT);
// Convolve downsampled cubemap
RenderCubemapGGXConvolution(renderLoop, m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT);
m_NeedLowLevelUpdateEnvironment = true;
m_UpdateRequired = false;
m_SkyParametersHash = skyParameters.GetHash();
m_CurrentUpdateTime = 0.0f;
}
}
else
{
// Disabled for now.
// We need to remove RenderSkyToCubemap from the RenderCubemapGGXConvolution first as it needs the skyparameter to be valid.
//if(m_SkyParametersHash != 0)
//{
// // Clear sky light probe
// RenderSettings.skybox = null;
// RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
// RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
// RenderSettings.reflectionIntensity = 1.0f;
// RenderSettings.customReflection = null;
// DynamicGI.UpdateEnvironment();
// // Clear temp cubemap and redo GGX from black
// Utilities.SetRenderTarget(renderLoop, m_SkyboxCubemapRT, ClearFlag.ClearColor);
// RenderCubemapGGXConvolution(renderLoop, m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT);
// m_SkyParametersHash = 0;
//}
}
}
}
}
public void RenderSky(HDRenderLoop.HDCamera camera, Light sunLight, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
{
if (IsSkyValid())
{
m_BuiltinParameters.renderLoop = renderLoop;
m_BuiltinParameters.sunLight = sunLight;
m_BuiltinParameters.invViewProjMatrix = camera.invViewProjectionMatrix;
m_BuiltinParameters.viewProjMatrix = camera.viewProjectionMatrix;
m_BuiltinParameters.screenSize = camera.screenSize;
m_BuiltinParameters.skyMesh = BuildSkyMesh(camera.camera.GetComponent<Transform>().position, m_BuiltinParameters.invViewProjMatrix, false);
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
m_Renderer.RenderSky(m_BuiltinParameters, skyParameters);
}
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs.meta


fileFormatVersion: 2
guid: 8bd4c656fd5e14747b942575f2e7e185
timeCreated: 1481626426
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

71
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System.Linq;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[ExecuteInEditMode]
public class SkyParameters : MonoBehaviour
{
protected class Unhashed : System.Attribute {}
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;
public SkyResolution resolution = SkyResolution.SkyResolution256;
public EnvironementUpdateMode updateMode = EnvironementUpdateMode.OnChanged;
public float updatePeriod = 0.0f;
private FieldInfo[] m_Properties;
protected void OnEnable()
{
HDRenderLoop renderLoop = Utilities.GetHDRenderLoop();
if (renderLoop == null)
{
return;
}
// Enumerate properties in order to compute the hash more quickly later on.
m_Properties = GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.ToArray();
if (renderLoop.skyManager.skyParameters == null || renderLoop.skyManager.skyParameters.GetType() != this.GetType()) // We allow override of parameters only if the type is different. It means that we changed the Sky Renderer and might need a new set of parameters.
renderLoop.skyManager.skyParameters = this;
else if (renderLoop.skyManager.skyParameters != this && renderLoop.skyManager.skyParameters.GetType() == this.GetType())
Debug.LogWarning("Tried to setup another SkyParameters component although there is already one enabled.");
}
protected void OnDisable()
{
HDRenderLoop renderLoop = Utilities.GetHDRenderLoop();
if (renderLoop == null)
{
return;
}
// Reset the current sky parameter on the render loop
if (renderLoop.skyManager.skyParameters == this)
renderLoop.skyManager.skyParameters = null;
}
public int GetHash()
{
unchecked
{
int hash = 13;
foreach (var p in m_Properties)
{
bool unhashedAttribute = p.GetCustomAttributes(typeof(Unhashed), true).Length != 0;
System.Object obj = p.GetValue(this);
if (obj != null && !unhashedAttribute) // Sometimes it can be a null reference.
hash = hash * 23 + obj.GetHashCode();
}
return hash;
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs.meta


fileFormatVersion: 2
guid: be80eb13382d90f4cb2738f69185b60c
timeCreated: 1481734433
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

正在加载...
取消
保存