立方体纹理简介
- 立方体纹理的形式:包含了6张图像,这些图像对应了一个立方体的6个面,立方体纹理的名称也由此而来。立方体的每个面表示沿着世界空间下的轴向(上、下、左、右、前、后)观察所得的图像。
- 对立方体纹理采样:需要提供一个三维的纹理坐标,这个三维纹理坐标表示了我们在世界空间下的一个3D方向。这个方向矢量从立方体的中心出发,当它向外部延伸时就会和立方体的6个纹理之一发生相交,而采样得到的结果就是由该交点计算而来的。
- 优缺点:
- 好处:它的实现简单快速,而且得到的效果也比较好。
- 缺点:(1)当场景中引入了新的物体、光源,或者物体发生移动时,需要重新生成立方体纹理。(2)立方体纹理也仅可以反射环境,但不能反射使用了该立方体纹理的物体本身。由于这样的原因,我们应该尽量对凸面体使用立方体纹理(因为凹面体会反射自身)。
立方体纹理应用
1.天空盒子
是什么?
天空盒子(Skybox)是游戏中用于模拟背景的一种方法。当我们在场景中使用了天空盒子时,整个场景就被包围在一个立方体内。在Unity中,天空盒子是在所有不透明物体之后渲染的,而其背后使用的网格是一个立方体或一个细分后的球体。
怎么用?
- 制作材质:
- 在Unity中,只需要创建一个Skybox材质,再把它赋给该场景的相关设置即可。
- 在SkyboxMat的Unity Shader下拉菜单中选择Unity自带的Skybox/6 Sided,该材质需要6张纹理。
- 注意这6张纹理的正确位置(如posz纹理对应了Front [+Z] 属性)。
- 我们还需要把这6张纹理的Wrap Mode设置为Clamp,以防止在接缝处出现不匹配的现象。
- 上面的材质中,除了6张纹理属性外还有3个属性:Tint Color,用于控制该材质的整体颜色;Exposure,用于调整天空盒子的亮度;Rotation,用于调整天空盒子沿+y轴方向的旋转角度。
- Window → Lighting菜单中,把SkyboxMat赋给Skybox选项。
- 设置摄像机:
- 为了让摄像机正常显示天空盒子,我们还需要保证渲染场景的摄像机的Camera组件中的ClearFlags被设置为Skybox。
- 在Window → Lighting → Skybox中设置的天空盒子会应用于该场景中的所有摄像机。如果我们希望某些摄像机可以使用不同的天空盒子,可以通过向该摄像机添加Skybox组件来覆盖掉之前的设置。
2.环境映射
如何创建用于环境映射的立方体纹理?
- 直接由一些特殊布局的纹理创建:
- 我们需要提供一张具有特殊布局的纹理,例如类似立方体展开图的交叉布局、全景布局等。然后,我们只需要把该纹理的Texture Type设置为Cubemap即可,Unity会为我们做好剩下的事情。
- 在Unity 5中,官方推荐这种方法创建立方体纹理,因为这种方法可以对纹理数据进行压缩,而且可以支持边缘修正、光滑反射(glossy reflection)和HDR等功能。
- 手动创建一个Cubemap资源,再把6张图赋给它。 在项目资源中创建一个Cubemap,然后把6张纹理拖曳到它的面板中。
- 由脚本生成(理想情况下,我们希望根据物体在场景中位置的不同,生成它们各自不同的立方体纹理)。
- Camera.RenderToCubemap函数可以把从任意位置观察到的场景图像存储到6张图像中,从而创建出该位置上对应的立方体纹理。
- 新建一个用于存储的立方体纹理(在Project视图下单击右键,选择Create → Legacy→Cubemap来创建)。为了让脚本可以顺利将图像渲染到该立方体纹理中,我们需要在它的面板中勾选Readable选项。
创建立方体纹理的脚本:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class RenderCubemapWizard : ScriptableWizard {
public Transform renderFromPosition;
public Cubemap cubemap;
void OnWizardUpdate () {
helpString = "Select transform to render from and cubemap to render into";
isValid = (renderFromPosition != null) && (cubemap != null);
}
void OnWizardCreate () {
// create temporary camera for rendering
GameObject go = new GameObject( "CubemapCamera");
go.AddComponent<Camera>();
// place it on the object
go.transform.position = renderFromPosition.position;
// render into cubemap
go.GetComponent<Camera>().RenderToCubemap(cubemap);
// destroy temporary camera
DestroyImmediate( go );
}
[MenuItem("GameObject/Render into Cubemap")]

最低0.47元/天 解锁文章
5889

被折叠的 条评论
为什么被折叠?



