国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Unity3D】激光燈、碰撞特效

這篇具有很好參考價(jià)值的文章主要介紹了【Unity3D】激光燈、碰撞特效。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1 需求描述

? ? ? ? 本文將模擬激光燈(或碰撞)特效,詳細(xì)需求如下:

  • 從鼠標(biāo)位置發(fā)射屏幕射線,檢測是否與物體發(fā)生碰撞
  • 當(dāng)與物體發(fā)生碰撞時(shí),在物體表面覆蓋一層激光燈(或碰撞)特效

【Unity3D】激光燈、碰撞特效

????????本文代碼見→激光燈、碰撞特效

2 原理

? ? ? ? 獲取屏幕射線與物體的碰撞點(diǎn),并在 shader 中計(jì)算頂點(diǎn)與碰撞點(diǎn)的距離(記為 dist),通過以下衰減函數(shù)計(jì)算頂點(diǎn)對應(yīng)的透明度,透明度隨碰撞點(diǎn)的距離增大逐漸減小,激光燈(或碰撞)效果逐漸減弱。

alpha = pow(exp(-dist), 4)

? ? ? ? 為使特效更加逼真,激光燈(或碰撞)特效的紅色分量由以下漫反射公式控制。其中,red 為紅色分量值,λ 為漫反射因子,值越大,漫反射效果越強(qiáng),本文?λ = 0.1;lightDir 為頂點(diǎn)光源向量,normalDir 為頂點(diǎn)法線向量。

red = λ * dot(lightDir, normalDir) + (1 - λ)

3 需求實(shí)現(xiàn)

????????SelectController.cs

using UnityEngine;
 
public class SelectController : MonoBehaviour { // 單擊選中控制
    private Transform target; // 選中的目標(biāo)
    private RaycastHit hit; // 碰撞信息
 
    private void Update() {
        if (Input.GetMouseButtonUp(0)) {
            Transform temp = GetHitTrans();
            if (temp != target) {
                DrawEffect(target, temp);
                target = temp;
            }
        }
    }

    private void DrawEffect(Transform old, Transform now) { // 繪制特效
        DrawEffect(old, false);
        DrawEffect(now, true);
    }

    private void DrawEffect(Transform trans, bool enable) { // 繪制特效
        if (trans != null) {
            foreach(Transform child in trans.transform.GetComponents<Transform>()) {
                if (child.GetComponent<ColliderEffect>() == null) {
                    if (enable) {
                        child.gameObject.AddComponent<ColliderEffect>();
                    }
                }
                else {
                    child.GetComponent<ColliderEffect>().enabled = enable;
                }
            }
        }
    }
 
    private Transform GetHitTrans() { // 獲取屏幕射線碰撞的物體
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit)) {
            return hit.transform;
        }
        return null;
    }
}

????????ColliderEffect.cs

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

[DisallowMultipleComponent]
public class ColliderEffect : MonoBehaviour { // 激光燈(或碰撞)特效
    private Renderer[] renderers; // 當(dāng)前對象及其子對象的渲染器
    private Material colliderMaterial; // 激光燈(碰撞)材質(zhì)
    private Vector4 hitPos; // 碰撞點(diǎn)
    private RaycastHit hit; // 碰撞信息

    private void Awake() {
        renderers = GetComponentsInChildren<Renderer>();
        colliderMaterial = new Material(Shader.Find("MyShader/ColliderEffect"));
        hitPos = Vector4.zero;
        CombineSubmeshes();
    }

    private void OnEnable() {
        hitPos = GetHitPoint();
        colliderMaterial.SetVector("_HitPos", hitPos);
        foreach (var renderer in renderers) {
            List<Material> materials = renderer.sharedMaterials.ToList();
            materials.Add(colliderMaterial);
            renderer.sharedMaterials = materials.ToArray();
        }
    }

    private void Update() {
        hitPos = GetHitPoint();
        if (!hitPos.Equals(Vector4.zero)) {
            colliderMaterial.SetInt("_Enable", 1);
            colliderMaterial.SetVector("_HitPos", hitPos);
        } else {
            colliderMaterial.SetInt("_Enable", 0);
        }
    }

    private void OnDisable() {
        foreach (var renderer in renderers) {
            List<Material> materials = renderer.sharedMaterials.ToList();
            materials.Remove(colliderMaterial);
            renderer.sharedMaterials = materials.ToArray();
        }
    }

    private Vector4 GetHitPoint() {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit, 1000) && hit.transform == transform) {
            return hit.point;
        }
        return Vector4.zero;
    }

    private void CombineSubmeshes() { // 綁定子網(wǎng)格
        foreach (var meshFilter in GetComponentsInChildren<MeshFilter>()) {
            var renderer = meshFilter.GetComponent<Renderer>();
            if (renderer != null) {
                CombineSubmeshes(meshFilter.sharedMesh, renderer.sharedMaterials.Length);
            }
        }
        foreach (var skinnedMeshRenderer in GetComponentsInChildren<SkinnedMeshRenderer>()) {
            CombineSubmeshes(skinnedMeshRenderer.sharedMesh, skinnedMeshRenderer.sharedMaterials.Length);
        }
    }

    private void CombineSubmeshes(Mesh mesh, int materialsLength) { // 綁定子網(wǎng)格
        if (mesh.subMeshCount == 1) {
            return;
        }
        if (mesh.subMeshCount > materialsLength) {
            return;
        }
        mesh.subMeshCount++;
        mesh.SetTriangles(mesh.triangles, mesh.subMeshCount - 1);
    }
}

????????ColliderEffect.shader

Shader "MyShader/ColliderEffect" {
    Properties {
        _HitPos ("HitPos", Vector) = (0, 0, 0, 0) // 屏幕射線碰撞位置
        _Enable ("Enable", Int) = 0 // 是否開啟特效
    }

    SubShader {
        Tags {
            // 渲染隊(duì)列: Background(1000, 后臺)、Geometry(2000, 幾何體, 默認(rèn))、Transparent(3000, 透明)、Overlay(4000, 覆蓋)
            "Queue" = "Transparent+110"
            "RenderType" = "Transparent"
            "DisableBatching" = "True"
        }

        Pass {
            Blend SrcAlpha OneMinusSrcAlpha // 混合測試, 與背后的物體顏色混合

            CGPROGRAM
            #include "UnityCG.cginc"

            #pragma vertex vert
            #pragma fragment frag

            uniform int _Enable;
            uniform float4 _HitPos;
   
            struct a2v {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float4 worldPos : TEXCOORD0;
                float3 worldNormal : Normal;
            };

            v2f vert(a2v v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex); // 裁剪坐標(biāo)系下頂點(diǎn)坐標(biāo)
                o.worldPos = mul(unity_ObjectToWorld, v.vertex); // 世界坐標(biāo)系下頂點(diǎn)坐標(biāo)
                o.worldNormal = UnityObjectToWorldNormal(v.normal); // 世界坐標(biāo)系下頂點(diǎn)法線向量
                return o;
            }

            fixed4 frag(v2f i) : SV_Target {
                if(_Enable == 1) {
                    float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); // 世界坐標(biāo)系下由頂點(diǎn)指向光源的方向向量
                    float diffuse = 0.1 * dot(worldLightDir, i.worldNormal) + 0.9; // 漫反射顏色強(qiáng)度
                    float dist = distance(i.worldPos, _HitPos);
                    float alpha = pow(exp(-dist), 4); // 透明度(隨距離衰減)
                    return float4(diffuse , 0, 0, alpha);
                } else {
                    return float4(0, 0, 0, 0);
                }
            }

            ENDCG
        }
    }
}

4 運(yùn)行效果

【Unity3D】激光燈、碰撞特效文章來源地址http://www.zghlxwxcb.cn/news/detail-424285.html

5 推薦閱讀

  • ?渲染管線
  • 固定管線著色器一
  • 固定管線著色器二
  • 表面著色器
  • 頂點(diǎn)和片元著色器
  • 選中物體描邊特效
  • 基于模板測試和頂點(diǎn)膨脹的描邊方法
  • 水波特效
  • 半球卷屏特效
  • 卷軸特效

到了這里,關(guān)于【Unity3D】激光燈、碰撞特效的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Unity3D】地面網(wǎng)格特效

    【Unity3D】地面網(wǎng)格特效

    1 前言 ? ? ? ? 本文實(shí)現(xiàn)了地面網(wǎng)格特效,包含以下兩種模式: 實(shí)時(shí)模式:網(wǎng)格線寬度和間距隨相機(jī)的高度實(shí)時(shí)變化; 分段模式:將相機(jī)高度分段,網(wǎng)格線寬度和間距在每段中對應(yīng)一個(gè)值。 ? ? ? ? 本文完整資源見→Unity3D地面網(wǎng)格特效。? 2?地面網(wǎng)格實(shí)現(xiàn) ???????? Sc

    2024年02月16日
    瀏覽(34)
  • 【Unity3D】高斯模糊特效

    【Unity3D】高斯模糊特效

    1?高斯模糊原理 ????????邊緣檢測特效中使用了卷積運(yùn)算進(jìn)行了邊緣檢測,本文實(shí)現(xiàn)的高斯模糊特效同樣使用了卷積運(yùn)算,關(guān)于卷積核和卷積運(yùn)算的概念,讀者可以參考邊緣檢測特效。 ? ? ? ? 本文完整資源見→Unity3D高斯模糊特效。 ? ? ? ? 我們將用于模糊處理的卷積

    2024年02月07日
    瀏覽(25)
  • Unity3D教程:2D游戲技能特效

    Unity3D教程:2D游戲技能特效

    在我們的2D圖形游戲中不可缺少大量的光影、技能特效,像Diablo II中的魔法效果的實(shí)現(xiàn),幸好我們擁有強(qiáng)大的CPU來為我們實(shí)現(xiàn)Alpha混合與色彩飽和混合,接下來讓我們來討論一下如何用這些方法來實(shí)現(xiàn)我們游戲中所需要的技能特效。 ? ? 一、Alpha混合特效 ? ? Alpha混合可以讓我

    2024年02月01日
    瀏覽(101)
  • Unity3d 物體不動,碰撞觸發(fā)不了的情況

    問題: 有一種情況,主角帶剛體,主角站著不動。玩家站在陷阱上,陷阱的碰撞體 Toggle 之后, OnCollisionEnter 觸發(fā)不了。 解決:盲猜玩家組件上才有剛體,而碰撞檢測是剛體運(yùn)動的時(shí)候,才進(jìn)行檢測的。

    2024年02月06日
    瀏覽(126)
  • Unity3D粒子系統(tǒng)之制作煙霧特效

    Unity3D粒子系統(tǒng)之制作煙霧特效

    本文將會介紹如何使用Unity內(nèi)的粒子系統(tǒng)制作煙霧效果。 如果想了解Unity粒子系統(tǒng)中的基礎(chǔ)屬性,可以看這篇博客:Unity3D 粒子系統(tǒng)之基礎(chǔ)屬性介紹 先附上預(yù)覽圖: 材質(zhì)貼圖 首先我們需要一張煙霧材質(zhì)用的材質(zhì)貼圖,我是自己畫的,可以參考下圖自己畫一張或者去網(wǎng)上找素材

    2024年02月02日
    瀏覽(35)
  • Unity3D粒子系統(tǒng)之制作火焰特效

    Unity3D粒子系統(tǒng)之制作火焰特效

    本文將會介紹如何使用Unity內(nèi)的粒子系統(tǒng)制作煙霧效果。 如果想了解Unity粒子系統(tǒng)中的基礎(chǔ)屬性,可以看這篇博客:Unity3D粒子系統(tǒng)之基礎(chǔ)屬性介紹 先上預(yù)覽圖吧 用自己熟悉的繪畫工具畫一張類似這樣的圖片(相似即可,白灰色部分邊緣不規(guī)則),注意一定要黑底。 將畫好的

    2024年02月02日
    瀏覽(22)
  • Unity3d bounds包圍盒 和collider碰撞器區(qū)別

    Unity3d bounds包圍盒 和collider碰撞器區(qū)別

    Bounds 叫作外包圍盒、邊界框、外擴(kuò)矩形. 是struct 結(jié)構(gòu)體。 而我們獲得Bounds的主要途徑有三種:Render,Collider,Mesh。 Render.bounds 世界坐標(biāo) Collider.bounds?世界坐標(biāo) Mesh.bounds? 本地坐標(biāo) 碰撞器的方框始終跟著模型旋轉(zhuǎn)移動,縮放跟著模型的,只要模型不縮放它也不縮放 Bounds 跟隨模型移

    2024年02月02日
    瀏覽(24)
  • 【Unity3D賽車游戲優(yōu)化篇】【十】汽車粒子特效和引擎咆哮打造極速漂移

    【Unity3D賽車游戲優(yōu)化篇】【十】汽車粒子特效和引擎咆哮打造極速漂移

    ?????個(gè)人主頁 :@元宇宙-秩沅 ????? hallo 歡迎 點(diǎn)贊?? 收藏? 留言?? 加關(guān)注?! ????? 本文由 秩沅 原創(chuàng) ????? 收錄于專欄 :Unity游戲demo – ??????版本: Unity2021 ??????適合人群:Unity初學(xué)者進(jìn)階 ??????學(xué)習(xí)目標(biāo):3D賽車游戲的基礎(chǔ)制作 ??????技能

    2024年02月09日
    瀏覽(44)
  • unity3D中用Mesh Collider創(chuàng)建的碰撞體與物體模型位置有偏差的解決方法

    unity3D中用Mesh Collider創(chuàng)建的碰撞體與物體模型位置有偏差的解決方法

    1.相信很多小伙伴在使用Mesh Collider時(shí)都遇到過下面這個(gè)情況: 1.解決方法:在這個(gè)對象Alpaca下面新建一個(gè)空對象Collider,我們把Mesh Collider添加到這個(gè)空對象上面就可以調(diào)整碰撞體的位置了? 3.完成效果:

    2024年02月13日
    瀏覽(102)
  • 【Unity3D日常開發(fā)】Unity3D中協(xié)程的使用

    【Unity3D日常開發(fā)】Unity3D中協(xié)程的使用

    推薦閱讀 CSDN主頁 GitHub開源地址 Unity3D插件分享 簡書地址 我的個(gè)人博客 大家好,我是佛系工程師 ☆恬靜的小魔龍☆ ,不定時(shí)更新Unity開發(fā)技巧,覺得有用記得一鍵三連哦。 最近有小伙伴問協(xié)程怎么用、怎么寫,我也是會用會寫,但是原理不是很明白。 學(xué)習(xí)了一下,總結(jié)出

    2024年02月12日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包