浏览代码

[ReflectionProbes] Refactored Cubemap Export

/feature-ReflectionProbeBaking
Frédéric Vauchelles 7 年前
当前提交
9ea01100
共有 3 个文件被更改,包括 121 次插入110 次删除
  1. 57
      ScriptableRenderPipeline/Core/CoreRP/CoreUtils.cs
  2. 139
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/EditorReflectionSystem.cs
  3. 35
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs

57
ScriptableRenderPipeline/Core/CoreRP/CoreUtils.cs


using System;
using System;
using UnityEngine.Assertions;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;

mesh.triangles = triangles;
return mesh;
}
/// <summary>
/// Export a cubemap to a texture2D.
///
/// The Texture2D size is (size * 6, size) and the layout is +X,-X,+Y,-Y,+Z,-Z
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Texture2D CopyCubemapToTexture2D(RenderTexture source)
{
Assert.AreEqual(TextureDimension.Cube, source.dimension);
Assert.AreEqual(RenderTextureFormat.ARGBFloat, source.format);
var resolution = source.width;
var result = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
var offset = 0;
for (var i = 0; i < 6; ++i)
{
Graphics.SetRenderTarget(source, 0, (CubemapFace)i);
result.ReadPixels(new Rect(0, 0, resolution, resolution), offset, 0);
result.Apply();
offset += resolution;
}
return result;
}
public static Texture2D FlipY(Texture2D source)
{
var result = new Texture2D(source.width, source.height, source.format, false);
var rtFormat = TextureFormatUtilities.GetUncompressedRenderTextureFormat(source);
var tempRT = new RenderTexture(source.width, source.height, 0, rtFormat, RenderTextureReadWrite.Linear)
{
dimension = TextureDimension.Tex2D,
useMipMap = false,
autoGenerateMips = false,
filterMode = FilterMode.Trilinear
};
tempRT.Create();
// Flip texture.
UnityEngine.Graphics.Blit(source, tempRT, new Vector2(1.0f, -1.0f), new Vector2(0.0f, 0.0f));
result.ReadPixels(new Rect(0, 0, source.width, source.height), 0, 0);
result.Apply();
UnityEngine.Graphics.SetRenderTarget(null);
Destroy(tempRT);
return result;
}
}
}

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


using System.Reflection;
using UnityEditor.Callbacks;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Experimental.Rendering.HDPipeline.Internal;

return;
}
// 1. Setup stage information
var stageProgress = job.reflectionProbesToBake.Count > 0
? 1f - job.m_StageIndex / (float)job.reflectionProbesToBake.Count
: 1f;

// 2. Probe rendering
var target = s_ReflectionProbeBaker.NewRenderTarget(
probe,
ReflectionSystem.parameters.reflectionProbeSize

var bakedTexture = probe.bakedTexture;
// 3. Get asset path and importer
var assetPath = string.Empty;
if (bakedTexture != null)
assetPath = AssetDatabase.GetAssetPath(bakedTexture);

if (bakedTexture == null || string.IsNullOrEmpty(assetPath))
{
bakedTexture = new Cubemap(target.width, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
probe.bakedTexture = bakedTexture;
Assert.IsFalse(string.IsNullOrEmpty(assetPath));
EditorUtility.SetDirty(probe);
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);
for (var j = 0; j < 6; ++j)
Graphics.CopyTexture(target, j, 0, bakedTexture, j, 0);
target.Release();
// 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)
var tmp2D = new Texture2D(bakedTexture.width * 6, bakedTexture.height, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
var cols = new Color[bakedTexture.width * 6 * bakedTexture.height];
var length = bakedTexture.width * bakedTexture.height;
var tmpCols = ((Cubemap)bakedTexture).GetPixels(CubemapFace.PositiveX, 0);
Array.Copy(tmpCols, 0, cols, 0, length);
tmpCols = ((Cubemap)bakedTexture).GetPixels(CubemapFace.NegativeX, 0);
Array.Copy(tmpCols, 0, cols, length, length);
tmpCols = ((Cubemap)bakedTexture).GetPixels(CubemapFace.PositiveY, 0);
Array.Copy(tmpCols, 0, cols, length * 2, length);
tmpCols = ((Cubemap)bakedTexture).GetPixels(CubemapFace.NegativeY, 0);
Array.Copy(tmpCols, 0, cols, length * 3, length);
tmpCols = ((Cubemap)bakedTexture).GetPixels(CubemapFace.PositiveZ, 0);
Array.Copy(tmpCols, 0, cols, length * 4, length);
tmpCols = ((Cubemap)bakedTexture).GetPixels(CubemapFace.NegativeZ, 0);
Array.Copy(tmpCols, 0, cols, length * 5, length);
tmp2D.SetPixels(cols);
tmp2D.Apply(false);
var bytes = tmp2D.EncodeToEXR(Texture2D.EXRFlags.OutputAsFloat);
File.WriteAllBytes(assetPath, bytes);
textureImporter.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.reflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
AssetDatabase.ImportAsset(assetPath);
// 5. Write texture into asset file and import
var tex2D = CoreUtils.CopyCubemapToTexture2D(target);
var bytes = tex2D.EncodeToEXR(Texture2D.EXRFlags.CompressZIP);
CoreUtils.Destroy(tex2D);
File.WriteAllBytes(assetPath, bytes);
textureImporter.SaveAndReimport();
target.Release();
var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
if (importer != null)
{
importer.alphaSource = TextureImporterAlphaSource.None;
importer.sRGBTexture = false;
importer.mipmapEnabled = false;
importer.textureShape = TextureImporterShape.TextureCube;
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
importer.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.reflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
}
// 6. Assign texture
probe.bakedTexture = bakedTexture;
EditorUtility.SetDirty(probe);
importer.SaveAndReimport();
}
++job.m_StageIndex;
}

return;
}
// 1. Setup stage information
var stageProgress = job.planarReflectionProbesToBake.Count > 0
? 1f - job.m_StageIndex / (float)job.planarReflectionProbesToBake.Count
: 1f;

// 2. Probe rendering
var probe = job.planarReflectionProbesToBake[job.m_StageIndex];
var target = s_PlanarReflectionProbeBaker.NewRenderTarget(
probe,

var bakedTexture = probe.bakedTexture;
// 3. Get asset path and importer
var assetPath = string.Empty;
if (bakedTexture != null)
assetPath = AssetDatabase.GetAssetPath(bakedTexture);

if (bakedTexture == null || string.IsNullOrEmpty(assetPath))
Assert.IsFalse(string.IsNullOrEmpty(assetPath));
if (bakedTexture == null)
bakedTexture = new Texture2D(target.width, target.height, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
probe.bakedTexture = bakedTexture;
// Import a small texture to get the TextureImporter quickly
bakedTexture = new Texture2D(4, 4, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None);
AssetDatabase.CreateAsset(bakedTexture, assetPath);
}
EditorUtility.SetDirty(probe);
var bytes = ((Texture2D)bakedTexture).EncodeToEXR(Texture2D.EXRFlags.OutputAsFloat);
File.WriteAllBytes(assetPath, bytes);
// 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;
Graphics.CopyTexture(target, 0, bakedTexture, 0);
// 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);
var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
if (importer != null)
{
importer.alphaSource = TextureImporterAlphaSource.None;
importer.sRGBTexture = false;
importer.mipmapEnabled = false;
importer.textureShape = TextureImporterShape.Texture2D;
// 6. Assign texture
probe.bakedTexture = bakedTexture;
EditorUtility.SetDirty(probe);
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
importer.textureCompression = hdrp.renderPipelineSettings.lightLoopSettings.planarReflectionCacheCompressed
? TextureImporterCompression.Compressed
: TextureImporterCompression.Uncompressed;
}
importer.SaveAndReimport();
}
++job.m_StageIndex;
}
}

35
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs


RenderTexture skyCubemap = m_SkyRenderingContext.cubemapRT;
int resolution = skyCubemap.width;
var tempRT = new RenderTexture(resolution * 6, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear)
{
dimension = TextureDimension.Tex2D,
useMipMap = false,
autoGenerateMips = false,
filterMode = FilterMode.Trilinear
};
tempRT.Create();
var temp = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
var result = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
var skyTex2DFlipped = CoreUtils.CopyCubemapToTexture2D(skyCubemap);
// Note: We need to invert in Y the cubemap faces because the current sky cubemap is inverted (because it's a RT)
// So to invert it again so that it's a proper cubemap image we need to do it in several steps because ReadPixels does not have scale parameters:

int offset = 0;
for (int i = 0; i < 6; ++i)
{
UnityEngine.Graphics.SetRenderTarget(skyCubemap, 0, (CubemapFace)i);
temp.ReadPixels(new Rect(0, 0, resolution, resolution), offset, 0);
temp.Apply();
offset += resolution;
}
var skyTex2D = CoreUtils.FlipY(skyTex2DFlipped);
// Flip texture.
UnityEngine.Graphics.Blit(temp, tempRT, new Vector2(1.0f, -1.0f), new Vector2(0.0f, 0.0f));
CoreUtils.Destroy(skyTex2DFlipped);
result.ReadPixels(new Rect(0, 0, resolution * 6, resolution), 0, 0);
result.Apply();
UnityEngine.Graphics.SetRenderTarget(null);
CoreUtils.Destroy(temp);
CoreUtils.Destroy(tempRT);
return result;
return skyTex2D;
}
}
}
正在加载...
取消
保存