Unity3D全景视频渲染

7 篇文章 0 订阅


实现在Unity3D中渲染YUV420P文件,可以渲染一帧(即全景图片),也可以渲染多帧(即全景视频)。

Unity3D中创建场景

Sphere

首先在Sence中创建一个Sphere
在这里插入图片描述
注意sphere中Scale的Z一定要是负数,因为我们是在球的内部观看视频的。

Material

创建一个材质球,右键Assets—>Create—>Material,并将其挂在创建的Sphere上

Shader

创建一个Unilt Shader,右键Assets—>Create—>Shader—>Unlit Shader
在LOD 200下面加入cull off命令,以此可以在球的内部看到内容物:
在这里插入图片描述
将此着色器文件挂在刚刚创建好的材质球上:
在这里插入图片描述

Render Texture

创建Render Texture,右键Assets—>Create—>Render Texture
设置Size
在这里插入图片描述
将此渲染纹理挂在材质球上:
在这里插入图片描述

编写CS脚本进行渲染

创建脚本

创建C#脚本,右键Assets—>Create—>C# Script,将其挂在Sphere上

完整代码

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using System;

namespace YUV
{


    public class yuvvideo : MonoBehaviour
    {

        public Renderer target;

        int frameCount;
        int frameNow = 0;

        byte[] file;//最大值255


        //public Renderer target;

        private int w = 3840;
        private int h = 1920;

        // Plana 連續儲存,Packed 交錯儲存
        // 使用 Plana YUV420 格式
        void Start()
        {

            //一次读取所有比特
            file = File.ReadAllBytes("D:/VideoPlayer/Assets/VideoSource/out3D_Rio.yuv");

            frameCount = GetFrameCount(file, w, h); // 影像寬高
                                                    //输出总帧数
            frameCount = 1;
            print("Frame Count : " + frameCount);


        }

        void Update()
        {

            if (frameNow > frameCount - 1) return;

            GetTexture(file,w, h) ; // 影像寬高

            frameNow++;

            print("Frame : " + (frameNow) + " (" + (int)(frameNow / (float)(frameCount) * 100) + "%)");
        }

        int GetFrameCount(byte[] file, int width, int height)
        {
            return file.Length / ((width * height) * 3 / 2);
        }

        //原始纹理t
        Texture2D t = null;

        private byte Y00, Y01, Y10, Y11;//Y分量     
        private float R00, G00, B00;
        private float R01, G01, B01;
        private float R10, G10, B10;
        private float R11, G11, B11;
        int i;
        int mY;//颠倒y值

        void GetTexture(byte[] file,int width, int height)
        {
            if (t != null) Destroy(t);

            t = new Texture2D(width, height, TextureFormat.RGB24, false);

            int Ysize = width * height;
            int UorVsize = width * height / 4;

          
            byte U = 0;
            byte V = 0;

            int k = 0;
            //offset偏移量
            int offset = frameNow * ((width * height) * 3 / 2);

            for (int y = 0; y < height; y += 2)
            {
                for (int x = 0; x < width; x += 2)
                {
                    U = file[offset + Ysize - 1 + k++]; //注意要减一
                    V = file[offset + Ysize - 1 + k + UorVsize];  //注意要减一

                    i = y * width + x;
                    mY = height - 1 - y;

                    Y00 = file[offset + i];
                    Y01 = file[offset + i + width];
                    Y10 = file[offset + i + 1];
                    Y11 = file[offset + i + width + 1];


                    R00 = (Y00 + 1.4075f * (V - 128)) / 255f;
                    G00 = (Y00 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
                    B00 = (Y00 + 1.779f * (U - 128)) / 255f;

                    R01 = (Y01 + 1.4075f * (V - 128)) / 255f;
                    G01 = (Y01 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
                    B01 = (Y01 + 1.779f * (U - 128)) / 255f;

                    R10 = (Y10 + 1.4075f * (V - 128)) / 255f;
                    G10 = (Y10 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
                    B10 = (Y10 + 1.779f * (U - 128)) / 255f;

                    R11 = (Y11 + 1.4075f * (V - 128)) / 255f;
                    G11 = (Y11 - 0.3455f * (U - 128) - 0.7169f * (V - 128)) / 255f;
                    B11 = (Y11 + 1.779f * (U - 128)) / 255f;

                    t.SetPixel(x, mY, new Color(R00, G00, B00, 1));
                    t.SetPixel(x, mY - 1, new Color(R01, G01, B01, 1));
                    t.SetPixel(x + 1, mY, new Color(R10, G10, B10, 1));
                    t.SetPixel(x + 1, mY - 1, new Color(R11, G11, B11, 1));
                }

            }
            t.Apply();
            target.sharedMaterial.SetTexture("_MainTex", t);
        }
    }
    
}

实现效果

在场景中的Sphere上完成全景图片的渲染
在这里插入图片描述

参考链接

https://blog.csdn.net/weixin_38884324/article/details/80638027
https://blog.csdn.net/weixin_43778515/article/details/90268117

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值