前言
在前文中介绍了cubemap方式模仿环境反射,全景高动态环境图即HDRI贴图被广泛应用于游戏、动画、设计等各种领域,作为环境光源起到环境照明和环境反射的作用。
因此,高质量且适合的HDRI贴图素材往往能给三维场景的光影渲染起到锦上添花的作用,因此本文就介绍一下一些HDRI素材的资源网站以及在引擎中制作HDRI素材的方法。
资源网站
UE4中制作HDRI贴图
如果想要将UE4场景转换成一张HDRI贴图的话,可以如下操作,制作方法参考自Youtube上的以下视频。
首先在内容窗口创建一个Cube Render Target,可以命名为CubeRenderTarget。
然后双击Cube Render Target打开属性窗口,修改贴图的尺寸
在场景中创建一个SceneCaptureCube,放置在适合作为HDRI贴图中心点的位置。
在SceneCaptureCube的Texture target属性中选择刚才创建的CubeRenderTarget。
右键CubeRenderTarget选择创建静态图片,这样旁边就会生成一张HDRI贴图素材了。
打开贴图看一下,效果还是很不错的。
如果需要导出HDRI贴图,可以通过右键菜单-Asset Actions-Export命令导出。
Unity中制作HDRI贴图
在Unity中可以通过C#脚本制作Cubemap,首先创建一个新的cubemap,取名为Cubemap。
修改Cubemap的属性,更改Face size即单张图片的尺寸(Unity中创建的Cubemap是以六张图片的形式存储的),并一定要勾选最后面的Readable属性。
然后在工程目录中新建Editor文件夹,在Editor文件夹中新建一个C# Script脚本,取名为RendCubemap.cs。
使用Visual Studio或者文本编辑器打开新创建的C#脚本,删除里面内容后写入以下代码。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class RenderCubeMap : ScriptableWizard { public Transform renderTrans; public Cubemap cubemap; [MenuItem("Tools/CreateCubemap")] static void CreateCubemap() { //"Create Cubemap"是打开的窗口名,"Create"是按钮名,点击时调用OnWizardCreate()方法 ScriptableWizard.DisplayWizard<RenderCubeMap>("Create Cubemap", "Create"); //打开向导 } private void OnWizardUpdate() //打开向导或者在向导中更改了其他内容的时候调用 { helpString = "选择渲染位置并且确定需要设置的cubemap"; isValid = renderTrans != null && cubemap != null; //isValid为true的时候,“Create”按钮才能点击 } private void OnWizardCreate() //点击创建按钮时调用 { GameObject go = new GameObject(); go.transform.position = renderTrans.position; Camera camera = go.AddComponent<Camera>(); camera.RenderToCubemap(cubemap); //用户提供的Cubemap传递给RenderToCubemap函数,生成六张图片 DestroyImmediate(go); //立即摧毁go } }
保存C#脚本后,可以在Unity的Tools菜单中找到新增的Create Cubemap的命令(命令的名称是上面代码中设置的),点击命令后会出现详细设置窗口。
设置窗口中的Render Trans用于选择HDRI中心处的物体,Cubemap则选择刚才创建的Cubemap,设置完成后点击Create按钮,生成的HDRI贴图就会被写入到刚才创建的Cubemap中。
如果需要导出该HDRI贴图,可以通过以下C#脚本,脚本的创建过程跟前边一样就不重复了。
using UnityEngine; using UnityEditor; using System.IO; using System.Collections; using System.Collections.Generic; public class CubeSplitter : EditorWindow { Cubemap splitCube; Color[] CubeMapColors; int splitSize; [MenuItem ("Tools/CubeSplitter")] static void Init () { CubeSplitter window = (CubeSplitter)EditorWindow.GetWindow (typeof (CubeSplitter), false); window.maxSize = new Vector2(512, 155); window.minSize = window.maxSize; window.title = ("Cube Splitter!"); window.Show(); } void OnGUI () { GUILayout.Label("Choose the Cube Map you want to save as 6 images and click EXPORT!", EditorStyles.boldLabel); splitCube = EditorGUILayout.ObjectField("My Cubemap:", splitCube, typeof(Cubemap), false) as Cubemap; GUILayout.Label("Make sure to set the Size to the same as the Cubemap you are using", EditorStyles.boldLabel); splitSize = EditorGUILayout.IntField("CubeMap Size: ", splitSize); if(GUILayout.Button("EXPORT!")) { if(splitCube) { Export(); } if(!splitCube) { Debug.Log ("Forget Something?"); } } } void Export() { var filePath = AssetDatabase.GetAssetPath(splitCube); Texture2D tex = new Texture2D (splitSize, splitSize, TextureFormat.RGB24, false); CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveY); tex.SetPixels(CubeMapColors, 0); tex.Apply (); byte[] bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath + "_Bot.png", bytes); CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeY); tex.SetPixels(CubeMapColors, 0); tex.Apply (); bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath + "_Top.png", bytes); CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveX); tex.SetPixels(CubeMapColors, 0); tex.Apply (); bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath + "_Lef.png", bytes); CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeX); tex.SetPixels(CubeMapColors, 0); tex.Apply (); bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath + "_Rig.png", bytes); CubeMapColors = splitCube.GetPixels(CubemapFace.PositiveZ); tex.SetPixels(CubeMapColors, 0); tex.Apply (); bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath + "_Fro.png", bytes); CubeMapColors = splitCube.GetPixels(CubemapFace.NegativeZ); tex.SetPixels(CubeMapColors, 0); tex.Apply (); bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath + "_Bak.png", bytes); this.Close(); } }
执行脚本命令后,在弹出的窗口中设置好要导出的Cubemap以及图片的尺寸,点击EXPORT按钮,就可以导出六张贴图。
可以通过nvidia-texture-tools-exporter工具把六张贴图合并成一张完整的HDRI,使用方法可参考下图。
当然,Unity这个创建导出过程是比较麻烦的,所以还是建议有条件的直接上钞能力。
你最可爱,
我说时来不及思索,
但思索之后,还是这样说。
——普希金
评论
837104 676209Hiya very cool site!!Man .. Beautiful .. Amazing. 202205
618610 981743I was reading some of your content material on this website and I conceive this internet internet site is truly informative ! Keep on putting up. 740187
17856 538540Hey mate, .This was an excellent post for such a hard subject to speak about. I look forward to seeing a lot of much more excellent posts like this one. Thanks 905250
276780 973567I like this web web site very much, Its a actually nice billet to read and obtain information . 199217
724757 12052You need to join in a contest first of the finest blogs on the web. I most surely will suggest this internet site! 703158
577822 607907You could definitely see your enthusiasm in the work you write. The world hopes for more passionate writers like you who arent afraid to say how they believe. Always go right after your heart. 576219