網(wǎng)頁美工設(shè)計需求分析網(wǎng)站快速優(yōu)化排名軟件
技術(shù)背景
隨著技術(shù)的不斷進步和應(yīng)用的不斷深化,Unity3D VR應(yīng)用的前景非常廣闊,它廣泛應(yīng)用于教育、醫(yī)療、軍事、工業(yè)設(shè)計、虛擬數(shù)字人等多個領(lǐng)域。
- 教育領(lǐng)域:Unity3D VR技術(shù)可以用來創(chuàng)建虛擬現(xiàn)實教室,讓學(xué)生能夠身臨其境地體驗課程內(nèi)容,提高學(xué)習(xí)效果和興趣;
- 醫(yī)療領(lǐng)域:Unity3D VR技術(shù)可以用來創(chuàng)建虛擬手術(shù)室,讓醫(yī)生能夠在真實手術(shù)之前進行模擬操作,提高手術(shù)技能和安全性;
- 軍事領(lǐng)域:Unity3D VR技術(shù)可以用來創(chuàng)建虛擬戰(zhàn)場環(huán)境,進行軍事訓(xùn)練和戰(zhàn)術(shù)演練,提高士兵的戰(zhàn)斗能力和應(yīng)變能力;
- 工業(yè)設(shè)計領(lǐng)域:Unity3D VR技術(shù)可以用來創(chuàng)建虛擬現(xiàn)實工作環(huán)境,讓設(shè)計師能夠在真實產(chǎn)品推出之前進行虛擬測試和修改,提高產(chǎn)品設(shè)計和制造的效率和質(zhì)量。
- 虛擬數(shù)字人是指使用虛擬現(xiàn)實技術(shù)創(chuàng)建的數(shù)字人物,具有人的外貌、動作、語言和思維等特征。VR虛擬數(shù)字人可以用來進行虛擬互動、虛擬演講、虛擬展覽、虛擬客服等多種應(yīng)用場景。例如,在虛擬展覽中,VR虛擬數(shù)字人可以作為虛擬講解員,為參觀者介紹展品,提供全方位的互動體驗。在虛擬客服中,VR虛擬數(shù)字人可以作為企業(yè)形象代表,與消費者進行互動交流,提高客戶滿意度和品牌形象。
技術(shù)實現(xiàn)
從技術(shù)的角度,分析如何在unity環(huán)境下,采集到camera數(shù)據(jù),然后編碼打包推RTMP或啟動輕量級RTSP服務(wù)。我們老早實現(xiàn)了Unity環(huán)境下的RTMP低延遲推送,原生環(huán)境下,比如windows下,可輕松實現(xiàn)50幀+的編碼和RTMP推送(需要播放端也有高幀率播放的能力)。
數(shù)據(jù)源是高幀率的基礎(chǔ),比如,我們在跟外部公司合作的時候,比如無人機在一些工業(yè)場景下的智能躲避等,幀率要求非常高,這時候,如果單獨還好,多路的話,ReadPixel()讀取數(shù)據(jù)耗時還是非常大的。讀取到的數(shù)據(jù),特別是高分辨率高幀率的,編碼一般建議硬編碼,幀率的控制,需要有個好的算法機制,確保比如我可以采集到60幀,但是我實際值需要編碼45幀,如何drop數(shù)據(jù),達到流暢無卡頓感。
此外,除了視頻數(shù)據(jù)外,音頻可以采集麥克風(fēng)、Unity內(nèi)部音頻、麥克風(fēng)+unity內(nèi)部音頻混音或Unity下2路內(nèi)部音頻混音。Unity內(nèi)部audio數(shù)據(jù)采集,可以使用AudioClip,編碼格式建議AAC。
以Windows平臺為例,Frame的構(gòu)建,可以參考一下設(shè)計:
/*
* 構(gòu)建FrameTexture
* Author: daniusdk.com
*/
public class FrameTexture
{public FrameTexture(Texture2D texture, IntPtr video_buffer, int video_buffer_size,int video_width, int video_height, int is_vertical_flip, int is_horizontal_flip, int scale_width, int scale_height, bool is_alpha){texture_ = texture;video_buffer_ = video_buffer;video_buffer_size_ = video_buffer_size;video_width_ = video_width;video_height_ = video_height;is_vertical_flip_ = is_vertical_flip;is_horizontal_flip_ = is_horizontal_flip;scale_width_ = scale_width;scale_height_ = scale_height;is_alpha_ = is_alpha;}public Texture2D texture_;public IntPtr video_buffer_;public int video_buffer_size_;public int video_width_;public int video_height_;public int is_vertical_flip_;public int is_horizontal_flip_;public int scale_width_;public int scale_height_;public bool is_alpha_;
}
PostImageWorker類,實現(xiàn)數(shù)據(jù)投遞到原始模塊:
private class PostImageWorker
{public PostImageWorker(TexturesPool pool, nt_publisher_wrapper handle){pool_ = pool;handle_ = handle;}public void run(){if (null == pool_ || null == handle_)return;while (!is_exit_){event_.WaitOne(100);if (is_exit_)break;while (sendImage()) ;}Debug.Log("PostImageWorker.run out...");FrameTexture frame;while (frames_.TryDequeue(out frame)){if (frame != null && frame.texture_){pool_.add(frame.texture_);frame.texture_ = null;}}frame = null;}private bool sendImage(){FrameTexture frame;if (frames_.TryDequeue(out frame)){if (frame != null && frame.texture_ != null){if (frame.video_buffer_ != IntPtr.Zero){handle_.OnPostRGBXData(0, frame.video_buffer_, video_buffer_size_, frame.video_width_ * 4, frame.video_width_, -frame.video_height_, frame.is_alpha_);}pool_.add(frame.texture_);frame.texture_ = null;}frame = null;return true;}frame = null;return false;}
Windows平臺,構(gòu)建個承載的圖層:
NT_PB_ExternalVideoFrameLayerConfig external_layer_c1 = new NT_PB_ExternalVideoFrameLayerConfig();external_layer_c1.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME;
external_layer_c1.base_.index_ = 0;
external_layer_c1.base_.enable_ = 1;
external_layer_c1.base_.region_.x_ = 0;
external_layer_c1.base_.region_.y_ = 0;
external_layer_c1.base_.region_.width_ = video_width_;
external_layer_c1.base_.region_.height_ = video_height_;external_layer_c1.base_.offset_ = Marshal.OffsetOf(external_layer_c1.GetType(), "base_").ToInt32();
external_layer_c1.base_.cb_size_ = (uint)Marshal.SizeOf(external_layer_c1);IntPtr external_layer_conf = Marshal.AllocHGlobal(Marshal.SizeOf(external_layer_c1));Marshal.StructureToPtr(external_layer_c1, external_layer_conf, true);UInt32 external_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,external_layer_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME,0, IntPtr.Zero);Marshal.FreeHGlobal(external_layer_conf);
然后通過NT_PB_PostLayerImage()給圖層投遞數(shù)據(jù)即可:
/** 給index層投遞Image數(shù)據(jù),目前主要是用來把rgb和yuv視頻數(shù)據(jù)傳給相關(guān)層* reserve: 保留字段,請傳0* index: 層索引* image: 圖像* flag: 請傳0* pReserve: 保留字段,請傳0* * 成功返回 NT_ERC_OK*/
[DllImport("SmartPublisherSDK", EntryPoint = "NT_PB_PostLayerImage", CallingConvention = CallingConvention.StdCall)]public static extern UInt32 NT_PB_PostLayerImage(IntPtr handle, Int32 reserve,Int32 index, IntPtr image,UInt32 flag, IntPtr pReserve);
如果需要預(yù)覽推送的數(shù)據(jù):
//預(yù)覽數(shù)據(jù)回調(diào)
public void SDKVideoPreviewImageCallBack(IntPtr handle, IntPtr user_data, IntPtr image)
{NT_PB_Image pb_image = (NT_PB_Image)Marshal.PtrToStructure(image, typeof(NT_PB_Image));NT_VideoFrame pVideoFrame = new NT_VideoFrame();pVideoFrame.width_ = pb_image.width_;pVideoFrame.height_ = pb_image.height_;pVideoFrame.stride_ = pb_image.stride_[0];Int32 argb_size = pb_image.stride_[0] * pb_image.height_;pVideoFrame.plane_data_ = new byte[argb_size];if (argb_size > 0){Marshal.Copy(pb_image.plane_[0],pVideoFrame.plane_data_,0, argb_size);}{cur_image_ = pVideoFrame;}
}
總結(jié)
Unity下的“多端同屏”云渲染以及相關(guān)可視化平臺解決方案,成為助力了工業(yè)領(lǐng)域數(shù)字化轉(zhuǎn)型。除上述場景外,還需要考慮多實例多camera模式,實現(xiàn)高效率低延遲和低資源占有的互動體驗。
?