【原】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%左右

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM