顶点动画-广告牌效果

效果

转动摄像机时,无论从哪个方向对着物体,会看到物体看起来总是正对着摄像机。
在这里插入图片描述

思路

为了使物体不会随着摄像机的角度的不同,而成像的面向不同。可以使用旋转矩阵,对物体实时进行旋转上的修正。即求得模型空间下,以视角方向做为法线方向,并计算出其他两个坐标方向,up与right,构成一组正交基。再使用它对原顶点进行转换。

实现

Shader "Custom/BillBoard" {
	Properties{
	    _MainTex("MainTex",2D) = "white" {}
	    _Color("Color",Color) = (1,1,1,1)
	    _VerticalBillBoard ("Board", Range(0,1)) = 1
	
	}
	SubShader{
	    //半透明纹理,三个选项
	    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
	    //模型空间的顶点动画, 需要关闭合批
	    Tags { "DisableBatching"="True" }
	    Pass{
	        //前向渲染 
	        Tags {"LightMode" = "ForwardBase"}
	        //半透,关闭深度写入
	        ZWrite Off
	        //需要双面渲染, 关闭裁剪背面
	        Cull Off
	        //混合 - 透明度混合模式
           Blend SrcAlpha OneMinusSrcAlpha
	        
	        CGPROGRAM
	        
	        sampler2D _MainTex;
	        float4 _MainTex_ST;
	        fixed4 _Color;
	        float _VerticalBillBoard;
	        
	        struct a2v{
	            float4 vertex : POSITION;
	            float4 texcoord : TEXCOORD0;
	        };
	        
	        struct v2f{
	            float4 pos : SV_POSITION;
	            float2 uv : TEXCOORD0;
	        };
	        
	        #include "UnityCG.cginc"
	        #include "Lighting.cginc"
	        #pragma vertex vert
	        #pragma fragment frag
	          
	        v2f vert (a2v v)  {
	            v2f o;
	            float3 center = float3(0,0,0);
	            float3 view = mul( unity_WorldToObject, float4(_WorldSpaceCameraPos,1 ) );   //得到模型空间下的视野方向 
	            float3 normalDir = view - center; //计算法线方向
	            
	            normalDir.y = normalDir.y * _VerticalBillBoard ; //约束垂直方向的程度 
	            normalDir = normalize(normalDir);//求得normal方向(即视野方向)
	            
	            float3 upDir = abs( normalDir.y ) > 0.999 ? float3(0,0,1) : float3 (0,1,0) ; //为防止upDIr与normalDir 平行, (因为平行时,求叉积会错误), 先假定一个up方向
	            float3 rightDir = normalize( cross( upDir,normalDir ) ); //先计算右方向
                upDir = normalize(cross(normalDir, rightDir)); //计算上方向 
	            
	            float3 centerOffs = v.vertex.xyz - center;
	            float3 localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;//根据计算得到的三个正交基,算出新的顶点位置
	            
	            o.pos = UnityObjectToClipPos( float4(localPos, 1));//计算到裁剪空间中
	            o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);  //uv修正
	            return o; 
	        };
	        
	        fixed4 frag (v2f i): SV_Target{
	            fixed4 c = tex2D( _MainTex, i.uv );//纹理采样
	            c.rgb *= _Color.rgb;
	            return c;
	        };
	        ENDCG
	    }
	}
	
	FallBack "Transparent/VertexLit"
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值