区块链+游戏的发展潜力
基于区块链的去中心化、不可篡改、共识算法、匿名性与跨平台等特性,区块链+游戏将带来如下变革:
1.去中心化运营
游戏中的各系统设置使用智能合约技术开发,游戏数据存储在区块链上,不依赖中心化服务器;
2.数据可信任
结合区块链技术开发游戏,重要的数据存储在区块链上,游戏运营方无法随意篡改与删除游戏数据,稀有道具内容、数量及抽签概率等算法完全公开,使得游戏数据透明化,可信任化,成为一个可信任的去中心化游戏应用;
3.虚拟资产确权
玩家游戏中的商品、道具使用区块链技术存储于区块链上,而不是存储在游戏厂商的数据库里,真正做到虚拟商品所有权属于玩家,已经购买的虚拟资产如皮肤、道具、视频等可完全根据玩家自身意愿进行调取、交互、转让等行为,不再受厂商限制;
4.加强安全保护
基于区块链技术有高冗余分布式共识,用户信息有强隐私保护和强安全保护,用户的信息和虚拟资产都存储区块链上,由用户持有私钥,用户数据能够得到有效保护;
5.打破孤岛经济
在游戏中使用加密数字资产作为结算方式,玩家的数字资产基于区块链上可在各游戏平台流通,而不再局限于单一游戏内,有望形成多游戏生态互通;
关于billboard技术,原理就是计算出来一个始终朝向摄像机的面片,可以在CPU里计算,也可以在GPU里实现。应用的场合很多:
游戏角色的头顶文字,血条
场景的树,草
特效粒子片
3d场景里的2d角色
world space计算
思路:shader中传入面片的中心点的世界坐标,以及摄像机的right和up在world space的方向,中心点直接沿着right和up方向计算四个顶点的世界坐标,定点数据中包含了每个顶点的偏移信息。然后乘以ViewProjection矩阵,作为输出。
这里有个trick的地方,就是从object space到world space是没有旋转的,只有偏移,所以摄像机在世界空间的right就是模型空间的right。MV的逆矩阵相当于View到Object的变换,转置是为了去列向量好取。
CGPROGRAM#pragma vertex vert
#pragma fragment frag
struct appdata{
float4 vertex:POSITION;
float2 uv:TEXCOORD0;
float2 vertexOffset:TEXCOORD1;
};
struct v2f{
float2 uv:TEXCOORD0;
float4 vertex:SV_POSITION;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
//这里相当于取列向量
float3 right=UNITY_MATRIX_IT_MV[0].xyz;
float3 up=UNITY_MATRIX_IT_MV[1].xyz;
v.vertex.xyz+=v.vertexOffset.xright+v.vertexOffset.yup;
o.vertex=mul(UNITY_MATRIX_VP,float4(v.vertex.xyz,1.0));
o.uv=v.uv;
return o;
}
fixed4 frag(v2f i):SV_Target{
//sample the texture
fixed4 col=tex2D(_MainTex,i.uv);
return col;
}
ENDCG
unity c#中生成mesh的代码
Vector3[]vertices=new Vector3[4]
{
worldPos,
worldPos,
worldPos,
worldPos};
int[]indices=new int[6]
{
0,2,1,0,3,2
};
Vector2[]uvs=new Vector2[4]
{
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
};
Vector2[]uv2s=new Vector2[4]
{
new Vector2(-0.5f,-0.5f),
new Vector2(0.5f,-0.5f),
new Vector2(0.5f,0.5f),
new Vector2(-0.5f,0.5f),
};
meshFilter.mesh.vertices=vertices;
meshFilter.mesh.triangles=indices;
meshFilter.mesh.uv=uvs;
meshFilter.mesh.uv2=uv2s;
clip space计算
思路:还是传入中心点的世界坐标,以及4个顶点的偏移信息。把中心点转到
clip space,然后按照偏移信息缩放。这个适用的场合是面片不随距离摄像机的远近而缩放。
CGPROGRAM#pragma vertex vert#pragma fragment frag struct appdata{
float4 vertex:POSITION;
float2 uv:TEXCOORD0;
float2 vertexOffset:TEXCOORD1;
};
struct v2f{
float2 uv:TEXCOORD0;
float3 color:TEXCOORD1;
float4 vertex:SV_POSITION;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
o.vertex=mul(UNITY_MATRIX_MVP,v.vertex);
o.vertex.xyz/=o.vertex.w;
o.vertex.xy+=v.vertexOffset.xy*float2(0.2,0.05);
o.vertex.w=1;
o.uv=v.uv;
return o;
}
fixed4 frag(v2f i):SV_Target{
//sample the texture
fixed4 col=tex2D(_MainTex,i.uv);
return col;
}
ENDCG
view space计算
上面两种方式都是通过传入中心点坐标到shader进行计算,但是有时候并不能获得面片的中心点坐标,比如Unity中的SpriteRenderer,这时候的思路是:把中心点即(0,0,0,1)(Object space)转到View Space,然后顶点再做偏移。
o.pos=mul(UNITY_MATRIX_P,
mul(UNITY_MATRIX_MV,float4(0.0,0.0,0.0,1.0))
+float4(i.vertex.x,i.vertex.y,0.0,0.0));
CPU计算
思路:面片的位置发生变化,或者摄像机发生变化的时候,重新计算一下面片的旋转,让它始终朝向摄像机
private void CalcBillboard()
{
if(instance!=null)
{
instance.transform.rotation=Camera.main.transform.rotation;
}
}