浏览代码

Merge branch 'master' into SkyFramework

# Conflicts:
#	Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
#	Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
/main
Julien Ignace 8 年前
当前提交
2ec18892
共有 40 个文件被更改,包括 595 次插入370 次删除
  1. 4
      Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs
  2. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/DebugViewMaterial.cs
  3. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/DebugViewMaterial.cs.hlsl
  4. 15
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewMaterialGBuffer.shader
  5. 85
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader
  6. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta
  7. 112
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  8. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs
  9. 20
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Resources/Deferred.shader
  10. 77
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  11. 64
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
  12. 25
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Attributes.hlsl
  13. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.cs
  14. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.cs.hlsl
  15. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin/BuiltinData.hlsl
  16. 29
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl
  17. 23
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl
  18. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitDepthPass.hlsl
  19. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitMetaPass.hlsl
  20. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl
  21. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl
  22. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitVelocityPass.hlsl
  23. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Unlit.shader
  24. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/UnlitData.hlsl
  25. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/UnlitSharePass.hlsl
  26. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDebugViewMaterial.hlsl
  27. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassDepthOnly.hlsl
  28. 16
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassForward.hlsl
  29. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassForwardUnlit.hlsl
  30. 14
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassGBuffer.hlsl
  31. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassLightTransport.hlsl
  32. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass/ShaderPassVelocity.hlsl
  33. 166
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl
  34. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader
  35. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader
  36. 19
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs
  37. 28
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
  38. 93
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  39. 30
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  40. 7
      README.md

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


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

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

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


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

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

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


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

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


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

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

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

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


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

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

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

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


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

112
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


// TODO TO CHECK: SebL I move allocation from Build() to here, but there was a comment "// Our object can be garbage collected, so need to be allocate here", it is still true ?
Lit.RenderLoop m_LitRenderLoop = new Lit.RenderLoop();
public struct HDCamera
{
public Camera camera;
public Vector4 screenSize;
public Matrix4x4 viewProjectionMatrix;
public Matrix4x4 invViewProjectionMatrix;
}
public override void Build()
{
#if UNITY_EDITOR

#if UNITY_EDITOR
UnityEditor.SupportedRenderingFeatures.active = UnityEditor.SupportedRenderingFeatures.Default;
#endif
UnityEngine.Rendering.GraphicsSettings.lightsUseLinearIntensity = previousLightsUseLinearIntensity;
UnityEngine.Rendering.GraphicsSettings.lightsUseCCT = previousLightsUseCCT;
// UnityEngine.Rendering.GraphicsSettings.lightsUseLinearIntensity = previousLightsUseLinearIntensity;
// UnityEngine.Rendering.GraphicsSettings.lightsUseCCT = previousLightsUseCCT;
}
void InitAndClearBuffer(Camera camera, RenderLoop renderLoop)

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

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

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

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

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

{
RenderTransparentRenderList(cullResults, camera, renderLoop, "Forward", Utilities.kRendererConfigurationBakedLighting);
}
}
}
// Render material that are forward opaque only (like eye)
// TODO: Think about hair that could be render both as opaque and transparent...
void RenderForwardOnly(CullResults cullResults, Camera camera, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Forward Only Pass", renderLoop))
{
// Bind material data
m_LitRenderLoop.Bind();
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT);
m_lightLoop.RenderForward(camera, renderLoop, true);
RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardOnly");
}
}

}
}
#if UNITY_EDITOR
public override void RenderSceneView(Camera camera, RenderLoop renderLoop)
{
base.RenderSceneView(camera, renderLoop);
renderLoop.PrepareForEditorRendering(camera, m_CameraDepthBufferRT);
renderLoop.Submit();
}
#endif
void FinalPass(RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Final Pass", renderLoop))

}
}
public void PushGlobalParams(Camera camera, RenderLoop renderLoop)
public void PushGlobalParams(HDCamera hdCamera, RenderLoop renderLoop)
{
if (m_SkyManager.IsSkyValid())
{

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

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

m_lightLoop.PrepareLightsForGPU(cullResults, camera, ref shadows);
m_lightLoop.BuildGPULightLists(camera, renderLoop, m_CameraDepthBufferRT);
PushGlobalParams(camera, renderLoop);
PushGlobalParams(hdCamera, renderLoop);
RenderDeferredLighting(camera, renderLoop);
RenderDeferredLighting(hdCamera, renderLoop);
// TODO: enable this for tile forward opaque
// RenderForward(cullResults, camera, renderLoop, true);
RenderForward(cullResults, camera, renderLoop, true);
RenderForwardOnly(cullResults, camera, renderLoop);
RenderSky(camera, renderLoop);
RenderSky(hdCamera, renderLoop);
RenderForward(cullResults, camera, renderLoop, false);

// RenderDistortion(cullResults, camera, renderLoop);
FinalPass(renderLoop);
}
// bind depth surface for editor grid/gizmo/selection rendering
if (camera.cameraType == CameraType.SceneView)
{
var cmd = new CommandBuffer();
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, m_CameraDepthBufferRT);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
renderLoop.Submit();

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


public virtual void PushGlobalParams(Camera camera, RenderLoop loop) {}
public virtual void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT) {}
public virtual void RenderDeferredLighting(HDRenderLoop.HDCamera hdCamera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT) {}
public virtual void RenderForward(Camera camera, RenderLoop renderLoop, bool renderOpaque) {}

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


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

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

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


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

m_lightList = new LightList();
m_lightList.Allocate();
s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnSCreen + k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_shadowDatas = new ComputeBuffer(k_MaxCascadeCount + k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
m_CookieTexArray = new TextureCache2D();

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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


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

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


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

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

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


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

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


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

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

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

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

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

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

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

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

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

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


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

builtinData.distortion = float2(0.0, 0.0);
builtinData.distortionBlur = 0.0;
builtinData.depthOffset = 0.0;
}
// Gather all kind of mapping in one struct, allow to improve code readability

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

isTriplanar = true;
#endif
ComputeLayerTexCoord(input, isTriplanar, layerTexCoord);
ApplyDisplacement(input, layerTexCoord);
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
ApplyDisplacement(input, viewDirTS, layerTexCoord);
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData);
GetBuiltinData(input, surfaceData, alpha, builtinData);

#define SURFACEDATA_BLEND_SCALAR(surfaceData, name, mask) BlendLayeredScalar(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define PROP_BLEND_SCALAR(name, mask) BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);

isTriplanar = true;
#endif
ComputeLayerTexCoord3(input, isTriplanar, layerTexCoord);
ApplyDisplacement0(input, layerTexCoord);
ApplyDisplacement1(input, layerTexCoord);
ApplyDisplacement2(input, layerTexCoord);
ApplyDisplacement3(input, layerTexCoord);
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
ApplyDisplacement0(input, viewDirTS, layerTexCoord);
ApplyDisplacement1(input, viewDirTS, layerTexCoord);
ApplyDisplacement2(input, viewDirTS, layerTexCoord);
ApplyDisplacement3(input, viewDirTS, layerTexCoord);
SurfaceData surfaceData0;
SurfaceData surfaceData1;

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


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

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


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

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


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

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


void ADD_IDX(ComputeLayerTexCoord)(FragInput input, bool isTriplanar, inout LayerTexCoord layerTexCoord)
void ADD_IDX(ComputeLayerTexCoord)(FragInputs input, bool isTriplanar, inout LayerTexCoord layerTexCoord)
{
// TODO: Do we want to manage local or world triplanar/planar
//float3 position = localTriplanar ? TransformWorldToObject(input.positionWS) : input.positionWS;

ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(ADD_IDX(layerTexCoord.base).uvXY, ADD_IDX(_DetailMap));
}
void ADD_IDX(ApplyDisplacement)(inout FragInput input, inout LayerTexCoord layerTexCoord)
void ADD_IDX(ApplyDisplacement)(inout FragInputs input, float3 viewDirTS, inout LayerTexCoord layerTexCoord)
// Transform view vector in tangent space
// Hope the compiler can optimize this in case of multiple layer
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
float height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
float2 offset = ParallaxOffset(viewDirTS, height);

ADD_IDX(layerTexCoord.details).uvZX += offset;
ADD_IDX(layerTexCoord.details).uvXY += offset;
// Only modify tex coord for first layer, this will be use by for builtin data (like lightmap)
// Only modify texcoord for first layer, this will be use by for builtin data (like lightmap)
if (LAYER_INDEX == 0)
{
input.texCoord0 += offset;

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

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


return output;
}
FragInput UnpackVaryings(PackedVaryings input)
FragInputs UnpackVaryings(PackedVaryings input)
FragInput output;
ZERO_INITIALIZE(FragInput, output);
FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.unPositionSS = input.positionCS; // as input we have the vpos
output.unPositionSS = input.positionCS; // input.positionCS is SV_Position
output.positionCS = float4(input.interpolators[0].xy, 0.0, input.interpolators[0].z);
output.previousPositionCS = float4(input.interpolators[1].xy, 0.0, input.interpolators[1].z);

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


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

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


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

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

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


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

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


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

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


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

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


float4 Frag(PackedVaryings packedInput) : SV_Target
{
FragInput input = UnpackVaryings(packedInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 positionWS = input.positionWS;
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
Coordinate coord = GetCoordinate(input.unPositionSS.xy, _ScreenSize.zw);
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
LightLoop(V, positionWS, coord, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
return float4(diffuseLighting + specularLighting, builtinData.opacity);
}

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


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

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


OUTPUT_GBUFFER_VELOCITY(outVelocityBuffer)
)
{
FragInput input = UnpackVaryings(packedInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 positionWS = input.positionWS;
FragInputs input = UnpackVaryings(packedInput);
// input.unPositionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.unPositionSS.xy, _ScreenSize.zw);
UpdatePositionInput(input.unPositionSS.z, input.unPositionSS.w, input.positionWS, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
Coordinate coord = GetCoordinate(input.unPositionSS.xy, _ScreenSize.zw);
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 bakeDiffuseLighting = GetBakedDiffuseLigthing(surfaceData, builtinData, bsdfData, preLightData);
ENCODE_INTO_GBUFFER(surfaceData, bakeDiffuseLighting, outGBuffer);

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


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

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


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

166
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl


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

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

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

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

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

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

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

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


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

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


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

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

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

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

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


public class BuiltinSkyParameters
{
public Matrix4x4 viewProjMatrix;
public Vector4 screenSize;
public Mesh skyMesh;
public RenderLoop renderLoop;
public Light sunLight;

Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceCameraViewProjectionMatrix = new Matrix4x4[6];
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];

m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT.Create();
}
m_CubemapScreenSize = new Vector4((float)skyParameters.resolution, (float)skyParameters.resolution, 1.0f / (float)skyParameters.resolution, 1.0f / (float)skyParameters.resolution);
}
void RebuildSkyMeshes()

for (int i = 0; i < 6; ++i)
{
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], UpVectorList[i]);
m_faceCameraInvViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj).inverse;
m_faceCameraViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj);
m_faceCameraInvViewProjectionMatrix[i] = m_faceCameraViewProjectionMatrix[i].inverse;
// When rendering into a texture the render will be flip (due to legacy unity openGL behavior), so we need to flip UV here...
m_CubemapFaceMesh[i] = BuildSkyMesh(Vector3.zero, m_faceCameraInvViewProjectionMatrix[i], true);

Utilities.SetRenderTarget(builtinParams.renderLoop, target, ClearFlag.ClearNone, 0, (CubemapFace)i);
builtinParams.invViewProjMatrix = m_faceCameraInvViewProjectionMatrix[i];
builtinParams.viewProjMatrix = m_faceCameraViewProjectionMatrix[i];
builtinParams.screenSize = m_CubemapScreenSize;
builtinParams.skyMesh = m_CubemapFaceMesh[i];
m_Renderer.RenderSky(builtinParams, skyParameters);
}

return (m_Renderer == null) ? null : m_Renderer.GetSkyParameterType();
}
public void RenderSky(Camera camera, Light sunLight, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
public void RenderSky(HDRenderLoop.HDCamera camera, Light sunLight, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
{

// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
m_BuiltinParameters.invViewProjMatrix = Utilities.GetViewProjectionMatrix(camera).inverse;
m_BuiltinParameters.skyMesh = BuildSkyMesh(camera.GetComponent<Transform>().position, m_BuiltinParameters.invViewProjMatrix, false);
m_BuiltinParameters.invViewProjMatrix = camera.invViewProjectionMatrix;
m_BuiltinParameters.viewProjMatrix = camera.viewProjectionMatrix;
m_BuiltinParameters.screenSize = camera.screenSize;
m_BuiltinParameters.skyMesh = BuildSkyMesh(camera.camera.GetComponent<Transform>().position, m_BuiltinParameters.invViewProjMatrix, false);
m_Renderer.RenderSky(m_BuiltinParameters, skyParameters);
}
else

28
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs


disposed = true;
}
}
public static Matrix4x4 GetViewProjectionMatrix(Matrix4x4 worldToViewMatrix, Matrix4x4 projectionMatrix)
{
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms

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

93
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


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

30
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


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

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

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

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

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

7
README.md


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

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