Unity Shader之廣告牌

廣告牌在實(shí)際游戲開發(fā)中使用非常廣泛,可以用于草叢,云朵等,其實(shí)現(xiàn)的具體效果就是讓攝像機(jī)在任意角度時(shí),使用廣告牌的物體都會(huì)面向攝像機(jī),廣告牌屬于經(jīng)典的頂點(diǎn)變換。

1. 創(chuàng)建相關(guān)場景,shader,材質(zhì)球,和一個(gè)Quad,為了方便觀察,我們將Quad沿x軸翻轉(zhuǎn)50度并設(shè)置后位置,完成后效果如下:
2. 我們都知道如果想讓一個(gè)物體面向攝像機(jī)的時(shí)候,需要表面法線和向上方向的垂直,但往往因物體角度的旋轉(zhuǎn)導(dǎo)致兩者并不垂直,此時(shí)我們需要固定一個(gè)方向來更正另一個(gè)方向
3. 打開shader文件,首先簡單定義一下shder內(nèi)屬性和方法,其中_VerticalBillboarding字段用來固定一個(gè)視角
Shader "Youcai/test/BillBoard" {
    Properties{
        _MainTex("Main Tex", 2D) = "white"{}
        _Color("Main Color", Color) = (1,1,1,1)
        _VerticalBillboarding("Vertical Restraints", Range(0,1)) = 1
    }
    SubShader{
        Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "DisableBatching" = "True"}
        Pass
        {
            Tags {"LightMode" = "ForwardBase"}
            ZWrite off
            Blend SrcAlpha OneMinusSrcAlpha
            Cull off
            CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;
            float _VerticalBillboarding;

            struct a2v
            {
                float4 vertex: POSITION;
                float4 texcoord : TEXCOORD0;
            };
            struct v2f
            {
                float4 pos: SV_POSITION;
                float2 uv: TEXCOORD0;
            };

            void vert(in a2v v, out v2f f)
            {
            }

            fixed4 frag(v2f f) : SV_Target
            {
            }
            ENDCG
        }

    }
    FallBack "Transparent/VertexLit"
}
4. 定義頂點(diǎn)著色器和片元著色器內(nèi)容,其中頂點(diǎn)著色器內(nèi)為核心部分
void vert(in a2v v, out v2f f)
{
     //計(jì)算以模型空間下原點(diǎn)為錨點(diǎn),根據(jù)頂點(diǎn)位置最后做偏移
     float3 center = float3(0, 0, 0);
     //將攝像機(jī)位置轉(zhuǎn)為模型空間位置
     float3 object_viewer = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
     /*
     1. 我們首先假定攝像機(jī)到錨點(diǎn)位置為表面法線(不理解可以看步驟2)
     2. 通過控制法線的y軸值來確定固定的視角為法線還是向上方向
     3. _VerticalBillboarding越接近1,normalDir值y值不偏移,則越強(qiáng)制偏向攝像機(jī)
     */
     float3 normalDir = object_viewer - center;
     normalDir.y = (normalDir.y * _VerticalBillboarding);
     normalDir = normalize(normalDir);
     //法線應(yīng)與向上方向垂直,我們通過三元表達(dá)式獲取一個(gè)向上方向的大致方向
     float3 upDir = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0);
     //通過向上方向和法線的叉乘獲得向右方向
     float3 rightDir = normalize(cross(normalDir, upDir));
     //通過向右方向在求取正確的向上方向
     upDir = normalize(cross(normalDir, rightDir));
     //獲取當(dāng)前頂點(diǎn)距錨點(diǎn)偏移值
     float3 centerOffs = v.vertex.xyz - center;
     //求取正確頂點(diǎn)位置 向右對(duì)應(yīng)x軸,向上對(duì)應(yīng)y軸,法線對(duì)應(yīng)z軸進(jìn)行偏移
     float3 localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;
     //片元傳遞正確uv和坐標(biāo)
     f.pos = UnityObjectToClipPos(float4(localPos, v.vertex.w));
     f.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
}

fixed4 frag(v2f f) : SV_Target
{
     fixed4 c = tex2D(_MainTex, f.uv);
     c.rgb *= _Color.rgb;
     return c;
}
5. 賦予Quad材質(zhì)球,通過更改Vertical Restraints屬性來查看效果吧!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容