您的位置:首页 > 移动开发 > Unity3D

【原】Unity实时环境贴图

2012-12-16 20:53 323 查看
一、什么是环境贴图?

  我的理解:一个物体周围(上下前后左右)环境的贴图。

二、如何生成环境贴图?

让相机在物体正上、正下、正前、正后、正左、正右各截一张图,生成的6张图就是该物体处于当前位置的环境贴图。

三、什么是实时环境?

实时环境贴图就是不停的生成环境贴图。具体获取,就是在物体移动的过程中实时获取周围的环境贴图。

下面来看具体实现:

所需的环境贴图shader

Shader"reflectionmap"{
Properties{
_Cube("ReflectionMap",Cube)=""{}
}
SubShader{
Pass{
CGPROGRAM
#pragmavertexvert
#pragmafragmentfrag
#include"UnityCG.cginc"

uniformsamplerCUBE_Cube;
structvertexInput{
float4vertex:POSITION;
float3normal:NORMAL;
};
structvertexOutput{
float4pos:SV_POSITION;
float3normalDir:TEXCOORD0;
float3viewDir:TEXCOORD1;
};

vertexOutputvert(vertexInputinput)
{
vertexOutputoutput;

float4x4modelMatrix=_Object2World;
float4x4modelMatrixInverse=_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);
returnoutput;
}

float4frag(vertexOutputinput):COLOR
{
float3reflectedDir=
reflect(input.viewDir,normalize(input.normalDir));
returntexCUBE(_Cube,reflectedDir);
}
ENDCG
}
}
}

动态生成贴图的脚本

publicinttextureSize;
publicLayerMaskmask=1<<0;//用来做优化,决定哪些层参与环境贴图生成
privateCameracam;
publicRenderTexturertex=null;
publicMaterialreflectingMaterial;
publicCubemapstaticCubemap=null;

//Usethisforinitialization
voidStart(){

textureSize=1024;//参数决定的环境贴图的清晰度
reflectingMaterial.SetTexture("_Cube",staticCubemap);
}

//简单的物体移动控制脚本
voidUpdate(){
if(Input.GetKey(KeyCode.A))
{
transform.position+=newVector3(Time.deltaTime*2,0,0);
}
if(Input.GetKey(KeyCode.D))
{
transform.position-=newVector3(Time.deltaTime*2,0,0);
}
if(Input.GetKey(KeyCode.W))
{
transform.position-=newVector3(0,0,Time.deltaTime*2);
}
if(Input.GetKey(KeyCode.S))
{
transform.position+=newVector3(0,0,Time.deltaTime*2);
}

}
voidOnDisable(){
if(rtex)
Destroy(rtex);

reflectingMaterial.SetTexture("_Cube",staticCubemap);
}
voidLateUpdate()
{
UpdateReflection(63);//allsixfaces

}
voidUpdateReflection(intfaceMask)
{
if(!cam)
{
GameObjectgo=newGameObject("CubemapCamera",typeof(Camera));
go.hideFlags=HideFlags.HideAndDontSave;
cam=go.camera;
Destroy(go);
cam.farClipPlane=100f;//决定周围环境的远近(因为是实时获取的,没必要太远)
cam.enabled=false;
cam.cullingMask=mask;
}
if(!rtex)
{
rtex=newRenderTexture(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%左右


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: