应用场景
Attach EncAll.cs to a Unity Project to generate all frames in the scene with specific granulity. The output format is .png .
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering;
public class EncAll : MonoBehaviour
{
StreamReader reader = null;
public string histFilename = "./histTrace.txt";
public bool encFlag = false;
public string frameDirName = "./frame/";
RenderTexture equirect;
RenderTexture cubemap;
FileStream fs;
int sqr = 1024;
public int width = 1920;
public int height = 1080;
public new Camera camera;
string pose;
Vector3 init_pos;
Vector3 prac_pos;
public float granular = 0.05f;
int enc_width;
int enc_height;
int cnt = 0;
void Start()
{
if (encFlag)
{
cubemap = new RenderTexture(sqr, sqr, 24, RenderTextureFormat.BGRA32);
cubemap.dimension = TextureDimension.Cube;
equirect = new RenderTexture(width, height, 24, RenderTextureFormat.BGRA32);
enc_width = width;
enc_height = height;
}
init_pos = transform.position;
prac_pos = transform.position;
}
void Update()
{
Vector3 pos = transform.position;
if ((pos.z - init_pos.z) >= 30) return;
prac_pos.x = pos.x - init_pos.x;
prac_pos.z = pos.z - init_pos.z;
Decimal posX = Math.Round((Decimal)(prac_pos.x * 100.0));
Decimal posZ = Math.Round((Decimal)((prac_pos.z) * 100.0));
pose = "(" + (int)(posX) + "," + (int)(posZ) + ")";
cnt++;
Debug.Log(cnt + " " + pos + " " + pose );
StreamWriter file = new StreamWriter(histFilename, true);
file.WriteLine(cnt + " " + pos + " " + pose);
file.Close();
}
void LateUpdate()
{
Vector3 pos = transform.position;
if ((pos.z - init_pos.z) >= 30) return;
geneFrame();
if ((pos.x + granular - init_pos.x) < 26)
{
pos.x += granular;
}
else
{
pos.z += granular;
pos.x = init_pos.x;
}
transform.position = pos;
}
void geneFrame()
{
string pos_file_name = frameDirName + pose + ".png";
camera.RenderToCubemap(cubemap, 63, Camera.MonoOrStereoscopicEye.Mono);
cubemap.ConvertToEquirect(equirect, Camera.MonoOrStereoscopicEye.Mono);
Texture2D ori_tex = new Texture2D(width , height, TextureFormat.BGRA32, false);
ori_tex.ReadPixels(new Rect(0 , 0, ori_tex.width, ori_tex.height), 0, 0, false);
ori_tex.Apply();
byte[] tex_bytes = ori_tex.EncodeToPNG();
System.IO.File.WriteAllBytes(frameDirName + pose + ".png", tex_bytes);
Destroy(ori_tex);
tex_bytes = null;
}
private void OnDestroy()
{
if (reader != null)
reader.Close();
}
}
1. RenderTexture.RenderTextureConstructor
cubemap = new RenderTexture(sqr, sqr, 24, RenderTextureFormat.BGRA32);
2. 渲染到一个立方体贴图
camera.RenderToCubemap(cubemap, 63, Camera.MonoOrStereoscopicEye.Mono);
public bool RenderToCubemap (RenderTexture cubemap, int faceMask, Camera.MonoOrStereoscopicEye stereoEye);
-
参数 cubemap 要渲染到的纹理。 faceMask 位域,指示应渲染到立方体贴图的哪些面。设置为整数值 63 将渲染所有面。 stereoEye 摄像机眼,对应于左眼或右眼(用于立体渲染),或不对应于眼睛(用于非立体渲染)。 -
返回 bool 如果渲染失败,返回 false,否则返回 true。 -
描述 从该摄像机将一个 360 度立体图像的一侧渲染到一个立方体贴图。
将 stereoEye 参数设置为 Camera.MonoOrStereoscopicEye.Left 或 Camera.MonoOrStereoscopicEye.Right 后将以适当的世界空间变换来渲染 360 度立体图像的左眼或右眼视角。 将 stereoEye 设置为 Camera.MonoOrStereoscopicEye.Mono 可渲染场景的单视场视图。渲 染单独的左右立方体贴图之后,可以将其转换成占用一个纹理的等距圆柱投影全景图像。
3. 将渲染纹理转换为等距圆柱投影格式
RenderTexture.ConvertToEquirect
cubemap.ConvertToEquirect(equirect,Camera.MonoOrStereoscopicEye.Mono);
public void ConvertToEquirect (RenderTexture equirect, Camera.MonoOrStereoscopicEye eye);
- 参数
equirect 要将等距圆柱投影格式渲染到的 RenderTexture。 eye 摄像机眼,对应于左眼或右眼(用于立体渲染),或不对应于眼睛(用于单视场渲染)。 - 描述
将渲染纹理转换为等距圆柱投影格式(都为立体或单视场等距圆柱投影)。 左眼占据上半部分,右眼占据底部。单视场版本将占据整个纹理。 纹理尺寸必须为 TextureDimension.Cube 类型。
4.Unity 保存 RenderTexture 为 .Png
Texture2D ori_tex = new Texture2D(width , height, TextureFormat.BGRA32, false);
ori_tex.ReadPixels(new Rect(0 , 0, ori_tex.width, ori_tex.height), 0, 0, false);
ori_tex.Apply();
byte[] tex_bytes = ori_tex.EncodeToPNG();
System.IO.File.WriteAllBytes(frameDirName + pose + ".png", tex_bytes);
Destroy(ori_tex);
tex_bytes = null;
|