最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Unity3D實現(xiàn)選中物體消融特效的方法詳解

 更新時間:2023年10月13日 15:40:48   作者:little_fat_sheep  
消融特效中基Shader?Graph實現(xiàn)了消融特效,本文將基于?Shader?實現(xiàn)消融特效,當前實現(xiàn)消融特效的方法主要有?Alpha?測試消融、clip(或?discard)消融,它們的本質都是隨機丟棄一些片元,以實現(xiàn)消融效果,文中有詳細代碼示例,需要的朋友可以參考下

1 消融特效原理

消融特效中基于 Shader Graph 實現(xiàn)了消融特效,本文將基于 Shader 實現(xiàn)消融特效。

當前實現(xiàn)消融特效的方法主要有 Alpha 測試消融、clip(或 discard)消融,它們的本質都是隨機丟棄一些片元,以實現(xiàn)消融效果。

1)噪聲紋理

為模擬隨機效果,可以通過對噪聲紋理進行采樣實現(xiàn),如下是一些常用的噪聲紋理。

這些噪聲紋理有一個共同特點:在較小的鄰域范圍內(nèi),灰度是漸變的,使得模擬的消融效果更加和諧。

2)Alpha 測試消融原理

將片元的 alpha 通道設置為隨機值,通過 AlphaTest 剔除 alpha 值小于閾值的片元,以實現(xiàn)消融效果,代碼如下。由于改變了 alpha 通道值,該方案會影響半透明物體的混合效果。

AlphaTest Greater [_AlphaThreshold]
...
fixed4 frag(v2f i) : SV_Target {
    fixed noise = tex2D(_NoiseTex, i.uvNoiseTex).r; // 噪聲采樣
    ...
    return fixed4(r, g, b, noise);
}

3)clip(或 discard)消融原理

對噪聲紋理進行采樣,使得每個片元都對應一個噪聲值,通過 clip(或 discard)函數(shù)剔除噪聲值小于閾值的片元,代碼如下。

fixed4 frag(v2f i) : SV_Target {
    fixed noise = tex2D(_NoiseTex, i.uvNoiseTex).r; // 噪聲采樣
    float factor = noise - _BurnAmount;
    clip(factor); // 剔除factor小于0的片元, 即: if(factor < 0) discard;
    ...
}

2 消融特效實現(xiàn)

DieController.cs

using UnityEngine;
public class DieController : MonoBehaviour {
    private RaycastHit hit; // 碰撞信息
    private void Start() {
        hit = new RaycastHit();
    }
    private void Update() {
        if (Input.GetMouseButtonUp(0)) {
            GameObject hitObj = GetHitObj();
            if (hitObj != null) {
                GameObject rootObj = GetRootObj(hitObj);
                rootObj.AddComponent<DissolveEffect>();
            }
        }
    }
    private GameObject GetHitObj() { // 獲取屏幕射線碰撞的物體
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit)) {
            return hit.collider.gameObject;
        }
        return null;
    }
 
    private GameObject GetRootObj(GameObject obj) { // 獲取根對象
        while (obj.transform.parent != null && obj.layer == obj.transform.parent.gameObject.layer) {
            obj = obj.transform.parent.gameObject;
        }
        return obj;
    }
}

說明:DieController 腳本組件掛在相機上。

DissolveEffect.cs

using UnityEngine;
 
[DisallowMultipleComponent] // 不允許在同一對象上掛載多個該組件
public class DissolveEffect : MonoBehaviour {
    private Renderer[] renderers; // 渲染器
    private Material dissolveMat; // 消融材質
    private float burnSpeed = 0.25f; // 燃燒速度
    private float burnAmount = 0; // 燃燒量, 值越大模型鏤空的越多
 
    private void Awake() {
        dissolveMat = Resources.Load<Material>("DissolveMat");
        renderers = GetComponentsInChildren<Renderer>();
    }
 
    private void OnEnable() {
        foreach (Renderer renderer in renderers) {
            Material[] materials = renderer.sharedMaterials;
            Material[] dissolveMaterials = new Material[materials.Length];
            for (int i = 0; i < materials.Length; i++) {
                Material newMaterial = new Material(dissolveMat);
                SetTexture(materials[i], newMaterial);
                SetColor(materials[i], newMaterial);
                newMaterial.SetFloat("_BurnAmount", 0);
                dissolveMaterials[i] = newMaterial;
            }
            renderer.sharedMaterials = dissolveMaterials;
        }
    }
 
    private void Update() {
        burnAmount += Time.deltaTime * burnSpeed;
        foreach (Renderer renderer in renderers) {
            Material[] materials = renderer.sharedMaterials;
            foreach (Material material in materials) {
                material.SetFloat("_BurnAmount", burnAmount);
            }
        }
        if (burnAmount >= 1f) {
            Destroy(gameObject);
        }
    }
 
    private void SetTexture(Material oldMaterial, Material newMaterial) { // 設置材質
        if (oldMaterial.HasTexture("_MainTex")) {
            Texture texture = oldMaterial.GetTexture("_MainTex");
            newMaterial.SetTexture("_MainTex", texture);
        }
    }
 
    private void SetColor(Material oldMaterial, Material newMaterial) { // 設置顏色
        Color color = Color.white;
        if (oldMaterial.HasColor("_Color")) {
            color = oldMaterial.GetColor("_Color");
        }
        newMaterial.SetColor("_Color", color);
    }
}

DissolveEffect.shader

Shader "MyShader/DissolveEffect" {
    Properties {
        _MainTex("Main Tex", 2D) = "white" {} // 主紋理
        _Color("Color", Color) = (1, 1, 1, 1) // 模型顏色
        _NoiseTex("Noise Tex", 2D) = "white"{} // 噪聲紋理
        _BurnAmount("Burn Amount", Range(0, 1)) = 0 // 燃燒量, 值越大模型鏤空的越多
        _LineWidth("Burn Line Width", Range(0, 0.2)) = 0.1 // 燃燒的線條寬度
        _BurnOuterColor("Burn Outer Color", Color) = (1, 0, 0, 1) // 燃燒線條的外側顏色
        _BurnInnerColor("Burn Inner Color", Color) = (1, 0, 0, 1) // 燃燒線條的內(nèi)側顏色
    }
 
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}
        Pass {
            Tags { "LightMode"="ForwardBase" }
 
            Cull Off // 關閉剔除, 正反面都渲染, 因為消融會裸漏模型內(nèi)部結構
            CGPROGRAM
            #include "Lighting.cginc"
 
            #pragma vertex vert
            #pragma fragment frag
            sampler2D _MainTex; // 主紋理
            fixed4 _Color; // 模型顏色
            sampler2D _NoiseTex; // 噪聲紋理
            fixed _BurnAmount; // 燃燒量, 值越大模型鏤空的越多
            fixed _LineWidth; // 燃燒的線條寬度
            fixed4 _BurnOuterColor; // 燃燒線條的外側顏色
            fixed4 _BurnInnerColor; // 燃燒線條的內(nèi)側顏色
            float4 _MainTex_ST; // _MainTex的縮放和偏移
            float4 _NoiseTex_ST; // _NoiseTex的縮放和偏移
            struct a2v {
                float4 vertex : POSITION; // 模型空間頂點坐標
                float3 normal : NORMAL; // 模型空間頂點法線向量
                float4 texcoord : TEXCOORD0; // 頂點紋理坐標
            };
            struct v2f {
                float4 pos : SV_POSITION; // 裁剪空間頂點坐標
                float3 normal : Normal; // 世界空間頂點法線向量
                half2 uvMainTex : TEXCOORD0; // 主紋理的紋理坐標
                half2 uvNoiseTex : TEXCOORD1; // 噪聲紋理的紋理坐標
                float3 worldPos : TEXCOORD2; // 世界空間頂點坐標
            };
            v2f vert(a2v v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex); // 模型空間頂點坐標變換到裁剪空間, 等價于: mul(UNITY_MATRIX_MVP, v.vertex)
                o.normal = UnityObjectToWorldNormal(v.normal); // 將模型空間法線向量變換到世界空間(已歸一化)
                o.uvMainTex = TRANSFORM_TEX(v.texcoord, _MainTex); // 主紋理坐標縮放和偏移
                o.uvNoiseTex = TRANSFORM_TEX(v.texcoord, _NoiseTex); // 噪聲紋理坐標縮放和偏移
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; // 將模型空間頂點坐標變換到世界空間
                return o;
            }
            fixed4 frag(v2f i) : SV_Target {
                fixed noise = tex2D(_NoiseTex, i.uvNoiseTex).r; // 噪聲采樣
                float factor = noise - _BurnAmount;
                clip(factor); // 剔除factor小于0的片元, 即: if(factor < 0) discard;
                fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); // 世界空間燈光向量
                fixed4 albedo = tex2D(_MainTex, i.uvMainTex) * _Color; // 模型顏色
                fixed4 ambient = UNITY_LIGHTMODEL_AMBIENT * albedo; // 環(huán)境光顏色
                fixed4 diffuse = _LightColor0 * albedo * max(0, dot(i.normal, lightDir)); // 漫反射光顏色
                fixed t = smoothstep(0, _LineWidth, factor);
                fixed4 burnColor = lerp(_BurnOuterColor, _BurnInnerColor, t);
                fixed4 finalColor = lerp(burnColor, ambient + diffuse, t);
                return fixed4(finalColor.xyz, 1);
            }
 
            ENDCG
        }
    }
 
    FallBack "Diffuse"
}

說明:在 Assets 目錄下面新建 Resources 目錄,接著在 Resources 目錄下面創(chuàng)建材質,重命名為 DissolveMat,將 DissolveEffect.shader 與 DissolveMat 材質綁定,并將噪聲紋理拖拽到 DissolveMat 的 Noise Tex 中。

3 運行效果

以上就是使用Unity3D實現(xiàn)選中物體消融特效的方法詳解的詳細內(nèi)容,更多關于Unity3D選中物體消融特效的資料請關注腳本之家其它相關文章!

相關文章

  • C# 當前系統(tǒng)時間獲取及時間格式詳解

    C# 當前系統(tǒng)時間獲取及時間格式詳解

    這篇文章主要介紹了C# 當前系統(tǒng)時間獲取及時間格式詳解的相關資料,這里提供代碼實例,幫助大家學習參考,需要的朋友可以參考下
    2016-12-12
  • C#實現(xiàn)簡單俄羅斯方塊

    C#實現(xiàn)簡單俄羅斯方塊

    這篇文章主要為大家詳細介紹了C#實現(xiàn)簡單俄羅斯方塊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 使用C#實現(xiàn)將Excel轉換為Markdown表格

    使用C#實現(xiàn)將Excel轉換為Markdown表格

    Markdown 表格廣泛應用于技術文檔,README 文件以及各類靜態(tài)站點生成器中,本文將介紹如何使用 C# 將 Excel 文件轉換為 Markdown 表格,感興趣的小伙伴可以了解下
    2026-01-01
  • C#學習筆記——基本語法

    C#學習筆記——基本語法

    本文給大家詳細介紹了C#的基本語法知識以及一些基礎知識的匯總,非常的簡單基礎,有需要的小伙伴可以參考下
    2017-02-02
  • C#高效比較兩個DataTable數(shù)據(jù)差異化的方法實現(xiàn)

    C#高效比較兩個DataTable數(shù)據(jù)差異化的方法實現(xiàn)

    本文主要介紹了C#高效比較兩個DataTable數(shù)據(jù)差異化的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • C#獲取DICOM圖像像素的像素值的代碼詳解

    C#獲取DICOM圖像像素的像素值的代碼詳解

    DICOM即醫(yī)學數(shù)字成像和通信,是醫(yī)學圖像和相關信息的國際標準(ISO 12052),它定義了質量能滿足臨床需要的可用于數(shù)據(jù)交換的醫(yī)學圖像格式,這篇文章主要介紹了C#獲取DICOM圖像像素的像素值的方法,需要的朋友可以參考下
    2024-07-07
  • c#訪問this關鍵字和base關鍵字示例

    c#訪問this關鍵字和base關鍵字示例

    this關鍵字引用類的當前實例。靜態(tài)成員方法中不能使用this關鍵字,this關鍵字只能在實例構造函數(shù)、實例方法或實例訪問器中使用。base關鍵字用于從派生類中訪問基類的成員。下面學習一下這二個關鍵字的使用方法
    2014-01-01
  • C#類的成員之Field字段的使用

    C#類的成員之Field字段的使用

    本文主要介紹了C#類的成員之Field字段的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • C# 時間和日期的處理方法

    C# 時間和日期的處理方法

    這篇文章主要介紹了C#時間和日期的處理,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-06-06
  • WPF利用TextBlock實現(xiàn)查找結果高亮顯示效果

    WPF利用TextBlock實現(xiàn)查找結果高亮顯示效果

    在應用開發(fā)過程中,經(jīng)常遇到這樣的需求:通過關鍵字查找數(shù)據(jù),把帶有關鍵字的數(shù)據(jù)顯示出來,同時在結果中高亮顯示關鍵字,所以本文就來和大家介紹一下如何利用TextBlock實現(xiàn)查找結果高亮顯示效果吧
    2023-08-08

最新評論

晋江市| 和顺县| 喀喇| 扶余县| 翁牛特旗| 临西县| 巫溪县| 吉安市| 肃宁县| 华容县| 大兴区| 漳平市| 炉霍县| 房产| 新安县| 布拖县| 吴旗县| 怀柔区| 巨鹿县| 清河县| 河曲县| 铁力市| 青冈县| 吉林省| 嘉义县| 武义县| 白玉县| 社旗县| 黑山县| 石泉县| 保康县| 灌南县| 伽师县| 宁阳县| 莱西市| 辽阳县| 长沙县| 渑池县| 呼玛县| 兰坪| 宜昌市|