|
|
|
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using UnityEngine.Rendering; |
|
|
|
|
|
|
|
namespace UnityEngine.Experimental.Rendering.HDPipeline.Internal |
|
|
|
|
|
|
static Camera s_RenderCamera = null; |
|
|
|
static HDAdditionalCameraData s_RenderCameraData; |
|
|
|
|
|
|
|
HashSet<PlanarReflectionProbe> m_PlanarReflectionProbes; |
|
|
|
HashSet<PlanarReflectionProbe> m_PlanarReflectionProbe_DirtyBounds; |
|
|
|
HashSet<PlanarReflectionProbe> m_PlanarReflectionProbe_RequestRealtimeRender; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HashSet<ReflectionProbe> m_ReflectionProbes; |
|
|
|
HashSet<ReflectionProbe> m_ReflectionProbe_DirtyBounds; |
|
|
|
HashSet<ReflectionProbe> m_ReflectionProbe_RequestRealtimeRender; |
|
|
|
HashSet<ReflectionProbe> m_ReflectionProbe_RealtimeUpdate; |
|
|
|
ReflectionProbe[] m_ReflectionProbes_RealtimeUpdate_WorkArray; |
|
|
|
Dictionary<ReflectionProbe, BoundingSphere> m_ReflectionProbeBounds; |
|
|
|
ReflectionProbe[] m_ReflectionProbesArray; |
|
|
|
BoundingSphere[] m_ReflectionProbeBoundsArray; |
|
|
|
|
|
|
|
PlanarReflectionProbeBaker m_PlanarReflectionProbeBaker = new PlanarReflectionProbeBaker(); |
|
|
|
ReflectionProbeBaker m_ReflectionProbeBaker = new ReflectionProbeBaker(); |
|
|
|
|
|
|
|
public ReflectionSystemParameters parameters { get { return m_Parameters; } } |
|
|
|
// Planar probes
|
|
|
|
|
|
|
|
// Persistent collections
|
|
|
|
m_PlanarReflectionProbes = new HashSet<PlanarReflectionProbe>(); |
|
|
|
m_PlanarReflectionProbe_DirtyBounds = new HashSet<PlanarReflectionProbe>(); |
|
|
|
|
|
|
|
|
|
|
// Reflection probes
|
|
|
|
// Runtime collections
|
|
|
|
m_ReflectionProbes_RealtimeUpdate_WorkArray = new ReflectionProbe[parameters.maxReflectionProbes]; |
|
|
|
m_ReflectionProbeBounds = new Dictionary<ReflectionProbe, BoundingSphere>(); |
|
|
|
m_ReflectionProbesArray = new ReflectionProbe[parameters.maxReflectionProbes]; |
|
|
|
m_ReflectionProbeBoundsArray = new BoundingSphere[parameters.maxReflectionProbes]; |
|
|
|
// Persistent collections
|
|
|
|
m_ReflectionProbes = new HashSet<ReflectionProbe>(); |
|
|
|
m_ReflectionProbe_RequestRealtimeRender = new HashSet<ReflectionProbe>(); |
|
|
|
m_ReflectionProbe_RealtimeUpdate = new HashSet<ReflectionProbe>(); |
|
|
|
m_ReflectionProbe_DirtyBounds = new HashSet<ReflectionProbe>(); |
|
|
|
|
|
|
|
// Planar probes
|
|
|
|
|
|
|
|
// Reflection probes
|
|
|
|
m_ReflectionProbes.UnionWith(previous.m_ReflectionProbes); |
|
|
|
m_ReflectionProbe_DirtyBounds.UnionWith(m_ReflectionProbes); |
|
|
|
m_ReflectionProbe_RequestRealtimeRender.UnionWith(previous.m_ReflectionProbe_RequestRealtimeRender); |
|
|
|
m_ReflectionProbe_RealtimeUpdate.UnionWith(previous.m_ReflectionProbe_RealtimeUpdate); |
|
|
|
public void RenderAllRealtimeProbesFor(ReflectionProbeType probeType, Camera viewerCamera) |
|
|
|
{ |
|
|
|
if ((probeType & ReflectionProbeType.PlanarReflection) != 0) |
|
|
|
RenderlAllPlanarRealtimeProbesFor(viewerCamera); |
|
|
|
} |
|
|
|
public void RenderAllRealtimeProbes(ReflectionProbeType probeTypes) |
|
|
|
{ |
|
|
|
if ((probeTypes & ReflectionProbeType.PlanarReflection) != 0) |
|
|
|
RenderAllPlanarRealtimeProbes(); |
|
|
|
if ((probeTypes & ReflectionProbeType.ReflectionProbe) != 0) |
|
|
|
RenderAllReflectionRealtimeProbes(); |
|
|
|
} |
|
|
|
|
|
|
|
#region Planar Probes
|
|
|
|
SetProbeBoundsDirty(planarProbe); |
|
|
|
SetPlanarProbeBoundsDirty(planarProbe); |
|
|
|
|
|
|
|
if (planarProbe.mode == ReflectionProbeMode.Realtime) |
|
|
|
{ |
|
|
|
|
|
|
m_PlanarReflectionProbe_PerCamera_RealtimeUpdate.Remove(planarProbe); |
|
|
|
} |
|
|
|
|
|
|
|
public void PrepareCull(Camera camera, ReflectionProbeCullResults results) |
|
|
|
{ |
|
|
|
UpdateAllPlanarReflectionProbeBounds(); |
|
|
|
|
|
|
|
var cullingGroup = new CullingGroup(); |
|
|
|
cullingGroup.targetCamera = camera; |
|
|
|
cullingGroup.SetBoundingSpheres(m_PlanarReflectionProbeBoundsArray); |
|
|
|
cullingGroup.SetBoundingSphereCount(m_PlanarReflectionProbeBounds.Count); |
|
|
|
|
|
|
|
results.PrepareCull(cullingGroup, m_PlanarReflectionProbesArray); |
|
|
|
} |
|
|
|
|
|
|
|
public void RenderAllRealtimeProbesFor(ReflectionProbeType probeType, Camera viewerCamera) |
|
|
|
public void RequestRealtimeRender(PlanarReflectionProbe probe) |
|
|
|
if ((probeType & ReflectionProbeType.PlanarReflection) != 0) |
|
|
|
{ |
|
|
|
var length = Mathf.Min(m_PlanarReflectionProbe_PerCamera_RealtimeUpdate.Count, m_PlanarReflectionProbe_RealtimeUpdate_WorkArray.Length); |
|
|
|
m_PlanarReflectionProbe_PerCamera_RealtimeUpdate.CopyTo(m_PlanarReflectionProbe_RealtimeUpdate_WorkArray); |
|
|
|
|
|
|
|
// 1. Allocate if necessary target texture
|
|
|
|
var renderCamera = GetRenderCamera(); |
|
|
|
for (var i = 0; i < length; i++) |
|
|
|
{ |
|
|
|
var probe = m_PlanarReflectionProbe_RealtimeUpdate_WorkArray[i]; |
|
|
|
var hdCamera = HDCamera.Get(renderCamera, null, probe.frameSettings); |
|
|
|
if (!IsRealtimeTextureValid(probe.realtimeTexture, hdCamera)) |
|
|
|
{ |
|
|
|
if (probe.realtimeTexture != null) |
|
|
|
probe.realtimeTexture.Release(); |
|
|
|
probe.realtimeTexture = NewRenderTarget(probe); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 2. Render
|
|
|
|
for (var i = 0; i < length; i++) |
|
|
|
{ |
|
|
|
var probe = m_PlanarReflectionProbe_RealtimeUpdate_WorkArray[i]; |
|
|
|
Render(probe, probe.realtimeTexture, viewerCamera); |
|
|
|
} |
|
|
|
} |
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.Add(probe); |
|
|
|
public void RenderAllRealtimeProbes(ReflectionProbeType probeTypes) |
|
|
|
public void Render(PlanarReflectionProbe probe, RenderTexture target, Camera viewerCamera = null) |
|
|
|
if ((probeTypes & ReflectionProbeType.PlanarReflection) != 0) |
|
|
|
{ |
|
|
|
// Discard disabled probes in requested render probes
|
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.IntersectWith(m_PlanarReflectionProbes); |
|
|
|
// Include all realtime probe modes
|
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.UnionWith(m_PlanarReflectionProbe_RealtimeUpdate); |
|
|
|
var length = Mathf.Min(m_PlanarReflectionProbe_RequestRealtimeRender.Count, m_PlanarReflectionProbe_RealtimeUpdate_WorkArray.Length); |
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.CopyTo(m_PlanarReflectionProbe_RealtimeUpdate_WorkArray); |
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.Clear(); |
|
|
|
|
|
|
|
// 1. Allocate if necessary target texture
|
|
|
|
var camera = GetRenderCamera(); |
|
|
|
for (var i = 0; i < length; i++) |
|
|
|
{ |
|
|
|
var probe = m_PlanarReflectionProbe_RealtimeUpdate_WorkArray[i]; |
|
|
|
var hdCamera = HDCamera.Get(camera, null, probe.frameSettings); |
|
|
|
if (!IsRealtimeTextureValid(probe.realtimeTexture, hdCamera)) |
|
|
|
{ |
|
|
|
if (probe.realtimeTexture != null) |
|
|
|
probe.realtimeTexture.Release(); |
|
|
|
probe.realtimeTexture = NewRenderTarget(probe); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 2. Render
|
|
|
|
for (var i = 0; i < length; i++) |
|
|
|
{ |
|
|
|
var probe = m_PlanarReflectionProbe_RealtimeUpdate_WorkArray[i]; |
|
|
|
Render(probe, probe.realtimeTexture); |
|
|
|
} |
|
|
|
} |
|
|
|
m_PlanarReflectionProbeBaker.Render(probe, target, viewerCamera); |
|
|
|
public RenderTexture NewRenderTarget(PlanarReflectionProbe probe) |
|
|
|
void RenderlAllPlanarRealtimeProbesFor(Camera viewerCamera) |
|
|
|
var rt = new RenderTexture(m_Parameters.planarReflectionProbeSize, m_Parameters.planarReflectionProbeSize, 0, RenderTextureFormat.ARGBHalf); |
|
|
|
// No hide and don't save for this one
|
|
|
|
rt.useMipMap = true; |
|
|
|
rt.autoGenerateMips = false; |
|
|
|
rt.name = CoreUtils.GetRenderTargetAutoName(m_Parameters.planarReflectionProbeSize, m_Parameters.planarReflectionProbeSize, RenderTextureFormat.ARGBHalf, "PlanarProbeRT"); |
|
|
|
rt.Create(); |
|
|
|
return rt; |
|
|
|
} |
|
|
|
var length = m_PlanarReflectionProbe_PerCamera_RealtimeUpdate.Count; |
|
|
|
m_PlanarReflectionProbe_PerCamera_RealtimeUpdate.CopyTo(m_PlanarReflectionProbe_RealtimeUpdate_WorkArray); |
|
|
|
//public float GetCaptureCameraFOVFor(PlanarReflectionProbe probe, Camera viewerCamera)
|
|
|
|
//{
|
|
|
|
// switch (probe.influenceVolume.shapeType)
|
|
|
|
// {
|
|
|
|
// case ShapeType.Box:
|
|
|
|
// {
|
|
|
|
// var captureToWorld = probe.GetCaptureToWorld(viewerCamera);
|
|
|
|
// var influenceToWorld = Matrix4x4.TRS(probe.transform.TransformPoint(probe.influenceVolume.boxBaseOffset), probe.transform.rotation, Vector3.one);
|
|
|
|
// var influenceToCapture = captureToWorld.inverse * influenceToWorld;
|
|
|
|
// var min = influenceToCapture.MultiplyPoint(-probe.influenceVolume.boxBaseSize * 0.5f);
|
|
|
|
// var max = influenceToCapture.MultiplyPoint(probe.influenceVolume.boxBaseSize * 0.5f);
|
|
|
|
// var minAngle = Mathf.Atan2(Mathf.Sqrt(min.x * min.x + min.y * min.y), min.z) * Mathf.Rad2Deg;
|
|
|
|
// var maxAngle = Mathf.Atan2(Mathf.Sqrt(max.x * max.x + max.y * max.y), max.z) * Mathf.Rad2Deg;
|
|
|
|
// return Mathf.Max(minAngle, maxAngle) * 2;
|
|
|
|
// }
|
|
|
|
// default:
|
|
|
|
// throw new NotImplementedException();
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
bool IsRealtimeTextureValid(RenderTexture renderTexture, HDCamera hdCamera) |
|
|
|
{ |
|
|
|
return renderTexture != null |
|
|
|
&& renderTexture.width == m_Parameters.planarReflectionProbeSize |
|
|
|
&& renderTexture.height == m_Parameters.planarReflectionProbeSize |
|
|
|
&& renderTexture.format == RenderTextureFormat.ARGBHalf |
|
|
|
&& renderTexture.useMipMap; |
|
|
|
m_PlanarReflectionProbeBaker.AllocateRealtimeTextureIfRequired( |
|
|
|
m_PlanarReflectionProbe_RealtimeUpdate_WorkArray, |
|
|
|
m_Parameters.planarReflectionProbeSize, |
|
|
|
length |
|
|
|
); |
|
|
|
m_PlanarReflectionProbeBaker.Render( |
|
|
|
m_PlanarReflectionProbe_RealtimeUpdate_WorkArray, |
|
|
|
viewerCamera, |
|
|
|
length |
|
|
|
); |
|
|
|
public void RequestRealtimeRender(PlanarReflectionProbe probe) |
|
|
|
void RenderAllPlanarRealtimeProbes() |
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.Add(probe); |
|
|
|
} |
|
|
|
// Discard disabled probes in requested render probes
|
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.IntersectWith(m_PlanarReflectionProbes); |
|
|
|
public void Render(PlanarReflectionProbe probe, RenderTexture target, Camera viewerCamera = null) |
|
|
|
{ |
|
|
|
var renderCamera = GetRenderHDCamera(probe); |
|
|
|
renderCamera.camera.targetTexture = target; |
|
|
|
// Include all realtime probe modes
|
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.UnionWith(m_PlanarReflectionProbe_RealtimeUpdate); |
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.CopyTo(m_PlanarReflectionProbe_RealtimeUpdate_WorkArray); |
|
|
|
var length = m_PlanarReflectionProbe_RequestRealtimeRender.Count; |
|
|
|
m_PlanarReflectionProbe_RequestRealtimeRender.Clear(); |
|
|
|
SetupCameraForRender(renderCamera.camera, probe, viewerCamera); |
|
|
|
GL.invertCulling = IsProbeCaptureMirrored(probe, viewerCamera); |
|
|
|
renderCamera.camera.Render(); |
|
|
|
GL.invertCulling = false; |
|
|
|
renderCamera.camera.targetTexture = null; |
|
|
|
target.IncrementUpdateCount(); |
|
|
|
m_PlanarReflectionProbeBaker.AllocateRealtimeTextureIfRequired( |
|
|
|
m_PlanarReflectionProbe_RealtimeUpdate_WorkArray, |
|
|
|
m_Parameters.planarReflectionProbeSize, |
|
|
|
length |
|
|
|
); |
|
|
|
m_PlanarReflectionProbeBaker.Render( |
|
|
|
m_PlanarReflectionProbe_RealtimeUpdate_WorkArray, |
|
|
|
null, |
|
|
|
length); |
|
|
|
void SetProbeBoundsDirty(PlanarReflectionProbe planarProbe) |
|
|
|
void SetPlanarProbeBoundsDirty(PlanarReflectionProbe planarProbe) |
|
|
|
{ |
|
|
|
m_PlanarReflectionProbe_DirtyBounds.Add(planarProbe); |
|
|
|
} |
|
|
|
|
|
|
m_PlanarReflectionProbeBounds[planarReflectionProbe] = planarReflectionProbe.boundingSphere; |
|
|
|
} |
|
|
|
|
|
|
|
static void SetupCameraForRender(Camera camera, PlanarReflectionProbe probe, Camera viewerCamera = null) |
|
|
|
public static void CalculateCaptureCameraProperties(PlanarReflectionProbe probe, out float nearClipPlane, out float farClipPlane, out float aspect, out float fov, out CameraClearFlags clearFlags, out Color backgroundColor, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera) |
|
|
|
float nearClipPlane, farClipPlane, aspect, fov; |
|
|
|
Color backgroundColor; |
|
|
|
CameraClearFlags clearFlags; |
|
|
|
Vector3 capturePosition; |
|
|
|
Quaternion captureRotation; |
|
|
|
Matrix4x4 worldToCamera, projection; |
|
|
|
|
|
|
|
CalculateCaptureCameraProperties(probe, |
|
|
|
out nearClipPlane, out farClipPlane, |
|
|
|
out aspect, out fov, out clearFlags, out backgroundColor, |
|
|
|
out worldToCamera, out projection, |
|
|
|
out capturePosition, out captureRotation, viewerCamera); |
|
|
|
|
|
|
|
camera.farClipPlane = farClipPlane; |
|
|
|
camera.nearClipPlane = nearClipPlane; |
|
|
|
camera.fieldOfView = fov; |
|
|
|
camera.aspect = aspect; |
|
|
|
camera.clearFlags = clearFlags; |
|
|
|
camera.backgroundColor = camera.backgroundColor; |
|
|
|
camera.projectionMatrix = projection; |
|
|
|
camera.worldToCameraMatrix = worldToCamera; |
|
|
|
|
|
|
|
var ctr = camera.transform; |
|
|
|
ctr.position = capturePosition; |
|
|
|
ctr.rotation = captureRotation; |
|
|
|
PlanarReflectionProbeBaker.CalculateCaptureCameraProperties( |
|
|
|
probe, |
|
|
|
out nearClipPlane, out farClipPlane, |
|
|
|
out aspect, out fov, |
|
|
|
out clearFlags, out backgroundColor, |
|
|
|
out worldToCamera, out projection, |
|
|
|
out capturePosition, out captureRotation, |
|
|
|
viewerCamera); |
|
|
|
public static void CalculateCaptureCameraViewProj(PlanarReflectionProbe probe, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera = null) |
|
|
|
public static void CalculateCaptureCameraViewProj(PlanarReflectionProbe probe, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera) |
|
|
|
float nearClipPlane, farClipPlane, aspect, fov; |
|
|
|
CameraClearFlags clearFlags; |
|
|
|
Color backgroundColor; |
|
|
|
CalculateCaptureCameraProperties( |
|
|
|
PlanarReflectionProbeBaker.CalculateCaptureCameraViewProj( |
|
|
|
out nearClipPlane, out farClipPlane, |
|
|
|
out aspect, out fov, out clearFlags, out backgroundColor, |
|
|
|
out worldToCamera, out projection, out capturePosition, out captureRotation, |
|
|
|
out worldToCamera, out projection, |
|
|
|
out capturePosition, out captureRotation, |
|
|
|
#endregion
|
|
|
|
public static void CalculateCaptureCameraProperties(PlanarReflectionProbe probe, out float nearClipPlane, out float farClipPlane, out float aspect, out float fov, out CameraClearFlags clearFlags, out Color backgroundColor, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera = null) |
|
|
|
#region Reflection probes
|
|
|
|
internal void UnregisterProbe(ReflectionProbe reflectionProbe) |
|
|
|
if (viewerCamera != null |
|
|
|
&& probe.mode == ReflectionProbeMode.Realtime |
|
|
|
&& probe.refreshMode == ReflectionProbeRefreshMode.EveryFrame |
|
|
|
&& probe.capturePositionMode == PlanarReflectionProbe.CapturePositionMode.MirrorCamera) |
|
|
|
CalculateMirroredCaptureCameraProperties(probe, viewerCamera, out nearClipPlane, out farClipPlane, out aspect, out fov, out clearFlags, out backgroundColor, out worldToCamera, out projection, out capturePosition, out captureRotation); |
|
|
|
else |
|
|
|
CalculateStaticCaptureCameraProperties(probe, out nearClipPlane, out farClipPlane, out aspect, out fov, out clearFlags, out backgroundColor, out worldToCamera, out projection, out capturePosition, out captureRotation); |
|
|
|
m_ReflectionProbes.Remove(reflectionProbe); |
|
|
|
static bool IsProbeCaptureMirrored(PlanarReflectionProbe probe, Camera viewerCamera) |
|
|
|
internal void RegisterProbe(ReflectionProbe reflectionProbe) |
|
|
|
return viewerCamera != null |
|
|
|
&& probe.mode == ReflectionProbeMode.Realtime |
|
|
|
&& probe.refreshMode == ReflectionProbeRefreshMode.EveryFrame |
|
|
|
&& probe.capturePositionMode == PlanarReflectionProbe.CapturePositionMode.MirrorCamera; |
|
|
|
m_ReflectionProbes.Add(reflectionProbe); |
|
|
|
SetReflectionProbeBoundsDirty(reflectionProbe); |
|
|
|
|
|
|
|
if (reflectionProbe.mode == ReflectionProbeMode.Realtime) |
|
|
|
{ |
|
|
|
switch (reflectionProbe.refreshMode) |
|
|
|
{ |
|
|
|
case ReflectionProbeRefreshMode.OnAwake: |
|
|
|
m_ReflectionProbe_RequestRealtimeRender.Add(reflectionProbe); |
|
|
|
break; |
|
|
|
case ReflectionProbeRefreshMode.EveryFrame: |
|
|
|
m_ReflectionProbe_RealtimeUpdate.Add(reflectionProbe); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
static void CalculateStaticCaptureCameraProperties(PlanarReflectionProbe probe, out float nearClipPlane, out float farClipPlane, out float aspect, out float fov, out CameraClearFlags clearFlags, out Color backgroundColor, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation) |
|
|
|
void SetReflectionProbeBoundsDirty(ReflectionProbe reflectionProbe) |
|
|
|
nearClipPlane = probe.captureNearPlane; |
|
|
|
farClipPlane = probe.captureFarPlane; |
|
|
|
aspect = 1f; |
|
|
|
fov = probe.overrideFieldOfView |
|
|
|
? probe.fieldOfViewOverride |
|
|
|
: 90f; |
|
|
|
clearFlags = CameraClearFlags.Nothing; |
|
|
|
backgroundColor = Color.white; |
|
|
|
m_ReflectionProbe_DirtyBounds.Add(reflectionProbe); |
|
|
|
} |
|
|
|
capturePosition = probe.transform.TransformPoint(probe.captureLocalPosition); |
|
|
|
captureRotation = Quaternion.LookRotation((Vector3)probe.influenceToWorld.GetColumn(3) - capturePosition, probe.transform.up); |
|
|
|
void UpdateAllReflectionProbeBounds() |
|
|
|
{ |
|
|
|
if (m_ReflectionProbe_DirtyBounds.Count > 0) |
|
|
|
{ |
|
|
|
m_ReflectionProbe_DirtyBounds.IntersectWith(m_ReflectionProbes); |
|
|
|
foreach (var reflectionProbe in m_ReflectionProbe_DirtyBounds) |
|
|
|
UpdateReflectionProbeBounds(reflectionProbe); |
|
|
|
worldToCamera = GeometryUtils.CalculateWorldToCameraMatrixRHS(capturePosition, captureRotation); |
|
|
|
var clipPlane = GeometryUtils.CameraSpacePlane(worldToCamera, probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal); |
|
|
|
projection = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane); |
|
|
|
projection = GeometryUtils.CalculateObliqueMatrix(projection, clipPlane); |
|
|
|
m_ReflectionProbeBounds.Values.CopyTo(m_ReflectionProbeBoundsArray, 0); |
|
|
|
m_ReflectionProbeBounds.Keys.CopyTo(m_ReflectionProbesArray, 0); |
|
|
|
} |
|
|
|
static void CalculateMirroredCaptureCameraProperties(PlanarReflectionProbe probe, Camera viewerCamera, out float nearClipPlane, out float farClipPlane, out float aspect, out float fov, out CameraClearFlags clearFlags, out Color backgroundColor, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation) |
|
|
|
void UpdateReflectionProbeBounds(ReflectionProbe reflectionProbe) |
|
|
|
nearClipPlane = viewerCamera.nearClipPlane; |
|
|
|
farClipPlane = viewerCamera.farClipPlane; |
|
|
|
aspect = 1; |
|
|
|
fov = probe.overrideFieldOfView |
|
|
|
? probe.fieldOfViewOverride |
|
|
|
: Mathf.Max(viewerCamera.fieldOfView, viewerCamera.fieldOfView * viewerCamera.aspect); |
|
|
|
clearFlags = viewerCamera.clearFlags; |
|
|
|
backgroundColor = viewerCamera.backgroundColor; |
|
|
|
|
|
|
|
var worldToCapture = GeometryUtils.CalculateWorldToCameraMatrixRHS(viewerCamera.transform); |
|
|
|
var reflectionMatrix = GeometryUtils.CalculateReflectionMatrix(probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal); |
|
|
|
worldToCamera = worldToCapture * reflectionMatrix; |
|
|
|
|
|
|
|
var clipPlane = GeometryUtils.CameraSpacePlane(worldToCamera, probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal); |
|
|
|
var sourceProj = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane); |
|
|
|
projection = GeometryUtils.CalculateObliqueMatrix(sourceProj, clipPlane); |
|
|
|
|
|
|
|
capturePosition = reflectionMatrix.MultiplyPoint(viewerCamera.transform.position); |
|
|
|
|
|
|
|
var forward = reflectionMatrix.MultiplyVector(viewerCamera.transform.forward); |
|
|
|
var up = reflectionMatrix.MultiplyVector(viewerCamera.transform.up); |
|
|
|
captureRotation = Quaternion.LookRotation(forward, up); |
|
|
|
m_ReflectionProbeBounds[reflectionProbe] = reflectionProbe.GetComponent<HDAdditionalReflectionData>().boundingSphere; |
|
|
|
public static HDCamera GetRenderHDCamera(PlanarReflectionProbe probe) |
|
|
|
void RenderAllReflectionRealtimeProbes() |
|
|
|
var camera = GetRenderCamera(); |
|
|
|
// Discard disabled probes in requested render probes
|
|
|
|
m_ReflectionProbe_RequestRealtimeRender.IntersectWith(m_ReflectionProbes); |
|
|
|
probe.frameSettings.CopyTo(s_RenderCameraData.GetFrameSettings()); |
|
|
|
// Include all realtime probe modes
|
|
|
|
m_ReflectionProbe_RequestRealtimeRender.UnionWith(m_ReflectionProbe_RealtimeUpdate); |
|
|
|
m_ReflectionProbe_RequestRealtimeRender.CopyTo(m_ReflectionProbes_RealtimeUpdate_WorkArray); |
|
|
|
var length = m_ReflectionProbe_RequestRealtimeRender.Count; |
|
|
|
m_ReflectionProbe_RequestRealtimeRender.Clear(); |
|
|
|
return HDCamera.Get(camera, null, probe.frameSettings); |
|
|
|
m_ReflectionProbeBaker.AllocateRealtimeTextureIfRequired( |
|
|
|
m_ReflectionProbes_RealtimeUpdate_WorkArray, |
|
|
|
m_Parameters.reflectionProbeSize, |
|
|
|
length |
|
|
|
); |
|
|
|
m_ReflectionProbeBaker.Render( |
|
|
|
m_ReflectionProbes_RealtimeUpdate_WorkArray, |
|
|
|
length); |
|
|
|
#endregion
|
|
|
|
static Camera GetRenderCamera() |
|
|
|
#region Culling
|
|
|
|
public void PrepareCull(Camera camera, ReflectionProbeCullResults results) |
|
|
|
if (s_RenderCamera == null) |
|
|
|
{ |
|
|
|
var go = GameObject.Find("__Probe Render Camera") ?? new GameObject("__Probe Render Camera"); |
|
|
|
go.hideFlags = HideFlags.HideAndDontSave; |
|
|
|
|
|
|
|
s_RenderCamera = go.GetComponent<Camera>(); |
|
|
|
if (s_RenderCamera == null || s_RenderCamera.Equals(null)) |
|
|
|
s_RenderCamera = go.AddComponent<Camera>(); |
|
|
|
UpdateAllPlanarReflectionProbeBounds(); |
|
|
|
UpdateAllReflectionProbeBounds(); |
|
|
|
// We need to setup cameraType before adding additional camera
|
|
|
|
s_RenderCamera.cameraType = CameraType.Reflection; |
|
|
|
var planarCullingGroup = new CullingGroup(); |
|
|
|
planarCullingGroup.targetCamera = camera; |
|
|
|
planarCullingGroup.SetBoundingSpheres(m_PlanarReflectionProbeBoundsArray); |
|
|
|
planarCullingGroup.SetBoundingSphereCount(m_PlanarReflectionProbeBounds.Count); |
|
|
|
s_RenderCameraData = go.GetComponent<HDAdditionalCameraData>(); |
|
|
|
if (s_RenderCameraData == null || s_RenderCameraData.Equals(null)) |
|
|
|
s_RenderCameraData = go.AddComponent<HDAdditionalCameraData>(); |
|
|
|
var reflectionCullingGroup = new CullingGroup(); |
|
|
|
reflectionCullingGroup.targetCamera = camera; |
|
|
|
reflectionCullingGroup.SetBoundingSpheres(m_ReflectionProbeBoundsArray); |
|
|
|
reflectionCullingGroup.SetBoundingSphereCount(m_ReflectionProbeBounds.Count); |
|
|
|
go.SetActive(false); |
|
|
|
} |
|
|
|
|
|
|
|
return s_RenderCamera; |
|
|
|
results.PrepareCull( |
|
|
|
planarCullingGroup, |
|
|
|
reflectionCullingGroup, |
|
|
|
m_PlanarReflectionProbesArray, |
|
|
|
m_ReflectionProbesArray); |
|
|
|
#endregion
|
|
|
|
} |
|
|
|
} |