浏览代码

[ReflectionProbe] Refactored reflection probes

/feature-ReflectionProbeBaking
Frédéric Vauchelles 7 年前
当前提交
4d0d4da6
共有 10 个文件被更改,包括 617 次插入556 次删除
  1. 144
      SampleScenes/HDTest/ReflectionProbeTest.unity
  2. 8
      ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorUtils.cs
  3. 716
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorReflectionSystem.cs
  4. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/HDAdditionalReflectionData.cs
  5. 104
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/BakeReflectionProbesJob.cs
  6. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/BakeReflectionProbesJob.cs.meta
  7. 40
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorHDLightingDataAsset.cs
  8. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorHDLightingDataAsset.cs.meta
  9. 123
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ReflectionProbeCustomBakingIntegration.cs
  10. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ReflectionProbeCustomBakingIntegration.cs.meta

144
SampleScenes/HDTest/ReflectionProbeTest.unity


m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 0}
m_UseRadianceAmbientProbe: 0
m_EnableLegacyReflectionProbeSystem: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

m_Father: {fileID: 1807687832}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &294011590
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 294011591}
m_Layer: 0
m_Name: Lights
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &294011591
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 294011590}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1559142268}
- {fileID: 738259934}
- {fileID: 835578584}
- {fileID: 1919516705}
m_Father: {fileID: 1807687832}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &704218176
GameObject:
m_ObjectHideFlags: 0

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 738259933}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0}
m_LocalPosition: {x: 0, y: 10, z: 0}
m_Father: {fileID: 975253291}
m_Father: {fileID: 294011591}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &738259935

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 835578583}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0}
m_LocalPosition: {x: 0, y: 20, z: 0}
m_Father: {fileID: 1460063755}
m_RootOrder: 1
m_Father: {fileID: 294011591}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &835578585
MonoBehaviour:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1360734518}
- {fileID: 738259934}
- {fileID: 2122262443}
- {fileID: 1314116688}
m_Father: {fileID: 1807687832}

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1460063755}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1017139649
MonoBehaviour:

blendNormalDistanceNegative: {x: 0, y: 0, z: 0}
boxSideFadePositive: {x: 1, y: 1, z: 1}
boxSideFadeNegative: {x: 1, y: 1, z: 1}
bakedTexture: {fileID: 0}
proxyVolumeComponent: {fileID: 208116711}
--- !u!23 &1017139650
MeshRenderer:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 975253291}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1314116689
MonoBehaviour:

blendNormalDistanceNegative: {x: 0, y: 0, z: 0}
boxSideFadePositive: {x: 1, y: 1, z: 1}
boxSideFadeNegative: {x: 1, y: 1, z: 1}
bakedTexture: {fileID: 0}
proxyVolumeComponent: {fileID: 208116711}
--- !u!23 &1314116690
MeshRenderer:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 993426561}
- {fileID: 1559142268}
- {fileID: 1968516698}
- {fileID: 1521507374}
m_Father: {fileID: 1807687832}

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1559383257}
- {fileID: 835578584}
- {fileID: 2086739506}
- {fileID: 1017139648}
m_Father: {fileID: 1807687832}

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1438899652}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1521507375
MonoBehaviour:

blendNormalDistanceNegative: {x: 0, y: 0, z: 0}
boxSideFadePositive: {x: 1, y: 1, z: 1}
boxSideFadeNegative: {x: 1, y: 1, z: 1}
bakedTexture: {fileID: 0}
proxyVolumeComponent: {fileID: 208116711}
--- !u!23 &1521507376
MeshRenderer:

m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1438899652}
m_RootOrder: 1
m_Father: {fileID: 294011591}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1559142269
MonoBehaviour:

- {fileID: 1438899652}
- {fileID: 975253291}
- {fileID: 1460063755}
- {fileID: 294011591}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 90.00001, y: 0, z: 0}

m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1828470159}
m_LocalRotation: {x: -0.34097207, y: -0.14720488, z: 0.054151595, w: -0.92689615}
m_LocalPosition: {x: -102.840866, y: 5.4326243, z: 25.258797}
m_LocalRotation: {x: -0.17014773, y: 0.77062833, z: -0.23029752, w: -0.5693372}
m_LocalPosition: {x: 18.986977, y: 12.710156, z: 18.199608}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

enableFptlForForwardOpaque: 1
enableBigTilePrepass: 1
isFptlEnabled: 1
--- !u!1 &1919516704
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1919516705}
- component: {fileID: 1919516706}
m_Layer: 0
m_Name: Point Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 4294967295
m_IsActive: 1
--- !u!4 &1919516705
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1919516704}
m_LocalRotation: {x: 0.00000017881393, y: -0.70711946, z: -0.00000017881393, w: -0.7070942}
m_LocalPosition: {x: -4.87, y: 4.66, z: -0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 294011591}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: -269.998, z: 0}
--- !u!108 &1919516706
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1919516704}
m_Enabled: 1
serializedVersion: 8
m_Type: 3
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 0
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 2
m_AreaSize: {x: 1.5, y: 6}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!1 &1968516697
GameObject:
m_ObjectHideFlags: 0

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1968516697}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 3.24, y: 0, z: 0.956}
m_LocalPosition: {x: 3.24, y: 0.53, z: 0.96}
m_RootOrder: 2
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!65 &1968516699
BoxCollider:

m_Script: {fileID: 11500000, guid: deb5229fc0604de4cb529aedf764520f, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ObjectList:
- Key: 0
Value: {fileID: 1521507378}
- Key: 1
Value: {fileID: 1314116692}
- Key: 2
Value: {fileID: 1017139652}
--- !u!4 &1976116801
Transform:
m_ObjectHideFlags: 19

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1460063755}
m_RootOrder: 2
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!65 &2086739507
BoxCollider:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 975253291}
m_RootOrder: 2
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!65 &2122262444
BoxCollider:

8
ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorUtils.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

{
// GUIContent cache utilities
static Dictionary<string, GUIContent> s_GUIContentCache = new Dictionary<string, GUIContent>();
public static bool IsPathInProject(string path)
{
var fullPath = Path.GetFullPath(path);
var sanitizedPath = fullPath.Replace("\\", "/");
return sanitizedPath.StartsWith(Application.dataPath);
}
public static GUIContent GetContent(string textAndTooltip)
{

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


using System;
using System.Collections.Generic;
using System;
using UnityEditor.SceneManagement;
using UnityEngine.Assertions;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Experimental.Rendering.HDPipeline.Internal;

namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public static class EditorReflectionSystem
public static partial class EditorReflectionSystem
static ReflectionBakeJob s_CurrentBakeJob = null;
static MethodInfo k_Lightmapping_BakeAllReflectionProbesSnapshots = typeof(UnityEditor.Lightmapping).GetMethod("BakeAllReflectionProbesSnapshots", BindingFlags.Static | BindingFlags.NonPublic);
public static bool BakeAllReflectionProbesSnapshots()
{
return (bool)k_Lightmapping_BakeAllReflectionProbesSnapshots.Invoke(null, new object[0]);
}
public static bool IsCollidingWithOtherProbes(string targetPath, ReflectionProbe targetProbe, out ReflectionProbe collidingProbe)
public static bool BakeReflectionProbeSnapshot(ReflectionProbe probe)
ReflectionProbe[] probes = Object.FindObjectsOfType<ReflectionProbe>().ToArray();
collidingProbe = null;
foreach (var probe in probes)
{
if (probe == targetProbe || probe.customBakedTexture == null)
continue;
string path = AssetDatabase.GetAssetPath(probe.customBakedTexture);
if (path == targetPath)
{
collidingProbe = probe;
return true;
}
}
return false;
return BakeReflectionProbeSnapshot(
probe,
p => p.bakedTexture,
(p, t) => p.bakedTexture = t,
BakeReflectionProbe);
public static bool IsCollidingWithOtherProbes(string targetPath, PlanarReflectionProbe targetProbe, out PlanarReflectionProbe collidingProbe)
public static void ResetProbeSceneTextureInMaterial(ReflectionProbe p)
PlanarReflectionProbe[] probes = Object.FindObjectsOfType<PlanarReflectionProbe>().ToArray();
collidingProbe = null;
foreach (var probe in probes)
{
if (probe == targetProbe || probe.customTexture == null)
continue;
var path = AssetDatabase.GetAssetPath(probe.customTexture);
if (path == targetPath)
{
collidingProbe = probe;
return true;
}
}
return false;
var renderer = p.GetComponent<Renderer>();
renderer.sharedMaterial.SetTexture(_Cubemap, p.texture);
}
public static void BakeCustomReflectionProbe(ReflectionProbe probe, bool usePreviousAssetPath)
{
BakeCustomReflectionProbe(
probe,
usePreviousAssetPath,
p => p.customBakedTexture,
(p, t) => p.customBakedTexture = t,
BakeReflectionProbe);
public static void BakeCustomReflectionProbe(PlanarReflectionProbe probe, bool usePreviousAssetPath)
public static bool BakeReflectionProbe(ReflectionProbe probe, string assetPath)
string path;
if (!GetCustomBakePath(probe, probe.customTexture, true, usePreviousAssetPath, out path))
return;
// Probe rendering
var target = s_ReflectionProbeBaker.NewRenderTarget(
probe,
ReflectionSystem.parameters.reflectionProbeSize
);
s_ReflectionProbeBaker.Render(probe, target);
PlanarReflectionProbe collidingProbe;
if (IsCollidingWithOtherProbes(path, probe, out collidingProbe))
var isPathInProject = CoreEditorUtils.IsPathInProject(assetPath);
TextureImporter textureImporter = null;
if (isPathInProject)
if (!EditorUtility.DisplayDialog("Texture is used by other reflection probe",
string.Format("'{0}' path is used by the game object '{1}', do you really want to overwrite it?",
path, collidingProbe.name), "Yes", "No"))
var bakedTexture = AssetDatabase.LoadAssetAtPath<Cubemap>(assetPath);
if (bakedTexture == null)
{
// Import a small texture to get the TextureImporter quickly
bakedTexture = new Cubemap(4, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
AssetDatabase.CreateAsset(bakedTexture, assetPath);
}
// Setup importer
textureImporter = (TextureImporter)AssetImporter.GetAtPath(assetPath);
textureImporter.alphaSource = TextureImporterAlphaSource.None;
textureImporter.sRGBTexture = false;
textureImporter.mipmapEnabled = false;
textureImporter.textureShape = TextureImporterShape.TextureCube;
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
return;
textureImporter.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.reflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
EditorUtility.DisplayProgressBar("Planar Reflection Probes", "Baking " + path, 0.5f);
if (!BakePlanarReflectionProbe(probe, path))
Debug.LogError("Failed to bake reflection probe to " + path);
EditorUtility.ClearProgressBar();
// Write texture into asset file and import
var tex2D = CoreUtils.CopyCubemapToTexture2D(target);
target.Release();
var bytes = tex2D.EncodeToEXR(Texture2D.EXRFlags.CompressZIP);
CoreUtils.Destroy(tex2D);
File.WriteAllBytes(assetPath, bytes);
if (isPathInProject)
textureImporter.SaveAndReimport();
AssetDatabase.ImportAsset(path);
probe.customTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
EditorUtility.SetDirty(probe);
return true;
public static void BakeAllPlanarReflectionProbes()
public static bool BakeReflectionProbeSnapshot(PlanarReflectionProbe probe)
var probes = Object.FindObjectsOfType<PlanarReflectionProbe>();
for (var i = 0; i < probes.Length; i++)
{
EditorUtility.DisplayProgressBar(
"Baking Planar Probes",
string.Format("Probe {0} / {1}", i + 1, probes.Length),
(i + 1) / (float)probes.Length);
var probe = probes[i];
var bakePath = GetBakePathFor(probe);
var bakePathInfo = new FileInfo(bakePath);
if (!bakePathInfo.Directory.Exists)
bakePathInfo.Directory.Create();
BakePlanarReflectionProbe(probe, bakePath);
}
return BakeReflectionProbeSnapshot(
probe,
p => p.bakedTexture,
(p, t) => p.bakedTexture = t,
BakeReflectionProbe);
static string GetBakePathFor(PlanarReflectionProbe probe)
public static void BakeCustomReflectionProbe(PlanarReflectionProbe probe, bool usePreviousAssetPath)
var scene = probe.gameObject.scene;
var directory = Path.Combine(Path.GetDirectoryName(scene.path), Path.GetFileNameWithoutExtension(scene.path));
var filename = string.Format("PlanarReflectionProbe-{0}.exr", 0);
return Path.Combine(directory, filename);
BakeCustomReflectionProbe(
probe,
usePreviousAssetPath,
p => p.customTexture,
(p, t) => p.customTexture = t,
BakeReflectionProbe);
public static bool BakePlanarReflectionProbe(PlanarReflectionProbe probe, string path)
public static void ResetProbeSceneTextureInMaterial(PlanarReflectionProbe p)
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;
target.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0, false);
RenderTexture.active = a;
rt.Release();
probe.bakedTexture = target;
if (!WriteAndImportTexture(path, target))
return false;
return true;
public static void BakeCustomReflectionProbe(ReflectionProbe probe, bool usePreviousAssetPath)
public static bool BakeReflectionProbe(PlanarReflectionProbe probe, string assetPath)
string path;
if (!GetCustomBakePath(probe, probe.customBakedTexture, probe.hdr, usePreviousAssetPath, out path))
return;
// Probe rendering
var target = s_PlanarReflectionProbeBaker.NewRenderTarget(
probe,
ReflectionSystem.parameters.planarReflectionProbeSize
);
s_PlanarReflectionProbeBaker.Render(probe, target);
ReflectionProbe collidingProbe;
if (IsCollidingWithOtherProbes(path, probe, out collidingProbe))
var isPathInProject = CoreEditorUtils.IsPathInProject(assetPath);
TextureImporter textureImporter = null;
Texture2D bakedTexture = null;
if (isPathInProject)
if (!EditorUtility.DisplayDialog("Cubemap is used by other reflection probe",
string.Format("'{0}' path is used by the game object '{1}', do you really want to overwrite it?",
path, collidingProbe.name), "Yes", "No"))
bakedTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
if (bakedTexture == null)
{
// Import a small texture to get the TextureImporter quickly
bakedTexture = new Texture2D(4, 4, TextureFormat.RGBAHalf, true, false);
AssetDatabase.CreateAsset(bakedTexture, assetPath);
}
// Setup importer
textureImporter = (TextureImporter)AssetImporter.GetAtPath(assetPath);
textureImporter.alphaSource = TextureImporterAlphaSource.None;
textureImporter.sRGBTexture = false;
textureImporter.mipmapEnabled = false;
textureImporter.textureShape = TextureImporterShape.Texture2D;
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
return;
textureImporter.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.planarReflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
EditorUtility.DisplayProgressBar("Reflection Probes", "Baking " + path, 0.5f);
if (!UnityEditor.Lightmapping.BakeReflectionProbe(probe, path))
Debug.LogError("Failed to bake reflection probe to " + path);
EditorUtility.ClearProgressBar();
}
// Write texture into asset file and import
var art = RenderTexture.active;
RenderTexture.active = target;
bakedTexture = new Texture2D(target.width, target.height, TextureFormat.RGBAHalf, true, false);
bakedTexture.ReadPixels(new Rect(0, 0, target.width, target.height), 0, 0, false);
RenderTexture.active = art;
var bytes = bakedTexture.EncodeToEXR(Texture2D.EXRFlags.CompressZIP);
CoreUtils.Destroy(bakedTexture);
File.WriteAllBytes(assetPath, bytes);
public static void ResetProbeSceneTextureInMaterial(ReflectionProbe p)
{
var renderer = p.GetComponent<Renderer>();
renderer.sharedMaterial.SetTexture(_Cubemap, p.texture);
}
if (isPathInProject)
textureImporter.SaveAndReimport();
public static void ResetProbeSceneTextureInMaterial(PlanarReflectionProbe p)
{
return true;
public static bool BakeReflectionProbeSnapshot(ReflectionProbe probe)
static bool BakeReflectionProbeSnapshot<TProbe>(
TProbe probe,
Func<TProbe, Texture> bakedTextureGetter,
Action<TProbe, Texture> bakedTextureSetter,
Func<TProbe, string, bool> baker)
where TProbe : Component
// 2. Probe rendering
var target = s_ReflectionProbeBaker.NewRenderTarget(
probe,
ReflectionSystem.parameters.reflectionProbeSize
);
s_ReflectionProbeBaker.Render(probe, target);
// Get asset path
var bakedTexture = bakedTextureGetter(probe);
var bakedTexture = probe.bakedTexture;
// 3. Get asset path and importer
var assetPath = string.Empty;
if (bakedTexture != null)
assetPath = AssetDatabase.GetAssetPath(bakedTexture);

bakedTexture = AssetDatabase.LoadAssetAtPath<Cubemap>(assetPath);
}
Assert.IsFalse(string.IsNullOrEmpty(assetPath));
if (bakedTexture == null)
{
// Import a small texture to get the TextureImporter quickly
bakedTexture = new Cubemap(4, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
AssetDatabase.CreateAsset(bakedTexture, assetPath);
}
// 4. Setup importer
var textureImporter = (TextureImporter)AssetImporter.GetAtPath(assetPath);
textureImporter.alphaSource = TextureImporterAlphaSource.None;
textureImporter.sRGBTexture = false;
textureImporter.mipmapEnabled = false;
textureImporter.textureShape = TextureImporterShape.TextureCube;
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
textureImporter.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.reflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
}
// 5. Write texture into asset file and import
var tex2D = CoreUtils.CopyCubemapToTexture2D(target);
target.Release();
var bytes = tex2D.EncodeToEXR(Texture2D.EXRFlags.CompressZIP);
CoreUtils.Destroy(tex2D);
File.WriteAllBytes(assetPath, bytes);
textureImporter.SaveAndReimport();
baker(probe, assetPath);
// 6. Assign texture
probe.bakedTexture = bakedTexture;
// Assign texture
bakedTextureSetter(probe, bakedTexture);
// 7. Register baking information
// Register baking information
var asset = GetOrCreateLightingDataAssetForScene(probe.gameObject.scene);
var asset = EditorHDLightingDataAsset.GetOrCreateLightingDataAssetForScene(probe.gameObject.scene);
if (id != SceneObjectIdentifier.Invalid && asset != null)
{
asset.SetBakedTexture(id, bakedTexture);

return true;
}
public static bool BakeReflectionProbeSnapshot(PlanarReflectionProbe probe)
static void BakeCustomReflectionProbe<TProbe>(
TProbe probe,
bool usePreviousAssetPath,
Func<TProbe, Texture> customTextureGetter,
Action<TProbe, Texture> customTextureSetter,
Func<TProbe, string, bool> baker)
where TProbe : Component
var rt = s_PlanarReflectionProbeBaker.NewRenderTarget(probe, ReflectionSystem.parameters.planarReflectionProbeSize);
var bakedTexture = probe.bakedTexture as Texture2D;
var assetPath = string.Empty;
if (bakedTexture != null)
assetPath = AssetDatabase.GetAssetPath(bakedTexture);
if (string.IsNullOrEmpty(assetPath))
assetPath = GetBakePath(probe);
string path;
if (!TryGetCustomBakePath(probe, customTextureGetter(probe), usePreviousAssetPath, out path))
return;
if (bakedTexture == null || string.IsNullOrEmpty(assetPath))
TProbe collidingProbe;
if (IsCollidingWithOtherProbes(path, probe, customTextureGetter, out collidingProbe))
bakedTexture = new Texture2D(rt.width, rt.height, TextureFormat.RGBAHalf, true, false);
probe.bakedTexture = bakedTexture;
if (!EditorUtility.DisplayDialog("Cubemap is used by other reflection probe",
string.Format("'{0}' path is used by the game object '{1}', do you really want to overwrite it?",
path, collidingProbe.name), "Yes", "No"))
return;
}
EditorUtility.DisplayProgressBar("Reflection Probes", "Baking " + path, 0.5f);
if (!baker(probe, path))
Debug.LogError("Failed to bake reflection probe to " + path);
else
{
var bakedTexture = AssetDatabase.LoadAssetAtPath<Cubemap>(path);
customTextureSetter(probe, bakedTexture);
EditorUtility.ClearProgressBar();
}
s_PlanarReflectionProbeBaker.Render(probe, rt);
var art = RenderTexture.active;
RenderTexture.active = rt;
bakedTexture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0, false);
RenderTexture.active = art;
static string GetBakePath(Component probe)
{
var id = SceneObjectIdentifierUtils.GetSceneObjectIdentifierFor(probe);
if (id == SceneObjectIdentifier.Invalid)
return string.Empty;
WriteAndImportTexture(assetPath, bakedTexture);
var scene = probe.gameObject.scene;
return true;
}
var targetPath = GetSceneBakeDirectoryPath(scene);
if (!Directory.Exists(targetPath))
Directory.CreateDirectory(targetPath);
static MethodInfo k_Lightmapping_BakeAllReflectionProbesSnapshots = typeof(UnityEditor.Lightmapping).GetMethod("BakeAllReflectionProbesSnapshots", BindingFlags.Static | BindingFlags.NonPublic);
public static bool BakeAllReflectionProbesSnapshots()
{
return (bool)k_Lightmapping_BakeAllReflectionProbesSnapshots.Invoke(null, new object[0]);
var fileName = string.Format("{0} {1}.exr", probe.GetType().Name, id);
return Path.Combine(targetPath, fileName);
static bool GetCustomBakePath(Component probe, Texture customBakedTexture, bool hdr, bool usePreviousAssetPath, out string path)
static bool TryGetCustomBakePath(Component probe, Texture customBakedTexture, bool usePreviousAssetPath, out string path)
{
var id = SceneObjectIdentifierUtils.GetSceneObjectIdentifierFor(probe);
if (id == SceneObjectIdentifier.Invalid)

if (usePreviousAssetPath)
path = AssetDatabase.GetAssetPath(customBakedTexture);
var targetExtension = hdr ? "exr" : "png";
if (string.IsNullOrEmpty(path) || Path.GetExtension(path) != "." + targetExtension)
if (string.IsNullOrEmpty(path) || Path.GetExtension(path) != ".exr")
{
// We use the path of the active scene as the target path
var targetPath = GetSceneBakeDirectoryPath(SceneManager.GetActiveScene());

var fileName = string.Format("Probe {0}.exr", id);
var fileName = string.Format("{0} {1}.exr", probe.GetType().Name, id);
path = EditorUtility.SaveFilePanelInProject("Save reflection probe's cubemap.", fileName, targetExtension, "", targetPath);
path = EditorUtility.SaveFilePanelInProject("Save reflection probe's cubemap.", fileName, "exr", "", targetPath);
if (string.IsNullOrEmpty(path))
return false;
}

static string GetBakePath(Component probe)
{
var id = SceneObjectIdentifierUtils.GetSceneObjectIdentifierFor(probe);
if (id == SceneObjectIdentifier.Invalid)
return string.Empty;
var scene = probe.gameObject.scene;
var targetPath = GetSceneBakeDirectoryPath(scene);
if (!Directory.Exists(targetPath))
Directory.CreateDirectory(targetPath);
var fileName = string.Format("Probe {0}.exr", id);
return Path.Combine(targetPath, fileName);
}
static string GetSceneBakeDirectoryPath(Scene scene)
{
var targetPath = scene.path;

return targetPath;
}
static HDLightingDataAsset GetOrCreateLightingDataAssetForScene(Scene scene)
{
var filePath = GetLightingDataAssetPathForScene(scene);
var filePathInfo = new FileInfo(filePath);
if (!filePathInfo.Directory.Exists)
filePathInfo.Directory.Create();
var asset = AssetDatabase.LoadAssetAtPath<HDLightingDataAsset>(filePath);
if (asset == null)
{
asset = ScriptableObject.CreateInstance<HDLightingDataAsset>();
AssetDatabase.CreateAsset(asset, filePath);
}
return asset;
}
static HDLightingDataAsset GetLightingDataAssetForScene(Scene scene)
{
var filePath = GetLightingDataAssetPathForScene(scene);
var asset = AssetDatabase.LoadAssetAtPath<HDLightingDataAsset>(filePath);
return asset;
}
static string GetLightingDataAssetPathForScene(Scene scene)
{
var parentFolder = Path.GetFileNameWithoutExtension(scene.path);
return Path.Combine(Path.GetDirectoryName(scene.path), Path.Combine(parentFolder, "HDLightingData.asset"));
}
static bool WriteAndImportTexture(string path, Texture2D target)
static bool IsCollidingWithOtherProbes<TType>(string targetPath, TType targetProbe, Func<TType, Texture> textureGetter, out TType collidingProbe)
where TType : Object
var bytes = target.EncodeToEXR();
try
var probes = Object.FindObjectsOfType<TType>().ToArray();
collidingProbe = null;
foreach (var probe in probes)
var targetFile = new FileInfo(path);
if (!targetFile.Directory.Exists)
targetFile.Directory.Create();
File.WriteAllBytes(path, bytes);
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
AssetDatabase.ImportAsset(path);
var importer = AssetImporter.GetAtPath(path) as TextureImporter;
if (importer != null)
{
importer.alphaSource = TextureImporterAlphaSource.None;
importer.sRGBTexture = false;
importer.mipmapEnabled = false;
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
importer.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.planarReflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
}
importer.SaveAndReimport();
}
return true;
}
[InitializeOnLoadMethod]
static void Initialize()
{
RenderSettings.enableLegacyReflectionProbeSystem = false;
Lightmapping.BakeReflectionProbeRequest += LightmappingOnBakeReflectionProbeRequest;
Lightmapping.ClearBakedReflectionProbeRequest += LightmappingOnClearBakedReflectionProbeRequest;
EditorSceneManager.sceneOpened += EditorSceneManagerOnSceneOpened;
EditorApplication.update += Update;
}
static void EditorSceneManagerOnSceneOpened(Scene scene, OpenSceneMode mode)
{
var asset = GetLightingDataAssetForScene(scene);
if (asset == null)
return;
var roots = scene.GetRootGameObjects();
var probes = new List<ReflectionProbe>();
for (var i = 0; i < roots.Length; i++)
{
var root = roots[i];
root.GetComponentsInChildren(probes);
for (var j = 0; j < probes.Count; j++)
{
var probe = probes[j];
var id = SceneObjectIdentifierUtils.GetSceneObjectIdentifierFor(probe);
if (id == SceneObjectIdentifier.Invalid)
continue;
var bakedTexture = asset.GetBakedTextureFor(id);
if (bakedTexture == null)
continue;
probe.bakedTexture = bakedTexture;
}
}
}
static void LightmappingOnClearBakedReflectionProbeRequest()
{
for (int i = 0, c = SceneManager.sceneCount; i < c; ++i)
{
var scene = SceneManager.GetSceneAt(i);
if (!scene.IsValid() || !scene.isLoaded)
if (probe == targetProbe)
var asset = GetLightingDataAssetForScene(scene);
if (asset == null)
var customTexture = textureGetter(probe);
if (customTexture == null)
asset.DeleteAssets();
var path = AssetDatabase.GetAssetPath(asset);
Assert.IsFalse(string.IsNullOrEmpty(path));
AssetDatabase.DeleteAsset(path);
}
}
static void Update()
{
if (s_CurrentBakeJob != null)
{
s_CurrentBakeJob.Tick();
if (s_CurrentBakeJob.isComplete)
{
s_CurrentBakeJob.Dispose();
s_CurrentBakeJob = null;
}
}
}
static void LightmappingOnBakeReflectionProbeRequest(BakeReflectionProbeRequest request)
{
if (request.IsCompleted)
return;
// Custom probe hashes should be handled here by the user
// var customProbeHash = CalculateCustomProbeHashes()
// dependencyHash = CombineHashes(dependencyHash, customProbeHash);
// Currently only one bounce is handled
// TODO: Use UnityEngine.RenderSettings.reflectionBounces and handle bounces
if (s_CurrentBakeJob != null)
{
s_CurrentBakeJob.Dispose();
s_CurrentBakeJob = null;
}
var job = new ReflectionBakeJob(request);
ReflectionSystem.QueryReflectionProbes(job.reflectionProbesToBake, mode: ReflectionProbeMode.Baked);
ReflectionSystem.QueryPlanarProbes(job.planarReflectionProbesToBake, mode: ReflectionProbeMode.Baked);
s_CurrentBakeJob = job;
request.Cancelled += LightmappingOnBakeReflectionProbeRequestCancelled;
}
static void LightmappingOnBakeReflectionProbeRequestCancelled(BakeReflectionProbeRequest request)
{
Debug.Log("Cancel: " + request.RequestHash);
request.Cancelled -= LightmappingOnBakeReflectionProbeRequestCancelled;
if (s_CurrentBakeJob != null && s_CurrentBakeJob.request == request)
{
s_CurrentBakeJob.Dispose();
s_CurrentBakeJob = null;
}
}
class ReflectionBakeJob : IDisposable
{
enum Stage
{
BakeReflectionProbe,
BakePlanarProbe,
Completed
}
delegate void BakingStage(ReflectionBakeJob job);
static readonly BakingStage[] s_Stages =
{
StageBakeReflectionProbe,
StageBakePlanarProbe,
};
Stage m_CurrentStage = Stage.BakeReflectionProbe;
int m_StageIndex;
public bool isComplete { get { return m_CurrentStage == Stage.Completed; } }
public BakeReflectionProbeRequest request;
public List<ReflectionProbe> reflectionProbesToBake = new List<ReflectionProbe>();
public List<PlanarReflectionProbe> planarReflectionProbesToBake = new List<PlanarReflectionProbe>();
public ReflectionBakeJob(BakeReflectionProbeRequest request)
{
this.request = request;
}
public void Tick()
{
if (m_StageIndex == -1 && m_CurrentStage != Stage.Completed)
var path = AssetDatabase.GetAssetPath(customTexture);
if (path == targetPath)
m_CurrentStage = (Stage)((int)m_CurrentStage + 1);
m_StageIndex = 0;
collidingProbe = probe;
return true;
if (m_CurrentStage == Stage.Completed)
{
request.Progress = 1;
return;
}
s_Stages[(int)m_CurrentStage](this);
public void Dispose()
{
request.Progress = 1;
m_CurrentStage = Stage.Completed;
m_StageIndex = 0;
}
static void StageBakeReflectionProbe(ReflectionBakeJob job)
{
if (job.m_StageIndex >= job.reflectionProbesToBake.Count)
{
job.m_StageIndex = -1;
return;
}
// 1. Setup stage information
var stageProgress = job.reflectionProbesToBake.Count > 0
? 1f - job.m_StageIndex / (float)job.reflectionProbesToBake.Count
: 1f;
job.request.Progress = ((float)Stage.BakeReflectionProbe + stageProgress) / (float)Stage.Completed;
job.request.ProgressMessage = string.Format("Reflection Probes ({0}/{1})", job.m_StageIndex + 1, job.reflectionProbesToBake.Count);
BakeReflectionProbeSnapshot(job.reflectionProbesToBake[job.m_StageIndex]);
++job.m_StageIndex;
}
static void StageBakePlanarProbe(ReflectionBakeJob job)
{
if (job.m_StageIndex >= job.planarReflectionProbesToBake.Count)
{
job.m_StageIndex = -1;
return;
}
// 1. Setup stage information
var stageProgress = job.planarReflectionProbesToBake.Count > 0
? 1f - job.m_StageIndex / (float)job.planarReflectionProbesToBake.Count
: 1f;
job.request.Progress = ((float)Stage.BakePlanarProbe + stageProgress) / (float)Stage.Completed;
job.request.ProgressMessage = string.Format("Reflection Probes ({0}/{1})", job.m_StageIndex + 1, job.planarReflectionProbesToBake.Count);
// 2. Probe rendering
var probe = job.planarReflectionProbesToBake[job.m_StageIndex];
var target = s_PlanarReflectionProbeBaker.NewRenderTarget(
probe,
ReflectionSystem.parameters.planarReflectionProbeSize
);
s_PlanarReflectionProbeBaker.Render(probe, target);
var bakedTexture = probe.bakedTexture;
// 3. Get asset path and importer
var assetPath = string.Empty;
if (bakedTexture != null)
assetPath = AssetDatabase.GetAssetPath(bakedTexture);
if (string.IsNullOrEmpty(assetPath))
{
assetPath = GetBakePath(probe);
bakedTexture = AssetDatabase.LoadAssetAtPath<Cubemap>(assetPath);
}
Assert.IsFalse(string.IsNullOrEmpty(assetPath));
if (bakedTexture == null)
{
// Import a small texture to get the TextureImporter quickly
bakedTexture = new Texture2D(4, 4, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
AssetDatabase.CreateAsset(bakedTexture, assetPath);
}
// 4. Setup importer
var textureImporter = (TextureImporter)AssetImporter.GetAtPath(assetPath);
textureImporter.alphaSource = TextureImporterAlphaSource.None;
textureImporter.sRGBTexture = false;
textureImporter.mipmapEnabled = false;
textureImporter.textureShape = TextureImporterShape.Texture2D;
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
textureImporter.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.planarReflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
}
// 5. Write texture into asset file and import
Graphics.CopyTexture(target, bakedTexture);
var bytes = ((Texture2D)bakedTexture).EncodeToEXR(Texture2D.EXRFlags.CompressZIP);
File.WriteAllBytes(assetPath, bytes);
textureImporter.SaveAndReimport();
AssetDatabase.ImportAsset(assetPath);
target.Release();
// 6. Assign texture
probe.bakedTexture = bakedTexture;
EditorUtility.SetDirty(probe);
// 7. Register baking information
var id = SceneObjectIdentifierUtils.GetSceneObjectIdentifierFor(probe);
var asset = GetOrCreateLightingDataAssetForScene(probe.gameObject.scene);
if (id != SceneObjectIdentifier.Invalid && asset != null)
{
asset.SetBakedTexture(id, bakedTexture);
EditorUtility.SetDirty(asset);
}
++job.m_StageIndex;
}
return false;
}
}
}

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


public Vector3 blendNormalDistanceNegative = Vector3.zero;
public Vector3 boxSideFadePositive = Vector3.one;
public Vector3 boxSideFadeNegative = Vector3.one;
public Cubemap bakedTexture;
public ReflectionProxyVolumeComponent proxyVolumeComponent;

void OnEnable()
{
ReflectionSystem.RegisterProbe(GetComponent<ReflectionProbe>());
var probe = GetComponent<ReflectionProbe>();
ReflectionSystem.RegisterProbe(probe);
probe.bakedTexture = bakedTexture;
}
void OnDisable()

104
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/BakeReflectionProbesJob.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
class ReflectionBakeJob : IDisposable
{
enum Stage
{
BakeReflectionProbe,
BakePlanarProbe,
Completed
}
delegate void BakingStage(ReflectionBakeJob job);
static readonly BakingStage[] s_Stages =
{
StageBakeReflectionProbe,
StageBakePlanarProbe,
};
Stage m_CurrentStage = Stage.BakeReflectionProbe;
int m_StageIndex;
public bool isComplete { get { return m_CurrentStage == Stage.Completed; } }
public BakeReflectionProbeRequest request;
public List<ReflectionProbe> reflectionProbesToBake = new List<ReflectionProbe>();
public List<PlanarReflectionProbe> planarReflectionProbesToBake = new List<PlanarReflectionProbe>();
public ReflectionBakeJob(BakeReflectionProbeRequest request)
{
this.request = request;
}
public void Tick()
{
if (m_StageIndex == -1 && m_CurrentStage != Stage.Completed)
{
m_CurrentStage = (Stage)((int)m_CurrentStage + 1);
m_StageIndex = 0;
}
if (m_CurrentStage == Stage.Completed)
{
request.Progress = 1;
return;
}
s_Stages[(int)m_CurrentStage](this);
}
public void Dispose()
{
request.Progress = 1;
m_CurrentStage = Stage.Completed;
m_StageIndex = 0;
}
static void StageBakeReflectionProbe(ReflectionBakeJob job)
{
if (job.m_StageIndex >= job.reflectionProbesToBake.Count)
{
job.m_StageIndex = -1;
return;
}
// 1. Setup stage information
var stageProgress = job.reflectionProbesToBake.Count > 0
? 1f - job.m_StageIndex / (float)job.reflectionProbesToBake.Count
: 1f;
job.request.Progress = ((float)Stage.BakeReflectionProbe + stageProgress) / (float)Stage.Completed;
job.request.ProgressMessage = string.Format("Reflection Probes ({0}/{1})", job.m_StageIndex + 1, job.reflectionProbesToBake.Count);
EditorReflectionSystem.BakeReflectionProbeSnapshot(job.reflectionProbesToBake[job.m_StageIndex]);
++job.m_StageIndex;
}
static void StageBakePlanarProbe(ReflectionBakeJob job)
{
if (job.m_StageIndex >= job.planarReflectionProbesToBake.Count)
{
job.m_StageIndex = -1;
return;
}
// 1. Setup stage information
var stageProgress = job.planarReflectionProbesToBake.Count > 0
? 1f - job.m_StageIndex / (float)job.planarReflectionProbesToBake.Count
: 1f;
job.request.Progress = ((float)Stage.BakePlanarProbe + stageProgress) / (float)Stage.Completed;
job.request.ProgressMessage = string.Format("Reflection Probes ({0}/{1})", job.m_StageIndex + 1, job.planarReflectionProbesToBake.Count);
EditorReflectionSystem.BakeReflectionProbeSnapshot(job.planarReflectionProbesToBake[job.m_StageIndex]);
++job.m_StageIndex;
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/BakeReflectionProbesJob.cs.meta


fileFormatVersion: 2
guid: bad5b9c08ef04724fbcaa1e144127d3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

40
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorHDLightingDataAsset.cs


using System.IO;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.SceneManagement;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public static class EditorHDLightingDataAsset
{
public static HDLightingDataAsset GetLightingDataAssetForScene(Scene scene)
{
var filePath = GetLightingDataAssetPathForScene(scene);
var asset = AssetDatabase.LoadAssetAtPath<HDLightingDataAsset>(filePath);
return asset;
}
public static HDLightingDataAsset GetOrCreateLightingDataAssetForScene(Scene scene)
{
var filePath = GetLightingDataAssetPathForScene(scene);
var filePathInfo = new FileInfo(filePath);
if (!filePathInfo.Directory.Exists)
filePathInfo.Directory.Create();
var asset = AssetDatabase.LoadAssetAtPath<HDLightingDataAsset>(filePath);
if (asset == null)
{
asset = ScriptableObject.CreateInstance<HDLightingDataAsset>();
AssetDatabase.CreateAsset(asset, filePath);
}
return asset;
}
static string GetLightingDataAssetPathForScene(Scene scene)
{
var parentFolder = Path.GetFileNameWithoutExtension(scene.path);
return Path.Combine(Path.GetDirectoryName(scene.path), Path.Combine(parentFolder, "HDLightingData.asset"));
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorHDLightingDataAsset.cs.meta


fileFormatVersion: 2
guid: c930b5a4c3d4d884aa99ba287cf4cd91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

123
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ReflectionProbeCustomBakingIntegration.cs


using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
static class ReflectionProbeCustomBakingIntegration
{
static ReflectionBakeJob s_CurrentBakeJob = null;
[InitializeOnLoadMethod]
static void Initialize()
{
GraphicsSettings.useBuiltinReflectionProbeSystem = false;
Lightmapping.BakeReflectionProbeRequest += LightmappingOnBakeReflectionProbeRequest;
Lightmapping.ClearBakedReflectionProbeRequest += LightmappingOnClearBakedReflectionProbeRequest;
EditorSceneManager.sceneOpened += EditorSceneManagerOnSceneOpened;
EditorApplication.update += Update;
}
static void EditorSceneManagerOnSceneOpened(Scene scene, OpenSceneMode mode)
{
var asset = EditorHDLightingDataAsset.GetLightingDataAssetForScene(scene);
if (asset == null)
return;
var roots = scene.GetRootGameObjects();
var probes = new List<ReflectionProbe>();
for (var i = 0; i < roots.Length; i++)
{
var root = roots[i];
root.GetComponentsInChildren(probes);
for (var j = 0; j < probes.Count; j++)
{
var probe = probes[j];
var id = SceneObjectIdentifierUtils.GetSceneObjectIdentifierFor(probe);
if (id == SceneObjectIdentifier.Invalid)
continue;
var bakedTexture = asset.GetBakedTextureFor(id);
if (bakedTexture == null)
continue;
probe.bakedTexture = bakedTexture;
}
}
}
static void LightmappingOnClearBakedReflectionProbeRequest()
{
for (int i = 0, c = SceneManager.sceneCount; i < c; ++i)
{
var scene = SceneManager.GetSceneAt(i);
if (!scene.IsValid() || !scene.isLoaded)
continue;
var asset = EditorHDLightingDataAsset.GetLightingDataAssetForScene(scene);
if (asset == null)
continue;
asset.DeleteAssets();
var path = AssetDatabase.GetAssetPath(asset);
Assert.IsFalse(string.IsNullOrEmpty(path));
AssetDatabase.DeleteAsset(path);
}
}
static void Update()
{
if (s_CurrentBakeJob != null)
{
s_CurrentBakeJob.Tick();
if (s_CurrentBakeJob.isComplete)
{
s_CurrentBakeJob.Dispose();
s_CurrentBakeJob = null;
}
}
}
static void LightmappingOnBakeReflectionProbeRequest(BakeReflectionProbeRequest request)
{
if (request.IsCompleted)
return;
// Custom probe hashes should be handled here by the user
// var customProbeHash = CalculateCustomProbeHashes()
// dependencyHash = CombineHashes(dependencyHash, customProbeHash);
// Currently only one bounce is handled
// TODO: Use UnityEngine.RenderSettings.reflectionBounces and handle bounces
if (s_CurrentBakeJob != null)
{
s_CurrentBakeJob.Dispose();
s_CurrentBakeJob = null;
}
var job = new ReflectionBakeJob(request);
ReflectionSystem.QueryReflectionProbes(job.reflectionProbesToBake, mode: ReflectionProbeMode.Baked);
ReflectionSystem.QueryPlanarProbes(job.planarReflectionProbesToBake, mode: ReflectionProbeMode.Baked);
s_CurrentBakeJob = job;
request.Cancelled += LightmappingOnBakeReflectionProbeRequestCancelled;
}
static void LightmappingOnBakeReflectionProbeRequestCancelled(BakeReflectionProbeRequest request)
{
Debug.Log("Cancel: " + request.RequestHash);
request.Cancelled -= LightmappingOnBakeReflectionProbeRequestCancelled;
if (s_CurrentBakeJob != null && s_CurrentBakeJob.request == request)
{
s_CurrentBakeJob.Dispose();
s_CurrentBakeJob = null;
}
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ReflectionProbeCustomBakingIntegration.cs.meta


fileFormatVersion: 2
guid: 853f88d9c68e9b5419b7c03a685d9de9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存