概述
立方体纹理是一种特殊的纹理类型,包含了6个独立的二维纹理,分别对应一个立方体的六个面;
用途
- 环境映射:用于模拟反射环境的效果,用立方体纹理存储周围环境的图像,当应用到反射表面时,可以让物体看起来像是在反射其周围的环境;
- 用于渲染天空盒:将立方体纹理的六个面映射到一个立方体的表面,从而模拟天空、云朵、远处的山脉等环境;
- 全景图:用于展示全景图像、视频,通过立方体纹理来存储全景照片、视频的六个部分等等;
采样
对立方体纹理进行采样需要提供一个三维的纹理坐标,该坐标表示了在世界空间下的一个三维方向,这个方向向量从立方体的中心出发,当它向外延伸时就会和六个纹理之一相交。采样结果就是由该交点计算而来;
优缺点
优点
- 多用途:可以有效模拟环境反射和全景效果,如反射、折射、天空盒、环境光照等;
- 无缝连接:立方体纹理设计为无缝连接六个面。减少了可见的接缝和瑕疵;
- 兼容性较好:大多数现代图形硬件对立方体纹理都有专门的支持;
缺点
- 内存开销:立方体纹理由6个2D纹理组成。内存占用较高,特别是高分辨率情况下;
- 采样复杂性:采样方式比起传统的2D纹理更加耗性能、计算更多;
- 透视变形:6个平面来近似模拟球形环境,有时会出现透视变形的问题;
动态生成立方体纹理
为什么需要动态生成
对于天空盒等不变的效果,这种立方体纹理往往是提前做好的,是场景中物体们共用的;
但如果制作反射、折射等效果还使用这样的立方体纹理,效果肯定不够理想,因为物体在场景上的位置不同,产生的对应效果也会是不同的;
为了更好的表现效果,需要为场景中的不同物体在不同位置生成不同的立方体纹理;
简易生成工具
using UnityEditor;
using UnityEngine;
namespace Editor
{
/// <summary>
/// 编辑器拓展 生成立方体纹理
/// </summary>
public sealed class RenderToCubeMapWindow: EditorWindow
{
private GameObject m_Obj;
private Cubemap m_Cubemap;
[MenuItem("立方体纹理动态生成/打开生成窗口")]
static void OpenWindow()
{
var window = EditorWindow.GetWindow<RenderToCubeMapWindow>("立方体纹理生成窗口");
window.Show();
}
private void OnGUI()
{
GUILayout.Label("关联对应位置对象");
m_Obj = EditorGUILayout.ObjectField(m_Obj, typeof(GameObject), true) as GameObject;
GUILayout.Label("关联对应立方体纹理");
m_Cubemap = EditorGUILayout.ObjectField(m_Cubemap, typeof(Cubemap), false) as Cubemap;
if (GUILayout.Button("生成立方体纹理"))
{
if (m_Obj == null || m_Cubemap == null)
{
EditorUtility.DisplayDialog("提醒", "请先关联对应对象和立方体贴图", "确认");
return;
}
// 动态生成立方体纹理
var tmpObj = new GameObject("临时对象");
tmpObj.transform.position = m_Obj.transform.position;
var camera = tmpObj.AddComponent<Camera>();
// 关键方法 可以马上生成6张2D纹理贴图
camera.RenderToCubemap(m_Cubemap);
DestroyImmediate(tmpObj);
}
}
}
}