|
|
|
|
|
|
using System; |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using UnityEngine.Experimental.Rendering.HDPipeline.Internal; |
|
|
|
using UnityEngine.Rendering; |
|
|
|
|
|
|
|
|
|
|
var stereoEnabled = m_FrameSettings.enableStereo; |
|
|
|
|
|
|
|
Vector3 camPosWS = camera.transform.position; |
|
|
|
|
|
|
|
var worldToView = WorldToCamera(camera); |
|
|
|
var rightEyeWorldToView = Matrix4x4.identity; |
|
|
|
if (stereoEnabled) |
|
|
|
{ |
|
|
|
worldToView = WorldToViewStereo(camera, Camera.StereoscopicEye.Left); |
|
|
|
rightEyeWorldToView = WorldToViewStereo(camera, Camera.StereoscopicEye.Right); |
|
|
|
} |
|
|
|
|
|
|
|
// Note: Light with null intensity/Color are culled by the C++, no need to test it here
|
|
|
|
if (cullResults.visibleLights.Count != 0 || cullResults.visibleReflectionProbes.Count != 0) |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
// 2. Go through all lights, convert them to GPU format.
|
|
|
|
// Simultaneously create data for culling (LightVolumeData and SFiniteLightBound)
|
|
|
|
Vector3 camPosWS = camera.transform.position; |
|
|
|
|
|
|
|
var worldToView = WorldToCamera(camera); |
|
|
|
var rightEyeWorldToView = Matrix4x4.identity; |
|
|
|
if (stereoEnabled) |
|
|
|
{ |
|
|
|
worldToView = WorldToViewStereo(camera, Camera.StereoscopicEye.Left); |
|
|
|
rightEyeWorldToView = WorldToViewStereo(camera, Camera.StereoscopicEye.Right); |
|
|
|
} |
|
|
|
|
|
|
|
for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex) |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Inject density volumes into the clustered data structure for efficient look up.
|
|
|
|
m_densityVolumeCount = densityVolumes.bounds != null ? densityVolumes.bounds.Count : 0; |
|
|
|
|
|
|
|
Matrix4x4 worldToViewCR = worldToView; |
|
|
|
|
|
|
|
if (ShaderConfig.s_CameraRelativeRendering != 0) |
|
|
|
{ |
|
|
|
// The OBBs are camera-relative, the matrix is not. Fix it.
|
|
|
|
worldToViewCR.SetColumn(3, new Vector4(0, 0, 0, 1)); |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0, n = m_densityVolumeCount; i < n; i++) |
|
|
|
{ |
|
|
|
// Density volumes are not lights and therefore should not affect light classification.
|
|
|
|
LightFeatureFlags featureFlags = 0; |
|
|
|
AddBoxVolumeDataAndBound(densityVolumes.bounds[i], LightCategory.DensityVolume, featureFlags, worldToViewCR); |
|
|
|
} |
|
|
|
|
|
|
|
m_lightCount = m_lightList.lights.Count + m_lightList.envLights.Count + m_densityVolumeCount; |
|
|
|
Debug.Assert(m_lightCount == m_lightList.bounds.Count); |
|
|
|
Debug.Assert(m_lightCount == m_lightList.lightVolumes.Count); |
|
|
|
|
|
|
|
int decalDatasCount = Math.Min(DecalSystem.m_DecalDatasCount, k_MaxDecalsOnScreen); |
|
|
|
if (decalDatasCount > 0) |
|
|
|
|
|
|
m_lightCount += decalDatasCount; |
|
|
|
} |
|
|
|
|
|
|
|
// Inject density volumes into the clustered data structure for efficient look up.
|
|
|
|
m_densityVolumeCount = densityVolumes.bounds != null ? densityVolumes.bounds.Count : 0; |
|
|
|
|
|
|
|
Matrix4x4 worldToViewCR = worldToView; |
|
|
|
|
|
|
|
if (ShaderConfig.s_CameraRelativeRendering != 0) |
|
|
|
{ |
|
|
|
// The OBBs are camera-relative, the matrix is not. Fix it.
|
|
|
|
worldToViewCR.SetColumn(3, new Vector4(0, 0, 0, 1)); |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0, n = m_densityVolumeCount; i < n; i++) |
|
|
|
{ |
|
|
|
// Density volumes are not lights and therefore should not affect light classification.
|
|
|
|
LightFeatureFlags featureFlags = 0; |
|
|
|
AddBoxVolumeDataAndBound(densityVolumes.bounds[i], LightCategory.DensityVolume, featureFlags, worldToViewCR); |
|
|
|
} |
|
|
|
|
|
|
|
m_lightCount = m_lightList.lights.Count + m_lightList.envLights.Count + m_densityVolumeCount + decalDatasCount; |
|
|
|
Debug.Assert(m_lightCount == m_lightList.bounds.Count); |
|
|
|
Debug.Assert(m_lightCount == m_lightList.lightVolumes.Count); |
|
|
|
|
|
|
|
if (stereoEnabled) |
|
|
|
{ |
|
|
|
// TODO: Proper decal + stereo cull management
|
|
|
|
|
|
|
m_lightList.bounds.AddRange(m_lightList.rightEyeBounds); |
|
|
|
m_lightList.lightVolumes.AddRange(m_lightList.rightEyeLightVolumes); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
UpdateDataBuffers(); |
|
|
|
|
|
|
|
return m_enableBakeShadowMask; |
|
|
|
|
|
|
// XRTODO: If possible, we could generate a non-oblique stereo projection
|
|
|
|
// matrix. It's ok if it's not the exact same matrix, as long as it encompasses
|
|
|
|
// the same FOV as the original projection matrix (which would mean padding each half
|
|
|
|
// of the frustum with the max half-angle). We don't need the light information in
|
|
|
|
// of the frustum with the max half-angle). We don't need the light information in
|
|
|
|
// real projection space. We just use screen space to figure out what is proximal
|
|
|
|
// to a cluster or tile.
|
|
|
|
// Once we generate this non-oblique projection matrix, it can be shared across both eyes (un-array)
|
|
|
|