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

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值