計算機圖形學(xué)與Shader

一阵面、計算機圖形學(xué)

1. 概述

  1. Unity的代碼在CPU中運行览爵,圖形學(xué)的代碼在GPU中運行
  2. 圖形學(xué)使用CG(C Graph)語言,是英偉達和微軟聯(lián)合開發(fā)的跨平臺語言
  3. 操作系統(tǒng)中的圖形處理軟件DX12,使用GLSL(OpenGL Shading Language)、DX語言
  4. shader 1.0實現(xiàn)的功能很少,更像設(shè)置參數(shù)浮梢;shader 2.0洲尊,為開發(fā)者留下了開發(fā)接口,可以進行可編程式的開發(fā)棺滞;Unity的shader,表面著色器,介于1.0和2.0之間,翻譯成2.0然后發(fā)給GPU
  5. shader 1.0 :固定管線著色器倒脓、shader 2.0:頂點片段著色器饲做、Unity shader:表面著色器
  6. shader:著色器,使用紋理、數(shù)據(jù)肮砾、顏色等原材料疆柔,通過編程的方式進行一些邏輯運算,設(shè)置到材質(zhì)球上
  7. 寫shader范咨,要使用的原材料盡量可以變化权旷,適應(yīng)多種平臺多種需求

2. 渲染繪圖管線

  • 圖像從GPU里的體現(xiàn)過程:一個個頂點連線,組成三角形作為面镣煮,由面拼成一個圖形介衔。
  • 繪圖流程:頂點處理、面處理影所、光柵化、像素處理

2.1 頂點處理

頂點處理就是坐標轉(zhuǎn)換,將物體的本地坐標最終轉(zhuǎn)換成屏幕坐標

  • 坐標按這四種坐標系的順序進行轉(zhuǎn)換:本地坐標,世界坐標十减,觀察坐標系,投影坐標系
  • unity中拼合的頂點分開算頂點,例如一個Cube有4 * 6 = 24個頂點

2.2 面的處理

  1. 面組裝:將頂點處理得到的點集合進行處理,把點連成面
  2. 面截仍ァ:連成面之后店展,判斷哪些在屏幕范圍,將這些面截取
  3. 面剔除:面截取后,判斷哪些面會被別的面擋住,顯示不出來逝变,將這些面剔除

2.3 光柵化

  • 將面處理得到的面轉(zhuǎn)換成一個個像素宴咧,稱為光柵化
  • 邊緣鋸齒等問題出在這步

2.4 像素處理

輸入像素的位置、深度茬高、貼圖坐標熏瞄、法線、切線、顏色等,給像素著色斗蒋,使用四通道RGBA

2.5 shader各版本能做的事情

  • shader 1.0:像素處理
  • shader 2.0:像素處理跷究、頂點處理

3. 固定管線著色器(Fixed Shader色冀、Shader 1.0)

每有一個像素与学,就執(zhí)行一次

3.1 結(jié)構(gòu)

// Shader關(guān)鍵字 路徑
Shader "AShader/FixedShader/Base001"{
    // 屬性模塊
    Properties
    {
    
    }
    
    // 子著色器,可以有多個杨赤,作用是面對不同的設(shè)備阳柔,從上到下做嘗試
    // 質(zhì)量高,渲染效果好的,性能消耗大的
    SubShader
    {
        // 通道1
        Pass
        {
            
        }
        
        // 通道2
        Pass
        {
            
        }
    }
    
    // 中等質(zhì)量
    SubShader
    {
        Pass
        {
            
        }
    }
    
    // 質(zhì)量差
    SubShader
    {
        Pass
        {
            
        }
    }
    
    // 最基礎(chǔ)的,Unity 4.x 預(yù)設(shè)的漫反射
    Fallback "Diffuse"
}

3.2 屬性

Properties
{
    // 屬性定義語法:屬性名("面板顯示名稱",屬性類型) = 初值
    
    // 浮點型(使用較少)
    _FloatValue("浮點數(shù)", float) = 0.5
    // 范圍浮點型(常用)
    _RangeValue("范圍浮點數(shù)", Range(0, 100)) = 30
    // 四維數(shù) (x, y, z, w) (使用較少)
    _VectorValue("四維數(shù)", Vector) = (1, 1, 1, 1)
    // 顏色,范圍[0 - 1](常用)
    _ColorValue("顏色值", Color) = (1, 0, 0, 1)
    // 2階貼圖,材質(zhì)的長寬是2的多少次冪 2x2 4x4 8x8 16x16(常用)
    // Tiling x, y :平鋪
    // Offset x, y :起始位置
    _MainTexture("主紋理", 2D) = ""{}
    // 非2階貼圖(使用較少)
    _RectTexture("非2階紋理", Rect) = ""{}
    // 立方體貼圖 6個紋理,每個紋理表示一個面(使用很少)
    _CubeTexture("3D紋理", Cube) = ""{}
}

3.3 命令

  • Tag命令
    寫在SubShader中
// 標簽
Tags
{
    // 渲染隊列,數(shù)字越小越先渲染虏两,數(shù)字大的會擋住數(shù)字小的
    // 隊列在賦值的時候可以使用運算引颈,但是是字符串賦值,所以+號左右不能有空格
    "Queue" = "Transparent+1"
}

預(yù)設(shè)的四種渲染隊列級別

級別 翻譯 代表數(shù)字
Background 后臺 1000
Geometry(默認) 幾何體 2000
Transparent 透明 3000
Overlay 覆蓋 4000
  • 渲染命令
    寫在Pass(通道)中
命令 作用
Color(r, g, b, a) 用指定顏色渲染
Color[Color] 用屬性顏色渲染
Lighting On/Off 開啟/關(guān)閉頂點光照
Cull Front/Back/Off 剔除正面/剔除背面/關(guān)閉剔除
ZWrite On/Off(默認為On) 是否要將像素的深度寫入深度緩存中
ZTest Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off(默認為LEqual) 通過比較深度來更改深度緩存的值完箩,Always指的是直接將當前像素顏色(不是深度)寫進顏色緩沖區(qū)中粱快,Never指的是永遠不會將當前像素顏色寫進顏色緩沖區(qū)中,相當于消失,Off指的是關(guān)閉深度測試
SeparateSpecular On/Off 鏡面反射開啟/關(guān)閉

利用渲染隊列修改顯示順序

Shader "AShader/FixedShader/Fixed003"
{
    Properties
    {
        _MainColor("主顏色", Color) = (1, 1, 1, 1)
    }

    SubShader
    {

        // 標簽
        Tags
        {
            // 渲染隊列
            "Queue" = "Transparent+1"
        }

        Pass
        {
            // 關(guān)閉深度測試
            ZTest Off

            Lighting On

            Material
            {
                Diffuse[_MainColor]
            }
        }
    }
}
  • 透明混合命令
命令 作用
Blend SrcAlpha OneMinusSrcAlpha 透明混合,有時候后面的東西會消失,不穩(wěn)定椎眯,基本不在shader 1.0中使用
Blend One One 相加乳丰,主顏色更亮
Blend One OneMinusDstColor 更柔和的相加
Blend DstColor Zero 相乘
Blend DstColor SrcColor 2倍乘法
Shader "AShader/FixedShader/Fixed009"{

    Properties
    {
        _MainTexture("主紋理", 2D) = ""{}

    }

    SubShader
    {
        // 透明混合
        //Blend SrcAlpha OneMinusSrcAlpha
        //Blend One One
        //Blend One OneMinusDstColor
        //Blend DstColor Zero
        Blend DstColor SrcColor

        Pass
        {
            SetTexture[_MainTexture]
            {
                combine texture
            }
        }
    }
}
  • Alpha測試命令
命令 作用
AlphaTest Off 關(guān)閉
AlphaTest Greater 大于
AlphaTest GEqual 大于等于
AlphaTest Less 小于
AlphaTest LEqual 小于等于
AlphaTest Equal 等于
AlphaTest NotEqual 不等于
AlphaTest Always 渲染所有像素
AlphaTest Never 不渲染任何像素
Shader "AShader/FixedShader/Fixed008"{

    Properties
    {
        _AlphaTest("透明測試", Range(0, 1)) = 1

        _MainTexture("主紋理", 2D) = ""{}
    }

    SubShader
    {
        Pass
        {
            // 溶解效果
            AlphaTest Greater [_AlphaTest]

            SetTexture[_MainTexture]
            {
                combine texture
            }
        }
    }
}
  • Material 材質(zhì)命令
    寫在Pass -> Material中
命令 作用
Diffuse[Color] 漫反射顏色
Ambient[Color] 環(huán)境光反射顏色
Shininess[float] 光澤度
Specular[Color] 高光顏色
Emission[Color] 自發(fā)光顏色
Shader "AShader/FixedShader/Fixed006"{

    Properties
    {
        _MainColor("主顏色", Color) = (1, 1, 1, 1)
        _SpecularColor("高光顏色", Color) = (1, 1, 1 ,1)
        _Shininess("光澤度", Range(0.1, 1)) = 0.5
        _Ambient("環(huán)境光顏色", Color) = (1, 1, 1, 1)
        _Emission("自發(fā)光顏色", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        Pass
        {
            Color[_MainColor]
            Lighting On
            SeparateSpecular On
            Material
            {
                Diffuse[_MainColor]
                Specular[_SpecularColor]
                Shininess[_Shininess]
                Ambient[_AmbientColor]
                Emission[_EmissionColor]
            }
        }
    }
}
  • Texture 紋理命令
    紋理命令寫在Pass中屎即,紋理命令不區(qū)分大小寫
SetTexture[Texture]
{
    // 定義constantColor
    constantColor(r, g, b, a)
    constantColor[Color]
    // 合并命令
    // 因為RGBA的值范圍是[0 - 1]统台,所以 + 更趨向于(1, 1, 1, 1)(白色)更亮,* 更趨向于(0, 0, 0, 0)(黑色)更暗
    combine src1 + src2
    combine src1 * src2
    
    // -src 為補色
    combine src1 - src2
    // 使用src2的透明通道值在src1和src3之間取插值,插值是反向的仪缸,透明度為0的時候取src3拴还,透明度為1的時候取src1
    combine src1 lerp(src2) src3
}
源類型(src) 描述
primary 來自光照計算的顏色或是當它綁定時的頂點顏色
texture 在SetTexture中定義的紋理的顏色
previous 上一次SetTexture的結(jié)果
constant 被constantColor定義的顏色
  • 兩張紋理圖漸變切換

Fixed007.shader

Shader "AShader/FixedShader/Fixed007"{

    Properties
    {
        _LerpScale("插值比例", Range(0, 1)) = 1
        _MainTexture("主紋理", 2D) = ""{}
        _DetailTexture("細節(jié)紋理", 2D) = ""{}
    }

    SubShader
    {
        Pass
        {
            SetTexture[_MainTexture]
            {
                constantColor(1, 0, 0, 0)
            }

            SetTexture[_DetailTexture]
            {
                constantColor(1, 1, 1, [_LerpScale])

                combine texture lerp(constant) previous
            }
        }
    }
}

SkinLerp.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SkinLerp : MonoBehaviour 
{
    // 拿到meshRenderer
    private MeshRenderer _meshRenderer;
    // 當前的lerpScale
    private float lerpScale;
    // 目標lerpScale
    private float targetScale;

    private void Awake()
    {
        _meshRenderer = GetComponent<MeshRenderer>();
    }

    private void Update()
    {
        // 取插值
        lerpScale = Mathf.Lerp(lerpScale, targetScale, Time.deltaTime * 2);
        // 0 - 1 之間來回切換
        if (Mathf.Abs(lerpScale - targetScale) < 0.05)
            targetScale = (targetScale == 0) ? 1 : 0;

        // 使用代碼控制
        // name : 屬性名
        // value : 值
        _meshRenderer.material.SetFloat("_LerpScale", lerpScale);

        // 修改Offset使圖片動起來
        _meshRenderer.material.SetTextureOffset("_MainTexture", new Vector2(Time.time, 0));
        _meshRenderer.material.SetTextureOffset("_DetailTexture", new Vector2(-Time.time, 0));

    }
}

4. 表面著色器(Surface Shader)

4.1 CG語言

  • 基本數(shù)據(jù)類型(所有的數(shù)據(jù)類型后面都可以加數(shù)字,表示多個該類型的,類似Vector)

    • float:32位 浮點數(shù)
      • float2:2個浮點數(shù)
      • float3:3個浮點數(shù)
      • float4:4個浮點數(shù)
    • half:16位 浮點數(shù)
    • int:32位 整型
    • fixed:12位 定點數(shù),取值范圍 [0 - 1] 的小數(shù) 或 整數(shù)
    • bool
    • sampler2D:紋理對象
    • string
  • 預(yù)設(shè)的Structure

    • 輸入

      變量名 代表內(nèi)容
      float2 uv_MainTex 紋理貼圖UV,模型上每個像素對應(yīng)到紋理圖的坐標陈莽,_MainTex為紋理圖的名字
      float3 viewDir 像素的視圖方向
      float3 worldPos 像素的世界坐標位置
      float4 screenPos 屏幕空間位置私植,是float4類型湖员,只需用前兩個值
      float4 color:COLOR 每個頂點的內(nèi)插值顏色
    • 輸出

      變量名 代表內(nèi)容
      half3 Albedo 反射率,即顏色紋理RGB
      half3 Normal 法線,即法向量(x, y, z)
      half3 Emission 自發(fā)光顏色RGB
      half Specular 鏡面反射度
      half Gloss 光澤度
      half Alpha 透明度
  • 語義綁定
    語法:變量名:語義定義,表示這個變量代表著某種指定的值名斟,例:color:COLOR 表示color這個變量是顏色

4.2 結(jié)構(gòu)

  • 表面著色器沒有Pass通道
  • 外部是Shader Lab杆融,內(nèi)部嵌入CG語言
Shader "Ashader/SurfaceShader/Shader001"
{
    Properties
    {
        
    }
    
    SubShader
    {
        // 不需要Pass通道

        // 預(yù)編譯指令 粉色高亮
        // --------- CG語言開始 ---------
        CGPROGRAM

        // 表面著色器 入口函數(shù)名稱 蘭伯特光照模型(漫反射)
        #pragma surface surf Lambert

        // 輸入結(jié)構(gòu)體
        struct Input
        {
            float3 viewDir;
        };              // CG語言結(jié)構(gòu)體定義后要加";"

        // 聲明外部屬性藕各,要求和屬性名字相同
        fixed4 _MainColor;

        // 入口函數(shù)
        // 參數(shù)
        // Input IN : 輸入結(jié)構(gòu)體
        // in/out/inout SurfaceOutput o : 常用于輸出
        // in:輸入 out:輸出 inout:既能輸入又能輸出
        void surf(Input IN, inout SurfaceOutput o)
        {
            // 輸出純色
            o.Albedo = float3(1, 0, 0);
            // 四個數(shù)字rgba或xyzw 轉(zhuǎn)三個數(shù)字:變量.rgb .gba .xyz .yzw膘魄,用到哪個寫哪個
            o.Albedo = _MainColor.rgb;
        }
        
        // --------- CG語言結(jié)束 ---------
        ENDCG
    }
}

4.3 方法使用

  • 設(shè)置紋理圖
Shader "AShader/SurfaceShader/Surface002"
{
    Properties
    {
        _MainTexture("主紋理", 2D) = ""{}
        _MainColor("主顏色", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        // --------- CG語言開始 ---------
        CGPROGRAM

        // 表面著色器 入口函數(shù)名稱 蘭伯特光照模型(漫反射)
        #pragma surface surf Lambert

        // 聲明外部屬性
        sampler2D _MainTexture;
        fixed4 _MainColor;

        // 輸入結(jié)構(gòu)體
        struct Input
        {
            // 主紋理的UV坐標
            float2 uv_MainTexture;
        };

        // 入口函數(shù)
        void surf(Input IN, inout SurfaceOutput o)
        {
            // 渲染紋理圖灿渴,通過UV坐標在紋理貼圖中獲取當前像素點的顏色值
            // 參數(shù)
            // _MainTexture:紋理圖
            // IN.uv_MainTexture:紋理圖UV
            o.Albedo = tex2D(_MainTexture, IN.uv_MainTexture).rgb;
            // 與顏色進行混合
            o.Albedo *= _MainColor.rgb;
        }

        // --------- CG語言結(jié)束 ---------
        ENDCG
    }
}
  • 設(shè)置法線貼圖
Shader "AShader/SurfaceShader/Surface003"
{
    Properties
    {
        _MainTexture("主紋理", 2D) = ""{}
        _NormalTexture("法線紋理", 2D) = ""{}
    }

    SubShader
    {
        // --------- CG語言開始 ---------
        CGPROGRAM

        // 表面著色器 入口函數(shù)名稱 蘭伯特光照模型(漫反射)
        #pragma surface surf Lambert

        // 聲明外部屬性
        sampler2D _MainTexture;
        sampler2D _NormalTexture;

        // 輸入結(jié)構(gòu)體
        struct Input
        {
            // 主紋理的UV坐標
            float2 uv_MainTexture;
            float2 uv_NormalTexture;
        };

        // 入口函數(shù)
        void surf(Input IN, inout SurfaceOutput o)
        {
            // 渲染紋理圖焰扳,通過UV坐標在紋理貼圖中獲取當前像素點的顏色值
            // 參數(shù)
            // _MainTexture:紋理圖
            // IN.uv_MainTexture:紋理圖UV
            o.Albedo = tex2D(_MainTexture, IN.uv_MainTexture).rgb;
            // 設(shè)置法線貼圖
            o.Normal = UnpackNormal(tex2D(_NormalTexture, IN.uv_NormalTexture));
        }

        // --------- CG語言結(jié)束 ---------
        ENDCG
    }
}
  • 邊緣發(fā)光
Shader "AShader/SurfaceShader/Surface004"
{
    Properties
    {
        _MainTexture("主紋理", 2D) = ""{}
        _NormalTexture("法線紋理", 2D) = ""{}

        _RimColor("發(fā)光顏色", Color) = (1, 1, 1, 1)
        _RimPower("發(fā)光強度", Range(1, 10)) = 1
    }

    SubShader
    {
        // --------- CG語言開始 ---------
        CGPROGRAM

        // 表面著色器 入口函數(shù)名稱 蘭伯特光照模型(漫反射)
        #pragma surface surf Lambert

        // 聲明外部屬性
        sampler2D _MainTexture;
        sampler2D _NormalTexture;
        fixed4 _RimColor;
        half _RimPower;

        // 輸入結(jié)構(gòu)體
        struct Input
        {
            // 主紋理的UV坐標
            float2 uv_MainTexture;
            float2 uv_NormalTexture;
            // 視圖方向
            float3 viewDir;
        };

        // 入口函數(shù)
        void surf(Input IN, inout SurfaceOutput o)
        {
            // 渲染紋理圖,通過UV坐標在紋理貼圖中獲取當前像素點的顏色值
            // 參數(shù)
            // _MainTexture:紋理圖
            // IN.uv_MainTexture:紋理圖UV
            o.Albedo = tex2D(_MainTexture, IN.uv_MainTexture).rgb;
            // 設(shè)置法線貼圖
            o.Normal = UnpackNormal(tex2D(_NormalTexture, IN.uv_NormalTexture));

            // 計算邊緣發(fā)光系數(shù)
            float rim = 1 - saturate(dot(normalize(IN.viewDir), normalize(o.Normal)));
            // 系數(shù)直接乘
            //o.Emission =  _RimColor * rim * _RimPower;
            // 系數(shù)的光強次冪
            o.Emission = _RimColor * pow(rim, 10 - _RimPower);
        }

        // --------- CG語言結(jié)束 ---------
        ENDCG
    }
}

5. 頂點片段著色器(Shader 2.0)

5.1 頂點語義

* model本地坐標
* view觀察坐標
* projection投影坐標
語義 代表內(nèi)容
float4 POSITION 頂點坐標位置
float3 NORMAL 頂點法線向量坐標
float4 TEXCOORD0 第一個UV坐標(用作臨時變量,存坐標存顏色等)
float4 TEXCOORD1/2/3... 第二/三/四...個UV坐標
float4 TENGENT 頂點切線向量坐標
float4 COLOR 頂點顏色值

5.2 常用函數(shù)庫

庫名 作用
HLSLSupport.cginc 輔助為跨平臺的著色器編譯宏和定義
UnityShaderVariables.cginc 常用全局變量
UnityCG.cginc 常用輔助函數(shù)
AutoLight.cginc 光、影函數(shù)
Lighting.cginc 光照模型相關(guān)
TerrainEngine.cginc 地形植被輔助

5.3 結(jié)構(gòu)

Shader "AShader/VFShader/VF001"
{
    Properties
    {
        _MainColor("主顏色", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM

            //      著色器類型 入口函數(shù)名稱
            #pragma vertex vert
            #pragma fragment frag
            // 聲明外部屬性
            fixed4 _MainColor;

            // 頂點著色器驻子,進行頂點處理
            // 返回值 入口函數(shù)名稱(參數(shù)類型 參數(shù)名:語義綁定):返回值語義綁定
            float4 vert(float4 vertexPos:POSITION):SV_POSITION
            {
                // 完成頂點變換,返回投影坐標
                // 5.4之前
                //return mul(UNITY_MATRIX_MVP, vertexPos);
                // 5.4之后
                return UnityObjectToClipPos(vertexPos);
            }

            // 片段著色器,著色
            fixed4 frag():COLOR
            {
                //return fixed4(1, 0, 0, 1);
                return _MainColor;
            }

            ENDCG
        }
    }
}

5.4 案例

  • 彩虹顏色
    將物體的坐標作為顏色值,會呈現(xiàn)彩虹效果
Shader "AShader/VFShader/VF002"
{
    Properties
    {
        _ColorOffset("顏色偏移量", Range(0, 1)) = 0
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM
            
            #pragma vertex vert
            #pragma fragment frag
            // 聲明外部屬性變量
            fixed _ColorOffset;
            // 由于return只能返回一個變量,所以當想返回多個值的時候使用結(jié)構(gòu)體
            // 頂點著色器輸出的結(jié)構(gòu)體
            struct v2f
            {
                // 0級紋理坐標(臨時變量疙赠,用于存儲頂點著色器算出來的頂點坐標捍岳,給片段著色器用)
                float4 col:TEXCOORD0;
                // 屏幕坐標
                float4 pos:SV_POSITION;
            };

            // 頂點著色器入口函數(shù)
            v2f vert(float4 vertexPos:POSITION)
            {
                // 定義結(jié)構(gòu)體對象
                v2f content;
                // 執(zhí)行頂點變換
                content.pos = UnityObjectToClipPos(vertexPos);
                // 獲取頂點坐標
                content.col = vertexPos + float4(_ColorOffset, _ColorOffset, _ColorOffset, 0);

                return content;
            }

            // 片段著色器入口函數(shù)
            float4 frag(v2f content):COLOR
            {
                // 將頂點坐標當成顏色值輸出
                return content.col;
            }

            ENDCG
        }
    }
}
  • 設(shè)定漫反射
Shader "AShader/VFShader/VF003"
{
    Properties
    {
        _MainColor("漫反射顏色", COLOR) = (1, 1, 1, 1)
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            // 引入庫
            #include "UnityCG.cginc"

            // 聲明外部變量
            fixed4 _MainColor;
            // 聲明內(nèi)置變量
            fixed4 _LightColor0;

            // 頂點著色器輸入結(jié)構(gòu)體
            struct appdata
            {
                // 頂點坐標
                float4 vertexPos:POSITION;
                // 頂點法線
                float3 vertexNormal:NORMAL;
            };

            // 頂點著色器輸出結(jié)構(gòu)體
            struct v2f
            {
                // 屏幕坐標
                float4 pos:SV_POSITION;
                // 屏幕法線
                float3 normal:NORMAL;
            };

            // 頂點著色器入口函數(shù)
            v2f vert(appdata data)
            {
                v2f content;
                content.pos = UnityObjectToClipPos(data.vertexPos);
                // 計算法線
                content.normal = mul(float4(data.vertexNormal, 1), unity_WorldToObject).xyz;
                return content;
            }

            // 片段著色器入口函數(shù)
            fixed4 frag(v2f content):COLOR
            {
                // 求法線的標準化向量
                float3 lightNormal = normalize(content.normal);
                // 求入射光的標準化向量
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                // 計算漫反射顏色
                float3 diffuseColor = _MainColor * _LightColor0 * -min(0, dot(lightNormal, lightDir));

                return fixed4(diffuseColor, 1) + UNITY_LIGHTMODEL_AMBIENT;
            }


            ENDCG
        }
    }
}
  • 技能釋放范圍
Shader "SkillShader/Skill1"
{
    Properties
    {
        // 技能釋放原點
        _BossPosition("BossPosition", Vector) = (1, 1, 1, 1)
        // 透明通道值
        _Alpha("BossSkillAlpha", Range(0, 1)) = 0
        // 用于代碼控制顯示范圍的值
        _Dis("SkillDis", Range(0, 10)) = 0
    }

    SubShader
    {
        Pass
        {
            // 開啟透明混合
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            float4 _BossPosition;
            float _Alpha;
            float _Dis;

            struct v2f
            {
                float4 vertPos:TEXCOORD0;
                float4 pos:SV_POSITION;
            };

            v2f vert(float4 vertexPos:POSITION)
            {
                v2f content;
                content.pos = UnityObjectToClipPos(vertexPos);
                content.vertPos = vertexPos;

                return content;
            }

            float4 frag(v2f content):COLOR
            {
                // 根據(jù)傳入坐標計算需要渲染的地方
                if (distance(content.vertPos.z, _BossPosition.z) < _Dis && abs(distance(content.vertPos.x, _BossPosition.x)) < 1)
                {
                    return float4(1, 0, 0, _Alpha);
                }
                else
                {
                    return float4(1, 0, 0, 0);
                }
            }

            ENDCG
        }
    }
}

6. 小知識點

  • 法線貼圖:法線決定光的反射方向,法線是一個向量,向量是vector3麻捻,顏色的rgb也是vector3,所以法線貼圖使用顏色來代表向量(例:紅色(1, 0, 0)代表右)
  • 邊緣發(fā)光公式:
    RimColor = EmissionColor * (1 - clamp01(dot(normalize(normal), normalize(viewDir))))

附:Shader詞典

單詞 描述 單詞 描述 單詞 描述
Shader 著色器 Properties 屬性 SubShader 子著色器
Pass 通道 Color 顏色 Cull 剔除
ZTest 深度測試 SeparateSpecular 鏡面反射 Diffuse 漫反射
Ambient 環(huán)境光 Shininess 光澤度 Specular 高光
Emission 自發(fā)光 Combine 結(jié)合 Primary 基本的
Previous 之前的 Constant 恒定的 Gloss 光澤度
Vertex 頂點 Fragment 片段
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婉宰,一起剝皮案震驚了整個濱河市馒铃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炉爆,老刑警劉巖逼裆,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡碗淌,警方通過查閱死者的電腦和手機纳像,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門岔帽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妥曲,“玉大人,你說我怎么就攤上這事箱玷】瞧海” “怎么了纫骑?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵煤墙,是天一觀的道長。 經(jīng)常有香客問我,道長球涛,這世上最難降的妖魔是什么灭翔? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任煌张,我火速辦了婚禮档玻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枣申。我一直安慰自己泊窘,他們只是感情好,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布龟劲。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裕坊,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音苹享,去河邊找鬼宫纬。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的剃允。 我是一名探鬼主播牡肉,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼跪另,長吁一口氣:“原來是場噩夢啊……” “哼擦盾!你這毒婦竟也來了徒仓?” 一聲冷哼從身側(cè)響起喂走,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后帮孔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姆坚,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡击喂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铲敛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片先鱼。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡寺枉,死狀恐怖砌烁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響授段,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宴胧,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦巨缘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春蛛株,著一層夾襖步出監(jiān)牢的瞬間笋粟,已是汗流浹背嫌变。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工疮跑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留渐苏,地道東北人庄新。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓哗戈,卻偏偏與公主長得像步做,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容