赞
踩
在做游戏的时候,有时候会出现很多道具在场景之中
如果用3D建模去实现,会比较耗性能
这个时候通常做的就是,用2D面片实现3D效果,让正面一直朝向相机
我们可以通过旋转物体来实现,也可以通过计算物体的屏幕坐标利用UI相机来实现,也可以通过shader来实现
用shader实现的思想是这样的,通过重新建立物体的模型坐标系,使得z轴始终朝向相机就可以了
问题在于x跟z轴如何确定
通过脑补,我们可以发现,当坐标系朝向相机时,满足x=cross((0,1,0),view)
又因为要建立正交坐标系,再用y = cross(z,x)就可以了
其中,z=view
当然因为是单位向量,都要做归一化操作,这里就省略了
重建坐标系之后,算出新的模型空间下的顶点坐标即可
Shader "Test/Unity Shaders Book/Chapter 11/BillboardTest"
{
Properties
{
_MainTex("MainTex",2D)="white"{}
}
SubShader
{
Tags {"DisableBatching"="True"}
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
struct a2v
{
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
v2f vert(a2v v)
{
v2f o;
float3 view = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1));
//这里取负数比较费解,不取的话会被cull掉,因为算出来的正反面相反
//我猜测,可能是哪里坐标系的旋性是相反导致的
float3 zDir = -normalize(view);
float3 yDir = float3(0,1,0);
//处理朝向跟y轴重合的情况,脑补一下,就知道此时用(1,0,0)和(0,0,1)算都是可以的
if(zDir.y>=0.999||zDir.y<=-0.999)
{
yDir = float3(0,0,1);
}
float3 xDir = normalize(cross(yDir,zDir));
yDir = normalize(cross(zDir,xDir));
float3 modelPos = v.vertex.x*xDir+v.vertex.y*yDir+v.vertex.z*zDir;
o.vertex = UnityObjectToClipPos(float4(modelPos,1));
o.texcoord = v.texcoord;
return o;
}
fixed4 frag(v2f f):SV_TARGET
{
fixed4 o = tex2D(_MainTex,f.texcoord);
return o;
}
ENDCG
}
}
}
这个系列主要是通过阅读《Unity Shader入门精要》之后的一些感想,给读者一些启发。
联系邮箱:glasirius@gmail.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。