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

在unity 2020 urp版本中實(shí)現(xiàn) LensFlare功能

這篇具有很好參考價(jià)值的文章主要介紹了在unity 2020 urp版本中實(shí)現(xiàn) LensFlare功能。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

這個(gè)官方里面沒有支持,只能自己去解決。
效果請(qǐng)查看地址:https://www.bilibili.com/video/BV1w24y1o7pY/

下面說一下我的實(shí)現(xiàn)過程。
找來找去,我找到了一篇不錯(cuò)的解決方案,還帶源碼:
http://warmcat.org/chai/blog/?p=5279
這個(gè)是一個(gè)大佬的個(gè)人博客里面的一篇文章。文章和代碼里面有很多的可取之處,希望大家也多支持一下大佬。
他在里面列出了四種解決方案:

  1. 后處理
  2. 給Renderer最高的SortingOrder或者Queue
  3. 在Overlay UI上繪制
  4. 使用一個(gè)單獨(dú)的相機(jī)并設(shè)置最高的priority

他的代碼里面使用的是第四種方式,就是額外的增加了一個(gè)正交相機(jī),單獨(dú)去渲染。
我把代碼下載下來以后,發(fā)現(xiàn)有一些bug,還有這個(gè)單獨(dú)相機(jī)渲染也不利于管理。所以,我對(duì)此進(jìn)行了一些修改。也將實(shí)現(xiàn)方式修改成了第二種方式,直接繪制在使用的相機(jī)的前面。
接下來我講解一下我是如何修改的,首先我對(duì)shader進(jìn)行了一下處理,因?yàn)楣こ痰膱?chǎng)景打開以后,沒有顯示。
在unity 2020 urp版本中實(shí)現(xiàn) LensFlare功能
原來使用了兩個(gè)對(duì)象掛載腳本,一個(gè)是掛載FlareSource,這個(gè)是制作光暈的一個(gè)資源的一個(gè)腳本。另一個(gè)是拿到設(shè)置的光暈的設(shè)置(上一個(gè)腳本中設(shè)置),進(jìn)行幾何體生成,然后給到正交相機(jī)去渲染。
麻煩的地方就是在這,所以,我實(shí)現(xiàn)是直接將兩個(gè)腳本都掛載到了一個(gè)對(duì)象上面,然后把正交相機(jī)去掉,多余的對(duì)象也刪除掉,將這個(gè)做成一個(gè)預(yù)制體,使用的時(shí)候,只需要將其放到場(chǎng)景中即可。

FlareSource中的修改,里面的實(shí)現(xiàn)是使用了掛載對(duì)象位置實(shí)現(xiàn)的,比較難操作,我直接將其修改成了,根據(jù)光的照射方向,然后加上相機(jī)的位置偏移,來計(jì)算光暈的出現(xiàn)方向。
然后為了保證性能,我還修改了,除了射線檢測(cè),還加入了對(duì)光暈位置的是否處于相機(jī)視椎體內(nèi)進(jìn)行了判斷

   void Update()
    {
        // Vector3 position = transform.position;
        Vector3 direction = m_MainLight.transform.TransformDirection(new Vector3(0, 0, -1)); //太陽(yáng)的朝向
        Vector3 position = m_GameCamera.transform.position + direction * m_GameCamera.farClipPlane;
        m_ViewportPosition = m_GameCamera.WorldToViewportPoint(position);

        Ray ray = new Ray(m_GameCamera.transform.position, position);
        // Ray ray = new Ray(m_GameCamera.transform.position, position - m_GameCamera.transform.position);

        RaycastHit hit;
        //射線拾取遮擋或者不處于相機(jī)范圍內(nèi)
        if (!IsVisableInCamera(position) || Physics.Raycast(ray, out hit))
        {
            //如果當(dāng)前在顯示,則計(jì)算漸變時(shí)間,設(shè)置漸變效果直至隱藏
            if (IsVisible)
            {
                if (!IsHitLast)
                    m_FadeTime = (1 - m_AlphaBase) * FadeDuration;

                m_FadeTime += Time.deltaTime;
                float fac = GetFadeCurveValue(m_FadeTime / FadeDuration);
                m_AlphaBase = Mathf.Lerp(1, 0, fac);

                if (m_AlphaBase <= 0)
                {
                    IsVisible = false;
                    m_FadeTime = 0;
                    m_AlphaBase = 0;
                }
            }
            IsHitLast = true;
        }
        else
        {
            if (IsHitLast)
                m_FadeTime = m_AlphaBase * FadeDuration;

            if (m_AlphaBase < 1)
            {
                m_FadeTime += Time.deltaTime;
                float fac = GetFadeCurveValue(m_FadeTime / FadeDuration);
                m_AlphaBase = Mathf.Lerp(0, 1, fac);

                if (m_AlphaBase >= 1)
                {
                    m_FadeTime = 0;
                    m_AlphaBase = 1;
                }
            }
            IsVisible = true;
            IsHitLast = false;
        }
        Debug.DrawLine(position, m_GameCamera.transform.position, IsHitLast ? Color.red : Color.white);
    }

判斷視椎體的代碼也很簡(jiǎn)單

    /// <summary>
    /// 判斷一個(gè)點(diǎn)是否處于視椎體內(nèi)
    /// </summary>
    /// <param name="pos">世界坐標(biāo)下的位置坐標(biāo)</param>
    /// <returns>布爾值,在顯示范圍為true</returns>
    public bool IsVisableInCamera(Vector3 pos)
    {
        //轉(zhuǎn)化為視角坐標(biāo)
        Vector3 viewPos = m_GameCamera.WorldToViewportPoint(pos);
        // z<0代表在相機(jī)背后
        if (viewPos.z < 0) return false;
        //太遠(yuǎn)了!看不到了!
        if (viewPos.z > m_GameCamera.farClipPlane)
            return false;
        // x,y取值在 0~1之外時(shí)代表在視角范圍外;
        if (viewPos.x < 0 || viewPos.y < 0 || viewPos.x > 1 || viewPos.y > 1) return false;
        return true;
    }

另一個(gè)文件則是FlareBatch,里面有一個(gè)mesh頂點(diǎn)合并的輔助函數(shù),而FlareBatch函數(shù)主要的就是UpdateGeometry方法,里面是用于更新幾何體。

    void UpdateGeometry(FlareSource source, List<Vertexhelper> meshes)
    {
        // Vector3 viewportPos = source.ViewportPosition;
        if (!source.IsVisible) //不顯示,將不再更新
            return;

        Vector2 center = source.Center; // 光暈“中心”,后續(xù)這個(gè)值可以變
        Vector2 flareSpacePos = ViewportToPerspFlareSpace(source.ViewportPosition); // 光源在flare space的坐標(biāo)
        Vector2 flareVec = flareSpacePos - center;
        float angle = Mathf.Atan2(flareSpacePos.y, flareSpacePos.x) * Mathf.Rad2Deg;
        float fac = 1;
        if (source.SpreadMaximum != 0)
            fac = Mathf.Clamp(flareVec.magnitude / source.SpreadMaximum, 0, 1); // 擴(kuò)散比例,離中心越遠(yuǎn),顯得越大

        //List<Vertexhelper> meshes = new List<Vertexhelper>();
        //遍歷創(chuàng)建的每一個(gè)資源,根據(jù)配置生成頂點(diǎn)信息
        for (int i = 0; i < source.Flares.Count; ++i)
        {
            Flare flare = source.Flares[i];
            if (!flare.IsActive)
                continue;

            Vector2 size = source.GetFlareSize(flare);
            float scale = Mathf.Lerp(flare.ScaleRange.x, flare.ScaleRange.y, source.GetScaleCurveValue(fac));
            float alpha = Mathf.Lerp(1, 0, source.GetAlphaCurveValue(fac));

            //實(shí)例化一個(gè)頂點(diǎn)數(shù)據(jù)類
            Vertexhelper vh = new Vertexhelper();

            //生成顏色
            Color col = flare.Color;
            col.a *= source.AlphaBase;
            col.a *= alpha;
            vh.color = new Color[] { col, col, col, col };

            //計(jì)算出位置
            Vector2 pos = flareSpacePos - flare.DistanceAspect * flareVec * source.SpreadAmount;
            Vector3 _pos = new Vector3(pos.x, pos.y, 0);

            Vector2 halfSize = size / 2;
            
            vh.vertices = new Vector3[]
            {
                Vec3(-halfSize.x, -halfSize.y, -i*0.01f),
                Vec3(-halfSize.x, halfSize.y, -i*0.01f),
                Vec3(halfSize.x, halfSize.y, -i*0.01f),
                Vec3(halfSize.x, -halfSize.y, -i*0.01f),
            };
            //對(duì)每個(gè)點(diǎn)的位置進(jìn)行縮放旋轉(zhuǎn)和偏移
            for (int j = 0; j < vh.vertices.Length; ++j)
            {
                vh.vertices[j] *= scale;
                vh.vertices[j] = Quaternion.Euler(0, 0, flare.Rotation) * vh.vertices[j];
                if (flare.RotateWith)
                    vh.vertices[j] = Quaternion.Euler(0, 0, angle) * vh.vertices[j];
                vh.vertices[j] += _pos;

                vh.vertices[j].z += 3;

                vh.vertices[j] = m_GameCamera.ViewportToWorldPoint(PerspFlareSpaceToViewport(vh.vertices[j]));
                // vh.vertices[j] -= m_GameCamera.transform.position;
            }

            //uv
            vh.uv = new Vector2[]
            {
                Vec2(0,0),
                Vec2(0,1),
                Vec2(1,1),
                Vec2(1,0),
            };
            for (int j = 0; j < vh.uv.Length; ++j)
            {
                Vector4 scaleOffset = flare.Atlas.GetScaleOffset(flare.Index);
                vh.uv[j] *= new Vector2(scaleOffset.x, scaleOffset.y);
                vh.uv[j] += new Vector2(scaleOffset.z, scaleOffset.w);
            }

            //面的索引
            vh.triangles = new int[] { 0, 1, 2, 0, 2, 3 };

            meshes.Add(vh);
        }
    }
    /// <summary>
    /// 將viewport坐標(biāo)轉(zhuǎn)換到“透視flare空間”
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    Vector3 ViewportToPerspFlareSpace(Vector3 pos)
    {
        //將視線空間的位置,轉(zhuǎn)換到了以中心為0 0, -1到1的空間
        pos += new Vector3(-0.5f, -0.5f, 0);
        pos.x *= m_GameCamera.aspect; //橫軸乘以寬高比
        pos.y *= 1; //縱軸
        pos.z = 0;
        pos *= 2;
        return pos;
    }

    /// <summary>
    /// 將“透視flare空間”坐標(biāo)轉(zhuǎn)換到viewport空間
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    Vector3 PerspFlareSpaceToViewport(Vector3 pos)
    {
        pos /= 2;
        pos.x /= m_GameCamera.aspect;
        pos += new Vector3(0.5f, 0.5f, 0);
        return pos;
    }

主要修改的地方,我不再使用正交相機(jī),而是直接將模型繪制使用的相機(jī)前面。所以之前是有一個(gè)光暈空間,我繼續(xù)保留了這個(gè)空間,在此空間處理完成以后,再轉(zhuǎn)換回主相機(jī)視角空間,然后將頂點(diǎn)從視角空間重新轉(zhuǎn)換回世界空間。這樣,主相機(jī)拿到頂點(diǎn)信息,也能正確渲染出來數(shù)據(jù)了。文章來源地址http://www.zghlxwxcb.cn/news/detail-435777.html

到了這里,關(guān)于在unity 2020 urp版本中實(shí)現(xiàn) LensFlare功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • Unity 場(chǎng)景烘培 ——LensFlare鏡頭光暈(三)

    Unity 場(chǎng)景烘培 ——LensFlare鏡頭光暈(三)

    提示:文章有錯(cuò)誤的地方,還望諸位大神指出! 一般情況下都會(huì)忽略的東西,鏡頭光暈。理論上不加鏡頭光暈,也不會(huì)有什么影響,但是有時(shí)候?yàn)榱俗非笠恍┨厥獾囊笮Ч?,也?huì)加上鏡頭光暈。 比如 下圖這種效果: 鏡頭光暈 (Lens Flares) 是模擬相機(jī)鏡頭內(nèi)的折射光線的效果

    2024年02月05日
    瀏覽(19)
  • unity urp 實(shí)現(xiàn)絲綢渲染

    unity urp 實(shí)現(xiàn)絲綢渲染

    首先看一下實(shí)際上真實(shí)的效果 再來一張 這是專門去找的。 可以看到絲綢渲染使用了各向異性的GGX去實(shí)現(xiàn),有點(diǎn)仿頭發(fā)的感覺,接下來看一下怎么實(shí)現(xiàn)的。 首先,準(zhǔn)備實(shí)現(xiàn)雙向反射率分布函數(shù)(BRDF)的DVF項(xiàng)。 D項(xiàng)使用UE里面的各項(xiàng)異性GGX: V項(xiàng)使用配合D項(xiàng)的Vis_SmithJointAniso F項(xiàng)

    2024年02月10日
    瀏覽(21)
  • Unity中URP下實(shí)現(xiàn)深度貼花

    Unity中URP下實(shí)現(xiàn)深度貼花

    在游戲中,有很多用到貼畫的地方。比如:地面污漬、地面噴漆、地面血跡、魔法陣、地裂等效果。 我們?cè)谶@篇文章中,來用深度圖實(shí)現(xiàn)一下貼畫的效果。 使用之前的棋盤格設(shè)置一個(gè)場(chǎng)景,且在場(chǎng)景中,增加一些物體,來給貼花吸附。 然后,我們創(chuàng)建一個(gè)面片用于承載貼花

    2024年01月21日
    瀏覽(18)
  • 【VR】【unity】如何在VR中實(shí)現(xiàn)遠(yuǎn)程投屏功能?

    【VR】【unity】如何在VR中實(shí)現(xiàn)遠(yuǎn)程投屏功能?

    目前主流的VD應(yīng)用,用于娛樂很棒,但是用于工作還是無法效率地操作鍵鼠。用虛擬鍵盤工作則顯然是不現(xiàn)實(shí)的。為了讓自己的頭顯能夠起到小面積代替多顯示屏的作用,自己動(dòng)手開發(fā)投屏VR應(yīng)用。 先實(shí)現(xiàn)C#的投屏應(yīng)用。 研究如何將C#投屏應(yīng)用用Unity 3D項(xiàng)目轉(zhuǎn)寫。 將Unity3D項(xiàng)目

    2024年02月08日
    瀏覽(45)
  • 【Unity3D小功能】Unity3D中實(shí)現(xiàn)UI擦除效果、刮刮卡功能

    【Unity3D小功能】Unity3D中實(shí)現(xiàn)UI擦除效果、刮刮卡功能

    推薦閱讀 CSDN主頁(yè) GitHub開源地址 Unity3D插件分享 簡(jiǎn)書地址 我的個(gè)人博客 大家好,我是佛系工程師 ☆恬靜的小魔龍☆ ,不定時(shí)更新Unity開發(fā)技巧,覺得有用記得一鍵三連哦。 使用Unity3D實(shí)現(xiàn)UI的擦拭效果、刮刮卡功能的效果實(shí)現(xiàn)方式比較多,比如說用Shader、Texture渲染都是可以

    2024年02月04日
    瀏覽(158)
  • 【Unity URP】風(fēng)格化草地01:實(shí)現(xiàn)方法概述

    【Unity URP】風(fēng)格化草地01:實(shí)現(xiàn)方法概述

    寫在前面 最近本專業(yè)開始多很多事情了,要開始建模寫論文了(不然研究生畢不了業(yè)),TA方面的學(xué)習(xí)進(jìn)度更慢了,,so sad。 廢話不多說,這篇文章其實(shí)是個(gè)小總結(jié),畢竟學(xué)習(xí)新東西就是先要當(dāng)一只copy cat(不是)。 至于草地交互,把草地做出來再說! 2021.5 【Unity】ShaderG

    2023年04月21日
    瀏覽(46)
  • 【Unity】URP屏幕后處理UI模糊效果實(shí)現(xiàn)

    【Unity】URP屏幕后處理UI模糊效果實(shí)現(xiàn)

    ?這里Canvas(1)設(shè)置為Overlay能渲染出指定UI高清,其他UI模糊,然而這做法非常不好,如果此時(shí)再打開UI 以及 關(guān)閉模糊效果 要將這些置頂U(kuò)I 恢復(fù)到原本Canvas里,也就是要管理2套Canvas Shader代碼實(shí)現(xiàn)模糊? 1個(gè)Canvas和2個(gè)攝像機(jī) 主要以上內(nèi)容,實(shí)際上就是因?yàn)镽ender Pass Event是只能Af

    2024年02月10日
    瀏覽(24)
  • Unity中URP下的菲涅爾效果實(shí)現(xiàn)(URP下的法線和視線向量怎么獲?。? decoding=

    Unity中URP下的菲涅爾效果實(shí)現(xiàn)(URP下的法線和視線向量怎么獲取)

    我們?cè)谶@篇文章中,了解一下URP中Shader怎么實(shí)現(xiàn)菲涅爾效果,同時(shí)學(xué)習(xí)一下URP下怎么獲取法線 和 視線向量。 Lambert光照模型公式: Diffuse = Ambient + Kd * LightColor * max(0,dot(N,L)) 實(shí)現(xiàn)燈光照射中間亮 周圍暗的效果,核心是dot(N,L) Unity中Shader的Lambert光照的實(shí)現(xiàn) 光照效果下, 視線單

    2024年02月02日
    瀏覽(19)
  • 在unity中實(shí)現(xiàn)視頻的暫停播放和拖拽進(jìn)度條的功能

    #Unity中實(shí)現(xiàn)視頻的暫停播放和拖拽進(jìn)度條的功能 在UI上,視頻包含一個(gè)播放、暫停和停止按鈕,以及一個(gè)拖動(dòng)條,可以使用這些按鈕來控制視頻的播放,使用拖動(dòng)進(jìn)度條來調(diào)整視頻的播放進(jìn)度。 1.建立一個(gè)UI,導(dǎo)入視頻素材,然后將視頻拖放到場(chǎng)景中。 2.建立一個(gè)Canvas對(duì)象作

    2024年02月07日
    瀏覽(82)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包