浏览代码

(wip) Reflection system for reflection probes

/feature-ReflectionProbeBaking
Frédéric Vauchelles 6 年前
当前提交
daae5ce2
共有 11 个文件被更改,包括 305 次插入271 次删除
  1. 31
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorReflectionSystem.cs
  2. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalLightLoopSettingsUI.cs
  3. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalLightLoopSettings.cs
  4. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  5. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.cs
  6. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/GlobalLightLoopSettings.cs
  7. 38
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/HDAdditionalReflectionData.cs
  8. 61
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCullResults.cs
  9. 24
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystem.cs
  10. 404
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemInternal.cs
  11. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemParameters.cs

31
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorReflectionSystem.cs


using System.Reflection;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Experimental.Rendering.HDPipeline.Internal;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;

{
static int _Cubemap = Shader.PropertyToID("_Cubemap");
const HideFlags k_ReflectionSystemDictionaryHideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.DontSaveInBuild;
static PlanarReflectionProbeBaker s_PlanarReflectionProbeBaker = new PlanarReflectionProbeBaker();
public static bool IsCollidingWithOtherProbes(string targetPath, ReflectionProbe targetProbe, out ReflectionProbe collidingProbe)
{

public static bool BakePlanarReflectionProbe(PlanarReflectionProbe probe, string path)
{
var rt = ReflectionSystem.NewRenderTarget(probe);
ReflectionSystem.Render(probe, rt);
var rt = s_PlanarReflectionProbeBaker.NewRenderTarget(probe, ReflectionSystem.parameters.planarReflectionProbeSize);
s_PlanarReflectionProbeBaker.Render(probe, rt);
var target = new Texture2D(rt.width, rt.height, TextureFormat.RGBAHalf, false, true);
var a = RenderTexture.active;
RenderTexture.active = rt;

probe.bakedTexture = target;
if (!WriteAndImportTexture(path, target))
return false;

public static bool BakeReflectionProbeSnapshot(PlanarReflectionProbe probe)
{
var rt = ReflectionSystem.NewRenderTarget(probe);
var rt = s_PlanarReflectionProbeBaker.NewRenderTarget(probe, ReflectionSystem.parameters.planarReflectionProbeSize);
var bakedTexture = probe.bakedTexture as Texture2D;
var assetPath = string.Empty;
if (bakedTexture != null)

EditorUtility.SetDirty(probe);
}
ReflectionSystem.Render(probe, rt);
s_PlanarReflectionProbeBaker.Render(probe, rt);
var art = RenderTexture.active;
RenderTexture.active = rt;

importer.SaveAndReimport();
}
return true;
}
[InitializeOnLoadMethod]
static void Initialize()
{
RenderSettings.enableLegacyReflectionProbeSystem = false;
Lightmapping.BakeReflectionProbeRequest += LightmappingOnBakeReflectionProbeRequest;
Lightmapping.BakeReflectionProbeRequestCancelled += LightmappingOnBakeReflectionProbeRequestCancelled;
}
static void LightmappingOnBakeReflectionProbeRequest(Hash128 dependencyHash)
{
Debug.Log("Bake: " + dependencyHash);
}
static void LightmappingOnBakeReflectionProbeRequestCancelled(Hash128 dependencyHash)
{
Debug.Log("Cancel: " + dependencyHash);
}
}
}

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalLightLoopSettingsUI.cs


EditorGUILayout.PropertyField(d.reflectionCacheCompressed, _.GetContent("Compress Reflection Probe Cache"));
EditorGUILayout.PropertyField(d.reflectionCubemapSize, _.GetContent("Reflection Cubemap Size"));
EditorGUILayout.PropertyField(d.reflectionProbeCacheSize, _.GetContent("Probe Cache Size"));
EditorGUILayout.PropertyField(d.maxReflectionProbes, _.GetContent("Max Reflection Probes"));
EditorGUILayout.Space();

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalLightLoopSettings.cs


public SerializedProperty pointCookieSize;
public SerializedProperty cubeCookieTexArraySize;
public SerializedProperty reflectionProbeCacheSize;
public SerializedProperty maxReflectionProbes;
public SerializedProperty reflectionCubemapSize;
public SerializedProperty reflectionCacheCompressed;
public SerializedProperty planarReflectionProbeCacheSize;

reflectionProbeCacheSize = root.Find((GlobalLightLoopSettings s) => s.reflectionProbeCacheSize);
reflectionCubemapSize = root.Find((GlobalLightLoopSettings s) => s.reflectionCubemapSize);
reflectionCacheCompressed = root.Find((GlobalLightLoopSettings s) => s.reflectionCacheCompressed);
maxReflectionProbes = root.Find((GlobalLightLoopSettings s) => s.maxReflectionProbes);
planarReflectionProbeCacheSize = root.Find((GlobalLightLoopSettings s) => s.planarReflectionProbeCacheSize);
planarReflectionCubemapSize = root.Find((GlobalLightLoopSettings s) => s.planarReflectionTextureSize);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


// TODO: Render only visible probes
var isReflection = cameras.Any(c => c.cameraType == CameraType.Reflection);
if (!isReflection)
ReflectionSystem.RenderAllRealtimeProbes(ReflectionProbeType.PlanarReflection);
ReflectionSystem.RenderAllRealtimeProbes(ReflectionProbeType.PlanarReflection | ReflectionProbeType.ReflectionProbe);
// We first update the state of asset frame settings as they can be use by various camera
// but we keep the dirty state to correctly reset other camera that use RenderingPath.Default.

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.cs


return new ReflectionSystemParameters
{
maxPlanarReflectionProbes = renderPipelineSettings.lightLoopSettings.maxPlanarReflectionProbes,
planarReflectionProbeSize = renderPipelineSettings.lightLoopSettings.planarReflectionTextureSize
planarReflectionProbeSize = renderPipelineSettings.lightLoopSettings.planarReflectionTextureSize,
reflectionProbeSize = renderPipelineSettings.lightLoopSettings.reflectionProbeCacheSize,
maxReflectionProbes = renderPipelineSettings.lightLoopSettings.maxReflectionProbes
};
}
}

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/GlobalLightLoopSettings.cs


public int planarReflectionTextureSize = 128;
public bool reflectionCacheCompressed = false;
public bool planarReflectionCacheCompressed = false;
public int maxReflectionProbes = 128;
public int maxPlanarReflectionProbes = 128;
public SkyResolution skyReflectionSize = SkyResolution.SkyResolution256;
public LayerMask skyLightingOverrideLayerMask = 0;

38
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/HDAdditionalReflectionData.cs


public float sphereBlendRadiusOffset { get { return -blendDistancePositive.x; } }
public float sphereBlendNormalRadiusOffset { get { return -blendNormalDistancePositive.x; } }
public BoundingSphere boundingSphere
{
get
{
switch (influenceShape)
{
default:
case ShapeType.Sphere:
return new BoundingSphere(transform.TransformPoint(Vector3.zero), influenceSphereRadius);
case ShapeType.Box:
{
var extents = GetComponent<ReflectionProbe>().bounds.extents;
var position = transform.TransformPoint(boxBlendCenterOffset);
var radius = Mathf.Max(extents.x, Mathf.Max(extents.y, extents.z));
return new BoundingSphere(position, radius);
}
}
}
}
void OnEnable()
{
ReflectionSystem.RegisterProbe(GetComponent<ReflectionProbe>());
}
void OnDisable()
{
ReflectionSystem.UnregisterProbe(GetComponent<ReflectionProbe>());
}
void OnValidate()
{
ReflectionSystem.UnregisterProbe(GetComponent<ReflectionProbe>());
if (isActiveAndEnabled)
ReflectionSystem.RegisterProbe(GetComponent<ReflectionProbe>());
}
}
}

61
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCullResults.cs


{
int[] m_PlanarReflectionProbeIndices;
PlanarReflectionProbe[] m_VisiblePlanarReflectionProbes;
int[] m_ReflectionProbeIndices;
ReflectionProbe[] m_VisibleReflectionProbes;
CullingGroup m_CullingGroup;
PlanarReflectionProbe[] m_Probes;
CullingGroup m_PlanarCullingGroup;
CullingGroup m_ReflectionCullingGroup;
PlanarReflectionProbe[] m_PlanarProbes;
ReflectionProbe[] m_ReflectionProbes;
public int visibleReflectionProbeCount { get; private set; }
public ReflectionProbe[] visibleReflectionProbes { get { return m_VisibleReflectionProbes; } }
Assert.IsTrue(parameters.maxReflectionProbes >= 0, "Maximum number of reflection probe must be positive");
visibleReflectionProbeCount = 0;
m_ReflectionProbeIndices = new int[parameters.maxReflectionProbes];
m_VisibleReflectionProbes = new ReflectionProbe[parameters.maxReflectionProbes];
public void CullPlanarReflectionProbes(CullingGroup cullingGroup, PlanarReflectionProbe[] planarReflectionProbes)
public void PrepareCull(
CullingGroup planarCullingGroup,
CullingGroup reflectionCullingGroup,
PlanarReflectionProbe[] planarReflectionProbesArray,
ReflectionProbe[] reflectionProbesArray)
visiblePlanarReflectionProbeCount = cullingGroup.QueryIndices(true, m_PlanarReflectionProbeIndices, 0);
for (var i = 0; i < visiblePlanarReflectionProbeCount; ++i)
m_VisiblePlanarReflectionProbes[i] = planarReflectionProbes[m_PlanarReflectionProbeIndices[i]];
}
Assert.IsNull(m_PlanarCullingGroup, "Culling was prepared but not used nor disposed");
Assert.IsNull(m_PlanarProbes, "Culling was prepared but not used nor disposed");
public void PrepareCull(CullingGroup cullingGroup, PlanarReflectionProbe[] planarReflectionProbesArray)
{
Assert.IsNull(m_CullingGroup, "Culling was prepared but not used nor disposed");
Assert.IsNull(m_Probes, "Culling was prepared but not used nor disposed");
m_CullingGroup = cullingGroup;
m_Probes = planarReflectionProbesArray;
m_PlanarCullingGroup = planarCullingGroup;
m_PlanarProbes = planarReflectionProbesArray;
m_ReflectionCullingGroup = reflectionCullingGroup;
m_ReflectionProbes = reflectionProbesArray;
Assert.IsNotNull(m_CullingGroup, "Culling was not prepared, please prepare cull before performing it.");
Assert.IsNotNull(m_Probes, "Culling was not prepared, please prepare cull before performing it.");
Assert.IsNotNull(m_PlanarCullingGroup, "Culling was not prepared, please prepare cull before performing it.");
Assert.IsNotNull(m_ReflectionCullingGroup, "Culling was not prepared, please prepare cull before performing it.");
Assert.IsNotNull(m_PlanarProbes, "Culling was not prepared, please prepare cull before performing it.");
Assert.IsNotNull(m_ReflectionProbes, "Culling was not prepared, please prepare cull before performing it.");
visiblePlanarReflectionProbeCount = m_CullingGroup.QueryIndices(true, m_PlanarReflectionProbeIndices, 0);
visiblePlanarReflectionProbeCount = m_PlanarCullingGroup.QueryIndices(true, m_PlanarReflectionProbeIndices, 0);
m_VisiblePlanarReflectionProbes[i] = m_Probes[m_PlanarReflectionProbeIndices[i]];
m_VisiblePlanarReflectionProbes[i] = m_PlanarProbes[m_PlanarReflectionProbeIndices[i]];
m_CullingGroup.Dispose();
m_CullingGroup = null;
m_Probes = null;
visibleReflectionProbeCount = m_ReflectionCullingGroup.QueryIndices(true, m_ReflectionProbeIndices, 0);
for (var i = 0; i < visibleReflectionProbeCount; ++i)
m_VisibleReflectionProbes[i] = m_ReflectionProbes[m_ReflectionProbeIndices[i]];
m_PlanarCullingGroup.Dispose();
m_PlanarCullingGroup = null;
m_PlanarProbes = null;
m_ReflectionCullingGroup.Dispose();
m_ReflectionCullingGroup = null;
m_ReflectionProbes = null;
}
}
}

24
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystem.cs


using UnityEngine.Experimental.Rendering.HDPipeline.Internal;
using System;
using UnityEngine.Experimental.Rendering.HDPipeline.Internal;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

public static ReflectionSystemParameters parameters
{
get { return s_Instance.parameters; }
set { s_Instance = new ReflectionSystemInternal(value, s_Instance); }
}
public static void SetParameters(ReflectionSystemParameters parameters)
{

s_Instance.RenderAllRealtimeProbes(probeTypes);
}
public static RenderTexture NewRenderTarget(PlanarReflectionProbe probe)
{
return s_Instance.NewRenderTarget(probe);
}
public static void Render(PlanarReflectionProbe probe, RenderTexture target)
{
s_Instance.Render(probe, target);

out aspect, out fov, out clearFlags, out backgroundColor,
out worldToCamera, out projection, out capturePosition, out captureRotation,
viewerCamera);
}
public static void UnregisterProbe(ReflectionProbe reflectionProbe)
{
s_Instance.RegisterProbe(reflectionProbe);
}
public static void RegisterProbe(ReflectionProbe reflectionProbe)
{
s_Instance.UnregisterProbe(reflectionProbe);
}
public static void CalculateCaptureCameraViewProj(PlanarReflectionProbe probe, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera = null)

404
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemInternal.cs


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
}
}

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemParameters.cs


{
public static ReflectionSystemParameters Default = new ReflectionSystemParameters
{
maxPlanarReflectionProbes = 512,
planarReflectionProbeSize = 128
maxPlanarReflectionProbes = 128,
planarReflectionProbeSize = 128,
maxReflectionProbes = 128,
reflectionProbeSize = 128
public int maxReflectionProbes;
public int reflectionProbeSize;
}
}
正在加载...
取消
保存