unity 导出全景图

方法一、直接用unity的api

    /// <summary>
    /// 导出全景图
    /// camera:用来拍场景里内容的相机
    /// width:全景图的宽度,高度是宽度的1/2
    /// </summary>
    void Export360Panorama(Camera camera, int width)
    {
        RenderTexture cubemap = new RenderTexture(width, width,0);
        cubemap.dimension = TextureDimension.Cube;
        camera.RenderToCubemap(cubemap, 63, Camera.MonoOrStereoscopicEye.Mono);

        RenderTexture equirect = new RenderTexture(width, width/2, 0);
        cubemap.ConvertToEquirect(equirect, Camera.MonoOrStereoscopicEye.Mono);

        Texture2D tex = new Texture2D(equirect.width, equirect.height, TextureFormat.ARGB32, false, true);
        tex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
        tex.Apply();
        byte[] bytes = tex.EncodeToPNG();
        System.IO.File.WriteAllBytes(@"E:\Temp\3\1\222.png", bytes);

    }

  

方法二、写个shader

Shader "Unlit/CubemapTo360Panorama"
{
	Properties
	{
		_MainTex ("Cubemap (RGB)", CUBE) = "" {}
		_OffsetX("Offset X", Float) = 0.0
	}

	Subshader
	{
		Pass
		{
			ZTest Always Cull Off ZWrite Off

			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma fragmentoption ARB_precision_hint_fastest
				//#pragma fragmentoption ARB_precision_hint_nicest
				#include "UnityCG.cginc"

				#define PI    3.141592653589793
				#define TWOPI 6.283185307179587

				struct v2f
				{
					float4 pos : POSITION;
					float2 uv : TEXCOORD0;
				};
		
				samplerCUBE _MainTex;
				float _OffsetX;
				
				v2f vert(appdata_img v)
				{
					v2f o;
					o.pos = UnityObjectToClipPos(v.vertex);
					o.uv = (v.texcoord.xy + float2(_OffsetX,0)) * float2(TWOPI, PI);
					return o;
				}
		
				fixed4 frag(v2f i) : COLOR 
				{
					float theta = i.uv.y;
					float phi = i.uv.x;
					float3 unit = float3(0,0,0);

					unit.x = sin(phi) * sin(theta) * -1;
					unit.y = cos(theta) * -1;
					unit.z = cos(phi) * sin(theta) * -1;

					return texCUBE(_MainTex, unit);
				}
			ENDCG
		}
	}
	Fallback Off
}

C#部分

    /// <summary>
    /// 导出全景图
    /// camera:用来拍场景里内容的相机
    /// width:全景图的宽度,高度是宽度的1/2
    /// offsetAngle:全景图内容的偏移角度
    /// </summary>
    void Export360Panorama(Camera camera,int width,float offsetAngle)
    {
        RenderTexture cubemap = RenderTexture.GetTemporary(width, width, 0);
        cubemap.dimension = TextureDimension.Cube;

        camera.RenderToCubemap(cubemap, 63);

        RenderTexture equirect = RenderTexture.GetTemporary(width, width / 2, 0);
        equirect.dimension = TextureDimension.Tex2D;

        Material equirectMat = new Material(Shader.Find("Unlit/CubemapTo360Panorama"));
        equirectMat.SetFloat("_OffsetX", offsetAngle / 360f);
        Graphics.Blit(cubemap, equirect, equirectMat);

        Texture2D t2 = new Texture2D(equirect.width, equirect.height);

        t2.ReadPixels(new Rect(0, 0, equirect.width, equirect.height), 0, 0);
        t2.Apply();

        System.IO.File.WriteAllBytes(@"E:\Temp\3\1\1111.png", t2.EncodeToPNG());
    }

  

调用比较简单,直接在Start里调用:

    void Start()
    {
        Export360Panorama(Camera.main, 1024);
        //Export360Panorama(Camera.main, 1024, 90);
    }

  

效果图:

 

posted on 2022-12-20 19:13  Jason_c  阅读(483)  评论(0编辑  收藏  举报