【原】Unity实时环境贴图
一、什么是环境贴图?
我的理解:一个物体周围(上下前后左右)环境的贴图。
二、如何生成环境贴图?
让相机在物体正上、正下、正前、正后、正左、正右各截一张图,生成的6张图就是该物体处于当前位置的环境贴图。
三、什么是实时环境?
实时环境贴图就是不停的生成环境贴图。具体获取,就是在物体移动的过程中实时获取周围的环境贴图。
下面来看具体实现:
所需的环境贴图shader Shader " reflection map" { Properties { _Cube("Reflection Map", Cube) = "" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"
uniform samplerCUBE _Cube; struct vertexInput { float4 vertex : POSITION; float3 normal : NORMAL; }; struct vertexOutput { float4 pos : SV_POSITION; float3 normalDir : TEXCOORD0; float3 viewDir : TEXCOORD1; }; vertexOutput vert(vertexInput input) { vertexOutput output; float4x4 modelMatrix = _Object2World; float4x4 modelMatrixInverse = _World2Object; output.viewDir = float3(mul(modelMatrix, input.vertex) - float4(_WorldSpaceCameraPos, 1.0)); output.normalDir = normalize(float3( mul(modelMatrixInverse,float4(input.normal, 0.0)))); output.pos = mul(UNITY_MATRIX_MVP, input.vertex); return output; } float4 frag(vertexOutput input) : COLOR { float3 reflectedDir = reflect(input.viewDir, normalize(input.normalDir)); return texCUBE(_Cube, reflectedDir); } ENDCG } } }
动态生成贴图的脚本
public int textureSize ;
public LayerMask mask = 1 << 0;//用来做优化,决定哪些层参与环境贴图生成
private Camera cam;
public RenderTexture rtex = null;
public Material reflectingMaterial;
public Cubemap staticCubemap = null;
// Use this for initialization
void Start () {
textureSize=1024;//参数决定的环境贴图的清晰度
reflectingMaterial.SetTexture("_Cube", staticCubemap);
}
// 简单的物体移动控制脚本
void Update () {
if(Input.GetKey(KeyCode.A))
{
transform.position+=new Vector3(Time.deltaTime*2,0,0);
}
if(Input.GetKey(KeyCode.D))
{
transform.position-=new Vector3(Time.deltaTime*2,0,0);
}
if(Input.GetKey(KeyCode.W))
{
transform.position-=new Vector3(0,0,Time.deltaTime*2);
}
if(Input.GetKey(KeyCode.S))
{
transform.position+=new Vector3(0,0,Time.deltaTime*2);
}
}
void OnDisable() {
if(rtex)
Destroy(rtex);
reflectingMaterial.SetTexture("_Cube", staticCubemap);
}
void LateUpdate()
{
UpdateReflection (63); // all six faces
}
void UpdateReflection(int faceMask )
{
if(!cam)
{
GameObject go = new GameObject("CubemapCamera", typeof(Camera));
go.hideFlags = HideFlags.HideAndDontSave;
cam = go.camera;
Destroy(go);
cam.farClipPlane =100f;//决定周围环境的远近(因为是实时获取的,没必要太远)
cam.enabled = false;
cam.cullingMask = mask;
}
if(!rtex)
{
rtex = new RenderTexture(textureSize, textureSize, 16);
rtex.hideFlags = HideFlags.HideAndDontSave;
rtex.isPowerOfTwo = true;
rtex.isCubemap = true;
rtex.useMipMap = false;
reflectingMaterial.SetTexture("_Cube", rtex);
}
cam.transform.position = Camera.main.transform.position;
cam.transform.rotation = Camera.main.transform.rotation;
cam.RenderToCubemap(rtex,faceMask );
}
实时环境贴图的实现效果
做了简单的性能测试,换行吧,PC上前后内存增加了0.5G,cpu增加了3%~5%左右