一、什么是环境贴图?
我的理解:一个物体周围(上下前后左右)环境的贴图。
二、如何生成环境贴图?
让相机在物体正上、正下、正前、正后、正左、正右各截一张图,生成的6张图就是该物体处于当前位置的环境贴图。
三、什么是实时环境?
实时环境贴图就是不停的生成环境贴图。具体获取,就是在物体移动的过程中实时获取周围的环境贴图。
下面来看具体实现:
所需的环境贴图shaderShader " 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%左右