浏览代码

Merge branch 'master' into metal

/main
Antti Tapaninen 7 年前
当前提交
0574ef6b
共有 191 个文件被更改,包括 4604 次插入3357 次删除
  1. 75
      Assets/ScriptableRenderPipeline/Editor/MaterialUpgrader.cs
  2. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader
  3. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayShadowMap.shader
  4. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader
  5. 406
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
  6. 100
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  7. 30
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  8. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/UpgradeStandardShaderMaterials.cs
  9. 81
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset
  10. 23
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  11. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs
  12. 22
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Lighting.hlsl
  13. 17
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader
  14. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TileLightLoopProducer.cs
  15. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
  16. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  17. 925
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild.compute
  18. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/scrbound.compute
  19. 183
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute
  20. 1001
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  21. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  22. 74
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  23. 747
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  24. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassResources.asset
  25. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassResources.cs
  26. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Builtin/BuiltinData.hlsl
  27. 22
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  28. 24
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  29. 33
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  30. 17
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs
  31. 17
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs
  32. 33
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  33. 24
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  34. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  35. 24
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  36. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs
  37. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.GGX.cs
  38. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  39. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/PreIntegratedFGD.shader
  40. 18
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl
  41. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader
  42. 20
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Editor/PostProcessingSRPEditor.cs
  43. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/EyeAdaptation.shader
  44. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/EyeHistogram.compute
  45. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/FinalPass.shader
  46. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/LutGen.shader
  47. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessingSRP.cs
  48. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessingSRP.Settings.cs
  49. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawGaussianProfile.shader
  50. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader
  51. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/FragInputs.hlsl
  52. 3
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
  53. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs
  54. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader
  55. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader
  56. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/BuildProbabilityTables.compute
  57. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute
  58. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/GGXConvolve.shader
  59. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  60. 41
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  61. 157
      Assets/ScriptableRenderPipeline/common/Camera/CameraSwitcher.cs
  62. 102
      Assets/ScriptableRenderPipeline/common/Camera/FreeCamera.cs
  63. 191
      Assets/ScriptableRenderPipeline/common/Debugging.cs
  64. 415
      Assets/ScriptableRenderPipeline/common/SkyboxHelper.cs
  65. 689
      Assets/ScriptableRenderPipeline/common/TextureCache.cs
  66. 21
      Assets/ScriptableRenderPipeline/fptl/TiledLightingUtils.hlsl
  67. 7
      Assets/ScriptableRenderPipeline/fptl/lightlistbuild-clustered.compute
  68. 2
      Assets/ScriptableRenderPipeline/fptl/lightlistbuild.compute
  69. 196
      Assets/TestScenes/HDTest/CascadedShadowsTest.unity
  70. 49
      Assets/TestScenes/HDTest/GlobalIlluminationTest.unity
  71. 3
      Assets/TestScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Rock.mat
  72. 2
      Assets/TestScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat
  73. 42
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity
  74. 40
      Assets/TestScenes/HDTest/LayeredLitTest.unity
  75. 40
      Assets/TestScenes/HDTest/LayeredLitTest/Textures/Detail_Checker.tga.meta
  76. 4
      Assets/TestScenes/HDTest/Rock/rcgRock012/Materials/rcgRock012Material.mat
  77. 2
      ProjectSettings/ProjectVersion.txt
  78. 2
      ProjectSettings/QualitySettings.asset
  79. 9
      Assets/LowEndMobilePipeline.meta
  80. 9
      Assets/Plugins.meta
  81. 35
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset
  82. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset.meta
  83. 41
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/FeatureFlags.hlsl
  84. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/FeatureFlags.hlsl.meta
  85. 11
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/cleardispatchindirect.compute
  86. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/cleardispatchindirect.compute.meta
  87. 494
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  88. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.meta
  89. 9
      Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset.meta
  90. 145
      Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.cs
  91. 12
      Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.cs.meta
  92. 9
      Assets/LowEndMobilePipeline/TestScenes.meta
  93. 9
      Assets/LowEndMobilePipeline/Editor.meta
  94. 12
      Assets/LowEndMobilePipeline/LowEndMobilePipeline.cs.meta
  95. 1001
      Assets/LowEndMobilePipeline/TestScenes/LDRenderPipelineVikingVillage/LightingData.asset
  96. 8
      Assets/LowEndMobilePipeline/TestScenes/LDRenderPipelineVikingVillage/LightingData.asset.meta

75
Assets/ScriptableRenderPipeline/Editor/MaterialUpgrader.cs


{
public class MaterialUpgrader
{
public delegate void MaterialFinalizer(Material mat);
MaterialFinalizer m_Finalizer;
Dictionary<string, float> m_FloatPropertiesToSet = new Dictionary<string, float>();
Dictionary<string, Color> m_ColorPropertiesToSet = new Dictionary<string, Color>();
List<string> m_TexturesToRemove = new List<string>();
class KeywordFloatRename
{
public string keyword;
public string property;
public float setVal, unsetVal;
}
List<KeywordFloatRename> m_KeywordFloatRename = new List<KeywordFloatRename>();
[Flags]
public enum UpgradeFlags
{

LogMessageWhenNoUpgraderFound = 4
}
public void Upgrade(Material material, UpgradeFlags flags)

material.shader = Shader.Find(m_NewShader);
material.CopyPropertiesFromMaterial(newMaterial);
UnityEngine.Object.DestroyImmediate(newMaterial);
if(m_Finalizer != null)
m_Finalizer(material);
}
// Overridable function to implement custom material upgrading functionality

foreach (var t in m_ColorRename)
dstMaterial.SetColor(t.Value, srcMaterial.GetColor(t.Key));
foreach (var prop in m_TexturesToRemove)
dstMaterial.SetTexture(prop, null);
foreach (var prop in m_FloatPropertiesToSet)
dstMaterial.SetFloat(prop.Key, prop.Value);
foreach (var prop in m_ColorPropertiesToSet)
dstMaterial.SetColor(prop.Key, prop.Value);
foreach (var t in m_KeywordFloatRename)
dstMaterial.SetFloat(t.property, srcMaterial.IsKeywordEnabled(t.keyword) ? t.setVal : t.unsetVal);
public void RenameShader(string oldName, string newName)
public void RenameShader(string oldName, string newName, MaterialFinalizer finalizer = null)
m_Finalizer = finalizer;
}
public void RenameTexture(string oldName, string newName)

m_ColorRename[oldName] = newName;
}
public void RemoveTexture(string name)
{
m_TexturesToRemove.Add(name);
}
public void SetFloat(string propertyName, float value)
{
m_FloatPropertiesToSet[propertyName] = value;
}
public void SetColor(string propertyName, Color value)
{
m_ColorPropertiesToSet[propertyName] = value;
}
public void RenameKeywordToFloat(string oldName, string newName, float setVal, float unsetVal)
{
m_KeywordFloatRename.Add(new KeywordFloatRename { keyword = oldName, property = newName, setVal = setVal, unsetVal = unsetVal });
}
static bool IsMaterialPath(string path)
{
return path.EndsWith(".mat", StringComparison.OrdinalIgnoreCase);

AssetDatabase.Refresh();
}
public static void UpgradeProjectFolder(List<MaterialUpgrader> upgraders, string progressBarName)
public static void UpgradeProjectFolder(List<MaterialUpgrader> upgraders, string progressBarName, UpgradeFlags flags = UpgradeFlags.None)
if (!EditorUtility.DisplayDialog("Material Upgrader", "The upgrade will overwrite material settings in your project." +
"Be sure to have a project backup before proceeding", "Proceed", "Cancel"))
return;
int totalMaterialCount = 0;
foreach (string s in UnityEditor.AssetDatabase.GetAllAssetPaths())
{

break;
Material m = UnityEditor.AssetDatabase.LoadMainAssetAtPath(path) as Material;
Upgrade(m, upgraders, UpgradeFlags.None);
Upgrade(m, upgraders, flags);
//SaveAssetsAndFreeMemory();
}

public static void Upgrade(Material material, List<MaterialUpgrader> upgraders, UpgradeFlags flags)
{
var upgrader = GetUpgrader(upgraders, material);
else if ((flags & UpgradeFlags.LogMessageWhenNoUpgraderFound) == UpgradeFlags.LogMessageWhenNoUpgraderFound)
Debug.Log(string.Format("There's no upgrader to convert {0} shader to selected pipeline", material.shader.name));
public static void UpgradeSelection(List<MaterialUpgrader> upgraders, string progressBarName)
public static void UpgradeSelection(List<MaterialUpgrader> upgraders, string progressBarName, UpgradeFlags flags = UpgradeFlags.None)
var selection = Selection.objects;
if (!EditorUtility.DisplayDialog("Material Upgrader", string.Format("The upgrade will possibly overwrite all the {0} selected material settings", selection.Length) +
"Be sure to have a project backup before proceeding", "Proceed", "Cancel"))
return;
var selection = Selection.objects;
for (int i = 0; i < selection.Length; i++)
{

var material = selection[i] as Material;
Upgrade(material, upgraders, UpgradeFlags.None);
Upgrade(material, upgraders, flags);
if (material != null)
lastMaterialName = material.name;
}

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayLatlong.shader


#pragma vertex Vert
#pragma fragment Frag
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
TEXTURECUBE(_InputCubemap);
SAMPLERCUBE(sampler_InputCubemap);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugDisplayShadowMap.shader


#pragma vertex Vert
#pragma fragment Frag
#include "ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
TEXTURE2D_FLOAT(g_tShadowBuffer);

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader


#pragma vertex Vert
#pragma fragment Frag
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/Color.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/Debug/DebugViewMaterial.cs.hlsl"
#include "HDRenderPipeline/Material/Material.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../Debug/DebugViewMaterial.cs.hlsl"
#include "../../Material/Material.hlsl"
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);

406
Assets/ScriptableRenderPipeline/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader


Shader "Hidden/HDRenderPipeline/DebugViewTiles"
{
SubShader
{
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag
#define LIGHTLOOP_TILE_PASS
#define LIGHTLOOP_TILE_ALL
#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/Common.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
uint _ViewTilesFlags;
float2 _MousePixelCoord;
float4 Vert(float3 positionOS : POSITION): SV_POSITION
{
return TransformWorldToHClip(TransformObjectToWorld(positionOS));
}
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)
{
const float4 kRadarColors[12] =
{
float4(0.0, 0.0, 0.0, 0.0), // black
float4(0.0, 0.0, 0.6, 0.5), // dark blue
float4(0.0, 0.0, 0.9, 0.5), // blue
float4(0.0, 0.6, 0.9, 0.5), // light blue
float4(0.0, 0.9, 0.9, 0.5), // cyan
float4(0.0, 0.9, 0.6, 0.5), // blueish green
float4(0.0, 0.9, 0.0, 0.5), // green
float4(0.6, 0.9, 0.0, 0.5), // yellowish green
float4(0.9, 0.9, 0.0, 0.5), // yellow
float4(0.9, 0.6, 0.0, 0.5), // orange
float4(0.9, 0.0, 0.0, 0.5), // red
float4(1.0, 0.0, 0.0, 0.9) // strong red
};
float maxNrLightsPerTile = 31; // TODO: setup a constant for that
int colorIndex = numLights == 0 ? 0 : (1 + (int)floor(10 * (log2((float)numLights) / log2(maxNrLightsPerTile))));
colorIndex = colorIndex < 0 ? 0 : colorIndex;
float4 col = colorIndex > 11 ? float4(1.0, 1.0, 1.0, 1.0) : kRadarColors[colorIndex];
int2 coord = pixCoord - int2(1, 1);
float4 color = float4(PositivePow(col.xyz, 2.2), 0.3 * col.w);
if (numLights > 0)
{
if (SampleDebugFontNumber(coord, numLights)) // Shadow
color = float4(0, 0, 0, 1);
if (SampleDebugFontNumber(coord + 1, numLights)) // Text
color = float4(1, 1, 1, 1);
}
return color;
}
float4 Frag(float4 positionCS : SV_POSITION) : SV_Target
{
// positionCS is SV_Position
PositionInputs posInput = GetPositionInput(positionCS.xy, _ScreenSize.zw, uint2(positionCS.xy) / GetTileSize());
float depth = LOAD_TEXTURE2D(_MainDepthTexture, 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 mask = 1u << category;
if (mask & _ViewTilesFlags)
{
uint start;
uint count;
GetCountAndStart(posInput, category, start, count);
n += count;
}
}
float4 result = float4(0.0, 0.0, 0.0, 0.0);
// Tile overlap counter
if (n > 0)
{
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);
}
// Print light lists for selected tile at the bottom of the screen
int maxLights = 32;
if (tileCoord.y < LIGHTCATEGORY_COUNT && tileCoord.x < maxLights + 3)
{
PositionInputs mousePosInput = GetPositionInput(_MousePixelCoord, _ScreenSize.zw, uint2(0,0));
float depthMouse = LOAD_TEXTURE2D(_MainDepthTexture, mousePosInput.unPositionSS).x;
UpdatePositionInput(depthMouse, _InvViewProjMatrix, _ViewProjMatrix, mousePosInput);
uint category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;
uint start;
uint 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 = (int)count;
}
else if(lightListIndex >= 0 && lightListIndex < (int)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
}
}
Fallback Off
}
Shader "Hidden/HDRenderPipeline/DebugViewTiles"
{
SubShader
{
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag
#define LIGHTLOOP_TILE_PASS
#define LIGHTLOOP_TILE_ALL
#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#pragma multi_compile SHOW_LIGHT_CATEGORIES SHOW_FEATURE_VARIANTS
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../ShaderLibrary/Common.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
uint _ViewTilesFlags;
uint _NumTiles;
float2 _MousePixelCoord;
StructuredBuffer<uint> g_TileList;
Buffer<uint> g_DispatchIndirectBuffer;
struct VSOut
{
float4 Pos : SV_POSITION;
int Variant : TEXCOORD0;
};
#if SHOW_FEATURE_VARIANTS
VSOut Vert(uint vertexID : SV_VertexID)
{
uint quadIndex = vertexID / 6;
uint quadVertex = vertexID - quadIndex * 6;
quadVertex = (0x312210 >> (quadVertex<<2)) & 3; //remap [0,5]->[0,3]
uint2 tileSize = GetTileSize();
uint variant = 0;
while (quadIndex >= g_DispatchIndirectBuffer[variant * 3 + 0] && variant < NUM_FEATURE_VARIANTS)
{
quadIndex -= g_DispatchIndirectBuffer[variant * 3 + 0];
variant++;
}
uint tileIndex = g_TileList[variant * _NumTiles + quadIndex];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = (tileCoord + uint2((quadVertex+1) & 1, (quadVertex >> 1) & 1)) * tileSize;
float2 clipCoord = (pixelCoord / _ScreenParams.xy) * 2.0 - 1.0;
clipCoord.y *= -1;
VSOut Out;
Out.Pos = float4(clipCoord, 0, 1.0);
Out.Variant = variant;
return Out;
}
#else
VSOut Vert(float3 positionOS : POSITION)
{
VSOut Out;
Out.Pos = TransformWorldToHClip(TransformObjectToWorld(positionOS));
Out.Variant = 0;
return Out;
}
#endif
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 n)
{
const float4 kRadarColors[12] =
{
float4(0.0, 0.0, 0.0, 0.0), // black
float4(0.0, 0.0, 0.6, 0.5), // dark blue
float4(0.0, 0.0, 0.9, 0.5), // blue
float4(0.0, 0.6, 0.9, 0.5), // light blue
float4(0.0, 0.9, 0.9, 0.5), // cyan
float4(0.0, 0.9, 0.6, 0.5), // blueish green
float4(0.0, 0.9, 0.0, 0.5), // green
float4(0.6, 0.9, 0.0, 0.5), // yellowish green
float4(0.9, 0.9, 0.0, 0.5), // yellow
float4(0.9, 0.6, 0.0, 0.5), // orange
float4(0.9, 0.0, 0.0, 0.5), // red
float4(1.0, 0.0, 0.0, 0.9) // strong red
};
float maxNrLightsPerTile = 31; // TODO: setup a constant for that
int colorIndex = n == 0 ? 0 : (1 + (int)floor(10 * (log2((float)n) / log2(maxNrLightsPerTile))));
colorIndex = colorIndex < 0 ? 0 : colorIndex;
float4 col = colorIndex > 11 ? float4(1.0, 1.0, 1.0, 1.0) : kRadarColors[colorIndex];
int2 coord = pixCoord - int2(1, 1);
float4 color = float4(PositivePow(col.xyz, 2.2), 0.3 * col.w);
if (n >= 0)
{
if (SampleDebugFontNumber(coord, n)) // Shadow
color = float4(0, 0, 0, 1);
if (SampleDebugFontNumber(coord + 1, n)) // Text
color = float4(1, 1, 1, 1);
}
return color;
}
float4 Frag(float4 positionCS : SV_POSITION, int Variant : TEXCOORD0) : SV_Target
{
// positionCS is SV_Position
PositionInputs posInput = GetPositionInput(positionCS.xy, _ScreenSize.zw, uint2(positionCS.xy) / GetTileSize());
float depth = LOAD_TEXTURE2D(_MainDepthTexture, 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;
#ifdef SHOW_LIGHT_CATEGORIES
for (int category = 0; category < LIGHTCATEGORY_COUNT; category++)
{
uint mask = 1u << category;
if (mask & _ViewTilesFlags)
{
uint start;
uint count;
GetCountAndStart(posInput, category, start, count);
n += count;
}
}
if(n == 0) n = -1;
#else
n = Variant;
#endif
float4 result = float4(0.0, 0.0, 0.0, 0.0);
// Tile overlap counter
if (n >= 0)
{
result = OverlayHeatMap(int2(posInput.unPositionSS.xy) & (TILE_SIZE - 1), n);
}
#ifdef SHOW_LIGHT_CATEGORIES
// 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);
}
// Print light lists for selected tile at the bottom of the screen
int maxLights = 32;
if (tileCoord.y < LIGHTCATEGORY_COUNT && tileCoord.x < maxLights + 3)
{
PositionInputs mousePosInput = GetPositionInput(_MousePixelCoord, _ScreenSize.zw, uint2(0,0));
float depthMouse = LOAD_TEXTURE2D(_MainDepthTexture, mousePosInput.unPositionSS).x;
UpdatePositionInput(depthMouse, _InvViewProjMatrix, _ViewProjMatrix, mousePosInput);
uint category = (LIGHTCATEGORY_COUNT - 1) - tileCoord.y;
uint start;
uint 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 = (int)count;
}
else if(lightListIndex >= 0 && lightListIndex < (int)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);
}
#endif
return result;
}
ENDHLSL
}
}
Fallback Off
}

100
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


public readonly GUIContent shadowsAtlasWidth = new GUIContent("Atlas width");
public readonly GUIContent shadowsAtlasHeight = new GUIContent("Atlas height");
// Subsurface Scaterring Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SubsurfaceScatteringSettings.maxNumProfiles] { new GUIContent("Profile #0"), new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"), new GUIContent("Profile #6"), new GUIContent("Profile #7") };
public readonly GUIContent sssProfilePreview0 = new GUIContent("Profile preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as radius increases to 1.");
public readonly GUIContent sssProfilePreview2 = new GUIContent("Note that the intensity of the region in the center may be clamped.");
public readonly GUIContent sssTransmittancePreview0 = new GUIContent("Transmittance preview");
public readonly GUIContent sssTransmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object as thickness increases to 1.");
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
public readonly GUIContent sssProfileStdDev1 = new GUIContent("Standard deviation #1", "Determines the shape of the 1st Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileStdDev2 = new GUIContent("Standard deviation #2", "Determines the shape of the 2nd Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileLerpWeight = new GUIContent("Filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssProfileTransmission = new GUIContent("Enable transmission", "Toggles simulation of light passing through thin objects. Depends on the thickness of the material.");
public readonly GUIContent sssProfileThicknessRemap = new GUIContent("Thickness remap", "Remaps the thickness parameter from [0, 1] to the desired range.");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing mode", "Specifies when the diffuse texture should be applied.");
// Subsurface Scattering Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SubsurfaceScatteringSettings.maxNumProfiles] { new GUIContent("Profile #0"), new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"), new GUIContent("Profile #6"), new GUIContent("Profile #7") };
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing mode", "Specifies when the diffuse texture should be applied.");
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);
// Tile pass Settings
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop Settings");

public readonly GUIContent lightingDebugAlbedo = new GUIContent("Lighting Debug Albedo");
public readonly GUIContent lightingDisplaySkyReflection = new GUIContent("Display Sky Reflection");
public readonly GUIContent lightingDisplaySkyReflectionMipmap = new GUIContent("Reflection Mipmap");
public Styles()
{
centeredMiniBoldLabel.alignment = TextAnchor.MiddleCenter;
centeredMiniBoldLabel.fontSize = 10;
centeredMiniBoldLabel.fontStyle = FontStyle.Bold;
}
}
private static Styles s_Styles = null;

SerializedProperty m_Profiles = null;
SerializedProperty m_NumProfiles = null;
// Subsurface Scattering internal data
private Material m_ProfileMaterial, m_TransmittanceMaterial;
private RenderTexture[] m_ProfileImages, m_TransmittanceImages;
private void InitializeProperties()
{
// Global debug

// Subsurface Scattering Settings
m_TexturingMode = FindProperty(x => x.sssSettings.texturingMode);
m_Profiles = FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
void InitializeSSS()
{
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_TransmittanceMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileImages = new RenderTexture[SubsurfaceScatteringSettings.maxNumProfiles];
m_TransmittanceImages = new RenderTexture[SubsurfaceScatteringSettings.maxNumProfiles];
for (int i = 0; i < SubsurfaceScatteringSettings.maxNumProfiles; i++)
{
m_ProfileImages[i] = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImages[i] = new RenderTexture(16, 256, 0, RenderTextureFormat.DefaultHDR);
}
m_Profiles = FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
SerializedProperty FindProperty<TValue>(Expression<Func<HDRenderPipeline, TValue>> expr)

{
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.sssProfiles[i]);
if (profile.isExpanded)
{
EditorGUI.indentLevel++;
SerializedProperty profileStdDev1 = profile.FindPropertyRelative("stdDev1");
SerializedProperty profileStdDev2 = profile.FindPropertyRelative("stdDev2");
SerializedProperty profileLerpWeight = profile.FindPropertyRelative("lerpWeight");
SerializedProperty profileTransmission = profile.FindPropertyRelative("enableTransmission");
SerializedProperty profileThicknessRemap = profile.FindPropertyRelative("thicknessRemap");
EditorGUILayout.PropertyField(profileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(profileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(profileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(profileTransmission, styles.sssProfileTransmission);
Vector2 thicknessRemap = profileThicknessRemap.vector2Value;
EditorGUILayout.LabelField("Min thickness: ", thicknessRemap.x.ToString());
EditorGUILayout.LabelField("Max thickness: ", thicknessRemap.y.ToString());
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
profileThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssProfilePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImages[i], m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", profileThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImages[i], m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
}
EditorGUI.indentLevel--;

public void OnEnable()
{
InitializeProperties();
InitializeSSS();
}
public override void OnInspectorGUI()

30
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs


EditorUtility.ClearProgressBar();
}
}
[MenuItem("HDRenderPipeline/Debug/Remove tessellation materials (not reversible)")]
static void RemoveTessellationMaterials()
{
Object[] materials = Resources.FindObjectsOfTypeAll<Material>();
Shader litShader = Shader.Find("HDRenderPipeline/Lit");
Shader layeredLitShader = Shader.Find("HDRenderPipeline/LayeredLit");
foreach (Object obj in materials)
{
Material mat = obj as Material;
if (mat.shader.name == "HDRenderPipeline/LitTessellation")
{
mat.shader = litShader;
// We remove all keyword already present
RemoveMaterialKeywords(mat);
LitGUI.SetupMaterialKeywordsAndPass(mat);
EditorUtility.SetDirty(mat);
}
else if (mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
{
mat.shader = layeredLitShader;
// We remove all keyword already present
RemoveMaterialKeywords(mat);
LayeredLitGUI.SetupMaterialKeywordsAndPass(mat);
EditorUtility.SetDirty(mat);
}
}
}
}
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/UpgradeStandardShaderMaterials.cs


namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class UpgradeStandardShaderMaterials
public class UpgradeStandardShaderMaterials
upgraders.Add(new StandardToHDLitMaterialUpgrader());
upgraders.Add(new StandardSpecularToHDLitMaterialUpgrader());
upgraders.Add(new StandardToHDLitMaterialUpgrader("Standard", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass));
upgraders.Add(new StandardSpecularToHDLitMaterialUpgrader("Standard (Specular setup)", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass));
return upgraders;
}

81
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset


type: 2}
globalDebugSettings:
debugOverlayRatio: 0.33
displayMaterialDebug: 0
displayRenderingDebug: 0
displayMaterialDebug: 1
displayRenderingDebug: 1
displayLightingDebug: 0
materialDebugSettings:
debugViewMaterial: 0

overrideSmoothness: 0
overrideSmoothnessValue: 0.5
debugLightingAlbedo: {r: 0.5, g: 0.5, b: 0.5, a: 1}
displaySkyReflection: 0
skyReflectionMipmap: 0
renderingDebugSettings:
displayOpaqueObjects: 1
displayTransparentObjects: 1

useDepthPrepass: 0
sssSettings:
numProfiles: 1
texturingMode: 0
- stdDev1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
stdDev2: {r: 0.6, g: 0.6, b: 0.6, a: 0}
lerpWeight: 0.5
enableTransmission: 0
thicknessRemap: {x: 0, y: 3}
m_FilterKernel:
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.6594821}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.3561445}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.000000048879357}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.35614443}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.659482}
m_HalfRcpVariances:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888}
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {fileID: 11400000, guid: 09521380d86baee43bf09b32473ea5f3, type: 2}
- 3
- 0
- 1
- 1
- 0
- 0
- 0

- 0
- 0
halfRcpVariancesAndLerpWeights:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553, w: 0.5}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888, w: 0.5}
- {x: 5.5555553, y: 5.5555553, z: 5.5555553, w: 0.5}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888, w: 0.5}
- {x: 0, y: 0, z: 0, w: 0}

- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
halfRcpWeightedVariances:
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
halfRcpWeightedVariances:
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
filterKernels:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.7609476}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.49358216}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.4935822}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.7609475}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.7609476}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.49358216}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.4935822}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.7609475}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}

- {x: 0, y: 0, z: 0, w: 0}
filterKernels:
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.6594821}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.3561445}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: -0.000000048879357}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.16454786}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.35614443}
- {x: 0.14285715, y: 0.14285715, z: 0.14285715, w: 0.659482}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}

23
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


public SubsurfaceScatteringSettings sssSettings = new SubsurfaceScatteringSettings();
[SerializeField]
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
[SerializeField] TextureSettings m_TextureSettings = TextureSettings.Default;
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
[SerializeField]
TextureSettings m_TextureSettings = TextureSettings.Default;
public ShadowSettings shadowSettings { get { return m_ShadowSettings; } }
public TextureSettings textureSettings { get { return m_TextureSettings; } set { m_TextureSettings = value; } }

return m_SkySettings;
}
}
public void ApplyDebugSettings()
{
m_ShadowSettings.enabled = globalDebugSettings.lightingDebugSettings.enableShadows;

get { return m_Owner.globalDebugSettings; }
}
public SubsurfaceScatteringSettings sssSettings
{
get { return m_Owner.sssSettings; }
}
public HDRenderPipelineInstance(HDRenderPipeline owner)
{
m_Owner = owner;

cmd.SetGlobalMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
cmd.SetGlobalVector("_InvProjParam", hdCamera.invProjectionParam);
// TODO: setting the Sky Settings to 'None' appears to do nothing (so no invalidation happens).
// TODO: cmd.SetGlobalInt() does not exist, so we are forced to use Shader.SetGlobalInt() instead.
Shader.EnableKeyword("SKY_LIGHTING");
Shader.SetGlobalInt("_EnvLightSkyEnabled", 1);
Shader.DisableKeyword("SKY_LIGHTING");
Shader.SetGlobalInt("_EnvLightSkyEnabled", 0);
}
// Broadcast SSS parameters to all shaders.

renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
if (m_LightLoop != null)
m_LightLoop.PushGlobalParams(hdCamera.camera, renderContext);
}
bool NeedDepthBufferCopy()

// All of this is temporary, sub-optimal and quickly hacked together but is necessary
// for artists to do lighting work until the fully-featured framework is ready
var localPostProcess = camera.GetComponent<PostProcessing>();
var localPostProcess = camera.GetComponent<PostProcessingSRP>();
bool localActive = localPostProcess != null && localPostProcess.enabled;

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs


// TODO: this should not be part of the interface but for now make something working
public virtual void BuildGPULightLists(Camera camera, ScriptableRenderContext loop, RenderTargetIdentifier cameraDepthBufferRT) { }
public virtual void PushGlobalParams(Camera camera, ScriptableRenderContext loop) {}
public virtual void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
LightingDebugSettings lightDebugParameters,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,

22
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Lighting.hlsl


#ifndef UNITY_LIGHTING_INCLUDED
#define UNITY_LIGHTING_INCLUDED
#include "ShaderLibrary/CommonLighting.hlsl"
#include "ShaderLibrary/CommonShadow.hlsl"
#include "ShaderLibrary/Sampling.hlsl"
#include "ShaderLibrary/AreaLighting.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../ShaderLibrary/CommonLighting.hlsl"
#include "../../ShaderLibrary/CommonShadow.hlsl"
#include "../../ShaderLibrary/Sampling.hlsl"
#include "../../ShaderLibrary/AreaLighting.hlsl"
#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
// The light loop (or lighting architecture) is in charge to:
// - Define light list

#define HAS_LIGHTLOOP // Allow to not define LightLoop related function in Material.hlsl
#include "HDRenderPipeline/Lighting/LightDefinition.cs.hlsl"
#include "HDRenderPipeline/Lighting/LightUtilities.hlsl"
#include "../Lighting/LightDefinition.cs.hlsl"
#include "../Lighting/LightUtilities.hlsl"
#include "HDRenderPipeline/Shadow/Shadow.hlsl"
#include "../Shadow/Shadow.hlsl"
#include "HDRenderPipeline/Lighting/TilePass/TilePass.hlsl"
#include "../Lighting/TilePass/TilePass.hlsl"
#include "HDRenderPipeline/Material/Material.hlsl"
#include "../Material/Material.hlsl"
#include "HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl"
#include "../Lighting/TilePass/TilePassLoop.hlsl"
#endif

17
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader


#pragma shader_feature _ SSS_PRE_SCATTER_TEXTURING SSS_POST_SCATTER_TEXTURING
// #endif
#pragma multi_compile _ SKY_LIGHTING
#pragma multi_compile _ LIGHTING_DEBUG
//-------------------------------------------------------------------------------------

#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration

PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
uint featureFlags = 0xFFFFFFFF;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
Outputs outputs;
#ifdef OUTPUT_SPLIT_LIGHTING

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TileLightLoopProducer.cs


public bool enableTileAndCluster; // For debug / test
public bool enableSplitLightEvaluation;
public bool enableComputeLightEvaluation;
public bool enableComputeFeatureVariants;
public int debugViewTilesFlags;
public bool enableClustered;
public bool enableFptlForOpaqueWhenClustered; // still useful on opaques. Should be true by default to force tile on opaque.
public bool enableBigTilePrepass;

[Range(0.0f, 1.0f)]
public float specularGlobalDimmer = 1.0f;
public enum TileDebug : int { None = 0, Punctual = 1, Area = 2, AreaAndPunctual = 3, Environment = 4, EnvironmentAndPunctual = 5, EnvironmentAndArea = 6, EnvironmentAndAreaAndPunctual = 7, FeatureVariants = 8 };
public TileDebug tileDebugByCategory;
enableComputeFeatureVariants = false,
debugViewTilesFlags = 0,
tileDebugByCategory = TileDebug.None,
enableClustered = true,
enableFptlForOpaqueWhenClustered = true,
enableBigTilePrepass = true,

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


#pragma kernel BigTileLightListGen
#include "ShaderLibrary/common.hlsl"
#include "../../../../ShaderLibrary/common.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#include "../SortingComputeUtils.hlsl"

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild-clustered.compute


#pragma kernel TileLightListGen_DepthRT_MSAA_SrcBigTile LIGHTLISTGEN=TileLightListGen_DepthRT_MSAA_SrcBigTile ENABLE_DEPTH_TEXTURE_BACKPLANE MSAA_ENABLED USE_TWO_PASS_TILED_LIGHTING
#pragma kernel ClearAtomic
#include "ShaderLibrary/common.hlsl"
#include "../../../../ShaderLibrary/common.hlsl"
#include "../ShaderBase.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"

{
for(int l=(int) t; l<((iNrCoarseLights+1)>>1); l += NR_THREADS)
{
const int l0 = coarseList[2*l+0], l1 = coarseList[min(2*l+1,iNrCoarseLights)];
const int l0 = coarseList[2*l+0], l1 = coarseList[min(2*l+1,iNrCoarseLights-1)];
const unsigned int clustIdxMi0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0].z), suggestedBase));
const unsigned int clustIdxMa0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0+g_iNrVisibLights].z), suggestedBase));
const unsigned int clustIdxMi1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1].z), suggestedBase));

{
int offs = 0;
for(int l=0; l<iNrCoarseLights; l++)
{ if(coarseList[l]!=0xffffffff) coarseList[offs++] = coarseList[l]; }
{
if(coarseList[l]!=0xffffffff)
coarseList[offs++] = coarseList[l];
}
lightOffsSph = offs;
}

925
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/lightlistbuild.compute


// The implementation is based on the demo on "fine pruned tiled lighting" published in GPU Pro 7.
// https://github.com/wolfgangfengel/GPU-Pro-7
#pragma kernel TileLightListGen LIGHTLISTGEN=TileLightListGen
#pragma kernel TileLightListGen_SrcBigTile LIGHTLISTGEN=TileLightListGen_SrcBigTile USE_TWO_PASS_TILED_LIGHTING
#include "ShaderLibrary/common.hlsl"
#include "../ShaderBase.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
#include "../SortingComputeUtils.hlsl"
#endif
#define FINE_PRUNING_ENABLED
#define PERFORM_SPHERICAL_INTERSECTION_TESTS
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform int _EnvLightIndexShift;
Texture2D g_depth_tex : register( t0 );
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );
StructuredBuffer<LightVolumeData> _LightVolumeData : register(t2);
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );
#ifdef USE_TWO_PASS_TILED_LIGHTING
StructuredBuffer<uint> g_vBigTileLightList : register( t4 ); // don't support Buffer yet in unity
#endif
#define NR_THREADS 64
// output buffer
RWStructuredBuffer<uint> g_vLightList : register( u0 ); // don't support RWBuffer yet in unity
#define MAX_NR_COARSE_ENTRIES 64
#define MAX_NR_PRUNED_ENTRIES 24
groupshared unsigned int coarseList[MAX_NR_COARSE_ENTRIES];
groupshared unsigned int prunedList[MAX_NR_COARSE_ENTRIES]; // temporarily support room for all 64 while in LDS
groupshared uint ldsZMin;
groupshared uint ldsZMax;
groupshared uint lightOffs;
#ifdef FINE_PRUNING_ENABLED
groupshared uint ldsDoesLightIntersect[2];
#endif
groupshared int ldsNrLightsFinal;
groupshared int ldsCategoryListCount[LIGHTCATEGORY_COUNT]; // since LIGHTCATEGORY_COUNT is 3
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
groupshared uint lightOffsSph;
#endif
//float GetLinearDepth(float3 vP)
//{
// float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
// return v4Pres.z / v4Pres.w;
//}
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
{
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
float fSx = g_mScrProjection[0].x;
float fCx = g_mScrProjection[0].z;
float fSy = g_mScrProjection[1].y;
float fCy = g_mScrProjection[1].z;
#if USE_LEFTHAND_CAMERASPACE
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
#else
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
#endif
}
float GetOnePixDiagWorldDistAtDepthOne()
{
float fSx = g_mScrProjection[0].x;
float fSy = g_mScrProjection[1].y;
return length( float2(1.0/fSx,1.0/fSy) );
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
int SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate);
#endif
#ifdef FINE_PRUNING_ENABLED
void FinePruneLights(uint threadID, int iNrCoarseLights, uint2 viTilLL, float4 vLinDepths);
#endif
[numthreads(NR_THREADS, 1, 1)]
void LIGHTLISTGEN(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
uint2 tileIDX = u3GroupID.xy;
uint t=threadID;
if(t<MAX_NR_COARSE_ENTRIES)
prunedList[t]=0;
uint iWidth = g_viDimensions.x;
uint iHeight = g_viDimensions.y;
uint nrTilesX = (iWidth+15)/16;
uint nrTilesY = (iHeight+15)/16;
// build tile scr boundary
const uint uFltMax = 0x7f7fffff; // FLT_MAX as a uint
if(t==0)
{
ldsZMin = uFltMax;
ldsZMax = 0;
lightOffs = 0;
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
uint2 viTilLL = 16*tileIDX;
// establish min and max depth first
float dpt_mi=asfloat(uFltMax), dpt_ma=0.0;
float4 vLinDepths;
{
// Fetch depths and calculate min/max
[unroll]
for(int i = 0; i < 4; i++)
{
int idx = i * NR_THREADS + t;
uint2 uCrd = min( uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1) );
const float fDepth = FetchDepth(g_depth_tex, uCrd);
vLinDepths[i] = GetLinearDepth(fDepth);
if(fDepth<VIEWPORT_SCALE_Z) // if not skydome
{
dpt_mi = min(fDepth, dpt_mi);
dpt_ma = max(fDepth, dpt_ma);
}
}
InterlockedMax(ldsZMax, asuint(dpt_ma));
InterlockedMin(ldsZMin, asuint(dpt_mi));
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
}
float3 vTileLL = float3(viTilLL.x/(float) iWidth, viTilLL.y/(float) iHeight, asfloat(ldsZMin));
float3 vTileUR = float3((viTilLL.x+16)/(float) iWidth, (viTilLL.y+16)/(float) iHeight, asfloat(ldsZMax));
vTileUR.xy = min(vTileUR.xy,float2(1.0,1.0)).xy;
// build coarse list using AABB
#ifdef USE_TWO_PASS_TILED_LIGHTING
int NrBigTilesX = (nrTilesX+3)>>2;
const int bigTileIdx = (tileIDX.y>>2)*NrBigTilesX + (tileIDX.x>>2); // map the idx to 64x64 tiles
int nrBigTileLights = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+0];
for(int l0=(int) t; l0<(int) nrBigTileLights; l0 += NR_THREADS)
{
int l = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+l0+1];
#else
for(int l=(int) t; l<(int) g_iNrVisibLights; l += NR_THREADS)
{
#endif
const float3 vMi = g_vBoundsBuffer[l];
const float3 vMa = g_vBoundsBuffer[l+g_iNrVisibLights];
if( all(vMa>vTileLL) && all(vMi<vTileUR))
{
unsigned int uInc = 1;
unsigned int uIndex;
InterlockedAdd(lightOffs, uInc, uIndex);
if(uIndex<MAX_NR_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
}
}
#ifdef FINE_PRUNING_ENABLED
if(t<2) ldsDoesLightIntersect[t] = 0;
#endif
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int iNrCoarseLights = min(lightOffs,MAX_NR_COARSE_ENTRIES);
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
iNrCoarseLights = SphericalIntersectionTests( t, iNrCoarseLights, float2(min(viTilLL.xy+uint2(16/2,16/2), uint2(iWidth-1, iHeight-1))) );
#endif
#ifndef FINE_PRUNING_ENABLED
{
if((int)t<iNrCoarseLights) prunedList[t] = coarseList[t];
if(t==0) ldsNrLightsFinal=iNrCoarseLights;
}
#else
{
// initializes ldsNrLightsFinal with the number of accepted lights.
// all accepted entries delivered in prunedList[].
FinePruneLights(t, iNrCoarseLights, viTilLL, vLinDepths);
}
#endif
//
if(t<LIGHTCATEGORY_COUNT) ldsCategoryListCount[t]=0;
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int nrLightsCombinedList = min(ldsNrLightsFinal,MAX_NR_COARSE_ENTRIES);
for(int i=t; i<nrLightsCombinedList; i+=NR_THREADS)
{
InterlockedAdd(ldsCategoryListCount[_LightVolumeData[prunedList[i]].lightCategory], 1);
}
// sort lights (gives a more efficient execution in both deferred and tiled forward lighting).
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
SORTLIST(prunedList, nrLightsCombinedList, MAX_NR_COARSE_ENTRIES, t, NR_THREADS);
//MERGESORTLIST(prunedList, coarseList, nrLightsCombinedList, t, NR_THREADS);
#endif
// write lights to global buffers
int localOffs=0;
int offs = tileIDX.y*nrTilesX + tileIDX.x;
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT] = {0, 0, _EnvLightIndexShift}; // 3 for now, will throw an error if we change LIGHTCATEGORY_COUNT
for(int category=0; category<LIGHTCATEGORY_COUNT; category++)
{
int nrLightsFinal = ldsCategoryListCount[category];
int nrLightsFinalClamped = nrLightsFinal<MAX_NR_PRUNED_ENTRIES ? nrLightsFinal : MAX_NR_PRUNED_ENTRIES;
const int nrDWords = ((nrLightsFinalClamped+1)+1)>>1;
for(int l=(int) t; l<(int) nrDWords; l += NR_THREADS)
{
// We remap the prunedList index to the original LightData / EnvLightData indices
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[2 * l - 1 + localOffs] - shiftIndex[category];
uint uHigh = prunedList[2 * l + 0 + localOffs] - shiftIndex[category];
g_vLightList[16*offs + l] = (uLow&0xffff) | (uHigh<<16);
}
localOffs += nrLightsFinal;
offs += (nrTilesX*nrTilesY);
}
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
int SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate)
{
if(threadID==0) lightOffsSph = 0;
// make a copy of coarseList in prunedList.
int l;
for(l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
prunedList[l]=coarseList[l];
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
#if USE_LEFTHAND_CAMERASPACE
float3 V = GetViewPosFromLinDepth( screenCoordinate, 1.0);
#else
float3 V = GetViewPosFromLinDepth( screenCoordinate, -1.0);
#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
for(l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lightData = g_data[prunedList[l]];
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);
coarseList[uIndex]=prunedList[l]; // read from the original copy of coarseList which is backed up in prunedList
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
return lightOffsSph;
}
#endif
#ifdef FINE_PRUNING_ENABLED
// initializes ldsNrLightsFinal with the number of accepted lights.
// all accepted entries delivered in prunedList[].
void FinePruneLights(uint threadID, int iNrCoarseLights, uint2 viTilLL, float4 vLinDepths)
{
uint t = threadID;
uint iWidth = g_viDimensions.x;
uint iHeight = g_viDimensions.y;
uint uLightsFlags[2] = {0,0};
int l=0;
// need this outer loop even on xb1 and ps4 since direct lights and
// reflection lights are kept in separate regions.
while(l<iNrCoarseLights)
{
// fetch light
int idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uint uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
// spot
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_CONE)
{
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// TODO: Change by SebL
const bool bIsSpotDisc = true; // (lightData.flags&IS_CIRCULAR_SPOT_SHAPE) != 0;
// serially check 4 pixels
uint uVal = 0;
for(int i=0; i<4; i++)
{
int idx = t + i*NR_THREADS;
uint2 uPixLoc = min(uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1));
float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 fromLight = vVPos-lightData.lightPos.xyz;
float distSq = dot(fromLight,fromLight);
const float fSclProj = dot(fromLight, lightData.lightAxisZ.xyz); // spotDir = lightData.lightAxisZ.xyz
float2 V = abs( float2( dot(fromLight, lightData.lightAxisX.xyz), dot(fromLight, lightData.lightAxisY.xyz) ) );
float fDist2D = bIsSpotDisc ? length(V) : max(V.x,V.y);
if( all( float2(lightData.radiusSq, fSclProj) > float2(distSq, fDist2D*lightData.cotan) ) ) uVal = 1;
}
uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
}
// sphere
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_SPHERE)
{
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;
for(int i=0; i<4; i++)
{
int idx = t + i*NR_THREADS;
uint2 uPixLoc = min(uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1));
float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 vLp = lightData.lightPos.xyz;
float3 toLight = vLp - vVPos;
float distSq = dot(toLight,toLight);
if(lightData.radiusSq>distSq) uVal = 1;
}
uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
}
// Box
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_BOX)
{
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;
for(int i=0; i<4; i++)
{
int idx = t + i*NR_THREADS;
uint2 uPixLoc = min(uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1));
float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 toLight = lightData.lightPos.xyz - vVPos;
float3 dist = float3( dot(toLight, lightData.lightAxisX), dot(toLight, lightData.lightAxisY), dot(toLight, lightData.lightAxisZ) );
dist = (abs(dist) - lightData.boxInnerDist) * lightData.boxInvRange; // not as efficient as it could be
if( max(max(dist.x, dist.y), dist.z)<1 ) uVal = 1; // but allows us to not write out OuterDists
}
uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
}
// in case we have some corrupt data make sure we terminate
if(uLightVolume >=LIGHTVOLUMETYPE_COUNT) ++l;
}
InterlockedOr(ldsDoesLightIntersect[0], uLightsFlags[0]);
InterlockedOr(ldsDoesLightIntersect[1], uLightsFlags[1]);
if(t==0) ldsNrLightsFinal = 0;
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
if(t<(uint) iNrCoarseLights && (ldsDoesLightIntersect[t<32 ? 0 : 1]&(1<<(t&31)))!=0 )
{
unsigned int uInc = 1;
unsigned int uIndex;
InterlockedAdd(ldsNrLightsFinal, uInc, uIndex);
if(uIndex<MAX_NR_COARSE_ENTRIES) prunedList[uIndex] = coarseList[t]; // we allow up to 64 pruned lights while stored in LDS.
}
}
#endif
// The implementation is based on the demo on "fine pruned tiled lighting" published in GPU Pro 7.
// https://github.com/wolfgangfengel/GPU-Pro-7
#pragma kernel TileLightListGen LIGHTLISTGEN=TileLightListGen
#pragma kernel TileLightListGen_SrcBigTile LIGHTLISTGEN=TileLightListGen_SrcBigTile USE_TWO_PASS_TILED_LIGHTING
#pragma kernel TileLightListGen_FeatureFlags LIGHTLISTGEN=TileLightListGen_FeatureFlags USE_FEATURE_FLAGS
#pragma kernel TileLightListGen_SrcBigTile_FeatureFlags LIGHTLISTGEN=TileLightListGen_SrcBigTile_FeatureFlags USE_TWO_PASS_TILED_LIGHTING USE_FEATURE_FLAGS
#pragma #pragma enable_d3d11_debug_symbols
#include "../../../../ShaderLibrary/common.hlsl"
#include "../ShaderBase.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#include "../FeatureFlags.hlsl"
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
#include "../SortingComputeUtils.hlsl"
#endif
#define FINE_PRUNING_ENABLED
#define PERFORM_SPHERICAL_INTERSECTION_TESTS
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform int _EnvLightIndexShift;
Texture2D g_depth_tex : register( t0 );
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );
StructuredBuffer<LightVolumeData> _LightVolumeData : register(t2);
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );
#ifdef USE_TWO_PASS_TILED_LIGHTING
StructuredBuffer<uint> g_vBigTileLightList : register( t4 ); // don't support Buffer yet in unity
#endif
#define NR_THREADS 64
// output buffer
RWStructuredBuffer<uint> g_vLightList : register( u0 ); // don't support RWBuffer yet in unity
#define MAX_NR_COARSE_ENTRIES 64
#define MAX_NR_PRUNED_ENTRIES 24
groupshared unsigned int coarseList[MAX_NR_COARSE_ENTRIES];
groupshared unsigned int prunedList[MAX_NR_COARSE_ENTRIES]; // temporarily support room for all 64 while in LDS
groupshared uint ldsZMin;
groupshared uint ldsZMax;
groupshared uint lightOffs;
#ifdef FINE_PRUNING_ENABLED
groupshared uint ldsDoesLightIntersect[2];
#endif
groupshared int ldsNrLightsFinal;
groupshared int ldsCategoryListCount[LIGHTCATEGORY_COUNT]; // since LIGHTCATEGORY_COUNT is 3
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
groupshared uint lightOffsSph;
#endif
uniform uint g_BaseFeatureFlags;
#ifdef USE_FEATURE_FLAGS
groupshared uint ldsFeatureFlags;
RWBuffer<uint> g_DispatchIndirectBuffer;
RWStructuredBuffer<uint> g_TileList;
#endif
//float GetLinearDepth(float3 vP)
//{
// float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
// return v4Pres.z / v4Pres.w;
//}
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
{
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
float fSx = g_mScrProjection[0].x;
float fCx = g_mScrProjection[0].z;
float fSy = g_mScrProjection[1].y;
float fCy = g_mScrProjection[1].z;
#if USE_LEFTHAND_CAMERASPACE
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
#else
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
#endif
}
float GetOnePixDiagWorldDistAtDepthOne()
{
float fSx = g_mScrProjection[0].x;
float fSy = g_mScrProjection[1].y;
return length( float2(1.0/fSx,1.0/fSy) );
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
int SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate);
#endif
#ifdef FINE_PRUNING_ENABLED
void FinePruneLights(uint threadID, int iNrCoarseLights, uint2 viTilLL, float4 vLinDepths);
#endif
[numthreads(NR_THREADS, 1, 1)]
void LIGHTLISTGEN(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
uint2 tileIDX = u3GroupID.xy;
uint t=threadID;
if(t<MAX_NR_COARSE_ENTRIES)
prunedList[t]=0;
uint iWidth = g_viDimensions.x;
uint iHeight = g_viDimensions.y;
uint nrTilesX = (iWidth+15)/16;
uint nrTilesY = (iHeight+15)/16;
uint nrTiles = nrTilesX * nrTilesY; // Precompute?
// build tile scr boundary
const uint uFltMax = 0x7f7fffff; // FLT_MAX as a uint
if(t==0)
{
ldsZMin = uFltMax;
ldsZMax = 0;
lightOffs = 0;
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
uint2 viTilLL = 16*tileIDX;
// establish min and max depth first
float dpt_mi=asfloat(uFltMax), dpt_ma=0.0;
float4 vLinDepths;
{
// Fetch depths and calculate min/max
[unroll]
for(int i = 0; i < 4; i++)
{
int idx = i * NR_THREADS + t;
uint2 uCrd = min( uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1) );
const float fDepth = FetchDepth(g_depth_tex, uCrd);
vLinDepths[i] = GetLinearDepth(fDepth);
if(fDepth<VIEWPORT_SCALE_Z) // if not skydome
{
dpt_mi = min(fDepth, dpt_mi);
dpt_ma = max(fDepth, dpt_ma);
}
}
InterlockedMax(ldsZMax, asuint(dpt_ma));
InterlockedMin(ldsZMin, asuint(dpt_mi));
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
}
float3 vTileLL = float3(viTilLL.x/(float) iWidth, viTilLL.y/(float) iHeight, asfloat(ldsZMin));
float3 vTileUR = float3((viTilLL.x+16)/(float) iWidth, (viTilLL.y+16)/(float) iHeight, asfloat(ldsZMax));
vTileUR.xy = min(vTileUR.xy,float2(1.0,1.0)).xy;
// build coarse list using AABB
#ifdef USE_TWO_PASS_TILED_LIGHTING
int NrBigTilesX = (nrTilesX+3)>>2;
const int bigTileIdx = (tileIDX.y>>2)*NrBigTilesX + (tileIDX.x>>2); // map the idx to 64x64 tiles
int nrBigTileLights = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+0];
for(int l0=(int) t; l0<(int) nrBigTileLights; l0 += NR_THREADS)
{
int l = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+l0+1];
#else
for(int l=(int) t; l<(int) g_iNrVisibLights; l += NR_THREADS)
{
#endif
const float3 vMi = g_vBoundsBuffer[l];
const float3 vMa = g_vBoundsBuffer[l+g_iNrVisibLights];
if( all(vMa>vTileLL) && all(vMi<vTileUR))
{
unsigned int uInc = 1;
unsigned int uIndex;
InterlockedAdd(lightOffs, uInc, uIndex);
if(uIndex<MAX_NR_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
}
}
#ifdef FINE_PRUNING_ENABLED
if(t<2) ldsDoesLightIntersect[t] = 0;
#endif
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int iNrCoarseLights = min(lightOffs,MAX_NR_COARSE_ENTRIES);
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
iNrCoarseLights = SphericalIntersectionTests( t, iNrCoarseLights, float2(min(viTilLL.xy+uint2(16/2,16/2), uint2(iWidth-1, iHeight-1))) );
#endif
#ifndef FINE_PRUNING_ENABLED
{
if((int)t<iNrCoarseLights) prunedList[t] = coarseList[t];
if(t==0) ldsNrLightsFinal=iNrCoarseLights;
}
#else
{
// initializes ldsNrLightsFinal with the number of accepted lights.
// all accepted entries delivered in prunedList[].
FinePruneLights(t, iNrCoarseLights, viTilLL, vLinDepths);
}
#endif
//
if(t<LIGHTCATEGORY_COUNT) ldsCategoryListCount[t]=0;
#ifdef USE_FEATURE_FLAGS
if(t==0) ldsFeatureFlags=0;
#endif
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int nrLightsCombinedList = min(ldsNrLightsFinal,MAX_NR_COARSE_ENTRIES);
for(int i=t; i<nrLightsCombinedList; i+=NR_THREADS)
{
InterlockedAdd(ldsCategoryListCount[_LightVolumeData[prunedList[i]].lightCategory], 1);
#ifdef USE_FEATURE_FLAGS
InterlockedOr(ldsFeatureFlags, _LightVolumeData[prunedList[i]].featureFlags);
#endif
}
// sort lights (gives a more efficient execution in both deferred and tiled forward lighting).
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
SORTLIST(prunedList, nrLightsCombinedList, MAX_NR_COARSE_ENTRIES, t, NR_THREADS);
//MERGESORTLIST(prunedList, coarseList, nrLightsCombinedList, t, NR_THREADS);
#endif
#ifdef USE_FEATURE_FLAGS
if(t == 0)
{
uint featureFlags = g_BaseFeatureFlags | ldsFeatureFlags;
if(ldsZMax < ldsZMin) // is background pixel
{
featureFlags &= ~(FEATURE_FLAG_PUNCTUAL_LIGHT | FEATURE_FLAG_AREA_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT | FEATURE_FLAG_ENV_LIGHT); // list of features that are not enabled on background
}
uint variant = FeatureFlagsToTileVariant(featureFlags);
uint offset;
InterlockedAdd(g_DispatchIndirectBuffer[variant * 3 + 0], 1, offset);
g_TileList[variant*nrTiles + offset] = (tileIDX.y << 16) + tileIDX.x;
}
#endif
// write lights to global buffers
int localOffs=0;
int offs = tileIDX.y*nrTilesX + tileIDX.x;
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT] = {0, 0, _EnvLightIndexShift}; // 3 for now, will throw an error if we change LIGHTCATEGORY_COUNT
for(int category=0; category<LIGHTCATEGORY_COUNT; category++)
{
int nrLightsFinal = ldsCategoryListCount[category];
int nrLightsFinalClamped = nrLightsFinal<MAX_NR_PRUNED_ENTRIES ? nrLightsFinal : MAX_NR_PRUNED_ENTRIES;
const int nrDWords = ((nrLightsFinalClamped+1)+1)>>1;
for(int l=(int) t; l<(int) nrDWords; l += NR_THREADS)
{
// We remap the prunedList index to the original LightData / EnvLightData indices
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[max(0,2 * l - 1 + localOffs)] - shiftIndex[category];
uint uHigh = prunedList[2 * l + 0 + localOffs] - shiftIndex[category];
g_vLightList[16*offs + l] = (uLow&0xffff) | (uHigh<<16);
}
localOffs += nrLightsFinal;
offs += (nrTilesX*nrTilesY);
}
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
int SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate)
{
if(threadID==0) lightOffsSph = 0;
// make a copy of coarseList in prunedList.
int l;
for(l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
prunedList[l]=coarseList[l];
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
#if USE_LEFTHAND_CAMERASPACE
float3 V = GetViewPosFromLinDepth( screenCoordinate, 1.0);
#else
float3 V = GetViewPosFromLinDepth( screenCoordinate, -1.0);
#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
for(l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lightData = g_data[prunedList[l]];
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);
coarseList[uIndex]=prunedList[l]; // read from the original copy of coarseList which is backed up in prunedList
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
return lightOffsSph;
}
#endif
#ifdef FINE_PRUNING_ENABLED
// initializes ldsNrLightsFinal with the number of accepted lights.
// all accepted entries delivered in prunedList[].
void FinePruneLights(uint threadID, int iNrCoarseLights, uint2 viTilLL, float4 vLinDepths)
{
uint t = threadID;
uint iWidth = g_viDimensions.x;
uint iHeight = g_viDimensions.y;
uint uLightsFlags[2] = {0,0};
int l=0;
// need this outer loop even on xb1 and ps4 since direct lights and
// reflection lights are kept in separate regions.
while(l<iNrCoarseLights)
{
// fetch light
int idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uint uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
// spot
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_CONE)
{
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// TODO: Change by SebL
const bool bIsSpotDisc = true; // (lightData.flags&IS_CIRCULAR_SPOT_SHAPE) != 0;
// serially check 4 pixels
uint uVal = 0;
for(int i=0; i<4; i++)
{
int idx = t + i*NR_THREADS;
uint2 uPixLoc = min(uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1));
float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 fromLight = vVPos-lightData.lightPos.xyz;
float distSq = dot(fromLight,fromLight);
const float fSclProj = dot(fromLight, lightData.lightAxisZ.xyz); // spotDir = lightData.lightAxisZ.xyz
float2 V = abs( float2( dot(fromLight, lightData.lightAxisX.xyz), dot(fromLight, lightData.lightAxisY.xyz) ) );
float fDist2D = bIsSpotDisc ? length(V) : max(V.x,V.y);
if( all( float2(lightData.radiusSq, fSclProj) > float2(distSq, fDist2D*lightData.cotan) ) ) uVal = 1;
}
uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
}
// sphere
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_SPHERE)
{
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;
for(int i=0; i<4; i++)
{
int idx = t + i*NR_THREADS;
uint2 uPixLoc = min(uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1));
float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 vLp = lightData.lightPos.xyz;
float3 toLight = vLp - vVPos;
float distSq = dot(toLight,toLight);
if(lightData.radiusSq>distSq) uVal = 1;
}
uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
}
// Box
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_BOX)
{
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;
for(int i=0; i<4; i++)
{
int idx = t + i*NR_THREADS;
uint2 uPixLoc = min(uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1));
float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 toLight = lightData.lightPos.xyz - vVPos;
float3 dist = float3( dot(toLight, lightData.lightAxisX), dot(toLight, lightData.lightAxisY), dot(toLight, lightData.lightAxisZ) );
dist = (abs(dist) - lightData.boxInnerDist) * lightData.boxInvRange; // not as efficient as it could be
if( max(max(dist.x, dist.y), dist.z)<1 ) uVal = 1; // but allows us to not write out OuterDists
}
uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
}
// in case we have some corrupt data make sure we terminate
if(uLightVolume >=LIGHTVOLUMETYPE_COUNT) ++l;
}
InterlockedOr(ldsDoesLightIntersect[0], uLightsFlags[0]);
InterlockedOr(ldsDoesLightIntersect[1], uLightsFlags[1]);
if(t==0) ldsNrLightsFinal = 0;
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
if(t<(uint) iNrCoarseLights && (ldsDoesLightIntersect[t<32 ? 0 : 1]&(1<<(t&31)))!=0 )
{
unsigned int uInc = 1;
unsigned int uIndex;
InterlockedAdd(ldsNrLightsFinal, uInc, uIndex);
if(uIndex<MAX_NR_COARSE_ENTRIES) prunedList[uIndex] = coarseList[t]; // we allow up to 64 pruned lights while stored in LDS.
}
}
#endif

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/scrbound.compute


#pragma kernel ScreenBoundsAABB
#include "ShaderLibrary/common.hlsl"
#include "../../../../ShaderLibrary/common.hlsl"
#include "../TilePass.cs.hlsl"
uniform int g_iNrVisibLights;

183
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute


#pragma kernel ShadeOpaque_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Fptl USE_FPTL_LIGHTLIST
#pragma kernel ShadeOpaque_Fptl_DebugLighting SHADE_OPAQUE_ENTRY=ShadeOpaque_Fptl_DebugLighting USE_FPTL_LIGHTLIST LIGHTING_DEBUG
#pragma kernel ShadeOpaque_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Clustered USE_CLUSTERED_LIGHTLIST
#pragma kernel ShadeOpaque_Clustered_DebugLighting SHADE_OPAQUE_ENTRY=ShadeOpaque_Clustered_DebugLighting USE_CLUSTERED_LIGHTLIST LIGHTING_DEBUG
#pragma #pragma enable_d3d11_debug_symbols
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
{
uint2 pixelCoord = dispatchThreadId;
//PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, uint2(pixelCoord.xy) / GetTileSize());
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, groupId);
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, bsdfData, bakeDiffuseLighting);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;
float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}
#pragma kernel ShadeOpaque_Direct_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl USE_FPTL_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Fptl_DebugLighting SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl_DebugLighting USE_FPTL_LIGHTLIST LIGHTING_DEBUG
#pragma kernel ShadeOpaque_Direct_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered USE_CLUSTERED_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Clustered_DebugLighting SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered_DebugLighting USE_CLUSTERED_LIGHTLIST LIGHTING_DEBUG
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant0 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant1 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant2 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant3 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant4 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant5 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant6 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant7 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant0 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant1 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant2 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant3 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant4 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant5 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant6 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant7 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma #pragma enable_d3d11_debug_symbols
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../../Debug/DebugLighting.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../../Lighting/TilePass/FeatureFlags.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
#if USE_INDIRECT
uint g_TileListOffset;
StructuredBuffer<uint> g_TileList;
// Indirect
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 groupThreadId : SV_GroupThreadID, uint groupId : SV_GroupID)
{
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, tileCoord);
uint featureFlags = TileVariantToFeatureFlags(VARIANT);
#else
// Direct
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
{
uint2 pixelCoord = dispatchThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, groupId);
uint featureFlags = 0xFFFFFFFF;
#endif
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, bsdfData, bakeDiffuseLighting);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;
float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}

1001
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
文件差异内容过多而无法显示
查看文件

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl


#define HAS_COOKIE_TEXTURE (2)
#define IS_BOX_PROJECTED (4)
#define HAS_SHADOW (8)
#define FEATURE_FLAG_PUNCTUAL_LIGHT (1)
#define FEATURE_FLAG_AREA_LIGHT (2)
#define FEATURE_FLAG_DIRECTIONAL_LIGHT (4)
#define FEATURE_FLAG_ENV_LIGHT (8)
#define FEATURE_FLAG_SKY_LIGHT (16)
#define NUM_FEATURE_VARIANTS (8)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.TilePass.SFiniteLightBound
// PackingRules = Exact

float3 lightAxisZ;
float cotan;
float3 boxInnerDist;
float unused;
uint featureFlags;
float3 boxInvRange;
float unused2;
};

{
return value.boxInnerDist;
}
float GetUnused(LightVolumeData value)
uint GetFeatureFlags(LightVolumeData value)
return value.unused;
return value.featureFlags;
}
float3 GetBoxInvRange(LightVolumeData value)
{

74
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


#if defined (LIGHTLOOP_TILE_DIRECT) || defined(LIGHTLOOP_TILE_ALL)
#if defined (LIGHTLOOP_TILE_DIRECT) || defined(LIGHTLOOP_TILE_ALL)
#define PROCESS_DIRECTIONAL_LIGHT
#define PROCESS_PUNCTUAL_LIGHT
#define PROCESS_AREA_LIGHT

#include "TilePass.cs.hlsl"
// For FPTL
uint _NumTileFtplX;
uint _NumTileFtplY;
StructuredBuffer<uint> g_vLightListGlobal; // don't support Buffer yet in unity
#ifdef USE_FPTL_LIGHTLIST

// these uniforms are only needed for when OPAQUES_ONLY is NOT defined
// but there's a problem with our front-end compilation of compute shaders with multiple kernels causing it to error
//#ifdef USE_CLUSTERED_LIGHTLIST
float4x4 g_mInvScrProjection;
float g_fClustScale;
float g_fClustBase;
float g_fNearPlane;

StructuredBuffer<float> g_logBaseBuffer; // don't support Buffer yet in unity
//#endif
struct LightingSettings
{
uint directionalLightCount;
uint punctualLightCount;
uint areaLightCount;
uint envLightCount;
uint numTileFtplX;
uint numTileFtplY;
uint pad0, pad1; // 16-byte alignment
// uint numTileClusteredX;
// uint numTileClusteredY;
// uint isLogBaseBufferEnabled;
// uint log2NumClusters;
// float clusterScale;
// float clusterBase;
// float nearPlane;
// float farPlane;
float4 dirShadowSplitSpheres[4]; // TODO: share this max between C# and hlsl
};
// We use a structured buffer instead of a constant buffer due to the delay between setting values via constant and other buffer types on PS4
StructuredBuffer<LightingSettings> _LightingSettings; // 1 element
StructuredBuffer<DirectionalLightData> _DirectionalLightDatas;
StructuredBuffer<LightData> _LightDatas;
StructuredBuffer<EnvLightData> _EnvLightDatas;

SAMPLER2D(sampler_CookieTextures);
// Used by point lights
#ifdef UNITY_NO_CUBEMAP_ARRAY
TEXTURE2D_ARRAY(_CookieCubeTextures);
SAMPLER2D(sampler_CookieCubeTextures);
#else
TEXTURECUBE_ARRAY(_CookieCubeTextures);
SAMPLERCUBE(sampler_CookieCubeTextures);
#endif
TEXTURECUBE_ARRAY_ABSTRACT(_CookieCubeTextures);
SAMPLERCUBE_ABSTRACT(sampler_CookieCubeTextures);
#ifdef UNITY_NO_CUBEMAP_ARRAY
TEXTURE2D_ARRAY(_EnvTextures);
SAMPLER2D(sampler_EnvTextures);
#else
TEXTURECUBE_ARRAY(_EnvTextures);
SAMPLERCUBE(sampler_EnvTextures);
#endif
TEXTURECUBE_ARRAY_ABSTRACT(_EnvTextures);
SAMPLERCUBE_ABSTRACT(sampler_EnvTextures);
/*
// See _LightingSettings
uint _DirectionalLightCount;
uint _PunctualLightCount;
uint _AreaLightCount;
uint _EnvLightCount;
float4 _DirShadowSplitSpheres[4]; // TODO: share this max between C# and hlsl
int _EnvLightSkyEnabled; // TODO: make it a bool
*/
struct LightLoopContext
{

float GetDirectionalShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
// Note Index is 0 for now, but else we need to provide the correct index in _LightingSettings[0].dirShadowSplitSpheres and _ShadowDatas
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _LightingSettings[0].dirShadowSplitSpheres);
// Note Index is 0 for now, but else we need to provide the correct index in _DirShadowSplitSpheres and _ShadowDatas
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
return 1.0;

// Returns the color in the RGB components, and the transparency (lack of occlusion) in A.
float4 SampleCookieCube(LightLoopContext lightLoopContext, float3 coord, int index)
{
#ifdef UNITY_NO_CUBEMAP_ARRAY
return SAMPLE_TEXTURE2D_ARRAY_LOD(_CookieCubeTextures, sampler_CookieCubeTextures, DirectionToLatLongCoordinate(coord), index, 0);
#else
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_CookieCubeTextures, sampler_CookieCubeTextures, coord, index, 0);
#endif
return SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(_CookieCubeTextures, sampler_CookieCubeTextures, coord, index, 0);
}
//-----------------------------------------------------------------------------

// This code will be inlined as lightLoopContext is hardcoded in the light loop
if (lightLoopContext.sampleReflection == SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES)
{
#ifdef UNITY_NO_CUBEMAP_ARRAY
return SAMPLE_TEXTURE2D_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, DirectionToLatLongCoordinate(texCoord), index, lod);
#else
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, texCoord, index, lod);
#endif
return SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(_EnvTextures, sampler_EnvTextures, texCoord, index, lod);
}
else // SINGLE_PASS_SAMPLE_SKY
{

747
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------
void ApplyDebug(LightLoopContext lightLoopContext, float3 positionWS, inout float3 diffuseLighting, inout float3 specularLighting)
{
#ifdef LIGHTING_DEBUG
int lightDebugMode = (int)_DebugLightModeAndAlbedo.x;
if (lightDebugMode == LIGHTINGDEBUGMODE_DIFFUSE_LIGHTING)
{
specularLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_SPECULAR_LIGHTING)
{
diffuseLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_VISUALIZE_CASCADE)
{
specularLighting = float3(0.0, 0.0, 0.0);
const float3 s_CascadeColors[] = {
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#endif
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _LightingSettings[0].dirShadowSplitSpheres);
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);
else
{
diffuseLighting = s_CascadeColors[shadowSplitIndex] * shadow;
}
}
#endif
}
#ifdef LIGHTLOOP_TILE_PASS
// Calculate the offset in global light index light for current light category
int GetTileOffset(PositionInputs posInput, uint lightCategory)
{
uint2 tileIndex = posInput.unTileCoord;
return (tileIndex.y + lightCategory * _LightingSettings[0].numTileFtplY) * _LightingSettings[0].numTileFtplX + tileIndex.x;
}
void GetCountAndStartTile(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
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;
start = tileOffset;
}
uint FetchIndexTile(uint tileOffset, uint lightIndex)
{
const uint lightIndexPlusOne = lightIndex + 1; // Add +1 as first slot is reserved to store number of light
// Light index are store on 16bit
return (g_vLightListGlobal[DWORD_PER_TILE * tileOffset + (lightIndexPlusOne >> 1)] >> ((lightIndexPlusOne & 1) * DWORD_PER_TILE)) & 0xffff;
}
#ifdef USE_FPTL_LIGHTLIST
uint GetTileSize()
{
return TILE_SIZE_FPTL;
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
return FetchIndexTile(tileOffset, lightIndex);
}
#elif defined(USE_CLUSTERED_LIGHTLIST)
#include "ClusteredUtils.hlsl"
uint GetTileSize()
{
return TILE_SIZE_CLUSTERED;
}
void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
uint2 tileIndex = posInput.unTileCoord;
float logBase = g_fClustBase;
if (g_isLogBaseBufferEnabled)
{
logBase = g_logBaseBuffer[tileIndex.y * _NumTileClusteredX + tileIndex.x];
}
int clustIdx = SnapToClusterIdxFlex(posInput.depthVS, logBase, g_isLogBaseBufferEnabled != 0);
int nrClusters = (1 << g_iLog2NumClusters);
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileClusteredY + tileIndex.y) * _NumTileClusteredX + tileIndex.x;
uint dataPair = g_vLayeredOffsetsBuffer[idx];
start = dataPair & 0x7ffffff;
lightCount = (dataPair >> 27) & 31;
}
uint FetchIndexCluster(uint tileOffset, uint lightIndex)
{
return g_vLightListGlobal[tileOffset + lightIndex];
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
if (_UseTileLightList)
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
else
GetCountAndStartCluster(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
if (_UseTileLightList)
return FetchIndexTile(tileOffset, lightIndex);
else
return FetchIndexCluster(tileOffset, 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, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
#ifdef PROCESS_DIRECTIONAL_LIGHT
for (i = 0; i < _LightingSettings[0].directionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_PUNCTUAL_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, punctualLightStart, punctualLightCount);
for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_AREA_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
for (i = 0; i < areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
uint areaIndex = FetchIndex(areaLightStart, i);
if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_ENV_LIGHT
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
#ifdef SKY_LIGHTING
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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, 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);
}
#endif
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
for (i = 0; i < envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
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);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
#endif
// TODO: currently apply GI at the same time as reflection
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
#endif
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#else // LIGHTLOOP_SINGLE_PASS
//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------
void ApplyDebug(LightLoopContext lightLoopContext, float3 positionWS, inout float3 diffuseLighting, inout float3 specularLighting)
{
#ifdef LIGHTING_DEBUG
int lightDebugMode = (int)_DebugLightModeAndAlbedo.x;
if (lightDebugMode == LIGHTINGDEBUGMODE_DIFFUSE_LIGHTING)
{
specularLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_SPECULAR_LIGHTING)
{
diffuseLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_VISUALIZE_CASCADE)
{
specularLighting = float3(0.0, 0.0, 0.0);
const float3 s_CascadeColors[] = {
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#endif
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);
else
{
diffuseLighting = s_CascadeColors[shadowSplitIndex] * shadow;
}
}
#endif
}
#ifdef LIGHTLOOP_TILE_PASS
// Calculate the offset in global light index light for current light category
int GetTileOffset(PositionInputs posInput, uint lightCategory)
{
uint2 tileIndex = posInput.unTileCoord;
return (tileIndex.y + lightCategory * _NumTileFtplY) * _NumTileFtplX + tileIndex.x;
}
void GetCountAndStartTile(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
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;
start = tileOffset;
}
#ifdef USE_FPTL_LIGHTLIST
uint GetTileSize()
{
return TILE_SIZE_FPTL;
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
const uint lightIndexPlusOne = lightIndex + 1; // Add +1 as first slot is reserved to store number of light
// Light index are store on 16bit
return (g_vLightListGlobal[DWORD_PER_TILE * tileOffset + (lightIndexPlusOne >> 1)] >> ((lightIndexPlusOne & 1) * DWORD_PER_TILE)) & 0xffff;
}
#elif defined(USE_CLUSTERED_LIGHTLIST)
#include "ClusteredUtils.hlsl"
uint GetTileSize()
{
return TILE_SIZE_CLUSTERED;
}
void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
uint2 tileIndex = posInput.unTileCoord;
float logBase = g_fClustBase;
if (g_isLogBaseBufferEnabled)
{
logBase = g_logBaseBuffer[tileIndex.y * _NumTileClusteredX + tileIndex.x];
}
int clustIdx = SnapToClusterIdxFlex(posInput.depthVS, logBase, g_isLogBaseBufferEnabled != 0);
int nrClusters = (1 << g_iLog2NumClusters);
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileClusteredY + tileIndex.y) * _NumTileClusteredX + tileIndex.x;
uint dataPair = g_vLayeredOffsetsBuffer[idx];
start = dataPair & 0x7ffffff;
lightCount = (dataPair >> 27) & 31;
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
if (_UseTileLightList)
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
else
GetCountAndStartCluster(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
uint offset = tileOffset + lightIndex;
const uint lightIndexPlusOne = lightIndex + 1; // Add +1 as first slot is reserved to store number of light
if (_UseTileLightList)
offset = DWORD_PER_TILE * tileOffset + (lightIndexPlusOne >> 1);
// Avoid generated HLSL bytecode to always access g_vLightListGlobal with
// two different offsets, fixes out of bounds issue
uint value = g_vLightListGlobal[offset];
// Light index are store on 16bit
return (_UseTileLightList ? ((value >> ((lightIndexPlusOne & 1) * DWORD_PER_TILE)) & 0xffff) : value);
}
#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, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting, uint featureFlags,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
#ifdef PROCESS_DIRECTIONAL_LIGHT
if(featureFlags & FEATURE_FLAG_DIRECTIONAL_LIGHT)
{
for(i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional(context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
}
#endif
#ifdef PROCESS_PUNCTUAL_LIGHT
if(featureFlags & FEATURE_FLAG_PUNCTUAL_LIGHT)
{
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, punctualLightStart, punctualLightCount);
for(i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual(context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
}
#endif
#ifdef PROCESS_AREA_LIGHT
if(featureFlags & FEATURE_FLAG_AREA_LIGHT)
{
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
for(i = 0; i < areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
uint areaIndex = FetchIndex(areaLightStart, i);
if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line(context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area(context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
}
#endif
#ifdef PROCESS_ENV_LIGHT
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
if(featureFlags & FEATURE_FLAG_SKY_LIGHT)
{
if(_EnvLightSkyEnabled)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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, 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);
}
}
if(featureFlags & FEATURE_FLAG_ENV_LIGHT)
{
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
for(i = 0; i < envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
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);
}
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
#endif
// TODO: currently apply GI at the same time as reflection
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
#endif
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#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, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _LightingSettings[0].directionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
for (i = 0; i < _LightingSettings[0].punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// Area are store with punctual, just offset the index
for (i = _LightingSettings[0].punctualLightCount; i < _LightingSettings[0].punctualLightCount + _LightingSettings[0].areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// TODO: Check the reflection hierarchy, for the current system (matching legacy unity) we must sort from bigger solid angle to lower (lower override bigger). So begging by sky
// TODO: Change the way it is done by reversing the order, from smaller solid angle to bigger, so we can early out when the weight is 1.
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
#ifdef SKY_LIGHTING
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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, 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);
}
#endif
for (i = 0; i < _LightingSettings[0].envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
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);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#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, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting, uint featureFlag,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
for (i = 0; i < _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// Area are store with punctual, just offset the index
for (i = _PunctualLightCount; i < _AreaLightCount + _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// TODO: Check the reflection hierarchy, for the current system (matching legacy unity) we must sort from bigger solid angle to lower (lower override bigger). So begging by sky
// TODO: Change the way it is done by reversing the order, from smaller solid angle to bigger, so we can early out when the weight is 1.
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
if (_EnvLightSkyEnabled)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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, 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);
}
for (i = 0; i < _EnvLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
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);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#endif

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassResources.asset


type: 3}
buildPerVoxelLightListShader: {fileID: 7200000, guid: 0bb1b7e0ddcd5c44baf3ddc7456eb196,
type: 3}
clearDispatchIndirectShader: {fileID: 7200000, guid: fc1f553acb80a6446a32d33e403d0656,
type: 3}
shadeOpaqueShader: {fileID: 7200000, guid: 0b64f79746d2daf4198eaf6eab9af259, type: 3}
m_DebugViewMaterialGBuffer: {fileID: 4800000, guid: 439949ea1bfa91b4ba0d04269fcde33d,
type: 3}

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassResources.cs


public ComputeShader buildPerTileLightListShader = null; // FPTL
public ComputeShader buildPerBigTileLightListShader = null;
public ComputeShader buildPerVoxelLightListShader = null; // clustered
public ComputeShader clearDispatchIndirectShader = null;
public ComputeShader shadeOpaqueShader = null;
// Various set of material use in render loop

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Builtin/BuiltinData.hlsl


//TODO: return this original relative path include after fixing a bug in Unity side
//#include "BuiltinData.cs.hlsl"
#include "HDRenderPipeline/Material/Builtin/BuiltinData.cs.hlsl"
#include "../../Material/Builtin/BuiltinData.cs.hlsl"
//-----------------------------------------------------------------------------
// common Encode/Decode functions

22
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
// enable dithering LOD crossfade
#pragma multi_compile _ LOD_FADE_CROSSFADE
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON

// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/common.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/ShaderPass/FragInputs.hlsl"
#include "HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
#include "../../../ShaderLibrary/common.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration

// variable declaration
//-------------------------------------------------------------------------------------
#include "HDRenderPipeline/Material/Lit/LitProperties.hlsl"
#include "../../Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_GBUFFER
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_FORWARD
#include "../../Lighting/Forward.hlsl"
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS

24
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader


#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
// enable dithering LOD crossfade
#pragma multi_compile _ LOD_FADE_CROSSFADE
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON

// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/common.hlsl"
#include "ShaderLibrary/tessellation.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/ShaderPass/FragInputs.hlsl"
#include "HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
#include "../../../ShaderLibrary/common.hlsl"
#include "../../../ShaderLibrary/tessellation.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration

// variable declaration
//-------------------------------------------------------------------------------------
#include "HDRenderPipeline/Material/Lit/LitProperties.hlsl"
#include "../../Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_GBUFFER
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_FORWARD
#include "../../Lighting/Forward.hlsl"
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS

33
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline

protected MaterialProperty detailSmoothnessScale = null;
protected const string kDetailSmoothnessScale = "_DetailSmoothnessScale";
protected MaterialProperty subsurfaceProfile = null;
protected const string kSubsurfaceProfile = "_SubsurfaceProfile";
protected SubsurfaceScatteringProfile subsurfaceProfile = null;
protected MaterialProperty subsurfaceProfileID = null;
protected const string kSubsurfaceProfileID = "_SubsurfaceProfile";
protected MaterialProperty subsurfaceRadius = null;
protected const string kSubsurfaceRadius = "_SubsurfaceRadius";
protected MaterialProperty subsurfaceRadiusMap = null;

detailSmoothnessScale = FindProperty(kDetailSmoothnessScale, props);
// Sub surface
subsurfaceProfile = FindProperty(kSubsurfaceProfile, props);
subsurfaceProfileID = FindProperty(kSubsurfaceProfileID, props);
subsurfaceRadius = FindProperty(kSubsurfaceRadius, props);
subsurfaceRadiusMap = FindProperty(kSubsurfaceRadiusMap, props);
thickness = FindProperty(kThickness, props);

protected void ShaderSSSInputGUI()
{
m_MaterialEditor.ShaderProperty(subsurfaceProfile, Styles.subsurfaceProfileText);
if (subsurfaceProfile == null)
{
int profileID = (int)subsurfaceProfileID.floatValue;
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if (profileID >= 0 && profileID < hdPipeline.sssSettings.profiles.Length)
{
// This is a valid profile ID.
subsurfaceProfile = hdPipeline.sssSettings.profiles[profileID];
}
else
{
subsurfaceProfile = SubsurfaceScatteringProfile.defaultProfile;
}
// Refresh the ID of the profile.
hdPipeline.sssSettings.OnValidate();
}
// Extract the profile ID.
subsurfaceProfile = EditorGUILayout.ObjectField(Styles.subsurfaceProfileText, subsurfaceProfile, subsurfaceProfile.GetType(), false, null) as SubsurfaceScatteringProfile;
subsurfaceProfileID.floatValue = subsurfaceProfile.settingsIndex;
m_MaterialEditor.ShaderProperty(subsurfaceRadius, Styles.subsurfaceRadiusText);
m_MaterialEditor.TexturePropertySingleLine(Styles.subsurfaceRadiusMapText, subsurfaceRadiusMap);
m_MaterialEditor.ShaderProperty(thickness, Styles.thicknessText);

17
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs


{
class StandardSpecularToHDLitMaterialUpgrader : MaterialUpgrader
{
public StandardSpecularToHDLitMaterialUpgrader()
public StandardSpecularToHDLitMaterialUpgrader() : this("Standard (Specular setup)", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass) {}
public StandardSpecularToHDLitMaterialUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer)
RenameShader("Standard (Specular setup)", "HDRenderPipeline/LitLegacySupport");
RenameShader(sourceShaderName, destShaderName, finalizer);
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");

RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameFloat("_Cutoff", "_AlphaCutoff");
RenameKeywordToFloat("_ALPHATEST_ON", "_AlphaCutoffEnable", 1f, 0f);
// the HD renderloop packs detail albedo and detail normals into a single texture.
// mapping the detail normal map, if any, to the detail map, should do the right thing if
// there is no detail albedo.
RenameTexture("_DetailNormalMap", "_DetailMap");
// Anything reasonable that can be done here?

[Test]
public void UpgradeMaterial()
{
var newShader = Shader.Find("HDRenderPipeline/LitLegacySupport");
var newShader = Shader.Find("HDRenderPipeline/Lit");
var mat = new Material(Shader.Find("Standard (Specular setup)"));
var albedo = new Texture2D(1, 1);
var normals = new Texture2D(1, 1);

mat.color = color;
mat.SetTextureScale("_MainTex", baseScale);
MaterialUpgrader.Upgrade(mat, new StandardSpecularToHDLitMaterialUpgrader(), MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties);
MaterialUpgrader.Upgrade(mat, this, MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties);
Assert.AreEqual(newShader, mat.shader);
Assert.AreEqual(albedo, mat.GetTexture("_BaseColorMap"));

Assert.IsTrue(mat.IsKeywordEnabled("_NORMALMAP"));
}
}
}

17
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs


using UnityEngine;
namespace UnityEditor.Experimental.Rendering.HDPipeline
class StandardToHDLitMaterialUpgrader : MaterialUpgrader
class StandardToHDLitMaterialUpgrader : MaterialUpgrader
public StandardToHDLitMaterialUpgrader()
public StandardToHDLitMaterialUpgrader() : this("Standard", "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass) { }
public StandardToHDLitMaterialUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer)
RenameShader("Standard", "HDRenderPipeline/LitLegacySupport");
RenameShader(sourceShaderName, destShaderName, finalizer);
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");

RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameFloat("_Cutoff", "_AlphaCutoff");
RenameKeywordToFloat("_ALPHATEST_ON", "_AlphaCutoffEnable", 1f, 0f);
// the HD renderloop packs detail albedo and detail normals into a single texture.
// mapping the detail normal map, if any, to the detail map, should do the right thing if

[Test]
public void UpgradeMaterial()
{
var newShader = Shader.Find("HDRenderPipeline/LitLegacySupport");
var newShader = Shader.Find("HDRenderPipeline/Lit");
var mat = new Material(Shader.Find("Standard"));
var albedo = new Texture2D(1, 1);
var normals = new Texture2D(1, 1);

mat.color = color;
mat.SetTextureScale("_MainTex", baseScale);
MaterialUpgrader.Upgrade(mat, new StandardToHDLitMaterialUpgrader(), MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties);
MaterialUpgrader.Upgrade(mat, this, MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties);
Assert.AreEqual(newShader, mat.shader);
Assert.AreEqual(albedo, mat.GetTexture("_BaseColorMap"));

Assert.IsTrue(mat.IsKeywordEnabled("_NORMALMAP"));
}
}
}

33
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


//-----------------------------------------------------------------------------
// SurfaceData is define in Lit.cs which generate Lit.cs.hlsl
//TODO: return this original relative path include after fixing a bug in Unity side
//#include "Lit.cs.hlsl"
#include "HDRenderPipeline/Material/Lit/Lit.cs.hlsl"
#include "Lit.cs.hlsl"
// In case we pack data uint16 buffer we need to change the output render target format to uint16
// TODO: Is there a way to automate these output type based on the format declare in lit.cs ?

#define LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX 2 // RGB, A unused
// SSS parameters
#define N_PROFILES 8
uint _TransmissionFlags; // One bit per profile; 1 = enabled
float _ThicknessRemaps[N_PROFILES][2]; // Remap: 0 = start, 1 = end - start
float4 _HalfRcpVariancesAndLerpWeights[N_PROFILES][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight
#define SSS_N_PROFILES 8
#define SSS_UNIT_CONVERSION (1.0 / 300.0) // From meters to 1/3 centimeters
uint _TransmissionFlags; // One bit per profile; 1 = enabled
float _ThicknessRemaps[SSS_N_PROFILES][2]; // Remap: 0 = start, 1 = end - start
float4 _HalfRcpVariancesAndLerpWeights[SSS_N_PROFILES][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material

// Thickness and SSS radius are decoupled for artists.
// In theory, we should modify the thickness by the inverse of the radius scale of the profile.
// thickness /= radiusScale;
thickness *= 100;
thickness /= SSS_UNIT_CONVERSION;
float t2 = thickness * thickness;

bsdfData.diffuseColor = surfaceData.baseColor;
bsdfData.fresnel0 = 0.028; // TODO take from subsurfaceProfile
bsdfData.subsurfaceProfile = surfaceData.subsurfaceProfile;
bsdfData.subsurfaceRadius = 0.01 * surfaceData.subsurfaceRadius;
bsdfData.thickness = 0.01 * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * surfaceData.thickness);
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule).
bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * surfaceData.subsurfaceRadius;
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * surfaceData.thickness);
bsdfData.enableTransmission = (1 << bsdfData.subsurfaceProfile) & _TransmissionFlags;
if (bsdfData.enableTransmission)
{

}
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile / 8.0); // Number of profile not define yet
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_N_PROFILES));
}
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT)
{

{
bsdfData.diffuseColor = baseColor;
bsdfData.fresnel0 = 0.028; // TODO take from subsurfaceProfile
bsdfData.subsurfaceProfile = 8.00 * inGBuffer2.a;
bsdfData.subsurfaceRadius = 0.01 * inGBuffer2.r;
bsdfData.thickness = 0.01 * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * inGBuffer2.g);
bsdfData.subsurfaceProfile = SSS_N_PROFILES * inGBuffer2.a;
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule).
bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * inGBuffer2.r;
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * inGBuffer2.g);
bsdfData.enableTransmission = (1 << bsdfData.subsurfaceProfile) & _TransmissionFlags;
if (bsdfData.enableTransmission)
{

24
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}
_SubsurfaceProfile("Subsurface Profile", Int) = 0
_SubsurfaceProfile("Subsurface Profile", Float) = 0
_SubsurfaceRadius("Subsurface Radius", Range(0.004, 1.0)) = 1.0
_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.004, 1.0)) = 1.0

#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
// enable dithering LOD crossfade
#pragma multi_compile _ LOD_FADE_CROSSFADE
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON

// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/common.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/ShaderPass/FragInputs.hlsl"
#include "HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
#include "../../../ShaderLibrary/common.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"
#include "HDRenderPipeline/Material/Lit/LitProperties.hlsl"
#include "../../Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_GBUFFER
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitSharePass.hlsl"
#include "LitData.hlsl"

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_FORWARD
#include "../../Lighting/Forward.hlsl"
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.y); // Note that we pass the quantized value of LOD fade
#endif
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;

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

void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.y); // Note that we pass the quantized value of LOD fade
#endif
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;

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

24
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader


#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
// enable dithering LOD crossfade
#pragma multi_compile _ LOD_FADE_CROSSFADE
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON

// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/common.hlsl"
#include "ShaderLibrary/tessellation.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/ShaderPass/FragInputs.hlsl"
#include "HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
#include "../../../ShaderLibrary/common.hlsl"
#include "../../../ShaderLibrary/tessellation.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"
#include "HDRenderPipeline/Material/Lit/LitProperties.hlsl"
#include "../../Material/Lit/LitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_GBUFFER
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitSharePass.hlsl"
#include "LitData.hlsl"

#define LIGHTING_DEBUG
#define SHADERPASS SHADERPASS_FORWARD
#include "../../Lighting/Forward.hlsl"
#include "HDRenderPipeline/Debug/HDRenderPipelineDebug.cs.hlsl"
#include "HDRenderPipeline/Debug/DebugLighting.hlsl"
#include "../../Debug/HDRenderPipelineDebug.cs.hlsl"
#include "../../Debug/DebugLighting.hlsl"
// TEMP until pragma work in include
#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs


{
public partial class RenderLoop : Object
{
static double[,] s_LtcDisneyDiffuseMatrixData = new double[k_LtcLUTResolution * k_LtcLUTResolution, k_LtcLUTMatrixDim * k_LtcLUTMatrixDim]
public static double[,] s_LtcDisneyDiffuseMatrixData = new double[k_LtcLUTResolution * k_LtcLUTResolution, k_LtcLUTMatrixDim * k_LtcLUTMatrixDim]
{
{1.018309, 0, 0.000000, 0, 1.018309, 0, 0.000000, 0, 1},
{1.018309, 0, 0.000000, 0, 1.018309, 0, 0.000000, 0, 1},

{1.106979, 0, 0.286686, 0, 1.061540, 0, -0.391058, 0, 1}
};
static float[] s_LtcDisneyDiffuseMagnitudeData = new float[k_LtcLUTResolution * k_LtcLUTResolution]
public static float[] s_LtcDisneyDiffuseMagnitudeData = new float[k_LtcLUTResolution * k_LtcLUTResolution]
{
0.978932f,
0.978932f,

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.GGX.cs


using UnityEngine;
using UnityEngine;
using UnityEngine.Rendering;
using System;

// This table is precomputed for squared roughness and normalized so that last entry
// is 1 and thus does not need to be store in a texture.
static double[,] s_LtcGGXMatrixData = new double[k_LtcLUTResolution * k_LtcLUTResolution, k_LtcLUTMatrixDim * k_LtcLUTMatrixDim]
public static double[,] s_LtcGGXMatrixData = new double[k_LtcLUTResolution * k_LtcLUTResolution, k_LtcLUTMatrixDim * k_LtcLUTMatrixDim]
{
{499.999756, 0, 0.000000, 0, 499.999756, 0, 0.000000, 0, 1},
{499.999756, 0, 0.000000, 0, 499.999756, 0, 0.000000, 0, 1},

{0.609037, 0, -0.053470, 0, 0.607151, 0, 0.031450, 0, 1}
};
static float[] s_LtcGGXMagnitudeData = new float[k_LtcLUTResolution * k_LtcLUTResolution]
public static float[] s_LtcGGXMagnitudeData = new float[k_LtcLUTResolution * k_LtcLUTResolution]
{
1.000000f,
1.000000f,

0.887423f
};
static float[] s_LtcGGXFresnelData = new float[k_LtcLUTResolution * k_LtcLUTResolution]
public static float[] s_LtcGGXFresnelData = new float[k_LtcLUTResolution * k_LtcLUTResolution]
{
0.000000f,
0.000000f,

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#include "HDRenderPipeline/Material/Material.hlsl"
#include "../../../Material/Material.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs

PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, uint2(0, 0));
float2 gBufferData = LOAD_TEXTURE2D(_GBufferTexture2, posInput.unPositionSS).ra;
int profileID = int(gBufferData.y * N_PROFILES);
float distScale = gBufferData.x * 0.01;
int profileID = N_PROFILES * gBufferData.y;
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule).
float distScale = (1.0 / 300.0) * gBufferData.x;
float invDistScale = rcp(distScale);
// Reconstruct the view-space position.

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


#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderVariables.hlsl"
struct Attributes

18
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl


#ifndef UNITY_MATERIAL_INCLUDED
#define UNITY_MATERIAL_INCLUDED
#include "ShaderLibrary/Color.hlsl"
#include "ShaderLibrary/Packing.hlsl"
#include "ShaderLibrary/BSDF.hlsl"
#include "ShaderLibrary/Debug.hlsl"
#include "ShaderLibrary/GeometricTools.hlsl"
#include "ShaderLibrary/CommonMaterial.hlsl"
#include "ShaderLibrary/EntityLighting.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../ShaderLibrary/Color.hlsl"
#include "../../ShaderLibrary/Packing.hlsl"
#include "../../ShaderLibrary/BSDF.hlsl"
#include "../../ShaderLibrary/Debug.hlsl"
#include "../../ShaderLibrary/GeometricTools.hlsl"
#include "../../ShaderLibrary/CommonMaterial.hlsl"
#include "../../ShaderLibrary/EntityLighting.hlsl"
#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
//-----------------------------------------------------------------------------
// BuiltinData

#include "Lit/Lit.hlsl"
#elif defined(UNITY_MATERIAL_UNLIT)
#include "Unlit/Unlit.hlsl"
#elif defined(UNITY_MATERIAL_IRIDESCENCE)
//#include "Iridescence/Iridescence.hlsl"
#endif
//-----------------------------------------------------------------------------

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader


// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/common.hlsl"
#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "HDRenderPipeline/ShaderPass/FragInputs.hlsl"
#include "HDRenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
#include "../../../ShaderLibrary/common.hlsl"
#include "../../ShaderConfig.cs.hlsl"
#include "../../ShaderVariables.hlsl"
#include "../../ShaderPass/FragInputs.hlsl"
#include "../../ShaderPass/ShaderPass.cs.hlsl"
#include "HDRenderPipeline/Material/Unlit/UnlitProperties.hlsl"
#include "../../Material/Unlit/UnlitProperties.hlsl"
// All our shaders use same name for entry point
#pragma vertex Vert

20
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Editor/PostProcessingSRPEditor.cs


namespace UnityEditor.Experimental.Rendering.HDPipeline
{
using GradingType = PostProcessing.ColorGradingSettings.GradingType;
using EyeAdaptationType = PostProcessing.EyeAdaptationSettings.EyeAdaptationType;
using GradingType = PostProcessingSRP.ColorGradingSettings.GradingType;
using EyeAdaptationType = PostProcessingSRP.EyeAdaptationSettings.EyeAdaptationType;
[CustomEditor(typeof(PostProcessing))]
[CustomEditor(typeof(PostProcessingSRP))]
public class PostProcessingEditor : Editor
{
#region Serialized settings

public VignetteSettings vignetteSettings;
public SerializedProperty globalDithering;
SerializedProperty FindProperty<TValue>(Expression<Func<PostProcessing, TValue>> expr)
SerializedProperty FindProperty<TValue>(Expression<Func<PostProcessingSRP, TValue>> expr)
{
var path = Utilities.GetFieldPath(expr);
return serializedObject.FindProperty(path);

void ColorGradingUI()
{
var camera = (target as PostProcessing).GetComponent<Camera>();
var camera = (target as PostProcessingSRP).GetComponent<Camera>();
if (camera != null)
{
using (new EditorGUILayout.HorizontalScope())

#region Color grading stuff
void SetLUTImportSettings()
{
var lut = (target as PostProcessing).colorGrading.logLut;
var lut = (target as PostProcessingSRP).colorGrading.logLut;
var importer = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(lut));
importer.textureType = TextureImporterType.Default;
importer.filterMode = FilterMode.Bilinear;

bool ValidateLutImportSettings()
{
var lut = (target as PostProcessing).colorGrading.logLut;
var lut = (target as PostProcessingSRP).colorGrading.logLut;
if (lut == null)
return true;

var targetRt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
// Render the current frame without post processing
var oldPPState = (target as PostProcessing).enabled;
(target as PostProcessing).enabled = false;
var oldPPState = (target as PostProcessingSRP).enabled;
(target as PostProcessingSRP).enabled = false;
var oldTarget = camera.targetTexture;
var oldActive = RenderTexture.active;
camera.targetTexture = targetRt;

texture.ReadPixels(new Rect(0, 0, targetRt.width, targetRt.height), 0, 0);
camera.targetTexture = oldTarget;
RenderTexture.active = oldActive;
(target as PostProcessing).enabled = oldPPState;
(target as PostProcessingSRP).enabled = oldPPState;
// Cleanup
RenderTexture.ReleaseTemporary(stampRt);

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/EyeAdaptation.shader


HLSLINCLUDE
#pragma target 4.5
#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../ShaderVariables.hlsl"
#include "EyeAdaptation.hlsl"
TEXTURE2D(_MainTex);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/EyeHistogram.compute


// Put the following line to 0 or comment it to disable vignette weighting
#define USE_VIGNETTE_WEIGHTING 1
#include "ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "EyeAdaptation.hlsl"
RWStructuredBuffer<uint> _Histogram;

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/FinalPass.shader


HLSLINCLUDE
#pragma target 4.5
#include "ShaderLibrary/Color.hlsl"
#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../ShaderVariables.hlsl"
#include "ColorGrading.hlsl"
TEXTURE2D(_MainTex);

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/LutGen.shader


Shader "Hidden/HDRenderPipeline/LutGen"
Shader "Hidden/HDRenderPipeline/LutGen"
#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../ShaderVariables.hlsl"
#include "ColorGrading.hlsl"
float4 _LutParams;

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessingSRP.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
using GradingType = PostProcessing.ColorGradingSettings.GradingType;
using EyeAdaptationType = PostProcessing.EyeAdaptationSettings.EyeAdaptationType;
using GradingType = PostProcessingSRP.ColorGradingSettings.GradingType;
using EyeAdaptationType = PostProcessingSRP.EyeAdaptationSettings.EyeAdaptationType;
public sealed partial class PostProcessing : MonoBehaviour
public sealed partial class PostProcessingSRP : MonoBehaviour
{
public EyeAdaptationSettings eyeAdaptation = new EyeAdaptationSettings();
public ColorGradingSettings colorGrading = new ColorGradingSettings();

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessingSRP.Settings.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
partial class PostProcessing
partial class PostProcessingSRP
{
[Serializable]
public sealed class ColorGradingSettings

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawGaussianProfile.shader


// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/Color.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../../ShaderVariables.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs

float4 Frag(Varyings input) : SV_Target
{
float dist = length(2 * input.texcoord - 1);
float dist = length(input.texcoord - 0.5);
float3 var1 = _StdDev1.rgb * _StdDev1.rgb;
float3 var2 = _StdDev2.rgb * _StdDev2.rgb;

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader


// Include
//-------------------------------------------------------------------------------------
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/Color.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../../ShaderVariables.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/FragInputs.hlsl


// This structure gather all possible varying/interpolator for this shader.
//-------------------------------------------------------------------------------------
#include "HDRenderPipeline/Debug/DebugViewMaterial.cs.hlsl"
#include "../Debug/DebugViewMaterial.cs.hlsl"
struct FragInputs
{

3
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
uint featureFlags = 0xFFFFFFFF;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
outColor = float4(diffuseLighting + specularLighting, builtinData.opacity);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs


float area = vl.screenRect.width * vl.screenRect.height;
long val = ShadowUtils.Asint( area );
val <<= 32;
val |= (long) vlidx;
val |= (long)(uint)vlidx;
m_TmpSortKeys.AddUnchecked( val );
}
m_TmpSortKeys.Sort();

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader


#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#include "ShaderLibrary/Color.hlsl"
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/CommonLighting.hlsl"
#include "../../../../ShaderLibrary/Color.hlsl"
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../../ShaderLibrary/CommonLighting.hlsl"
TEXTURECUBE(_Cubemap);
SAMPLERCUBE(sampler_Cubemap);

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader


#pragma multi_compile _ ATMOSPHERICS_DEBUG
#pragma multi_compile _ PERFORM_SKY_OCCLUSION_TEST
#include "ShaderLibrary/Color.hlsl"
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/CommonLighting.hlsl"
#include "../../../../ShaderLibrary/Color.hlsl"
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../../ShaderLibrary/CommonLighting.hlsl"
TEXTURECUBE(_Cubemap);
SAMPLERCUBE(sampler_Cubemap);

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/BuildProbabilityTables.compute


// Ref: PBRT v3, 13.6.7 "Piecewise-Constant 2D Distributions".
// Note that we use the equiareal sphere-to-square mapping instead of the latitude-longitude one.
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
/* --- Input --- */

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute


// Precomputes data for IntegrateLD(). See that function for a detailed description.
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
#define MAX_IBL_SAMPLE_CNT 89

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/Resources/GGXConvolve.shader


#pragma vertex Vert
#pragma fragment Frag
#include "ShaderLibrary/Common.hlsl"
#include "ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "../SkyManager.cs.hlsl"
struct Attributes

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs


Utilities.Destroy(m_SkyboxMarginalRowCdfRT);
Utilities.Destroy(m_SkyboxConditionalCdfRT);
m_UpdateRequired = true; // Special case. Even if update mode is set to OnDemand, we need to regenerate the environment after destroying the texture.
m_SkyboxCubemapRT = null;
m_SkyboxGGXCubemapRT = null;
m_SkyboxMarginalRowCdfRT = null;
m_SkyboxConditionalCdfRT = null;
}
if (m_SkyboxCubemapRT == null)

m_SkyboxConditionalCdfRT.filterMode = FilterMode.Point;
m_SkyboxConditionalCdfRT.Create();
}
m_UpdateRequired = true; // Special case. Even if update mode is set to OnDemand, we need to regenerate the environment after destroying the texture.
}
m_CubemapScreenSize = new Vector4((float)resolution, (float)resolution, 1.0f / (float)resolution, 1.0f / (float)resolution);

41
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


// This is the purpose of this macro
#define MERGE_NAME(X, Y) X##Y
// These define are use to abstract the way we sample into a cubemap array.
// Some platform don't support cubemap array so we fallback on 2D latlong
#ifdef UNITY_NO_CUBEMAP_ARRAY
#define TEXTURECUBE_ARRAY_ABSTRACT TEXTURE2D_ARRAY
#define SAMPLERCUBE_ABSTRACT SAMPLER2D
#define TEXTURECUBE_ARRAY_ARGS_ABSTRACT TEXTURE2D_ARRAY_ARGS
#define TEXTURECUBE_ARRAY_PARAM_ABSTRACT TEXTURE2D_ARRAY_PARAM
#define SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(textureName, samplerName, coord3, index, lod) SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, DirectionToLatLongCoordinate(coord3), index, lod)
#else
#define TEXTURECUBE_ARRAY_ABSTRACT TEXTURECUBE_ARRAY
#define SAMPLERCUBE_ABSTRACT SAMPLERCUBE
#define TEXTURECUBE_ARRAY_ARGS_ABSTRACT TEXTURECUBE_ARRAY_ARGS
#define TEXTURECUBE_ARRAY_PARAM_ABSTRACT TEXTURECUBE_ARRAY_PARAM
#define SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(textureName, samplerName, coord3, index, lod) SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#endif
// ----------------------------------------------------------------------------
// Common intrinsic (general implementation of intrinsic available on some platform)
// ----------------------------------------------------------------------------

return positionVS.xyz / positionVS.w;
}
// 'depthOffsetVS' is always along the forward direction 'camDirWS' pointing away from the camera.
void ApplyDepthOffsetPositionInput(float3 camDirWS, float depthOffsetVS, float4x4 viewProjMatrix, inout PositionInputs posInput)
// The view direction 'V' points towards the camera.
// 'depthOffsetVS' is always applied in the opposite direction (-V).
void ApplyDepthOffsetPositionInput(float3 V, float depthOffsetVS, float4x4 viewProjMatrix, inout PositionInputs posInput)
posInput.depthVS += depthOffsetVS;
posInput.positionWS += depthOffsetVS * camDirWS;
posInput.positionWS += depthOffsetVS * (-V);
posInput.depthVS = positionCS.w;
posInput.depthRaw = positionCS.z / positionCS.w;
}

{
float2 uv = float2((vertexID << 1) & 2, vertexID & 2);
return float4(uv * 2.0 - 1.0, 1.0, 1.0);
}
// LOD dithering transition helper
// ditherFactor should be a quantized value between 0..15/16, i.e the one provide by Unity
// LOD0 must use this function with ditherFactor 1..0
// LOD1 must use this functoin with ditherFactor 0..1
void LODDitheringTransition(uint2 unPositionSS, float ditherFactor)
{
// Generate a fixed pattern
float p = cos(dot(unPositionSS, float2(443.8975, 397.2973)));
p = frac(p * 491.1871);
// We want to have a symmetry between 0..0.5 ditherFactor and 0.5..1 so no pixels are transparent during the transition
// this is handled by this test which reverse the pattern
p = (ditherFactor >= 0.5) ? (15.0 / 16.0) - p : p;
clip(ditherFactor - p);
}
#endif // UNITY_COMMON_INCLUDED

157
Assets/ScriptableRenderPipeline/common/Camera/CameraSwitcher.cs


using System.Collections.Generic;
using UnityEngine;
public class CameraSwitcher : MonoBehaviour
namespace UnityEngine.Experimental.Rendering
public Camera[] m_Cameras;
public class CameraSwitcher : MonoBehaviour
{
public Camera[] m_Cameras;
private int m_CurrentCameraIndex = -1;
private Camera m_OriginalCamera = null;
private Vector3 m_OriginalCameraPosition;
private Quaternion m_OriginalCameraRotation;
private Camera m_CurrentCamera = null;
private int m_CurrentCameraIndex = -1;
private Camera m_OriginalCamera = null;
private Vector3 m_OriginalCameraPosition;
private Quaternion m_OriginalCameraRotation;
private Camera m_CurrentCamera = null;
private float m_MessageDuration = 1.0f;
private float m_MessageTimer = 1000.0f;
private float m_MessageDuration = 1.0f;
private float m_MessageTimer = 1000.0f;
private static string kDebugNext = "Debug Next";
private static string kDebugPrevious = "Debug Previous";
private string[] m_RequiredInputButtons = { kDebugNext, kDebugPrevious };
private bool m_Valid = true;
private static string kDebugNext = "Debug Next";
private static string kDebugPrevious = "Debug Previous";
private string[] m_RequiredInputButtons = { kDebugNext, kDebugPrevious };
private bool m_Valid = true;
void OnEnable()
{
m_OriginalCamera = GetComponent<Camera>();
m_CurrentCamera = m_OriginalCamera;
void OnEnable()
{
m_OriginalCamera = GetComponent<Camera>();
m_CurrentCamera = m_OriginalCamera;
m_Valid = Debugging.CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
m_Valid = Debugging.CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
int GetCameraCount()
{
return m_Cameras.Length + 1; // We need +1 for handling the original camera.
}
int GetCameraCount()
{
return m_Cameras.Length + 1; // We need +1 for handling the original camera.
}
void NextCamera()
{
m_CurrentCameraIndex = (m_CurrentCameraIndex + 1) % GetCameraCount();
}
void NextCamera()
{
m_CurrentCameraIndex = (m_CurrentCameraIndex + 1) % GetCameraCount();
}
void PreviousCamera()
{
m_CurrentCameraIndex = m_CurrentCameraIndex - 1;
if (m_CurrentCameraIndex == -1)
m_CurrentCameraIndex = m_Cameras.Length;
}
void PreviousCamera()
{
m_CurrentCameraIndex = m_CurrentCameraIndex - 1;
if (m_CurrentCameraIndex == -1)
m_CurrentCameraIndex = m_Cameras.Length;
}
Camera GetNextCamera()
{
if (m_CurrentCameraIndex == m_Cameras.Length)
return m_OriginalCamera;
else
return m_Cameras[m_CurrentCameraIndex];
}
Camera GetNextCamera()
{
if (m_CurrentCameraIndex == m_Cameras.Length)
return m_OriginalCamera;
else
return m_Cameras[m_CurrentCameraIndex];
}
void Update()
{
if (m_Valid && Debugging.debugControlEnabled && m_OriginalCamera != null)
void Update()
m_MessageTimer += Time.deltaTime;
bool needUpdateCamera = false;
if (Input.GetButtonDown(kDebugNext))
if (m_Valid && Debugging.debugControlEnabled && m_OriginalCamera != null)
NextCamera();
needUpdateCamera = true;
}
m_MessageTimer += Time.deltaTime;
bool needUpdateCamera = false;
if (Input.GetButtonDown(kDebugNext))
{
NextCamera();
needUpdateCamera = true;
}
if (Input.GetButtonDown(kDebugPrevious))
{
PreviousCamera();
needUpdateCamera = true;
}
if (needUpdateCamera)
{
m_MessageTimer = 0.0f;
if(m_CurrentCamera == m_OriginalCamera)
if (Input.GetButtonDown(kDebugPrevious))
m_OriginalCameraPosition = m_OriginalCamera.transform.position;
m_OriginalCameraRotation = m_OriginalCamera.transform.rotation;
PreviousCamera();
needUpdateCamera = true;
m_CurrentCamera = GetNextCamera();
if(m_CurrentCamera != null)
if (needUpdateCamera)
// If we witch back to the original camera, put back the transform in it.
if (m_CurrentCamera == m_OriginalCamera)
m_MessageTimer = 0.0f;
if(m_CurrentCamera == m_OriginalCamera)
m_OriginalCamera.transform.position = m_OriginalCameraPosition;
m_OriginalCamera.transform.rotation = m_OriginalCameraRotation;
m_OriginalCameraPosition = m_OriginalCamera.transform.position;
m_OriginalCameraRotation = m_OriginalCamera.transform.rotation;
transform.position = m_CurrentCamera.transform.position;
transform.rotation = m_CurrentCamera.transform.rotation;
m_CurrentCamera = GetNextCamera();
if(m_CurrentCamera != null)
{
// If we witch back to the original camera, put back the transform in it.
if (m_CurrentCamera == m_OriginalCamera)
{
m_OriginalCamera.transform.position = m_OriginalCameraPosition;
m_OriginalCamera.transform.rotation = m_OriginalCameraRotation;
}
transform.position = m_CurrentCamera.transform.position;
transform.rotation = m_CurrentCamera.transform.rotation;
}
}
if (m_MessageTimer < m_MessageDuration)
{
string cameraName = m_CurrentCamera != null ? m_CurrentCamera.name : "NULL";
string message = string.Format("Switching to camera : {0}", cameraName);
Debugging.PushDebugMessage(message);
if (m_MessageTimer < m_MessageDuration)
{
string cameraName = m_CurrentCamera != null ? m_CurrentCamera.name : "NULL";
string message = string.Format("Switching to camera : {0}", cameraName);
Debugging.PushDebugMessage(message);
}
}
}
}

102
Assets/ScriptableRenderPipeline/common/Camera/FreeCamera.cs


using UnityEngine;
public class FreeCamera : MonoBehaviour
namespace UnityEngine.Experimental.Rendering
public float m_LookSpeedController = 120f;
public float m_LookSpeedMouse = 10.0f;
public float m_MoveSpeed = 50.0f;
public float m_Turbo = 10.0f;
public class FreeCamera : MonoBehaviour
{
public float m_LookSpeedController = 120f;
public float m_LookSpeedMouse = 10.0f;
public float m_MoveSpeed = 50.0f;
public float m_Turbo = 10.0f;
private static string kMouseX = "Mouse X";
private static string kMouseY = "Mouse Y";
private static string kRightStickX = "Controller Right Stick X";
private static string kRightStickY = "Controller Right Stick Y";
private static string kVertical = "Vertical";
private static string kHorizontal = "Horizontal";
private string[] m_RequiredInputAxes = { kMouseX, kMouseY, kRightStickX, kRightStickY, kVertical, kHorizontal };
private static string kMouseX = "Mouse X";
private static string kMouseY = "Mouse Y";
private static string kRightStickX = "Controller Right Stick X";
private static string kRightStickY = "Controller Right Stick Y";
private static string kVertical = "Vertical";
private static string kHorizontal = "Horizontal";
private string[] m_RequiredInputAxes = { kMouseX, kMouseY, kRightStickX, kRightStickY, kVertical, kHorizontal };
private bool m_Valid = true;
void OnEnable()
{
m_Valid = Debugging.CheckRequiredInputAxisMapping(m_RequiredInputAxes);
}
private bool m_Valid = true;
void OnEnable()
{
m_Valid = Debugging.CheckRequiredInputAxisMapping(m_RequiredInputAxes);
}
void Update()
{
if(m_Valid)
void Update()
float inputRotateAxisX = 0.0f;
float inputRotateAxisY = 0.0f;
if (Input.GetMouseButton(1))
if(m_Valid)
inputRotateAxisX = Input.GetAxis(kMouseX) * m_LookSpeedMouse;
inputRotateAxisY = Input.GetAxis(kMouseY) * m_LookSpeedMouse;
}
inputRotateAxisX += (Input.GetAxis(kRightStickX) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisY += (Input.GetAxis(kRightStickY) * m_LookSpeedController * Time.deltaTime);
float inputRotateAxisX = 0.0f;
float inputRotateAxisY = 0.0f;
if (Input.GetMouseButton(1))
{
inputRotateAxisX = Input.GetAxis(kMouseX) * m_LookSpeedMouse;
inputRotateAxisY = Input.GetAxis(kMouseY) * m_LookSpeedMouse;
}
inputRotateAxisX += (Input.GetAxis(kRightStickX) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisY += (Input.GetAxis(kRightStickY) * m_LookSpeedController * Time.deltaTime);
float inputVertical = Input.GetAxis(kVertical);
float inputHorizontal = Input.GetAxis(kHorizontal);
float inputVertical = Input.GetAxis(kVertical);
float inputHorizontal = Input.GetAxis(kHorizontal);
bool moved = inputRotateAxisX != 0.0f || inputRotateAxisY != 0.0f || inputVertical != 0.0f || inputHorizontal != 0.0f;
if (moved)
{
float rotationX = transform.localEulerAngles.x;
float newRotationY = transform.localEulerAngles.y + inputRotateAxisX;
bool moved = inputRotateAxisX != 0.0f || inputRotateAxisY != 0.0f || inputVertical != 0.0f || inputHorizontal != 0.0f;
if (moved)
{
float rotationX = transform.localEulerAngles.x;
float newRotationY = transform.localEulerAngles.y + inputRotateAxisX;
// Weird clamping code due to weird Euler angle mapping...
float newRotationX = (rotationX - inputRotateAxisY);
if (rotationX <= 90.0f && newRotationX >= 0.0f)
newRotationX = Mathf.Clamp(newRotationX, 0.0f, 90.0f);
if (rotationX >= 270.0f)
newRotationX = Mathf.Clamp(newRotationX, 270.0f, 360.0f);
// Weird clamping code due to weird Euler angle mapping...
float newRotationX = (rotationX - inputRotateAxisY);
if (rotationX <= 90.0f && newRotationX >= 0.0f)
newRotationX = Mathf.Clamp(newRotationX, 0.0f, 90.0f);
if (rotationX >= 270.0f)
newRotationX = Mathf.Clamp(newRotationX, 270.0f, 360.0f);
transform.localRotation = Quaternion.Euler(newRotationX, newRotationY, transform.localEulerAngles.z);
transform.localRotation = Quaternion.Euler(newRotationX, newRotationY, transform.localEulerAngles.z);
float moveSpeed = Time.deltaTime * m_MoveSpeed;
if (Input.GetMouseButton(1))
moveSpeed *= Input.GetKey(KeyCode.LeftShift) ? m_Turbo : 1.0f;
else
moveSpeed *= Input.GetAxis("Fire1") > 0.0f ? m_Turbo : 1.0f;
transform.position += transform.forward * moveSpeed * inputVertical;
transform.position += transform.right * moveSpeed * inputHorizontal;
float moveSpeed = Time.deltaTime * m_MoveSpeed;
if (Input.GetMouseButton(1))
moveSpeed *= Input.GetKey(KeyCode.LeftShift) ? m_Turbo : 1.0f;
else
moveSpeed *= Input.GetAxis("Fire1") > 0.0f ? m_Turbo : 1.0f;
transform.position += transform.forward * moveSpeed * inputVertical;
transform.position += transform.right * moveSpeed * inputHorizontal;
}
}
}
}

191
Assets/ScriptableRenderPipeline/common/Debugging.cs


using System.Collections.Generic;
using UnityEngine;
public class Debugging : MonoBehaviour
namespace UnityEngine.Experimental.Rendering
public class Debugging : MonoBehaviour
{
private static bool m_DebugControlEnabled = false;
public static bool debugControlEnabled { get { return m_DebugControlEnabled; } }
private static bool m_DebugControlEnabled = false;
public static bool debugControlEnabled { get { return m_DebugControlEnabled; } }
private float m_DebugControlEnabledMsgTime = 3.0f;
private float m_DebugControlEnabledMsgTimer = 0.0f;
private float m_DebugControlEnabledMsgTime = 3.0f;
private float m_DebugControlEnabledMsgTimer = 0.0f;
private bool m_DebugKeyUp1 = false;
private bool m_DebugKeyUp2 = false;
private bool m_CanReceiveInput = true;
private bool m_DebugKeyUp1 = false;
private bool m_DebugKeyUp2 = false;
private bool m_CanReceiveInput = true;
private static List<string> m_DebugMessages = new List<string>();
private static List<string> m_DebugMessages = new List<string>();
private static string kEnableDebugBtn1 = "Enable Debug Button 1";
private static string kEnableDebugBtn2 = "Enable Debug Button 2";
private string[] m_RequiredInputButtons = { kEnableDebugBtn1, kEnableDebugBtn2 };
private bool m_Valid = true;
private static string kEnableDebugBtn1 = "Enable Debug Button 1";
private static string kEnableDebugBtn2 = "Enable Debug Button 2";
private string[] m_RequiredInputButtons = { kEnableDebugBtn1, kEnableDebugBtn2 };
private bool m_Valid = true;
public static void PushDebugMessage(string message)
{
m_DebugMessages.Add(message);
}
public static void PushDebugMessage(string message)
{
m_DebugMessages.Add(message);
}
static public bool CheckRequiredInputButtonMapping(string[] values)
{
bool inputsOk = true;
foreach(string value in values)
static public bool CheckRequiredInputButtonMapping(string[] values)
try
{
Input.GetButton(value);
}
catch
bool inputsOk = true;
foreach(string value in values)
Debug.LogWarning(string.Format("Required input button mapping missing: {0}.", value));
inputsOk = false;
try
{
Input.GetButton(value);
}
catch
{
Debug.LogWarning(string.Format("Required input button mapping missing: {0}.", value));
inputsOk = false;
}
}
return inputsOk;
}
return inputsOk;
}
static public bool CheckRequiredInputAxisMapping(string[] values)
{
bool inputsOk = true;
foreach (string value in values)
static public bool CheckRequiredInputAxisMapping(string[] values)
try
{
Input.GetAxis(value);
}
catch
bool inputsOk = true;
foreach (string value in values)
Debug.LogWarning(string.Format("Required input axis mapping missing: {0}.", value));
inputsOk = false;
try
{
Input.GetAxis(value);
}
catch
{
Debug.LogWarning(string.Format("Required input axis mapping missing: {0}.", value));
inputsOk = false;
}
return inputsOk;
return inputsOk;
}
void OnEnable()
{
m_Valid = CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
void OnEnable()
{
m_Valid = CheckRequiredInputButtonMapping(m_RequiredInputButtons);
}
void Update()
{
if(m_Valid)
void Update()
m_DebugControlEnabledMsgTimer += Time.deltaTime;
if(m_Valid)
{
m_DebugControlEnabledMsgTimer += Time.deltaTime;
bool enableDebug = Input.GetButton(kEnableDebugBtn1) && Input.GetButton(kEnableDebugBtn2) || Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.Backspace);
bool enableDebug = Input.GetButton(kEnableDebugBtn1) && Input.GetButton(kEnableDebugBtn2) || Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.Backspace);
if (m_CanReceiveInput && enableDebug)
{
m_DebugControlEnabled = !m_DebugControlEnabled;
m_DebugControlEnabledMsgTimer = 0.0f;
m_CanReceiveInput = false;
m_DebugKeyUp1 = false;
m_DebugKeyUp2 = false;
}
if (m_CanReceiveInput && enableDebug)
{
m_DebugControlEnabled = !m_DebugControlEnabled;
m_DebugControlEnabledMsgTimer = 0.0f;
m_CanReceiveInput = false;
m_DebugKeyUp1 = false;
m_DebugKeyUp2 = false;
}
if (Input.GetButtonUp(kEnableDebugBtn1))
{
m_DebugKeyUp1 = true;
}
if (Input.GetButtonUp(kEnableDebugBtn2))
{
m_DebugKeyUp2 = true;
}
if (Input.GetButtonUp(kEnableDebugBtn1))
{
m_DebugKeyUp1 = true;
}
if (Input.GetButtonUp(kEnableDebugBtn2))
{
m_DebugKeyUp2 = true;
}
// For keyboard you want to be able to keep ctrl pressed.
if (Input.GetKeyUp(KeyCode.Backspace))
{
m_DebugKeyUp1 = m_DebugKeyUp2 = true;
}
// For keyboard you want to be able to keep ctrl pressed.
if (Input.GetKeyUp(KeyCode.Backspace))
{
m_DebugKeyUp1 = m_DebugKeyUp2 = true;
}
m_CanReceiveInput = m_DebugKeyUp1 && m_DebugKeyUp2;
m_CanReceiveInput = m_DebugKeyUp1 && m_DebugKeyUp2;
if (m_DebugControlEnabledMsgTimer < m_DebugControlEnabledMsgTime)
{
if (m_DebugControlEnabled)
PushDebugMessage("Debug Controls Enabled");
else
PushDebugMessage("Debug Controls Disabled");
if (m_DebugControlEnabledMsgTimer < m_DebugControlEnabledMsgTime)
{
if (m_DebugControlEnabled)
PushDebugMessage("Debug Controls Enabled");
else
PushDebugMessage("Debug Controls Disabled");
}
}
void OnGUI()
{
using(new GUILayout.HorizontalScope())
void OnGUI()
GUILayout.Space(10.0f);
using(new GUILayout.VerticalScope())
using(new GUILayout.HorizontalScope())
for (int i = 0; i < m_DebugMessages.Count; ++i)
using(new GUILayout.VerticalScope())
GUILayout.Label(m_DebugMessages[i]);
GUILayout.Space(10.0f);
for (int i = 0; i < m_DebugMessages.Count; ++i)
{
GUILayout.Label(m_DebugMessages[i]);
}
// Make sure to clear only after all relevant events have occured.
if (Event.current.type == EventType.Repaint)
m_DebugMessages.Clear();
// Make sure to clear only after all relevant events have occured.
if (Event.current.type == EventType.Repaint)
m_DebugMessages.Clear();
}
}

415
Assets/ScriptableRenderPipeline/common/SkyboxHelper.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
public class SkyboxHelper
namespace UnityEngine.Experimental.Rendering
public SkyboxHelper()
public class SkyboxHelper
}
const int k_NumFullSubdivisions = 3; // 3 subdivs == 2048 triangles
const int k_NumHorizonSubdivisions = 2;
public void CreateMesh()
{
var vertData = new Vector3[8 * 3];
for (int i = 0; i < 8 * 3; i++)
public SkyboxHelper()
vertData[i] = m_OctaVerts[i];
// Regular subdivisions
for (int i = 0; i < k_NumFullSubdivisions; i++)
const int k_NumFullSubdivisions = 3; // 3 subdivs == 2048 triangles
const int k_NumHorizonSubdivisions = 2;
public void CreateMesh()
var srcData = vertData.Clone() as Vector3[];
var verts = new List<Vector3>();
for (int k = 0; k < srcData.Length; k += 3)
var vertData = new Vector3[8 * 3];
for (int i = 0; i < 8 * 3; i++)
Subdivide(verts, srcData[k], srcData[k + 1], srcData[k + 2]);
vertData[i] = m_OctaVerts[i];
vertData = verts.ToArray();
}
// Horizon subdivisions
var horizonLimit = 1.0f;
for (int i = 0; i < k_NumHorizonSubdivisions; i++)
{
var srcData = vertData.Clone() as Vector3[];
var verts = new List<Vector3>();
horizonLimit *= 0.5f; // First iteration limit to y < +-0.5, next one 0.25 etc.
for (int k = 0; k < srcData.Length; k += 3)
// Regular subdivisions
for (int i = 0; i < k_NumFullSubdivisions; i++)
var maxAbsY = Mathf.Max(Mathf.Abs(srcData[k].y), Mathf.Abs(srcData[k + 1].y), Mathf.Abs(srcData[k + 2].y));
if (maxAbsY > horizonLimit)
{
// Pass through existing triangle
verts.Add(srcData[k]);
verts.Add(srcData[k + 1]);
verts.Add(srcData[k + 2]);
}
else
var srcData = vertData.Clone() as Vector3[];
var verts = new List<Vector3>();
for (int k = 0; k < srcData.Length; k += 3)
SubdivideYOnly(verts, srcData[k], srcData[k + 1], srcData[k + 2]);
Subdivide(verts, srcData[k], srcData[k + 1], srcData[k + 2]);
vertData = verts.ToArray();
vertData = verts.ToArray();
}
// Write out the mesh
var vertexCount = vertData.Length;
var triangles = new int[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
triangles[i] = i;
}
// Horizon subdivisions
var horizonLimit = 1.0f;
for (int i = 0; i < k_NumHorizonSubdivisions; i++)
{
var srcData = vertData.Clone() as Vector3[];
var verts = new List<Vector3>();
m_Mesh = new Mesh
{
vertices = vertData,
triangles = triangles
};
}
horizonLimit *= 0.5f; // First iteration limit to y < +-0.5, next one 0.25 etc.
for (int k = 0; k < srcData.Length; k += 3)
{
var maxAbsY = Mathf.Max(Mathf.Abs(srcData[k].y), Mathf.Abs(srcData[k + 1].y), Mathf.Abs(srcData[k + 2].y));
if (maxAbsY > horizonLimit)
{
// Pass through existing triangle
verts.Add(srcData[k]);
verts.Add(srcData[k + 1]);
verts.Add(srcData[k + 2]);
}
else
{
SubdivideYOnly(verts, srcData[k], srcData[k + 1], srcData[k + 2]);
}
}
vertData = verts.ToArray();
}
public UnityEngine.Mesh mesh
{
get { return m_Mesh; }
}
// Write out the mesh
var vertexCount = vertData.Length;
var triangles = new int[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
triangles[i] = i;
}
public void Draw(ScriptableRenderContext loop, Camera camera)
{
if (camera.clearFlags != CameraClearFlags.Skybox)
{
return;
m_Mesh = new Mesh
{
vertices = vertData,
triangles = triangles
};
var mat = RenderSettings.skybox;
if (mat == null)
public UnityEngine.Mesh mesh
return;
get { return m_Mesh; }
var cmd = new CommandBuffer { name = "Skybox" };
var looksLikeSixSidedShader = true;
looksLikeSixSidedShader &= (mat.passCount == 6); // should have six passes
//looksLikeSixSidedShader &= !mat.GetShader()->GetShaderLabShader()->HasLightingPasses();
if (looksLikeSixSidedShader)
public void Draw(ScriptableRenderContext loop, Camera camera)
Debug.LogWarning("Six sided skybox not yet supported.");
}
else
{
if (mesh == null)
if (camera.clearFlags != CameraClearFlags.Skybox)
CreateMesh();
return;
var dist = camera.farClipPlane * 10.0f;
var mat = RenderSettings.skybox;
var world = Matrix4x4.TRS(camera.transform.position, Quaternion.identity, new Vector3(dist, dist, dist));
if (mat == null)
{
return;
}
var skyboxProj = SkyboxHelper.GetProjectionMatrix(camera);
cmd.SetViewProjectionMatrices (camera.worldToCameraMatrix, skyboxProj);
cmd.DrawMesh(mesh, world, mat);
var cmd = new CommandBuffer { name = "Skybox" };
cmd.SetViewProjectionMatrices (camera.worldToCameraMatrix, camera.projectionMatrix);
}
var looksLikeSixSidedShader = true;
looksLikeSixSidedShader &= (mat.passCount == 6); // should have six passes
//looksLikeSixSidedShader &= !mat.GetShader()->GetShaderLabShader()->HasLightingPasses();
loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
if (looksLikeSixSidedShader)
{
Debug.LogWarning("Six sided skybox not yet supported.");
}
else
{
if (mesh == null)
{
CreateMesh();
}
public static Matrix4x4 GetProjectionMatrix(Camera camera)
{
var skyboxProj = Matrix4x4.Perspective(camera.fieldOfView, camera.aspect, camera.nearClipPlane, camera.farClipPlane);
var dist = camera.farClipPlane * 10.0f;
var nearPlane = camera.nearClipPlane * 0.01f;
skyboxProj = AdjustDepthRange(skyboxProj, camera.nearClipPlane, nearPlane, camera.farClipPlane);
return MakeProjectionInfinite(skyboxProj, nearPlane);
}
var world = Matrix4x4.TRS(camera.transform.position, Quaternion.identity, new Vector3(dist, dist, dist));
static Matrix4x4 MakeProjectionInfinite(Matrix4x4 m, float nearPlane)
{
const float epsilon = 1e-6f;
var skyboxProj = SkyboxHelper.GetProjectionMatrix(camera);
cmd.SetViewProjectionMatrices (camera.worldToCameraMatrix, skyboxProj);
cmd.DrawMesh(mesh, world, mat);
var r = m;
r[2, 2] = -1.0f + epsilon;
r[2, 3] = (-2.0f + epsilon) * nearPlane;
r[3, 2] = -1.0f;
return r;
}
cmd.SetViewProjectionMatrices (camera.worldToCameraMatrix, camera.projectionMatrix);
}
static Matrix4x4 AdjustDepthRange(Matrix4x4 mat, float origNear, float newNear, float newFar)
{
var x = mat[0, 0];
var y = mat[1, 1];
var w = mat[0, 2];
var z = mat[1, 2];
loop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
var r = ((2.0f * origNear) / x) * ((w + 1) * 0.5f);
var t = ((2.0f * origNear) / y) * ((z + 1) * 0.5f);
var l = ((2.0f * origNear) / x) * (((w + 1) * 0.5f) - 1);
var b = ((2.0f * origNear) / y) * (((z + 1) * 0.5f) - 1);
public static Matrix4x4 GetProjectionMatrix(Camera camera)
{
var skyboxProj = Matrix4x4.Perspective(camera.fieldOfView, camera.aspect, camera.nearClipPlane, camera.farClipPlane);
var ratio = (newNear / origNear);
var nearPlane = camera.nearClipPlane * 0.01f;
skyboxProj = AdjustDepthRange(skyboxProj, camera.nearClipPlane, nearPlane, camera.farClipPlane);
return MakeProjectionInfinite(skyboxProj, nearPlane);
}
r *= ratio;
t *= ratio;
l *= ratio;
b *= ratio;
var ret = new Matrix4x4();
static Matrix4x4 MakeProjectionInfinite(Matrix4x4 m, float nearPlane)
{
const float epsilon = 1e-6f;
ret[0, 0] = (2.0f * newNear) / (r - l); ret[0, 1] = 0; ret[0, 2] = (r + l) / (r - l); ret[0, 3] = 0;
ret[1, 0] = 0; ret[1, 1] = (2.0f * newNear) / (t - b); ret[1, 2] = (t + b) / (t - b); ret[1, 3] = 0;
ret[2, 0] = 0; ret[2, 1] = 0; ret[2, 2] = -(newFar + newNear) / (newFar - newNear); ret[2, 3] = -(2.0f * newFar * newNear) / (newFar - newNear);
ret[3, 0] = 0; ret[3, 1] = 0; ret[3, 2] = -1.0f; ret[3, 3] = 0;
var r = m;
r[2, 2] = -1.0f + epsilon;
r[2, 3] = (-2.0f + epsilon) * nearPlane;
r[3, 2] = -1.0f;
return r;
}
return ret;
}
static Matrix4x4 AdjustDepthRange(Matrix4x4 mat, float origNear, float newNear, float newFar)
{
var x = mat[0, 0];
var y = mat[1, 1];
var w = mat[0, 2];
var z = mat[1, 2];
// Octahedron vertices
readonly Vector3[] m_OctaVerts =
{
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(-1.0f, 0.0f, 0.0f),
};
var r = ((2.0f * origNear) / x) * ((w + 1) * 0.5f);
var t = ((2.0f * origNear) / y) * ((z + 1) * 0.5f);
var l = ((2.0f * origNear) / x) * (((w + 1) * 0.5f) - 1);
var b = ((2.0f * origNear) / y) * (((z + 1) * 0.5f) - 1);
Vector3 SubDivVert(Vector3 v1, Vector3 v2)
{
return Vector3.Normalize(v1 + v2);
}
var ratio = (newNear / origNear);
void Subdivide(ICollection<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
{
var v12 = SubDivVert(v1, v2);
var v23 = SubDivVert(v2, v3);
var v13 = SubDivVert(v1, v3);
r *= ratio;
t *= ratio;
l *= ratio;
b *= ratio;
dest.Add(v1);
dest.Add(v12);
dest.Add(v13);
dest.Add(v12);
dest.Add(v2);
dest.Add(v23);
dest.Add(v23);
dest.Add(v13);
dest.Add(v12);
dest.Add(v3);
dest.Add(v13);
dest.Add(v23);
}
var ret = new Matrix4x4();
void SubdivideYOnly(ICollection<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
{
// Find out which vertex is furthest out from the others on the y axis
ret[0, 0] = (2.0f * newNear) / (r - l); ret[0, 1] = 0; ret[0, 2] = (r + l) / (r - l); ret[0, 3] = 0;
ret[1, 0] = 0; ret[1, 1] = (2.0f * newNear) / (t - b); ret[1, 2] = (t + b) / (t - b); ret[1, 3] = 0;
ret[2, 0] = 0; ret[2, 1] = 0; ret[2, 2] = -(newFar + newNear) / (newFar - newNear); ret[2, 3] = -(2.0f * newFar * newNear) / (newFar - newNear);
ret[3, 0] = 0; ret[3, 1] = 0; ret[3, 2] = -1.0f; ret[3, 3] = 0;
var d12 = Mathf.Abs(v2.y - v1.y);
var d23 = Mathf.Abs(v2.y - v3.y);
var d31 = Mathf.Abs(v3.y - v1.y);
return ret;
}
Vector3 top, va, vb;
// Octahedron vertices
readonly Vector3[] m_OctaVerts =
{
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, -1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(-1.0f, 0.0f, 0.0f),
};
if (d12 < d23 && d12 < d31)
Vector3 SubDivVert(Vector3 v1, Vector3 v2)
top = v3;
va = v1;
vb = v2;
}
else if (d23 < d12 && d23 < d31)
{
top = v1;
va = v2;
vb = v3;
}
else
{
top = v2;
va = v3;
vb = v1;
return Vector3.Normalize(v1 + v2);
var v12 = SubDivVert(top, va);
var v13 = SubDivVert(top, vb);
dest.Add(top);
dest.Add(v12);
dest.Add(v13);
// A bit of extra logic to prevent triangle slivers: choose the shorter of (13->va), (12->vb) as triangle base
if ((v13 - va).sqrMagnitude > (v12 - vb).sqrMagnitude)
void Subdivide(ICollection<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
var v12 = SubDivVert(v1, v2);
var v23 = SubDivVert(v2, v3);
var v13 = SubDivVert(v1, v3);
dest.Add(v1);
dest.Add(va);
dest.Add(vb);
dest.Add(v13);
dest.Add(v12);
dest.Add(v2);
dest.Add(v23);
dest.Add(v23);
dest.Add(vb);
dest.Add(v3);
dest.Add(v13);
dest.Add(v23);
else
void SubdivideYOnly(ICollection<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
dest.Add(v13);
// Find out which vertex is furthest out from the others on the y axis
var d12 = Mathf.Abs(v2.y - v1.y);
var d23 = Mathf.Abs(v2.y - v3.y);
var d31 = Mathf.Abs(v3.y - v1.y);
Vector3 top, va, vb;
if (d12 < d23 && d12 < d31)
{
top = v3;
va = v1;
vb = v2;
}
else if (d23 < d12 && d23 < d31)
{
top = v1;
va = v2;
vb = v3;
}
else
{
top = v2;
va = v3;
vb = v1;
}
var v12 = SubDivVert(top, va);
var v13 = SubDivVert(top, vb);
dest.Add(top);
dest.Add(va);
dest.Add(va);
dest.Add(vb);
// A bit of extra logic to prevent triangle slivers: choose the shorter of (13->va), (12->vb) as triangle base
if ((v13 - va).sqrMagnitude > (v12 - vb).sqrMagnitude)
{
dest.Add(v12);
dest.Add(va);
dest.Add(vb);
dest.Add(v13);
dest.Add(v12);
dest.Add(vb);
}
else
{
dest.Add(v13);
dest.Add(v12);
dest.Add(va);
dest.Add(v13);
dest.Add(va);
dest.Add(vb);
}
}
Mesh m_Mesh;
Mesh m_Mesh;
}
}

689
Assets/ScriptableRenderPipeline/common/TextureCache.cs


using UnityEditor;
#endif
public class TextureCache2D : TextureCache
namespace UnityEngine.Experimental.Rendering
private Texture2DArray m_Cache;
public override void TransferToSlice(int sliceIndex, Texture texture)
public class TextureCache2D : TextureCache
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
private Texture2DArray m_Cache;
if (texture is Texture2D)
public override void TransferToSlice(int sliceIndex, Texture texture)
mismatch |= (m_Cache.format != (texture as Texture2D).format);
}
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
if (mismatch)
{
if (!Graphics.ConvertTexture(texture, 0, m_Cache, sliceIndex))
if (texture is Texture2D)
Debug.LogErrorFormat(texture, "Unable to convert texture \"{0}\" to match renderloop settings ({1}x{2} {3})",
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
mismatch |= (m_Cache.format != (texture as Texture2D).format);
}
if (mismatch)
{
if (!Graphics.ConvertTexture(texture, 0, m_Cache, sliceIndex))
{
Debug.LogErrorFormat(texture, "Unable to convert texture \"{0}\" to match renderloop settings ({1}x{2} {3})",
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
}
}
else
{
Graphics.CopyTexture(texture, 0, m_Cache, sliceIndex);
else
public override Texture GetTexCache()
Graphics.CopyTexture(texture, 0, m_Cache, sliceIndex);
return m_Cache;
}
public bool AllocTextureArray(int numTextures, int width, int height, TextureFormat format, bool isMipMapped)
{
var res = AllocTextureArray(numTextures);
m_NumMipLevels = GetNumMips(width, height);
public override Texture GetTexCache()
{
return m_Cache;
}
m_Cache = new Texture2DArray(width, height, numTextures, format, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp
};
public bool AllocTextureArray(int numTextures, int width, int height, TextureFormat format, bool isMipMapped)
{
var res = AllocTextureArray(numTextures);
m_NumMipLevels = GetNumMips(width, height);
return res;
}
m_Cache = new Texture2DArray(width, height, numTextures, format, isMipMapped)
public void Release()
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp
};
return res;
Texture.DestroyImmediate(m_Cache); // do I need this?
}
public void Release()
public class TextureCacheCubemap : TextureCache
Texture.DestroyImmediate(m_Cache); // do I need this?
}
}
private CubemapArray m_Cache;
public class TextureCacheCubemap : TextureCache
{
private CubemapArray m_Cache;
// the member variables below are only in use when TextureCache.supportsCubemapArrayTextures is false
private Texture2DArray m_CacheNoCubeArray;
private RenderTexture[] m_StagingRTs;
private int m_NumPanoMipLevels;
private Material m_CubeBlitMaterial;
private int m_CubeMipLevelPropName;
private int m_cubeSrcTexPropName;
// the member variables below are only in use when TextureCache.supportsCubemapArrayTextures is false
private Texture2DArray m_CacheNoCubeArray;
private RenderTexture[] m_StagingRTs;
private int m_NumPanoMipLevels;
private Material m_CubeBlitMaterial;
private int m_CubeMipLevelPropName;
private int m_cubeSrcTexPropName;
public override void TransferToSlice(int sliceIndex, Texture texture)
{
if(!TextureCache.supportsCubemapArrayTextures)
TransferToPanoCache(sliceIndex, texture);
else
public override void TransferToSlice(int sliceIndex, Texture texture)
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
if (texture is Cubemap)
if(!TextureCache.supportsCubemapArrayTextures)
TransferToPanoCache(sliceIndex, texture);
else
mismatch |= (m_Cache.format != (texture as Cubemap).format);
}
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
if (mismatch)
{
bool failed = false;
if (texture is Cubemap)
{
mismatch |= (m_Cache.format != (texture as Cubemap).format);
}
for (int f = 0; f < 6; f++)
if (mismatch)
if (!Graphics.ConvertTexture(texture, f, m_Cache, 6 * sliceIndex + f))
bool failed = false;
for (int f = 0; f < 6; f++)
failed = true;
break;
if (!Graphics.ConvertTexture(texture, f, m_Cache, 6 * sliceIndex + f))
{
failed = true;
break;
}
}
if (failed)
if (failed)
{
Debug.LogErrorFormat(texture, "Unable to convert texture \"{0}\" to match renderloop settings ({1}x{2} {3})",
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
}
}
else
Debug.LogErrorFormat(texture, "Unable to convert texture \"{0}\" to match renderloop settings ({1}x{2} {3})",
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
for (int f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, m_Cache, 6 * sliceIndex + f);
else
{
for (int f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, m_Cache, 6 * sliceIndex + f);
}
}
public override Texture GetTexCache()
{
return !TextureCache.supportsCubemapArrayTextures ? (Texture) m_CacheNoCubeArray : m_Cache;
}
public override Texture GetTexCache()
{
return !TextureCache.supportsCubemapArrayTextures ? (Texture) m_CacheNoCubeArray : m_Cache;
}
public bool AllocTextureArray(int numCubeMaps, int width, TextureFormat format, bool isMipMapped)
{
var res = AllocTextureArray(numCubeMaps);
m_NumMipLevels = GetNumMips(width, width); // will calculate same way whether we have cube array or not
public bool AllocTextureArray(int numCubeMaps, int width, TextureFormat format, bool isMipMapped)
{
var res = AllocTextureArray(numCubeMaps);
m_NumMipLevels = GetNumMips(width, width); // will calculate same way whether we have cube array or not
if(!TextureCache.supportsCubemapArrayTextures)
{
if(!m_CubeBlitMaterial) m_CubeBlitMaterial = new Material(Shader.Find("Hidden/CubeToPano"));
if(!TextureCache.supportsCubemapArrayTextures)
{
if(!m_CubeBlitMaterial) m_CubeBlitMaterial = new Material(Shader.Find("Hidden/CubeToPano"));
int panoWidthTop = 4*width;
int panoHeightTop = 2*width;
int panoWidthTop = 4*width;
int panoHeightTop = 2*width;
// create panorama 2D array. Hardcoding the render target for now. No convenient way atm to
// map from TextureFormat to RenderTextureFormat and don't want to deal with sRGB issues for now.
m_CacheNoCubeArray = new Texture2DArray(panoWidthTop, panoHeightTop, numCubeMaps, TextureFormat.RGBAHalf, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Repeat,
wrapModeV = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0
};
// create panorama 2D array. Hardcoding the render target for now. No convenient way atm to
// map from TextureFormat to RenderTextureFormat and don't want to deal with sRGB issues for now.
m_CacheNoCubeArray = new Texture2DArray(panoWidthTop, panoHeightTop, numCubeMaps, TextureFormat.RGBAHalf, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Repeat,
wrapModeV = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0
};
m_NumPanoMipLevels = isMipMapped ? GetNumMips(panoWidthTop, panoHeightTop) : 1;
m_StagingRTs = new RenderTexture[m_NumPanoMipLevels];
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_StagingRTs[m] = new RenderTexture(Mathf.Max(1,panoWidthTop>>m), Mathf.Max(1,panoHeightTop>>m), 0, RenderTextureFormat.ARGBHalf);
}
m_NumPanoMipLevels = isMipMapped ? GetNumMips(panoWidthTop, panoHeightTop) : 1;
m_StagingRTs = new RenderTexture[m_NumPanoMipLevels];
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_StagingRTs[m] = new RenderTexture(Mathf.Max(1,panoWidthTop>>m), Mathf.Max(1,panoHeightTop>>m), 0, RenderTextureFormat.ARGBHalf);
if(m_CubeBlitMaterial)
{
m_CubeMipLevelPropName = Shader.PropertyToID("_cubeMipLvl");
m_cubeSrcTexPropName = Shader.PropertyToID("_srcCubeTexture");
}
if(m_CubeBlitMaterial)
else
m_CubeMipLevelPropName = Shader.PropertyToID("_cubeMipLvl");
m_cubeSrcTexPropName = Shader.PropertyToID("_srcCubeTexture");
m_Cache = new CubemapArray(width, numCubeMaps, format, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0 // It is important to set 0 here, else unity force anisotropy filtering
};
return res;
else
public void Release()
m_Cache = new CubemapArray(width, numCubeMaps, format, isMipMapped)
if (m_CacheNoCubeArray)
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0 // It is important to set 0 here, else unity force anisotropy filtering
};
Texture.DestroyImmediate(m_CacheNoCubeArray);
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_StagingRTs[m].Release();
}
m_StagingRTs=null;
if(m_CubeBlitMaterial) Material.DestroyImmediate(m_CubeBlitMaterial);
}
if (m_Cache)
Texture.DestroyImmediate(m_Cache);
return res;
}
public void Release()
{
if (m_CacheNoCubeArray)
private void TransferToPanoCache(int sliceIndex, Texture texture)
Texture.DestroyImmediate(m_CacheNoCubeArray);
m_CubeBlitMaterial.SetTexture(m_cubeSrcTexPropName, texture);
m_StagingRTs[m].Release();
m_CubeBlitMaterial.SetInt(m_CubeMipLevelPropName, Mathf.Min(m_NumMipLevels-1,m) );
Graphics.SetRenderTarget(m_StagingRTs[m]);
Graphics.Blit(null, m_CubeBlitMaterial, 0);
m_StagingRTs=null;
if(m_CubeBlitMaterial) Material.DestroyImmediate(m_CubeBlitMaterial);
}
if (m_Cache)
Texture.DestroyImmediate(m_Cache);
}
private void TransferToPanoCache(int sliceIndex, Texture texture)
{
m_CubeBlitMaterial.SetTexture(m_cubeSrcTexPropName, texture);
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_CubeBlitMaterial.SetInt(m_CubeMipLevelPropName, Mathf.Min(m_NumMipLevels-1,m) );
Graphics.SetRenderTarget(m_StagingRTs[m]);
Graphics.Blit(null, m_CubeBlitMaterial, 0);
for(int m=0; m<m_NumPanoMipLevels; m++)
Graphics.CopyTexture(m_StagingRTs[m], 0, 0, m_CacheNoCubeArray, sliceIndex, m);
for(int m=0; m<m_NumPanoMipLevels; m++)
Graphics.CopyTexture(m_StagingRTs[m], 0, 0, m_CacheNoCubeArray, sliceIndex, m);
}
public abstract class TextureCache
{
protected int m_NumMipLevels;
public abstract class TextureCache
{
protected int m_NumMipLevels;
static int s_GlobalTextureCacheVersion = 0;
int m_TextureCacheVersion = 0;
static int s_GlobalTextureCacheVersion = 0;
int m_TextureCacheVersion = 0;
#if UNITY_EDITOR
internal class AssetReloader : UnityEditor.AssetPostprocessor
{
void OnPostprocessTexture(Texture texture)
#if UNITY_EDITOR
internal class AssetReloader : UnityEditor.AssetPostprocessor
s_GlobalTextureCacheVersion++;
void OnPostprocessTexture(Texture texture)
{
s_GlobalTextureCacheVersion++;
}
}
#endif
#endif
public static bool isMobileBuildTarget
{
get
public static bool isMobileBuildTarget
#if UNITY_EDITOR
switch (EditorUserBuildSettings.activeBuildTarget)
get
case BuildTarget.iOS:
case BuildTarget.Android:
case BuildTarget.Tizen:
case BuildTarget.WSAPlayer:
// Note: We return true on purpose even if Windows Store Apps are running on Desktop.
return true;
default:
return false;
#if UNITY_EDITOR
switch (EditorUserBuildSettings.activeBuildTarget)
{
case BuildTarget.iOS:
case BuildTarget.Android:
case BuildTarget.Tizen:
case BuildTarget.WSAPlayer:
// Note: We return true on purpose even if Windows Store Apps are running on Desktop.
return true;
default:
return false;
}
#else
return Application.isMobilePlatform;
#endif
#else
return Application.isMobilePlatform;
#endif
}
public static TextureFormat GetPreferredCompressedTextureFormat
{
get
public static TextureFormat GetPreferredCompressedTextureFormat
var format = TextureFormat.RGBAHalf;
get
{
var format = TextureFormat.RGBAHalf;
var probeFormat = TextureFormat.BC6H;
var probeFormat = TextureFormat.BC6H;
// On editor the texture is uncompressed when operating against mobile build targets
if (SystemInfo.SupportsTextureFormat(probeFormat) && !TextureCache.isMobileBuildTarget)
format = probeFormat;
// On editor the texture is uncompressed when operating against mobile build targets
if (SystemInfo.SupportsTextureFormat(probeFormat) && !TextureCache.isMobileBuildTarget)
format = probeFormat;
return format;
return format;
}
}
public static bool supportsCubemapArrayTextures
{
get
public static bool supportsCubemapArrayTextures
return (SystemInfo.supportsCubemapArrayTextures && !TextureCache.isMobileBuildTarget);
get
{
return (SystemInfo.supportsCubemapArrayTextures && !TextureCache.isMobileBuildTarget);
}
}
private struct SSliceEntry
{
public uint texId;
public uint countLRU;
};
private struct SSliceEntry
{
public uint texId;
public uint countLRU;
};
private int m_NumTextures;
private int[] m_SortedIdxArray;
private SSliceEntry[] m_SliceArray;
private int m_NumTextures;
private int[] m_SortedIdxArray;
private SSliceEntry[] m_SliceArray;
Dictionary<uint, int> m_LocatorInSliceArray;
Dictionary<uint, int> m_LocatorInSliceArray;
private static uint g_MaxFrameCount = unchecked((uint)(-1));
private static uint g_InvalidTexID = (uint)0;
private static uint g_MaxFrameCount = unchecked((uint)(-1));
private static uint g_InvalidTexID = (uint)0;
public int FetchSlice(Texture texture)
{
var texId = (uint)texture.GetInstanceID();
public int FetchSlice(Texture texture)
{
var texId = (uint)texture.GetInstanceID();
//assert(TexID!=g_InvalidTexID);
if (texId == g_InvalidTexID) return 0;
//assert(TexID!=g_InvalidTexID);
if (texId == g_InvalidTexID) return 0;
var bSwapSlice = false;
var bFoundAvailOrExistingSlice = false;
var sliceIndex = -1;
var bSwapSlice = false;
var bFoundAvailOrExistingSlice = false;
var sliceIndex = -1;
// search for existing copy
if (m_LocatorInSliceArray.ContainsKey(texId))
{
if (m_TextureCacheVersion != s_GlobalTextureCacheVersion)
// search for existing copy
if (m_LocatorInSliceArray.ContainsKey(texId))
m_LocatorInSliceArray.Remove(texId);
m_TextureCacheVersion++;
Debug.Assert(m_TextureCacheVersion <= s_GlobalTextureCacheVersion);
if (m_TextureCacheVersion != s_GlobalTextureCacheVersion)
{
m_LocatorInSliceArray.Remove(texId);
m_TextureCacheVersion++;
Debug.Assert(m_TextureCacheVersion <= s_GlobalTextureCacheVersion);
}
else
{
sliceIndex = m_LocatorInSliceArray[texId];
bFoundAvailOrExistingSlice = true;
}
//assert(m_SliceArray[sliceIndex].TexID==TexID);
else
// If no existing copy found in the array
if (!bFoundAvailOrExistingSlice)
sliceIndex = m_LocatorInSliceArray[texId];
bFoundAvailOrExistingSlice = true;
// look for first non zero entry. Will by the least recently used entry
// since the array was pre-sorted (in linear time) in NewFrame()
var bFound = false;
int j = 0, idx = 0;
while ((!bFound) && j < m_NumTextures)
{
idx = m_SortedIdxArray[j];
if (m_SliceArray[idx].countLRU == 0) ++j; // if entry already snagged by a new texture in this frame then ++j
else bFound = true;
}
if (bFound)
{
// if we are replacing an existing entry delete it from m_locatorInSliceArray.
if (m_SliceArray[idx].texId != g_InvalidTexID)
{
m_LocatorInSliceArray.Remove(m_SliceArray[idx].texId);
}
m_LocatorInSliceArray.Add(texId, idx);
m_SliceArray[idx].texId = texId;
sliceIndex = idx;
bFoundAvailOrExistingSlice = true;
bSwapSlice = true;
}
//assert(m_SliceArray[sliceIndex].TexID==TexID);
// wrap up
//assert(bFoundAvailOrExistingSlice);
if (bFoundAvailOrExistingSlice)
{
m_SliceArray[sliceIndex].countLRU = 0; // mark slice as in use this frame
if (bSwapSlice) // if this was a miss
{
// transfer new slice to sliceIndex from source texture
TransferToSlice(sliceIndex, texture);
}
}
return sliceIndex;
// If no existing copy found in the array
if (!bFoundAvailOrExistingSlice)
public void NewFrame()
// look for first non zero entry. Will by the least recently used entry
// since the array was pre-sorted (in linear time) in NewFrame()
var bFound = false;
int j = 0, idx = 0;
while ((!bFound) && j < m_NumTextures)
var numNonZeros = 0;
var tmpBuffer = new int[m_NumTextures];
for (int i = 0; i < m_NumTextures; i++)
idx = m_SortedIdxArray[j];
if (m_SliceArray[idx].countLRU == 0) ++j; // if entry already snagged by a new texture in this frame then ++j
else bFound = true;
tmpBuffer[i] = m_SortedIdxArray[i]; // copy buffer
if (m_SliceArray[m_SortedIdxArray[i]].countLRU != 0) ++numNonZeros;
if (bFound)
int nonZerosBase = 0, zerosBase = 0;
for (int i = 0; i < m_NumTextures; i++)
// if we are replacing an existing entry delete it from m_locatorInSliceArray.
if (m_SliceArray[idx].texId != g_InvalidTexID)
if (m_SliceArray[tmpBuffer[i]].countLRU == 0)
{
m_SortedIdxArray[zerosBase + numNonZeros] = tmpBuffer[i];
++zerosBase;
}
else
m_LocatorInSliceArray.Remove(m_SliceArray[idx].texId);
m_SortedIdxArray[nonZerosBase] = tmpBuffer[i];
++nonZerosBase;
}
m_LocatorInSliceArray.Add(texId, idx);
m_SliceArray[idx].texId = texId;
sliceIndex = idx;
bFoundAvailOrExistingSlice = true;
bSwapSlice = true;
for (int i = 0; i < m_NumTextures; i++)
{
if (m_SliceArray[i].countLRU < g_MaxFrameCount) ++m_SliceArray[i].countLRU; // next frame
//for(int q=1; q<m_numTextures; q++)
// assert(m_SliceArray[m_SortedIdxArray[q-1]].CountLRU>=m_SliceArray[m_SortedIdxArray[q]].CountLRU);
// wrap up
//assert(bFoundAvailOrExistingSlice);
if (bFoundAvailOrExistingSlice)
protected TextureCache()
m_SliceArray[sliceIndex].countLRU = 0; // mark slice as in use this frame
if (bSwapSlice) // if this was a miss
{
// transfer new slice to sliceIndex from source texture
TransferToSlice(sliceIndex, texture);
}
m_NumTextures = 0;
m_NumMipLevels = 0;
return sliceIndex;
}
public virtual void TransferToSlice(int sliceIndex, Texture texture)
{
}
public void NewFrame()
{
var numNonZeros = 0;
var tmpBuffer = new int[m_NumTextures];
for (int i = 0; i < m_NumTextures; i++)
public virtual Texture GetTexCache()
tmpBuffer[i] = m_SortedIdxArray[i]; // copy buffer
if (m_SliceArray[m_SortedIdxArray[i]].countLRU != 0) ++numNonZeros;
return null;
int nonZerosBase = 0, zerosBase = 0;
for (int i = 0; i < m_NumTextures; i++)
protected bool AllocTextureArray(int numTextures)
if (m_SliceArray[tmpBuffer[i]].countLRU == 0)
if (numTextures > 0)
m_SortedIdxArray[zerosBase + numNonZeros] = tmpBuffer[i];
++zerosBase;
}
else
{
m_SortedIdxArray[nonZerosBase] = tmpBuffer[i];
++nonZerosBase;
m_SliceArray = new SSliceEntry[numTextures];
m_SortedIdxArray = new int[numTextures];
m_LocatorInSliceArray = new Dictionary<uint, int>();
m_NumTextures = numTextures;
for (int i = 0; i < m_NumTextures; i++)
{
m_SliceArray[i].countLRU = g_MaxFrameCount; // never used before
m_SliceArray[i].texId = g_InvalidTexID;
m_SortedIdxArray[i] = i;
}
//return m_SliceArray != NULL && m_SortedIdxArray != NULL && numTextures > 0;
return numTextures > 0;
for (int i = 0; i < m_NumTextures; i++)
// should not really be used in general. Assuming lights are culled properly entries will automatically be replaced efficiently.
public void RemoveEntryFromSlice(Texture texture)
if (m_SliceArray[i].countLRU < g_MaxFrameCount) ++m_SliceArray[i].countLRU; // next frame
}
var texId = (uint)texture.GetInstanceID();
//for(int q=1; q<m_numTextures; q++)
// assert(m_SliceArray[m_SortedIdxArray[q-1]].CountLRU>=m_SliceArray[m_SortedIdxArray[q]].CountLRU);
}
//assert(TexID!=g_InvalidTexID);
if (texId == g_InvalidTexID) return;
protected TextureCache()
{
m_NumTextures = 0;
m_NumMipLevels = 0;
}
// search for existing copy
if (!m_LocatorInSliceArray.ContainsKey(texId))
return;
public virtual void TransferToSlice(int sliceIndex, Texture texture)
{
}
var sliceIndex = m_LocatorInSliceArray[texId];
public virtual Texture GetTexCache()
{
return null;
}
protected bool AllocTextureArray(int numTextures)
{
if (numTextures > 0)
{
m_SliceArray = new SSliceEntry[numTextures];
m_SortedIdxArray = new int[numTextures];
m_LocatorInSliceArray = new Dictionary<uint, int>();
//assert(m_SliceArray[sliceIndex].TexID==TexID);
m_NumTextures = numTextures;
for (int i = 0; i < m_NumTextures; i++)
// locate entry sorted by uCountLRU in m_pSortedIdxArray
var foundIdxSortLRU = false;
var i = 0;
while ((!foundIdxSortLRU) && i < m_NumTextures)
m_SliceArray[i].countLRU = g_MaxFrameCount; // never used before
m_SliceArray[i].texId = g_InvalidTexID;
m_SortedIdxArray[i] = i;
if (m_SortedIdxArray[i] == sliceIndex) foundIdxSortLRU = true;
else ++i;
}
//return m_SliceArray != NULL && m_SortedIdxArray != NULL && numTextures > 0;
return numTextures > 0;
}
if (!foundIdxSortLRU)
return;
// should not really be used in general. Assuming lights are culled properly entries will automatically be replaced efficiently.
public void RemoveEntryFromSlice(Texture texture)
{
var texId = (uint)texture.GetInstanceID();
// relocate sliceIndex to front of m_pSortedIdxArray since uCountLRU will be set to maximum.
for (int j = 0; j < i; j++)
{
m_SortedIdxArray[j + 1] = m_SortedIdxArray[j];
}
m_SortedIdxArray[0] = sliceIndex;
//assert(TexID!=g_InvalidTexID);
if (texId == g_InvalidTexID) return;
// search for existing copy
if (!m_LocatorInSliceArray.ContainsKey(texId))
return;
var sliceIndex = m_LocatorInSliceArray[texId];
//assert(m_SliceArray[sliceIndex].TexID==TexID);
// delete from m_locatorInSliceArray and m_pSliceArray.
m_LocatorInSliceArray.Remove(texId);
m_SliceArray[sliceIndex].countLRU = g_MaxFrameCount; // never used before
m_SliceArray[sliceIndex].texId = g_InvalidTexID;
}
// locate entry sorted by uCountLRU in m_pSortedIdxArray
var foundIdxSortLRU = false;
var i = 0;
while ((!foundIdxSortLRU) && i < m_NumTextures)
protected int GetNumMips(int width, int height)
if (m_SortedIdxArray[i] == sliceIndex) foundIdxSortLRU = true;
else ++i;
return GetNumMips(width > height ? width : height);
if (!foundIdxSortLRU)
return;
// relocate sliceIndex to front of m_pSortedIdxArray since uCountLRU will be set to maximum.
for (int j = 0; j < i; j++)
protected int GetNumMips(int dim)
m_SortedIdxArray[j + 1] = m_SortedIdxArray[j];
var uDim = (uint)dim;
var iNumMips = 0;
while (uDim > 0)
{ ++iNumMips; uDim >>= 1; }
return iNumMips;
m_SortedIdxArray[0] = sliceIndex;
// delete from m_locatorInSliceArray and m_pSliceArray.
m_LocatorInSliceArray.Remove(texId);
m_SliceArray[sliceIndex].countLRU = g_MaxFrameCount; // never used before
m_SliceArray[sliceIndex].texId = g_InvalidTexID;
}
protected int GetNumMips(int width, int height)
{
return GetNumMips(width > height ? width : height);
}
protected int GetNumMips(int dim)
{
var uDim = (uint)dim;
var iNumMips = 0;
while (uDim > 0)
{ ++iNumMips; uDim >>= 1; }
return iNumMips;
}
}

21
Assets/ScriptableRenderPipeline/fptl/TiledLightingUtils.hlsl


uStart = tileOffs;
}
uint FetchIndexOpaque(const uint tileOffs, const uint l)
{
const uint l1 = l+1;
return (g_vLightListGlobal[ 16*tileOffs + (l1>>1)]>>((l1&1)*16))&0xffff;
}
#ifdef OPAQUES_ONLY
void GetCountAndStart(out uint uStart, out uint uNrLights, uint2 pixCoord, float linDepth, uint model)

uint FetchIndex(const uint tileOffs, const uint l)
{
return FetchIndexOpaque(tileOffs, l);
const uint l1 = l+1;
return (g_vLightListGlobal[ 16*tileOffs + (l1>>1)]>>((l1&1)*16))&0xffff;
}
#else

uint FetchIndex(const uint tileOffs, const uint l)
{
uint offs = tileOffs+l;
const uint l1 = l+1;
return FetchIndexOpaque(tileOffs, l);
else
return g_vLightListGlobal[ tileOffs+l ];
offs = 16*tileOffs + (l1>>1);
// Avoid generated HLSL bytecode to always access g_vLightListGlobal with
// two different offsets, fixes out of bounds issue
uint value = g_vLightListGlobal[offs];
return (g_isOpaquesOnlyEnabled ? ((value >>((l1&1)*16))&0xffff) : value);
}
#endif

7
Assets/ScriptableRenderPipeline/fptl/lightlistbuild-clustered.compute


{
for(int l=(int) t; l<((iNrCoarseLights+1)>>1); l += NR_THREADS)
{
const int l0 = coarseList[2*l+0], l1 = coarseList[min(2*l+1,iNrCoarseLights)];
const int l0 = coarseList[2*l+0], l1 = coarseList[min(2*l+1,iNrCoarseLights-1)];
const unsigned int clustIdxMi0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0].z), suggestedBase));
const unsigned int clustIdxMa0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0+g_iNrVisibLights].z), suggestedBase));
const unsigned int clustIdxMi1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1].z), suggestedBase));

{
int offs = 0;
for(int l=0; l<iNrCoarseLights; l++)
{ if(coarseList[l]!=0xffffffff) coarseList[offs++] = coarseList[l]; }
{
if(coarseList[l]!=0xffffffff)
coarseList[offs++] = coarseList[l];
}
lightOffsSph = offs;
}

2
Assets/ScriptableRenderPipeline/fptl/lightlistbuild.compute


const int nrDWords = ((nrLightsFinalClamped+1)+1)>>1;
for(int l=(int) t; l<(int) nrDWords; l += NR_THREADS)
{
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[2 * l - 1 + localOffs];
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[max(0,2 * l - 1 + localOffs)];
uint uHigh = prunedList[2 * l + 0 + localOffs];
g_vLightList[16*offs + l] = (uLow&0xffff) | (uHigh<<16);

196
Assets/TestScenes/HDTest/CascadedShadowsTest.unity


--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2

m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 8
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024

m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 3
m_MixedBakeMode: 2
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0

m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 112000001, guid: 486568bfdf60faf4ebe9d16745eee81f,
type: 2}
m_ShadowMaskMode: 2
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_Father: {fileID: 1072694791}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1479937107
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1479937113}
- component: {fileID: 1479937112}
- component: {fileID: 1479937111}
- component: {fileID: 1479937110}
- component: {fileID: 1479937109}
- component: {fileID: 1479937108}
m_Layer: 0
m_Name: Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1479937108
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1479937107}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 618b0e3f6c65dd247a4a016150006c57, type: 3}
m_Name:
m_EditorClassIdentifier:
m_LookSpeedController: 120
m_LookSpeedMouse: 10
m_MoveSpeed: 50
m_Turbo: 10
--- !u!81 &1479937109
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1479937107}
m_Enabled: 1
--- !u!92 &1479937110
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1479937107}
m_Enabled: 1
--- !u!124 &1479937111
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1479937107}
m_Enabled: 1
--- !u!20 &1479937112
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1479937107}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
m_StereoMirrorMode: 0
--- !u!4 &1479937113
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1479937107}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -41.54449, y: 13.5, z: 6.8429947}
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}
--- !u!1 &1492665064
GameObject:
m_ObjectHideFlags: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

shadowResolution: 1024
m_innerSpotPercent: 0
shadowDimmer: 1
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1018c405244bf2a4486e83573f3d173d, type: 2}
- {fileID: 2100000, guid: 906f2e00230e2a34b832d52909cc5906, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

49
Assets/TestScenes/HDTest/GlobalIlluminationTest.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.3199536, g: 0.2875398, b: 0.2644253, a: 1}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
serializedVersion: 9
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2

m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 7
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024

m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_StationaryBakeMode: 0
m_MixedBakeMode: 0
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0

m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 112000022, guid: 3d51fc2c60f333c44b613049001dfba8,
type: 2}
m_RuntimeCPUUsage: 50
m_ShadowMaskMode: 0
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2

m_Name:
m_EditorClassIdentifier:
shadowResolution: 512
m_innerSpotPercent: 0
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

m_Name:
m_EditorClassIdentifier:
shadowResolution: 512
m_innerSpotPercent: 0
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

- component: {fileID: 1879932839}
- component: {fileID: 1879932838}
- component: {fileID: 1879932843}
- component: {fileID: 1879932844}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera

m_Script: {fileID: 11500000, guid: 92bb16b4ee20841929b24d6bd771738d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1879932844
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1879932837}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 618b0e3f6c65dd247a4a016150006c57, type: 3}
m_Name:
m_EditorClassIdentifier:
m_LookSpeedController: 120
m_LookSpeedMouse: 10
m_MoveSpeed: 50
m_Turbo: 10
--- !u!1 &1910068096
GameObject:
m_ObjectHideFlags: 0

m_Script: {fileID: 11500000, guid: bc357c46587fc9d4cb8f311794d7d2f3, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SkyRendererTypeName: UnityEngine.Experimental.Rendering.HDPipeline.HDRISkyRenderer
m_ShadowMaxDistance: 1000
m_ShadowCascadeCount: 4
m_ShadowCascadeSplit0: 0.05
m_ShadowCascadeSplit1: 0.2
m_ShadowCascadeSplit2: 0.3
m_Settings:
m_ShadowMaxDistance: 1000
m_ShadowCascadeCount: 4
m_ShadowCascadeSplit0: 0.05
m_ShadowCascadeSplit1: 0.2
m_ShadowCascadeSplit2: 0.3
m_ShadowNearPlaneOffset: 5
--- !u!4 &1944423448
Transform:
m_ObjectHideFlags: 0

3
Assets/TestScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Rock.mat


m_Name: Tessellation - Rock
m_Shader: {fileID: 4800000, guid: 756bac9090102564582875f4c7e30202, type: 3}
m_ShaderKeywords: _EMISSIVE_COLOR _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_TESSELLATION_DISPLACEMENT
_TESSELLATION_DISPLACEMENT _TESSELLATION_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_CustomRenderQueue: -1

- _TessellationMode: 1
- _TessellationObjectScale: 0
- _TessellationShapeFactor: 0.75
- _TessellationTilingScale: 1
- _TexWorldScale: 1
- _Thickness: 0.5
- _UVBase: 0

2
Assets/TestScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat


m_Name: Tessellation - Wood
m_Shader: {fileID: 4800000, guid: 756bac9090102564582875f4c7e30202, type: 3}
m_ShaderKeywords: _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE _TESSELLATION_DISPLACEMENT
_TESSELLATION_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_CustomRenderQueue: -1

- _TessellationMode: 1
- _TessellationObjectScale: 0
- _TessellationShapeFactor: 0.75
- _TessellationTilingScale: 1
- _TexWorldScale: 1
- _Thickness: 1
- _UVBase: 0

42
Assets/TestScenes/HDTest/HDRenderLoopTest.unity


m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 192903503}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.317, y: -3.331, z: -2}
m_LocalPosition: {x: -0.05, y: -0.25, z: -2.0000005}
m_LocalScale: {x: 0, y: 0, z: 1.0000005}
m_Children: []
m_Father: {fileID: 2026378394}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 733865593}
m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068}
m_LocalPosition: {x: -70.16, y: 19.980022, z: 20.6868}
m_LocalPosition: {x: -15.023401, y: 19.980022, z: 20.6868}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 645322208}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 785457124}
m_LocalRotation: {x: -0.0034919123, y: 0.0089843245, z: -0.007998787, w: 0.99992156}
m_LocalPosition: {x: -98.92, y: 1.87, z: 0}
m_LocalPosition: {x: 4.38, y: 1.87, z: 6.11}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 144382660}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 970745596}
m_LocalRotation: {x: 0.31429112, y: 0.005978446, z: -0.010438241, w: 0.94925046}
m_LocalPosition: {x: -93.29, y: 2.75, z: -3.662}
m_LocalPosition: {x: 3.576, y: 2.75, z: -3.662}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 144382660}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1035518232}
m_LocalRotation: {x: -0, y: 0.51840013, z: -0, w: 0.8551382}
m_LocalPosition: {x: -19.7, y: 1.8, z: -16.28}
m_LocalPosition: {x: -0.7599983, y: 1.8, z: -1.5999994}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 933267878}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1085128921}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.067, y: -3.081, z: -2}
m_LocalPosition: {x: -0.3, y: 0, z: -2.0000005}
m_LocalScale: {x: 1, y: 1, z: 1.0000005}
m_Children: []
m_Father: {fileID: 2026378394}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1220024533}
m_LocalRotation: {x: -0.0034919123, y: 0.0089843245, z: -0.007998787, w: 0.99992156}
m_LocalPosition: {x: -96.23, y: 1.453, z: 1.334}
m_LocalPosition: {x: 0.632, y: 1.453, z: 1.334}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 144382660}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1226270484}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 10, y: 0, z: -35}
m_LocalPosition: {x: 10, y: 1, z: -35}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 399109505}

- component: {fileID: 1828470161}
- component: {fileID: 1828470160}
- component: {fileID: 1828470165}
- component: {fileID: 1828470166}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera

m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1828470159}
m_LocalRotation: {x: 0.45985717, y: -0, z: -0, w: 0.887993}
m_LocalPosition: {x: -99.9, y: 4.52, z: -8.07}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalEulerAnglesHint: {x: 54.756004, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1828470165
MonoBehaviour:
m_ObjectHideFlags: 0

m_Script: {fileID: 11500000, guid: 92bb16b4ee20841929b24d6bd771738d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1828470166
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1828470159}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 618b0e3f6c65dd247a4a016150006c57, type: 3}
m_Name:
m_EditorClassIdentifier:
m_LookSpeedController: 120
m_LookSpeedMouse: 10
m_MoveSpeed: 50
m_Turbo: 10
--- !u!1 &1828745839
GameObject:
m_ObjectHideFlags: 0

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1854618464}
m_LocalRotation: {x: -0.0034919123, y: 0.0089843245, z: -0.007998787, w: 0.99992156}
m_LocalPosition: {x: -99.85, y: 1.411, z: -3.83}
m_LocalPosition: {x: 3.446, y: 1.411, z: 2.277}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 144382660}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2015022933}
m_LocalRotation: {x: -0.258819, y: 0, z: 0, w: 0.9659259}
m_LocalPosition: {x: 1.317, y: -3.081, z: -2}
m_LocalPosition: {x: -0.05, y: 0, z: -2}
m_LocalScale: {x: 0, y: 0, z: 1.0000005}
m_Children: []
m_Father: {fileID: 2026378394}

40
Assets/TestScenes/HDTest/LayeredLitTest.unity


--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2

m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 7
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024

m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_StationaryBakeMode: 1
m_MixedBakeMode: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0

m_PVRFilteringAtrousNormalSigma: 1
m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 0}
m_ShadowMaskMode: 2
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2

shadowResolution: 512
m_innerSpotPercent: 0
shadowDimmer: 1
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 0
archetype: 0

shadowResolution: 512
m_innerSpotPercent: 0
shadowDimmer: 1
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

shadowResolution: 512
m_innerSpotPercent: 0
shadowDimmer: 1
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

shadowResolution: 512
m_innerSpotPercent: 0
shadowDimmer: 1
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

- component: {fileID: 1879932839}
- component: {fileID: 1879932838}
- component: {fileID: 1879932843}
- component: {fileID: 1879932844}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera

m_Script: {fileID: 11500000, guid: 92bb16b4ee20841929b24d6bd771738d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1879932844
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1879932837}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 618b0e3f6c65dd247a4a016150006c57, type: 3}
m_Name:
m_EditorClassIdentifier:
m_LookSpeedController: 120
m_LookSpeedMouse: 10
m_MoveSpeed: 50
m_Turbo: 10
--- !u!43 &1895850407
Mesh:
m_ObjectHideFlags: 0

shadowResolution: 512
m_innerSpotPercent: 0
shadowDimmer: 1
lightDimmer: 1
fadeDistance: 10000
shadowFadeDistance: 10000
affectDiffuse: 1
affectSpecular: 1
archetype: 0

40
Assets/TestScenes/HDTest/LayeredLitTest/Textures/Detail_Checker.tga.meta


mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0

textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
wrapMode: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50

crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Tizen
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: PS4
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
physicsShape: []
spritePackingTag:
userData:
assetBundleName:

4
Assets/TestScenes/HDTest/Rock/rcgRock012/Materials/rcgRock012Material.mat


- _HorizonFade: 1
- _MaterialID: 0
- _Metalic: 0
- _Metallic: 0.583
- _Metallic: 0
- _Mettalic: 0
- _Mode: 0
- _NormalMapSpace: 0

- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _Parallax: 0.02
- _Smoothness: 0
- _Smoothness: 0.524
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.1.0a4
m_EditorVersion: 2017.1.0a5

2
ProjectSettings/QualitySettings.asset


shadowProjection: 1
shadowCascades: 2
shadowDistance: 200
shadowNearPlaneOffset: 5
shadowNearPlaneOffset: 2
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.021409363, y: 0.051549375, z: 0.07213539}
blendWeights: 4

9
Assets/LowEndMobilePipeline.meta


fileFormatVersion: 2
guid: 7a2706b41ea31e54d9e4ca93be22278a
folderAsset: yes
timeCreated: 1481548458
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/Plugins.meta


fileFormatVersion: 2
guid: b18282e7b9e41194a9ccbdd7f1e00f91
folderAsset: yes
timeCreated: 1484737171
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

35
Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: Default SSS Profile
m_EditorClassIdentifier:
stdDev1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
stdDev2: {r: 0.6, g: 0.6, b: 0.6, a: 0}
lerpWeight: 0.5
enableTransmission: 0
thicknessRemap: {x: 0, y: 1}
settingsIndex: 0
m_FilterKernel:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.7609476}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.49358216}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.4935822}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.7609475}
m_HalfRcpVariances:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888}
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset.meta


fileFormatVersion: 2
guid: 09521380d86baee43bf09b32473ea5f3
timeCreated: 1490117690
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

41
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/FeatureFlags.hlsl


#ifndef __FEATURE_FLAGS_H__
#define __FEATURE_FLAGS_H__
#include "TilePass.cs.hlsl"
static const uint FeatureVariantFlags[NUM_FEATURE_VARIANTS] =
{
/* 0 */ 0,
/* 1 */ FEATURE_FLAG_SKY_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT,
/* 2 */ FEATURE_FLAG_SKY_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT | FEATURE_FLAG_ENV_LIGHT,
/* 3 */ FEATURE_FLAG_SKY_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT | FEATURE_FLAG_PUNCTUAL_LIGHT,
/* 3 */ FEATURE_FLAG_SKY_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT | FEATURE_FLAG_PUNCTUAL_LIGHT | FEATURE_FLAG_ENV_LIGHT,
/* 5 */ FEATURE_FLAG_SKY_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT | FEATURE_FLAG_AREA_LIGHT,
/* 6 */ FEATURE_FLAG_SKY_LIGHT | FEATURE_FLAG_DIRECTIONAL_LIGHT | FEATURE_FLAG_AREA_LIGHT | FEATURE_FLAG_PUNCTUAL_LIGHT | FEATURE_FLAG_ENV_LIGHT,
/* 7 */ 0xFFFFFFFF,
};
/*
public static uint FEATURE_FLAG_PUNCTUAL_LIGHT = 1<<0;
public static uint FEATURE_FLAG_AREA_LIGHT = 1<<1;
public static uint FEATURE_FLAG_DIRECTIONAL_LIGHT = 1<<2;
public static uint FEATURE_FLAG_ENV_LIGHT = 1<<3;
public static uint FEATURE_FLAG_SKY_LIGHT = 1<<4;
*/
uint FeatureFlagsToTileVariant(uint featureFlags)
{
for(int i = 0; i < NUM_FEATURE_VARIANTS; i++)
{
if((featureFlags & FeatureVariantFlags[i]) == featureFlags)
return i;
}
return NUM_FEATURE_VARIANTS - 1;
}
uint TileVariantToFeatureFlags(uint variant)
{
return FeatureVariantFlags[variant];
}
#endif

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/FeatureFlags.hlsl.meta


fileFormatVersion: 2
guid: 0ef495ee49d152b419e9fd62aa24523f
timeCreated: 1489679489
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

11
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/cleardispatchindirect.compute


#pragma kernel ClearDispatchIndirect
RWBuffer<uint> g_DispatchIndirectBuffer : register( u0 ); // Indirect arguments have to be in a _buffer_, not a structured buffer
[numthreads(64, 1, 1)]
void ClearDispatchIndirect(uint dispatchThreadId : SV_DispatchThreadID)
{
g_DispatchIndirectBuffer[dispatchThreadId * 3 + 0] = 0; // ThreadGroupCountX
g_DispatchIndirectBuffer[dispatchThreadId * 3 + 1] = 1; // ThreadGroupCountY
g_DispatchIndirectBuffer[dispatchThreadId * 3 + 2] = 1; // ThreadGroupCountZ
}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/cleardispatchindirect.compute.meta


fileFormatVersion: 2
guid: fc1f553acb80a6446a32d33e403d0656
timeCreated: 1490196244
licenseType: Pro
ComputeShaderImporter:
currentAPIMask: 8196
userData:
assetBundleName:
assetBundleVariant:

494
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public class SubsurfaceScatteringProfile : ScriptableObject
{
public const int numSamples = 11; // Must be an odd number
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev1;
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev2;
[SerializeField]
public float lerpWeight;
[SerializeField]
public bool enableTransmission;
[SerializeField]
public Vector2 thicknessRemap;
[SerializeField] [HideInInspector]
public int settingsIndex;
[SerializeField] [HideInInspector]
Vector4[] m_FilterKernel;
[SerializeField] [HideInInspector]
Vector3[] m_HalfRcpVariances;
[SerializeField] [HideInInspector]
Vector4 m_HalfRcpWeightedVariances;
private static SubsurfaceScatteringProfile s_DefaultProfile = null; // Singleton
// --- Public Methods ---
public static SubsurfaceScatteringProfile defaultProfile
{
get
{
if (s_DefaultProfile == null)
{
#if UNITY_EDITOR
s_DefaultProfile = CreateInstance<SubsurfaceScatteringProfile>();
AssetDatabase.CreateAsset(s_DefaultProfile, "Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset");
AssetDatabase.SaveAssets();
#else
throw new UnassignedReferenceException("SubsurfaceScatteringProfile.defaultProfile can not be null.");
#endif
}
return s_DefaultProfile;
}
}
public SubsurfaceScatteringProfile()
{
stdDev1 = new Color(0.3f, 0.3f, 0.3f, 0.0f);
stdDev2 = new Color(0.6f, 0.6f, 0.6f, 0.0f);
lerpWeight = 0.5f;
enableTransmission = false;
thicknessRemap = new Vector2(0, 1);
settingsIndex = 0;
UpdateKernelAndVarianceData();
}
public Vector4[] filterKernel
{
// Set via UpdateKernelAndVarianceData().
get { return m_FilterKernel; }
}
public Vector3[] halfRcpVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpVariances; }
}
public Vector4 halfRcpWeightedVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpWeightedVariances; }
}
public void UpdateKernelAndVarianceData()
{
if (m_FilterKernel == null || m_FilterKernel.Length != numSamples)
{
m_FilterKernel = new Vector4[numSamples];
}
if (m_HalfRcpVariances == null)
{
m_HalfRcpVariances = new Vector3[2];
}
// Our goal is to blur the image using a filter which is represented
// as a product of a linear combination of two normalized 1D Gaussians
// as suggested by Jimenez et al. in "Separable Subsurface Scattering".
// A normalized (i.e. energy-preserving) 1D Gaussian with the mean of 0
// is defined as follows: G1(x, v) = exp(-x * x / (2 * v)) / sqrt(2 * Pi * v),
// where 'v' is variance and 'x' is the radial distance from the origin.
// Using the weight 'w', our 1D and the resulting 2D filters are given as:
// A1(v1, v2, w, x) = G1(x, v1) * (1 - w) + G1(r, v2) * w,
// A2(v1, v2, w, x, y) = A1(v1, v2, w, x) * A1(v1, v2, w, y).
// The resulting filter function is a non-Gaussian PDF.
// It is separable by design, but generally not radially symmetric.
// Find the widest Gaussian across 3 color channels.
float maxStdDev1 = Mathf.Max(stdDev1.r, stdDev1.g, stdDev1.b);
float maxStdDev2 = Mathf.Max(stdDev2.r, stdDev2.g, stdDev2.b);
Vector3 weightSum = new Vector3(0, 0, 0);
// Importance sample the linear combination of two Gaussians.
for (uint i = 0; i < numSamples; i++)
{
float u = (i + 0.5f) / numSamples;
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, lerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, lerpWeight);
Vector3 val;
val.x = GaussianCombination(pos, stdDev1.r, stdDev2.r, lerpWeight);
val.y = GaussianCombination(pos, stdDev1.g, stdDev2.g, lerpWeight);
val.z = GaussianCombination(pos, stdDev1.b, stdDev2.b, lerpWeight);
// We do not divide by 'numSamples' since we will renormalize, anyway.
m_FilterKernel[i].x = val.x * (1 / pdf);
m_FilterKernel[i].y = val.y * (1 / pdf);
m_FilterKernel[i].z = val.z * (1 / pdf);
m_FilterKernel[i].w = pos;
weightSum.x += m_FilterKernel[i].x;
weightSum.y += m_FilterKernel[i].y;
weightSum.z += m_FilterKernel[i].z;
}
// Renormalize the weights to conserve energy.
for (uint i = 0; i < numSamples; i++)
{
m_FilterKernel[i].x *= 1 / weightSum.x;
m_FilterKernel[i].y *= 1 / weightSum.y;
m_FilterKernel[i].z *= 1 / weightSum.z;
}
// Store (1 / (2 * Variance)) per color channel per Gaussian.
m_HalfRcpVariances[0].x = 0.5f / (stdDev1.r * stdDev1.r);
m_HalfRcpVariances[0].y = 0.5f / (stdDev1.g * stdDev1.g);
m_HalfRcpVariances[0].z = 0.5f / (stdDev1.b * stdDev1.b);
m_HalfRcpVariances[1].x = 0.5f / (stdDev2.r * stdDev2.r);
m_HalfRcpVariances[1].y = 0.5f / (stdDev2.g * stdDev2.g);
m_HalfRcpVariances[1].z = 0.5f / (stdDev2.b * stdDev2.b);
Vector4 weightedStdDev;
weightedStdDev.x = Mathf.Lerp(stdDev1.r, stdDev2.r, lerpWeight);
weightedStdDev.y = Mathf.Lerp(stdDev1.g, stdDev2.g, lerpWeight);
weightedStdDev.z = Mathf.Lerp(stdDev1.b, stdDev2.b, lerpWeight);
weightedStdDev.w = Mathf.Lerp(maxStdDev1, maxStdDev2, lerpWeight);
// Store (1 / (2 * WeightedVariance)) per color channel.
m_HalfRcpWeightedVariances.x = 0.5f / (weightedStdDev.x * weightedStdDev.x);
m_HalfRcpWeightedVariances.y = 0.5f / (weightedStdDev.y * weightedStdDev.y);
m_HalfRcpWeightedVariances.z = 0.5f / (weightedStdDev.z * weightedStdDev.z);
m_HalfRcpWeightedVariances.w = 0.5f / (weightedStdDev.w * weightedStdDev.w);
}
// --- Private Methods ---
static float Gaussian(float x, float stdDev)
{
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
}
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
}
static float RationalApproximation(float t)
{
// Abramowitz and Stegun formula 26.2.23.
// The absolute value of the error should be less than 4.5 e-4.
float[] c = {2.515517f, 0.802853f, 0.010328f};
float[] d = {1.432788f, 0.189269f, 0.001308f};
return t - ((c[2] * t + c[1]) * t + c[0]) / (((d[2] * t + d[1]) * t + d[0]) * t + 1.0f);
}
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
{
float x;
if (p < 0.5)
{
// F^-1(p) = - G^-1(p)
x = -RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(p)));
}
else
{
// F^-1(p) = G^-1(1-p)
x = RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(1.0f - p)));
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
}
[Serializable]
public class SubsurfaceScatteringSettings
{
public enum TexturingMode : int { PreScatter = 0, PostScatter = 1, PreAndPostScatter = 2, MaxValue = 2 };
public const int maxNumProfiles = 8;
public int numProfiles;
public TexturingMode texturingMode;
public int transmissionFlags;
public SubsurfaceScatteringProfile[] profiles;
public float[] thicknessRemaps;
public Vector4[] halfRcpVariancesAndLerpWeights;
public Vector4[] halfRcpWeightedVariances;
public Vector4[] filterKernels;
// --- Public Methods ---
public SubsurfaceScatteringSettings()
{
numProfiles = 1;
texturingMode = TexturingMode.PreScatter;
profiles = null;
thicknessRemaps = null;
halfRcpVariancesAndLerpWeights = null;
halfRcpWeightedVariances = null;
filterKernels = null;
}
public void OnValidate()
{
if (profiles == null)
{
// It will be called during the initialization of the HDRenderPipeline.
CreateProfiles();
}
numProfiles = Math.Max(1, Math.Min(profiles.Length, maxNumProfiles));
if (profiles.Length != numProfiles)
{
Array.Resize(ref profiles, numProfiles);
}
for (int i = 0; i < numProfiles; i++)
{
if (profiles[i] == null)
{
// No invalid/empty assets allowed!
profiles[i] = SubsurfaceScatteringProfile.defaultProfile;
}
// Assign profile IDs.
profiles[i].settingsIndex = i;
}
texturingMode = (TexturingMode)Math.Max(0, Math.Min((int)texturingMode, (int)TexturingMode.MaxValue));
if (thicknessRemaps == null || thicknessRemaps.Length != (maxNumProfiles * 2))
{
thicknessRemaps = new float[maxNumProfiles * 2];
}
if (halfRcpVariancesAndLerpWeights == null || halfRcpVariancesAndLerpWeights.Length != (maxNumProfiles * 2))
{
halfRcpVariancesAndLerpWeights = new Vector4[maxNumProfiles * 2];
}
if (halfRcpWeightedVariances == null || halfRcpWeightedVariances.Length != maxNumProfiles)
{
halfRcpWeightedVariances = new Vector4[maxNumProfiles];
}
if (filterKernels == null || filterKernels.Length != (maxNumProfiles * SubsurfaceScatteringProfile.numSamples))
{
filterKernels = new Vector4[maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
}
transmissionFlags = 0;
Color c = new Color();
for (int i = 0; i < numProfiles; i++)
{
transmissionFlags |= (profiles[i].enableTransmission ? 1 : 0) << i;
c.r = Mathf.Clamp(profiles[i].stdDev1.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].stdDev1.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(profiles[i].stdDev1.b, 0.05f, 2.0f);
c.a = 0.0f;
profiles[i].stdDev1 = c;
c.r = Mathf.Clamp(profiles[i].stdDev2.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].stdDev2.g, 0.05f, 2.0f);
c.b = Mathf.Clamp(profiles[i].stdDev2.b, 0.05f, 2.0f);
c.a = 0.0f;
profiles[i].stdDev2 = c;
profiles[i].lerpWeight = Mathf.Clamp01(profiles[i].lerpWeight);
profiles[i].thicknessRemap.x = Mathf.Clamp(profiles[i].thicknessRemap.x, 0, profiles[i].thicknessRemap.y);
profiles[i].thicknessRemap.y = Mathf.Max(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y);
profiles[i].UpdateKernelAndVarianceData();
}
// Use the updated data to fill the cache.
for (int i = 0; i < numProfiles; i++)
{
thicknessRemaps[2 * i] = profiles[i].thicknessRemap.x;
thicknessRemaps[2 * i + 1] = profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x;
halfRcpVariancesAndLerpWeights[2 * i] = profiles[i].halfRcpVariances[0];
halfRcpVariancesAndLerpWeights[2 * i].w = 1.0f - profiles[i].lerpWeight;
halfRcpVariancesAndLerpWeights[2 * i + 1] = profiles[i].halfRcpVariances[1];
halfRcpVariancesAndLerpWeights[2 * i + 1].w = profiles[i].lerpWeight;
halfRcpWeightedVariances[i] = profiles[i].halfRcpWeightedVariances;
for (int j = 0, n = SubsurfaceScatteringProfile.numSamples; j < n; j++)
{
filterKernels[n * i + j] = profiles[i].filterKernel[j];
}
}
}
// --- Private Methods ---
// Limitation of Unity - cannot create assets in the constructor.
public void CreateProfiles()
{
profiles = new SubsurfaceScatteringProfile[numProfiles];
for (int i = 0; i < numProfiles; i++)
{
profiles[i] = SubsurfaceScatteringProfile.defaultProfile;
}
}
}
#if UNITY_EDITOR
public class SubsurfaceScatteringProfileFactory
{
[MenuItem("Assets/Create/Subsurface Scattering Profile", priority = 666)]
static void MenuCreateSubsurfaceScatteringProfile()
{
Texture2D icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,
ScriptableObject.CreateInstance<DoCreateSubsurfaceScatteringProfile>(),
"New SSS Profile.asset", icon, null);
}
public static SubsurfaceScatteringProfile CreateSssProfileAtPath(string path)
{
var profile = ScriptableObject.CreateInstance<SubsurfaceScatteringProfile>();
profile.name = System.IO.Path.GetFileName(path);
AssetDatabase.CreateAsset(profile, path);
return profile;
}
}
class DoCreateSubsurfaceScatteringProfile : UnityEditor.ProjectWindowCallback.EndNameEditAction
{
public override void Action(int instanceId, string pathName, string resourceFile)
{
var profiles = SubsurfaceScatteringProfileFactory.CreateSssProfileAtPath(pathName);
ProjectWindowUtil.ShowCreatedAsset(profiles);
}
}
[CustomEditor(typeof(SubsurfaceScatteringProfile))]
public class SubsurfaceScatteringProfileEditor : Editor {
private class Styles
{
public readonly GUIContent sssProfilePreview0 = new GUIContent("Profile preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as radius increases to 1.");
public readonly GUIContent sssProfilePreview2 = new GUIContent("Note that the intensity of the region in the center may be clamped.");
public readonly GUIContent sssTransmittancePreview0 = new GUIContent("Transmittance preview");
public readonly GUIContent sssTransmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object as thickness increases to 1.");
public readonly GUIContent sssProfileStdDev1 = new GUIContent("Standard deviation #1", "Determines the shape of the 1st Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileStdDev2 = new GUIContent("Standard deviation #2", "Determines the shape of the 2nd Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileLerpWeight = new GUIContent("Filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssProfileTransmission = new GUIContent("Enable transmission", "Toggles simulation of light passing through thin objects. Depends on the thickness of the material.");
public readonly GUIContent sssProfileThicknessRemap = new GUIContent("Thickness remap", "Remaps the thickness parameter from [0, 1] to the desired range.");
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);
public Styles()
{
centeredMiniBoldLabel.alignment = TextAnchor.MiddleCenter;
centeredMiniBoldLabel.fontSize = 10;
centeredMiniBoldLabel.fontStyle = FontStyle.Bold;
}
}
private static Styles styles
{
get
{
if (s_Styles == null)
{
s_Styles = new Styles();
}
return s_Styles;
}
}
private static Styles s_Styles = null;
private RenderTexture m_ProfileImage, m_TransmittanceImage;
private Material m_ProfileMaterial, m_TransmittanceMaterial;
private SerializedProperty m_ProfileStdDev1, m_ProfileStdDev2,
m_ProfileLerpWeight, m_ProfileTransmission,
m_ProfileThicknessRemap;
void OnEnable()
{
m_ProfileStdDev1 = serializedObject.FindProperty("stdDev1");
m_ProfileStdDev2 = serializedObject.FindProperty("stdDev2");
m_ProfileLerpWeight = serializedObject.FindProperty("lerpWeight");
m_ProfileTransmission = serializedObject.FindProperty("enableTransmission");
m_ProfileThicknessRemap = serializedObject.FindProperty("thicknessRemap");
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_TransmittanceMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileImage = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImage = new RenderTexture( 16, 256, 0, RenderTextureFormat.DefaultHDR);
}
public override void OnInspectorGUI() {
serializedObject.Update();
EditorGUI.BeginChangeCheck();
{
EditorGUILayout.PropertyField(m_ProfileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(m_ProfileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(m_ProfileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(m_ProfileTransmission, styles.sssProfileTransmission);
Vector2 thicknessRemap = m_ProfileThicknessRemap.vector2Value;
EditorGUILayout.LabelField("Min thickness: ", thicknessRemap.x.ToString());
EditorGUILayout.LabelField("Max thickness: ", thicknessRemap.y.ToString());
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
m_ProfileThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssProfilePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
}
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", m_ProfileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", m_ProfileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", m_ProfileLerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImage, m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", m_ProfileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", m_ProfileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", m_ProfileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", m_ProfileThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
serializedObject.ApplyModifiedProperties();
if (EditorGUI.EndChangeCheck())
{
// Validate each individual asset and update caches.
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
hdPipeline.sssSettings.OnValidate();
}
}
}
#endif
}

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.meta


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

9
Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset.meta


fileFormatVersion: 2
guid: 877878ed40e8ad94095582ff91179016
timeCreated: 1489068733
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

145
Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.cs


namespace UnityEngine.Experimental.Rendering.LowendMobile
{
public enum ShadowCascades
{
NO_CASCADES = 1,
TWO_CASCADES = 2,
FOUR_CASCADES = 4,
}
public enum ShadowType
{
NO_SHADOW = 0,
HARD_SHADOWS,
SOFT_SHADOWS,
}
public enum ShadowResolution
{
_512 = 512,
_1024 = 1024,
_2048 = 2048
}
public class LowEndMobilePipelineAsset : RenderPipelineAsset
{
#region AssetAndPipelineCreation
#if UNITY_EDITOR
[UnityEditor.MenuItem("RenderPipeline/LowEndMobilePipeline/Create Pipeline Asset")]
static void CreateLowEndPipeline()
{
var instance = ScriptableObject.CreateInstance<LowEndMobilePipelineAsset>();
UnityEditor.AssetDatabase.CreateAsset(instance,
"Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.asset");
}
#endif
protected override IRenderPipeline InternalCreatePipeline()
{
return new LowEndMobilePipeline(this);
}
#endregion
#region PipelineAssetSettings
[SerializeField] private int m_MaxPixelLights = 1;
[SerializeField] private bool m_SupportsVertexLight = true;
[SerializeField] private bool m_EnableLightmaps = true;
[SerializeField] private bool m_EnableAmbientProbe = true;
[SerializeField] private ShadowType m_ShadowType = ShadowType.HARD_SHADOWS;
[SerializeField] private ShadowResolution m_ShadowAtlasResolution = ShadowResolution._1024;
[SerializeField] private float m_ShadowNearPlaneOffset = 2.0f;
[SerializeField] private float m_ShadowDistance = 50.0f;
[SerializeField] private float m_ShadowBias = 0.0005f;
[SerializeField] private ShadowCascades m_ShadowCascades = ShadowCascades.NO_CASCADES;
[SerializeField] private float m_Cascade2Split = 0.25f;
[SerializeField] private Vector3 m_Cascade4Split = new Vector3(0.067f, 0.2f, 0.467f);
public int MaxSupportedPixelLights
{
get { return m_MaxPixelLights; }
private set { m_MaxPixelLights = value; }
}
public bool SupportsVertexLight
{
get { return m_SupportsVertexLight; }
private set { m_SupportsVertexLight = value; }
}
public bool EnableLightmap
{
get { return m_EnableLightmaps; }
private set { m_EnableLightmaps = value; }
}
public bool EnableAmbientProbe
{
get { return m_EnableAmbientProbe; }
private set { m_EnableAmbientProbe = value; }
}
public ShadowType CurrShadowType
{
get { return m_ShadowType; }
private set { m_ShadowType = value; }
}
public int ShadowAtlasResolution
{
get { return (int) m_ShadowAtlasResolution; }
private set { m_ShadowAtlasResolution = (ShadowResolution) value; }
}
public float ShadowNearOffset
{
get { return m_ShadowNearPlaneOffset; }
private set { m_ShadowNearPlaneOffset = value; }
}
public float ShadowDistance
{
get { return m_ShadowDistance; }
private set { m_ShadowDistance = value; }
}
public float ShadowBias
{
get { return m_ShadowBias; }
private set { m_ShadowBias = value; }
}
public int CascadeCount
{
get { return (int) m_ShadowCascades; }
private set { m_ShadowCascades = (ShadowCascades) value; }
}
public float Cascade2Split
{
get { return m_Cascade2Split; }
private set { m_Cascade2Split = value; }
}
public Vector3 Cascade4Split
{
get { return m_Cascade4Split; }
private set { m_Cascade4Split = value; }
}
#endregion
}
}

12
Assets/LowEndMobilePipeline/LowEndMobilePipelineAsset.cs.meta


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

9
Assets/LowEndMobilePipeline/TestScenes.meta


fileFormatVersion: 2
guid: 2c0fa72aa713a664b9be2de857697293
folderAsset: yes
timeCreated: 1488808638
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/LowEndMobilePipeline/Editor.meta


fileFormatVersion: 2
guid: 316ed34724625cb47b31136769381b57
folderAsset: yes
timeCreated: 1484576996
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

12
Assets/LowEndMobilePipeline/LowEndMobilePipeline.cs.meta


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

1001
Assets/LowEndMobilePipeline/TestScenes/LDRenderPipelineVikingVillage/LightingData.asset
文件差异内容过多而无法显示
查看文件

8
Assets/LowEndMobilePipeline/TestScenes/LDRenderPipelineVikingVillage/LightingData.asset.meta


fileFormatVersion: 2
guid: 8964f843d8f1330418cbd7ae5166468f
timeCreated: 1485353234
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

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

正在加载...
取消
保存