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

Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)

這篇具有很好參考價(jià)值的文章主要介紹了Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 概述

在前兩篇文章《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(1)》《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(2)》分別介紹了通過簡單的頂點(diǎn)著色器+片元著色器,以及通過表面著色器實(shí)現(xiàn)GPU實(shí)例化的過程。而在Unity的官方文檔Creating shaders that support GPU instancing里,也提供了一個(gè)GPU實(shí)例化的案例,這里就詳細(xì)論述一下。

2. 詳論

2.1. 自動(dòng)實(shí)例化

一個(gè)有意思的地方在于,Unity提供的標(biāo)準(zhǔn)材質(zhì)支持自動(dòng)實(shí)例化,而不用像《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(1)》《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(2)》那樣額外編寫腳本和Shader。并且,會(huì)自動(dòng)將transform,也就是模型矩陣作為每個(gè)實(shí)例的屬性。

照例,還是編寫一個(gè)腳本掛到一個(gè)空的GameObject對象上:

using UnityEngine;

public class Note8Main : MonoBehaviour
{
    public Mesh mesh;
    public Material material;
    public int instanceCount = 5000;

    // Start is called before the first frame update
    void Start()
    {
        MaterialPropertyBlock props = new MaterialPropertyBlock();
      
        for (int i = 0; i < instanceCount; i++)
        {
            GameObject go = new GameObject();
            go.name = i.ToString();

            MeshFilter mf = go.AddComponent<MeshFilter>();
            mf.mesh = mesh;

            MeshRenderer mr = go.AddComponent<MeshRenderer>();
            mr.material = material;
            
            go.transform.position = Random.insideUnitSphere * 5;
            go.transform.eulerAngles = new Vector3(Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f));
            float s = Random.value;
            go.transform.localScale = new Vector3(s, s, s);
       
            go.transform.parent = gameObject.transform;
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

這個(gè)腳本的意思是,給掛接的GameObject下新建很多GameObject,它們使用我們傳入的Mesh和Material,但是位置、姿態(tài)和大小是隨機(jī)的。傳入的Mesh使用Unity自帶的膠囊體,Material使用Unity的標(biāo)準(zhǔn)材質(zhì)。運(yùn)行結(jié)果如下:

Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)

這個(gè)時(shí)候Unity還沒有自動(dòng)實(shí)例化,打開Frame Debug就可以看到:
Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)

這個(gè)時(shí)候我們可以在使用的材質(zhì)上勾選打開實(shí)例化的選項(xiàng):
Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)

再次運(yùn)行,就會(huì)在Frame Debug看到Unity實(shí)現(xiàn)了自動(dòng)實(shí)例化,繪制的批次明顯減少,并且性能會(huì)有所提升:
Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)

可以看到確實(shí)是自動(dòng)進(jìn)行實(shí)例化繪制了,但是這種方式卻似乎存在實(shí)例化個(gè)數(shù)的上限,所有的實(shí)例化數(shù)據(jù)還是分成了好幾個(gè)批次進(jìn)行繪制。與《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(1)》《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(2)》提到的通過底層接口Graphic進(jìn)行實(shí)例化繪制相比,效率還是要低一些。

2.2. MaterialPropertyBlock

自動(dòng)實(shí)例化只能將transform,也就是模型矩陣作為每個(gè)實(shí)例的屬性。如果需要增加自己的實(shí)例屬性,就需要使用MaterialPropertyBlock,也就是材質(zhì)屬性塊。

修改上面的腳本:

using UnityEngine;

public class Note8Main : MonoBehaviour
{
    public Mesh mesh;
    public Material material;
    public int instanceCount = 5000;

    // Start is called before the first frame update
    void Start()
    {
        MaterialPropertyBlock props = new MaterialPropertyBlock();
      
        for (int i = 0; i < instanceCount; i++)
        {
            GameObject go = new GameObject();
            go.name = i.ToString();

            MeshFilter mf = go.AddComponent<MeshFilter>();
            mf.mesh = mesh;

            MeshRenderer mr = go.AddComponent<MeshRenderer>();
            mr.material = material;

            float r = Random.Range(0.0f, 1.0f);
            float g = Random.Range(0.0f, 1.0f);
            float b = Random.Range(0.0f, 1.0f);
            props.SetColor("_Color", new Color(r, g, b));
            mr.SetPropertyBlock(props);

            go.transform.position = Random.insideUnitSphere * 5;
            go.transform.eulerAngles = new Vector3(Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f));
            float s = Random.value;
            go.transform.localScale = new Vector3(s, s, s);
       
            go.transform.parent = gameObject.transform;
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

腳本使用的材質(zhì),其使用的Shader如下,可以直接在Standard Surface Shader的基礎(chǔ)上改:

Shader "Custom/HiddenSurfaceIntanceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        //fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
			UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            //fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

關(guān)鍵的代碼在于Unity內(nèi)置宏UNITY_INSTANCING_BUFFER_START和UNITY_INSTANCING_BUFFER_END、UNITY_DEFINE_INSTANCED_PROP定義了實(shí)例化屬性,在著色器中,通過內(nèi)置宏UNITY_ACCESS_INSTANCED_PROP來獲取這個(gè)屬性值。這個(gè)實(shí)例化屬性也就是腳本代碼中MaterialPropertyBlock傳入的顏色值。

查看Unity Shader源代碼,這四個(gè)用于實(shí)例化的宏封裝的是一個(gè)cbuffer數(shù)組,cbuffer就是hlsl的常量緩沖區(qū):

#define UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(name)  cbuffer name {
#define UNITY_INSTANCING_CBUFFER_SCOPE_END          }

#define UNITY_INSTANCING_BUFFER_START(buf)      UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf) struct {
#define UNITY_INSTANCING_BUFFER_END(arr)        } arr##Array[UNITY_INSTANCED_ARRAY_SIZE]; UNITY_INSTANCING_CBUFFER_SCOPE_END
#define UNITY_DEFINE_INSTANCED_PROP(type, var)  type var;
#define UNITY_ACCESS_INSTANCED_PROP(arr, var)   arr##Array[unity_InstanceID].var

運(yùn)行的結(jié)果如下:
Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)

可以看到除了紋理,每一個(gè)膠囊體還獲取了隨機(jī)賦予給材質(zhì)的顏色,也就是我們設(shè)置的顏色成為了實(shí)例化屬性數(shù)據(jù)。MaterialPropertyBlock主要由Graphics.DrawMesh和Renderer.SetPropertyBlock使用,在希望繪制具有相同材質(zhì),但屬性略有不同的多個(gè)對象時(shí)可使用它。

個(gè)人認(rèn)為使用MaterialPropertyBlock自動(dòng)實(shí)例化性能比不上使用Graphics.DrawMeshInstancedIndirect(),但是它有個(gè)優(yōu)點(diǎn)是實(shí)例化的要求沒那么高,Graphics.DrawMeshInstancedIndirect()要求使用同一mesh,同一貼圖;但是MaterialPropertyBlock沒這個(gè)要求,只要是同一材質(zhì),任何屬性不一樣都可以用,在減少繪制批次的同時(shí)還能減少材質(zhì)的個(gè)數(shù)。

3. 參考

  1. 《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(1)》
  2. 《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(2)》
  3. Creating shaders that support GPU instancing
  4. MaterialPropertyBlock

具體實(shí)現(xiàn)代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-421138.html

到了這里,關(guān)于Unity3D學(xué)習(xí)筆記8——GPU實(shí)例化(3)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(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制作FPS游戲的學(xué)習(xí)筆記————人物移動(dòng)、利用鼠標(biāo)實(shí)現(xiàn)視角轉(zhuǎn)動(dòng)和人物跳躍(含人物懸空不掉落修復(fù))

    用Unity3D制作FPS游戲的學(xué)習(xí)筆記————人物移動(dòng)、利用鼠標(biāo)實(shí)現(xiàn)視角轉(zhuǎn)動(dòng)和人物跳躍(含人物懸空不掉落修復(fù))

    前言: 這是我第一次發(fā)布文章,此文章僅供參考,我也是剛學(xué)習(xí)接觸untiy,在制作項(xiàng)目的過程中將有用的寫下來記一記,以便自己之后能回頭看看,各位大佬輕點(diǎn)噴,若有錯(cuò)誤請麻煩積極提謝謝各位。該文章參考自B站UP主蔡先森_rm-rf發(fā)布的 【第一人稱射擊游戲教程2.0【已完結(jié)

    2024年04月27日
    瀏覽(24)
  • Unity3D學(xué)習(xí)記錄02——PloyBrush場景搭建

    Unity3D學(xué)習(xí)記錄02——PloyBrush場景搭建

    首先在Window-Package Manager里面搜索Poly Brush,下載后將URP的Shader樣例導(dǎo)入 ?導(dǎo)入后Asset文件夾下會(huì)有Sample的文件夾,在菜單欄 Tools-PolyBrush-PolyBrush Window 打開窗口 這個(gè)窗口最上面的五個(gè),第一個(gè)是用來調(diào)整地形高低的,第二個(gè)是進(jìn)行柔化場景的,第三個(gè)是調(diào)整顏色的, 第四個(gè)可以

    2024年02月08日
    瀏覽(96)
  • GameFrameWork框架(Unity3D)使用筆記(八) 實(shí)現(xiàn)場景加載進(jìn)度條

    GameFrameWork框架(Unity3D)使用筆記(八) 實(shí)現(xiàn)場景加載進(jìn)度條

    ? ? ? ? 游戲在轉(zhuǎn)換場景的時(shí)候,需要花費(fèi)時(shí)間來加載相關(guān)的資源。而這個(gè)過程往往因?yàn)橛螒驁鼍暗囊?guī)模和復(fù)雜度以及玩家電腦配置的原因花費(fèi)一小段時(shí)間(雖然這個(gè)項(xiàng)目里用不到)。 ? ? ? ? 所以,如果這一小段時(shí)間,畫面就卡在這里,啥也做不了,玩家也不知道啥時(shí)候能

    2024年02月02日
    瀏覽(25)
  • Unity3D學(xué)習(xí)-Day01-環(huán)境搭建及學(xué)習(xí)資源導(dǎo)入

    Unity3D學(xué)習(xí)-Day01-環(huán)境搭建及學(xué)習(xí)資源導(dǎo)入

    版本選擇可以最新,但是不能太老。因?yàn)楹芏噘Y源都只兼容后續(xù)版本。 總體步驟可以概括為: 一:安裝 1.下載 Unity Hub 2.下載最新的 Unity Personal 正式版 3.登錄 Unity ID 4.安裝編輯器時(shí),保持默認(rèn)安裝選項(xiàng)。(盡量選擇LTS的,我選擇的是2020.3.4) 二:導(dǎo)入 1.下載項(xiàng)目 2.使用 Unit

    2024年02月07日
    瀏覽(98)
  • Unity3D學(xué)習(xí) ② 物體的正常跳躍、二段跳、沖刺

    Unity3D學(xué)習(xí) ② 物體的正常跳躍、二段跳、沖刺

    限制物體在按下跳躍鍵的時(shí)候只能跳躍一次。而不是能夠無限跳躍。 具體實(shí)現(xiàn)思路是:給地面設(shè)置標(biāo)簽,檢測物體是否和地面碰撞。 1.1.1 地面(plane)標(biāo)簽設(shè)置 我們?yōu)榱宋矬w能夠正常跳躍,需要給地面添加一個(gè)標(biāo)簽。 點(diǎn)擊地面plane 再點(diǎn)擊 tag 下面的AddTag選項(xiàng) 在AddTag頁面點(diǎn)擊?

    2023年04月08日
    瀏覽(32)
  • Unity3D學(xué)習(xí)記錄03——Navigation智能導(dǎo)航地圖烘焙

    Unity3D學(xué)習(xí)記錄03——Navigation智能導(dǎo)航地圖烘焙

    首先還是在Package Manager中安裝AI Navigation 接著選擇我們場景的地面,右鍵,找到AI的NavMesh Surface,它會(huì)為我們的Ground添加一個(gè)叫NavMesh Surface的子物體 在Inspector窗口中可以看到它的詳細(xì)的參數(shù): 圖中的R,H為你人物的參數(shù),45°為你的人物可以爬行的最大角度 Agent Type里面可以改

    2024年02月08日
    瀏覽(28)
  • Unity3D學(xué)習(xí)記錄01:URP渲染管線以及3D游戲場景設(shè)置

    Unity3D學(xué)習(xí)記錄01:URP渲染管線以及3D游戲場景設(shè)置

    以下內(nèi)容所使用的版本均為Unity2022.3 先在 Window-Package Manager-Unity Registry 里面搜索添加Universal RP ? Unity中,創(chuàng)建渲染管線的方式為Asset文件夾下右鍵 Create-Readering-URP Asset(with Universal Asset) 會(huì)創(chuàng)建以下兩個(gè)Pipeline: ?接著在圖中的設(shè)置里添加這兩個(gè)渲染管線(Project Setting在Edit窗口下

    2024年02月08日
    瀏覽(102)
  • Unity3D學(xué)習(xí)記錄04——利用射線實(shí)現(xiàn)角色類似LOL的移動(dòng)

    Unity3D學(xué)習(xí)記錄04——利用射線實(shí)現(xiàn)角色類似LOL的移動(dòng)

    首先新建一個(gè)空白的GameObject,掛在一個(gè)MouseManager的腳本 實(shí)現(xiàn)思路: 通過獲取鼠標(biāo)點(diǎn)擊的位置,獲得該位置的信息,然后使角色移動(dòng)到該位置 MouseManager腳本的代碼如下: ? 代碼解釋: 先創(chuàng)建了一個(gè)Action類型的事件OnMouseClicked 這個(gè)是C#中事件的內(nèi)容,我們可以在滿足條件的時(shí)

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

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

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

    2024年02月12日
    瀏覽(31)
  • unity3D基礎(chǔ)操作之01--unity3d窗口界面介紹

    unity3D基礎(chǔ)操作之01--unity3d窗口界面介紹

    提示:文章寫完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔 1、Scene場景編輯窗口; 2、Game游戲運(yùn)行窗口; 3、Hierarchy場景物體列表窗口; 4、Project項(xiàng)目資源列表窗口; 5、Inspector屬性編輯列表窗口; 6、其他常調(diào)節(jié)窗口 在屏幕左上方為場景編輯窗口Scene,在場景編

    2024年02月06日
    瀏覽(31)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包