2019-12-24 13:04:10 qq_23158477 阅读数 11
  • VMware的云原生应用技术揭秘

    本次分享将主要介绍VMware全面开放的云原生应用平台,在演讲中将分别从开发栈、生产栈和DevOps等方面做具体的介绍,揭密相关的技术细节,包括Harbor企业级容器镜像Registry、企业级容器运行平台vSphere Integrated Containers、大规模云原生应用光子平台Photon Platform等等,帮助观众深入了解云原生应用和容器的技术要点。

    2599 人正在学习 去看看 CSDN讲师

基于PHOTON网络游戏AI中的设计思路

首先要搞清楚photon的网络实现框架,要不然在网络多客户端设计上就容易混乱,有时还不太好调试bug。
photon中平等的客户端中有一个是主客户端,masterclient,他要兼任服务器的角色。那又要将游戏中的服务端、普通客户端的逻辑剥离清楚,比如服务端生成整个场景的AI,物体等,其他底层的数据共享传输事件更新我们可以忽略掉,因为已经封装在里面,知道怎么使用这种共享更新方法就行,这里有一个比较不好剥离的关系就是,masterclient这个角色既是客户端又是服务器端。把另外一个关系拿过来一起比对学习下吧,就是场景中的多个AI,因为手控的角色好理解 我就不多说,在运行逻辑时如何剥离理解透彻,非常关键,弄不清楚没法继续下去。masterclient 要判断是不否担任服务器角色,不要担心之前担任服务器角色的客户端已经离线退出,masterclient会自动切换,这个我们不需要具体知道是切换到哪个客户端,知道masterclient会一直存在就好了。比如AI身上有很多逻辑处理脚本,有一些智能运行在服务器端,然后位置、动画其他的运用更新方法来实现同步,不要让这种逻辑脚本在每个客户端都运行,会相互牵扯,位置等都会比较怪异,因为既有更新又有本地的执行变化。photonview判断是自己的再操作,这是每次控制的对象非常清晰,不能操作了其他对象。AI同样如此。有需要继续深入探讨的可以留言,相互交流。
下面是一个AI树前段一个条件判断,如果是服务器才运行ai逻辑,什么时候攻击、逃跑、释放技能。。等
using Photon.Pun.Demo.PunBasics;
using BehaviorDesigner.Runtime.Tasks;
using Photon.Pun;

public class isMasterClient : Conditional
{
public override void OnStart()
{
base.OnStart();
}
// Use this for initialization
public override TaskStatus OnUpdate()
{
if (PhotonNetwork.IsMasterClient)
{
return TaskStatus.Success;
}
else
{
return TaskStatus.Failure;
}
}
public override void OnReset()
{
base.OnReset();
}
}
AI树

2017-05-28 11:05:02 qq_33999892 阅读数 463
  • VMware的云原生应用技术揭秘

    本次分享将主要介绍VMware全面开放的云原生应用平台,在演讲中将分别从开发栈、生产栈和DevOps等方面做具体的介绍,揭密相关的技术细节,包括Harbor企业级容器镜像Registry、企业级容器运行平台vSphere Integrated Containers、大规模云原生应用光子平台Photon Platform等等,帮助观众深入了解云原生应用和容器的技术要点。

    2599 人正在学习 去看看 CSDN讲师

      前阵子做的项目音之国度,用到了Unity的原生网络框架RPC,不如Photon之类的功能强大,但却十分好理解。

1.基本原理

    服务器程序初始化一个server型的network,初始化完后,所有的客户端通过ip和端口,和服务器建立起传输的初始化,当真正需要传输数据的时候,是基于一种叫rpc的机制——远程主机调用,比如客户端想执行走的业务逻辑,首先在客户端申明走的函数的原型,但并没有具体实现,他将参数传入服务器,找到在服务器里走函数的具体的实现,执行具体逻辑,服务器再向所有客户端返回结果,完成网络同步的交互。

2.初始化服务器

if(Network.peerType==NetworkPeerType.Disconnected)
		{
			var error=Network.InitializeServer (12,Port,false);
			switch (error) 
			{
			case NetworkConnectionError.NoError:
				console.text = Network.player.ipAddress;
				break;
			default:
				break;
			}
		}
Port是一个整型数字,大致范围在几万以内,建议使用比较靠后的数字,端口被其他程序占用的可能较小。

3.客户端和服务器建立连接

public void connect_server(string ip)
	{
		if (Network.peerType == NetworkPeerType.Disconnected) 
		{
			var error = Network.Connect (ip, port);
			Debug.Log (error.ToString());
			switch (error) 
			{
			case NetworkConnectionError.NoError:
				IP_PLAYER = Random.Range (int.MinValue,int.MaxValue);
				break;
			default:
				break;
			}
		}
	}
这里的ip是服务器的ip,可事先查看自己的服务器主机的ip放在这里。
这里同时还生成一个IP_PLAYER的标识符,这是因为在我的项目中,玩家很少,所以我生成了一个随机的标识符,这是发生碰撞的概率很低,所以使用了这样一个int代替一个string的ip作为标识符。

4.以注册为例,演示RPC的用法

客户端申明register的函数原型:

[RPC]
	void Register(string account,string password,int info){}
服务器拥有具体的实现:

[RPC]
	void  Register(string account,string password,int Virtual_IP,NetworkMessageInfo info)
	{
		if (!dic.ContainsKey (account)) 
		{
			XmlElement xe = xml_document.CreateElement ("USERMESSAGE");
			xe.InnerText = account;
			xe.SetAttribute ("password",password);
			xml_document.FirstChild.AppendChild (xe);
			xml_document.Save (Path);
			dic.Add (account, password);
			GetComponent<NetworkView> ().RPC ("RegisterSucceed", RPCMode.Others, Virtual_IP);
		} 
		else
		{
			GetComponent<NetworkView> ().RPC ("RegisterFailed", RPCMode.Others, Virtual_IP);
		}
	}
调用:

[RPC]
	public void RegisterUI()
	{
		if (Network.peerType == NetworkPeerType.Client)
			network_manager.GetComponent<NetworkView> ().RPC ("Register", RPCMode.Server, UserAccount.text,UserPassWord.text,IP_PLAYER);
		else
			Debug.LogError ("DisConnect");
	}




2016-02-15 15:10:02 xoyojank 阅读数 15134
  • VMware的云原生应用技术揭秘

    本次分享将主要介绍VMware全面开放的云原生应用平台,在演讲中将分别从开发栈、生产栈和DevOps等方面做具体的介绍,揭密相关的技术细节,包括Harbor企业级容器镜像Registry、企业级容器运行平台vSphere Integrated Containers、大规模云原生应用光子平台Photon Platform等等,帮助观众深入了解云原生应用和容器的技术要点。

    2599 人正在学习 去看看 CSDN讲师

VR中的”延迟”, 特指”Motion-To-Photon Latency”, 指的是从用户运动开始到相应画面显示到屏幕上所花的时间.
这里写图片描述
这中间经过了大概这么几个步骤:

  1. 传感器采集运动输入数据
  2. 采集到的数据进行过滤并通过线缆传输到主机
  3. 游戏引擎根据获取的输入数据更新逻辑和渲染视口
  4. 提交到驱动并由驱动发送到显卡进行渲染
  5. 把渲染的结果提交到屏幕, 像素进行颜色的切换
  6. 用户在屏幕上看到相应的画面

当然, 实际上还有很多细节问题, 比如屏幕上的像素并不是同一时间切换的, 可能面上面的那行先切换, 再一行行更新到最下面的, 在这里就不纠结这些细节了.

这其中的每一个步骤都会产生一定的延迟, 而目前公认的大众能接受的延迟是20ms以下, 这基本上可以做为衡量一个VR头显是不是合格的一个标准. 虽然20ms是非常短的时间, 但通过努力还是可以达到的, 主要有这么几个思路:

硬件层面的优化

  • 提升传感器的采样频率, 减少刷新率与传感器频率的同步等待时间消耗
  • 提升传感器的精度, 减少对采样数据进行稳定性过滤产生的延迟
  • 采用有线传输也有一部分原因是出于延迟的考虑
  • 屏幕使用OLED替代LCD, 减少像素颜色切换的时间
  • 提升屏幕刷新率, 主流的屏幕是60Hz, 那每帧就是16.67ms; 如果提升到90Hz, 那每帧就是11.11ms

大部分的手机VR产品在延迟上都是不合格的, 最明显的表现就是转头时的画面不连续/抖动/残影等:

  • 市面上的手机采用OLED屏的还是少数, 比如iPhone配个VR壳子那延迟就很感人
  • 如果依赖手机的陀螺仪进行转向模拟, 其精度和频率远远达不到要求
  • 手机屏幕目前都是60Hz的刷新率, 在延迟上本身就受限

刷新率的提升

假设刷新率为60Hz, 并不是代表每帧就有16.67ms的延迟, 而是说屏幕图像每16.67ms才更新一次, 渲染选项中的”垂直同步”的概念就是来源于此. 这就对我们提交渲染画面的时机要求非常高, 如下图:
这里写图片描述
为了方便计算, 这里先假设传感器, 传输, 屏幕像素切换的延迟都为0

  • 假设我们在每帧开始的时候(上一次垂直同步结束)采样一次传感器数据, 在垂直同步之前完成提交, 那延迟就是16.67ms
  • 如果当前帧无法在16.67ms内完成渲染, 比如花了17ms, 那么就会拖到下一帧进行提交, 屏幕上显示的画面就还是上一次的图像, 这时候的延迟就变成了16.67*2=33.33ms

这就对VR的渲染提出了非常高的要求:

  • FPS必须达到刷新率的要求, 90Hz就是90Hz, 80FPS是不行的, 会被垂直同步拖累成45FPS
  • FPS必须保证稳定, 偶尔掉一两帧在VR中的感觉非常明显, 可能某个物体的位置已经差了几十个像素了

以Oculus Rift(消费版)为例, 1080x1200x2的屏幕分辨率, 90Hz的刷新率, 再加上因为变形所需要的UpSampling, 实际的渲染画面就是3024x1680@90Hz, 这性能压力几乎与4k@60Hz相当. 所以, 单纯的提升刷新率和分辨率, 目前来说渲染能力还是跟不上. 不过既然有了性能需求, 硬件厂商才有前进动力, 对整个行业生态来说, 是件好事.

引擎层面的优化

除了拼命优化降低每帧画面的渲染时间外, 引擎层面还可以通过一些策略进行优化, 关键的思路就是: 能不能把采样传感器数据的时间点尽量延后, 让它与垂直同步的时间点尽量靠近?

这里我们仍然假设60Hz, 每帧时间16.67ms(约17ms), 忽略硬件延迟
这里写图片描述
如果在游戏逻辑过程中(1ms时)采样传感器数据, 那延迟大约就是16ms
这里写图片描述
如果在渲染线程进行绘制之前(5ms时), 重新再采样一下传感器数据, 修正一下视口信息(不会对游戏逻辑产生影响), 那延迟就缩短到了约12ms
这里写图片描述
做过渲染优化的人都知道, 提交D3D Command后, 需要等待GPU执行完毕, 这部分时间在整帧时间中的占比还是相当高的. 那有没有办法在渲染完成之后, 提交到屏幕之前再次采样一次传感器数据呢? 如果像下图那样的话, 延迟可以缩短到3ms!!!
这里写图片描述
这就是Timewarp的主要思想, 我们来看看它是怎么实现的

Timewarp

了解过延迟渲染的人应该都知道, 我们可以利用ZBuffer的深度数据, 逆向推导出屏幕上每个像素的世界坐标
这里写图片描述
这就意味着, 我们可以把所有像素变换到世界空间, 再根据新的摄像机位置, 重新计算每个像素的屏幕坐标, 生成一幅新的图像:
这里写图片描述
可以看到之前被遮挡区域的像素是缺失的, 因为我们的摄像机位置变化了. 那如果摄像机位置不变, 仅仅是朝向变了呢? 这样就不存在像素可见性的变化了:
这里写图片描述
Timewarp正是利用了这个特性, 在保证位置不变的情况下, 把渲染完的画面根据最新获取的传感器朝向信息计算出一帧新的画面, 再提交到显示屏. 由于角度变化非常小, 所以边缘不会出大面积的像素缺失情况.
这里写图片描述
Oculus的Demo中可以停止渲染新的画面, 完全由单帧图像计算出各个朝向的新画面:
原始图像向左上看向右下看
也就是说, 只要角度变化不是非常大(上图为了演示效果偏转的角度很大了), 可以通过这项技术”凭空渲染”出下一帧的图像, SONY的PSVR正是利用这一点, 把60FPS的画面Reproject成了120FPS.
Timewarp只能处理头部转向, 不能处理头部移动的情况, 而且一旦错过了垂直同步的时机, 一样需要等待下一次垂直同步才能显示出来. 那能不能在每次垂直同步之前, 强制进行一次Timewarp呢? 那就需要驱动来开个后门了…

驱动层面的优化

假设垂直同步时, 当前帧还没有渲染完毕, 这时如果要进行Timewarp的话, 就需要驱动提供一种高优先级的异步调用, 这就是异步Timewarp的由来: Timewarp操作与场景渲染并行执行, 如果没有新的渲染画面, 就继续使用上一帧的画面进行Timewarp.
这里写图片描述
这可以在一定程度上补偿FPS不达标造成的延迟问题, GearVR中正是应用了这项技术, 保证了手机VR的体验.
当然, PC上使用项技术还是有一些限制:

  • 必须是Fermi, Kepler, Maxwell(或更新)核心的GPU
  • GPU是以DrawCall为单位调度的, 所以耗时太长的DrawCall是插入不了Timewarp绘制操作的
  • 需要最新的Oculus和NVIDIA驱动支持

异步Timewarp并不是说FPS低于标准还能流畅跑, 这只是一种补救措施, 所以优化仍然要好好做-_-

驱动方面还有一些其它的优化空间, 比如强制提交渲染队列:
这里写图片描述
如果驱动中缓存了3帧, 那延迟优化就白做了…
这里写图片描述

另外就是大家耳熟能详的Back Buffer(Double Buffer Rendering), 其实也会增加一点延迟, 不如省掉这一步, 即Front Buffer Rendering, 或者叫Direct Mode:
这里写图片描述

参考资料

What is Motion-To-Photon Latency?
Optimizing VR Graphics with Late Latching
VR Direct: How NVIDIA Technology is Improving the VR Experience
Virtual Reality with AMD LiquidVR™ Technology
Lessons from Integrating the Oculus Rift into Unreal Engine 4
Oculus Rift - How Does Time Warping Work?
Asynchronous Timewarp Examined

2015-01-23 10:20:32 book_longssl 阅读数 2221
  • VMware的云原生应用技术揭秘

    本次分享将主要介绍VMware全面开放的云原生应用平台,在演讲中将分别从开发栈、生产栈和DevOps等方面做具体的介绍,揭密相关的技术细节,包括Harbor企业级容器镜像Registry、企业级容器运行平台vSphere Integrated Containers、大规模云原生应用光子平台Photon Platform等等,帮助观众深入了解云原生应用和容器的技术要点。

    2599 人正在学习 去看看 CSDN讲师

1,创建一个数据库表,我们就以 test数据库为例,数据库里建一个tb_User表, tb_User里有User_Name , User_Pass 字段.

2,创建一个验证用户基本信息的asp.net页面,页面名字是:Default.aspx

后台代码如下:
  1. using System;
  2. using System.Configuration;
  3. using System.Data;
  4. using System.Web;
  5. using System.Web.Security;
  6. using System.Web.UI;
  7. using System.Web.UI.HtmlControls;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Data.SqlClient;

  11. public partial class _Default : System.Web.UI.Page
  12. {

  13. SqlConnection conn = new SqlConnection("Data Source=.sqlexpress2008;Initial Catalog=test;Integrated Security=True");

  14. protected void Page_Load(object sender, EventArgs e)
  15. {
  16. string name = Request.Form["name2";
  17. string pwd=Request.Form["pwd";

  18. conn.Open();

  19. string sql = "select User_Name from tb_User where User_Name='" + name + "' and User_Pass='"+pwd+"'";
  20. SqlCommand cmd = new SqlCommand(sql, conn);
  21. if (cmd.ExecuteScalar() != null)
  22. Response.Write("success");
  23. else
  24. Response.Write("faield");
  25. conn.Close();
  26. }
  27. }
复制代码



前台代码不用管.

3,新建一个Unity 3D项目,新建一个Javascript文件, 在Javascript文件上编写如下代码:

  1. var URL = "http://devmac.net/domino/rui/Default.aspx"; //提交的URL地址
  2. static var return_data:String;
  3. var strname:String;
  4. var strpwd:String;
  5. var cls:boolean=false;
  6. var xx:Rect = Rect (20, 10, 150, 100);
  7. function OnGUI() {
  8. if(cls)
  9. xx = GUI.Window(1, xx, windowjj, "Window");
  10. GUI.Label(Rect(10,10,80,20),"UserName:");
  11. GUI.Label(Rect(10,30,80,20),"Userpass:");
  12. strname=GUI.TextField(Rect(90,10,100,20),strname);
  13. strpwd=GUI.PasswordField(Rect(90,30,100,20),strpwd,"*"[0],25);
  14. //same as above, but for password
  15. if ( GUI.Button ( Rect (60, 60, 100, 20) , "Login" ) ){ //just a button
  16. Login();
  17. }
  18. }
  19. function windowjj(windowID : int){
  20. GUI.Label(Rect(55,25,50,20),return_data);
  21. if(GUI.Button(Rect(50,55,50,20),"Close")) cls=false;//
  22. }
  23. function Login() {
  24. var form = new WWWForm(); //创建一个WWWForm对象。
  25. form.AddField( "name2", strname );
  26. form.AddField("pwd",strpwd);
  27. var w:WWW=new WWW(URL,form);
  28. yield w; //we wait for the form to check the PHP file, so our game dont just hang
  29. cls=true;
  30. if (w.error != null) {
  31. //if there is an error, tell us
  32. return_data=w.error;
  33. } else {
  34. return_data=w.text;
  35. w.Dispose(); //clear our form in game
  36. }
  37. }
复制代码


4. 此代码放在主相机上。

5.最后在网上搜一个crossdomain.xml文件,自己写也行,把它放在挂有Asp.net网站的根目录下,这样就大功告成了.



6,导入到IPhone手机里也成功访问到数据库.

2017-09-09 21:14:31 u013617409 阅读数 2814
  • VMware的云原生应用技术揭秘

    本次分享将主要介绍VMware全面开放的云原生应用平台,在演讲中将分别从开发栈、生产栈和DevOps等方面做具体的介绍,揭密相关的技术细节,包括Harbor企业级容器镜像Registry、企业级容器运行平台vSphere Integrated Containers、大规模云原生应用光子平台Photon Platform等等,帮助观众深入了解云原生应用和容器的技术要点。

    2599 人正在学习 去看看 CSDN讲师

前几天用了花生壳 免费域名

用域名连接 感觉不错 重点是这个内网穿透 要不只能天天自己单机测试 要不就买个与服务器

之前大学没毕业某云服务器便宜 买了两个月 把我的毕设挂上了 Tomcat做服务器 确实好使

但是现在已经毕业了 还不想花钱 就拿这个很不错

 然后用Photon做服务器 客户端是uLua自带的network 进行数据传输

确实在本机用域名(外网正要试试)连上了

但是今天我打算用个最简单的测试版本跟朋友用外网测试的时候(这里两端用的都是c#  socket)却发现问题:

 IPAddress ipAddress = IPAddress.Parse("www.xxxxxx.xxx");

连接的时候报错 后来百度 发现域名应该用下面代码解析:

IPHostEntry hostInfo = Dns.GetHostEntry("www.xxxxxx.xxx");
IPAddress ipAddress = hostInfo.AddressList[0]; 
 这样 在本机用域名连接就好使了

一会试试外网连接好使不


。。。。。。

第二天了 修改一下 确实好使了 这样以后就可以拿本机当服务器 然后让朋友们都测试就可以了

PhotonServer(3)

阅读数 17

没有更多推荐了,返回首页