|
|
|
|
|
|
|
|
|
|
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_DebugViewTilesMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewTiles"); |
|
|
|
|
|
|
|
m_SingleDeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred"); |
|
|
|
m_SingleDeferredMaterial.EnableKeyword("LIGHTLOOP_SINGLE_PASS"); |
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
loop.ExecuteCommandBuffer(cmd); |
|
|
|
cmd.Dispose(); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
private Vector2 m_mousePosition = Vector2.zero; |
|
|
|
private void OnSceneGUI(UnityEditor.SceneView sceneview) |
|
|
|
{ |
|
|
|
m_mousePosition = Event.current.mousePosition; |
|
|
|
} |
|
|
|
#endif
|
|
|
|
|
|
|
|
var screenSize = Utilities.ComputeScreenSize(camera); |
|
|
|
|
|
|
|
var screenSize = Utilities.ComputeScreenSize(camera); |
|
|
|
|
|
|
|
Vector2 mousePixelCoord = Input.mousePosition; |
|
|
|
#if UNITY_EDITOR
|
|
|
|
if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) |
|
|
|
{ |
|
|
|
mousePixelCoord = m_mousePosition; |
|
|
|
mousePixelCoord.y = (screenSize.y - 1.0f) - mousePixelCoord.y; |
|
|
|
} |
|
|
|
#endif
|
|
|
|
|
|
|
|
m_DeferredDirectMaterial.SetMatrix("_InvViewProjMatrix", invViewProj); |
|
|
|
m_DeferredDirectMaterial.SetVector("_ScreenSize", screenSize); |
|
|
|
m_DeferredDirectMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|
|
|
|
|
|
m_DebugViewTilesMaterial.SetMatrix("_InvViewProjMatrix", invViewProj); |
|
|
|
m_DebugViewTilesMaterial.SetVector("_ScreenSize", screenSize); |
|
|
|
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", debugViewTilesFlags); |
|
|
|
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord); |
|
|
|
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST"); |
|
|
|
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST"); |
|
|
|
|
|
|
|