<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

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

      1. 概述

      在上一篇文章《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(1)》詳細(xì)介紹了Unity3d中GPU實(shí)例化的實(shí)現(xiàn),并且給出了詳細(xì)代碼。不過其著色器實(shí)現(xiàn)是簡單的頂點(diǎn)+片元著色器實(shí)現(xiàn)的。Unity提供的很多著色器是表面著色器,通過表面著色器,也是可以實(shí)現(xiàn)GPU實(shí)例化的。

      2. 詳論

      2.1. 實(shí)現(xiàn)

      首先,我們還是掛接與上篇文章一樣的腳本:

      using UnityEngine;
      
      [ExecuteInEditMode]
      public class Note7Main : MonoBehaviour
      {
          public Mesh mesh;
          public Material material;
          
          int instanceCount = 200;
          Bounds instanceBounds;
      
          ComputeBuffer bufferWithArgs = null;
          ComputeBuffer instanceParamBufferData = null;
          
          // Start is called before the first frame update
          void Start()
          {
              instanceBounds = new Bounds(new Vector3(0, 0, 0), new Vector3(100, 100, 100));
      
              uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
              bufferWithArgs = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
              int subMeshIndex = 0;
              args[0] = mesh.GetIndexCount(subMeshIndex);
              args[1] = (uint)instanceCount;
              args[2] = mesh.GetIndexStart(subMeshIndex);
              args[3] = mesh.GetBaseVertex(subMeshIndex);
              bufferWithArgs.SetData(args);
      
              InstanceParam[] instanceParam = new InstanceParam[instanceCount];
      
              for (int i = 0; i < instanceCount; i++)
              {
                  Vector3 position = Random.insideUnitSphere * 5;
                  Quaternion q = Quaternion.Euler(Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f), Random.Range(0.0f, 90.0f));
                  float s = Random.value;
                  Vector3 scale = new Vector3(s, s, s);
      
                  instanceParam[i].instanceToObjectMatrix = Matrix4x4.TRS(position, q, scale);
                  instanceParam[i].color = Random.ColorHSV();
              }
      
              int stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(InstanceParam));
              instanceParamBufferData = new ComputeBuffer(instanceCount, stride);
              instanceParamBufferData.SetData(instanceParam);
              material.SetBuffer("dataBuffer", instanceParamBufferData);
              material.SetMatrix("ObjectToWorld", Matrix4x4.identity);
          }
      
          // Update is called once per frame
          void Update()
          {
              if (bufferWithArgs != null)
              {
                  Graphics.DrawMeshInstancedIndirect(mesh, 0, material, instanceBounds, bufferWithArgs, 0);
              }
          }
      
          private void OnDestroy()
          {
              if (bufferWithArgs != null)
              {
                  bufferWithArgs.Release();
              }
      
              if (instanceParamBufferData != null)
              {
                  instanceParamBufferData.Release();
              }
          }
      }
      
      

      不過,腳本的材質(zhì)設(shè)置需要使用我們新的材質(zhì):

      imglink1

      這個(gè)材質(zhì)可以通過使用Standard Surface Shader作為我們修改的模板:

      imglink2

      修改后的著色器代碼如下:

      Shader "Custom/SimpleSurfaceIntanceShader"
      {
          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
      		#pragma target 4.5
      		#pragma multi_compile_instancing
              #pragma instancing_options procedural:setup     
              
      		struct InstanceParam
      		{			
      			float4 color;
      			float4x4 instanceToObjectMatrix;
      		};
      
      	#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
              StructuredBuffer<InstanceParam> dataBuffer;
          #endif
      
      		float4x4 ObjectToWorld;
      	
              sampler2D _MainTex;
      
              struct Input
              {
                  float2 uv_MainTex;
              };
      
              half _Glossiness;
              half _Metallic;
              fixed4 _Color;
      
      		void setup()
              {
              #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
                  InstanceParam data = dataBuffer[unity_InstanceID];
                  unity_ObjectToWorld = mul(ObjectToWorld, data.instanceToObjectMatrix);        
              #endif
              }
      
              void surf (Input IN, inout SurfaceOutputStandard o)
              {
                  // Albedo comes from a texture tinted by color
                  fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _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"
      }
      

      最后的顯示效果如下:
      imglink3

      2.2. 解析

      對(duì)比修改之前的著色器代碼:

      1. #pragma multi_compile_instancing的意思是給這個(gè)著色器增加了實(shí)例化的變體,也就是增加了諸如INSTANCING_ON PROCEDURAL_ON這樣的關(guān)鍵字,可以編譯實(shí)例化的著色器版本。
      2. #pragma instancing_options procedural:setup是搭配Graphics.DrawMeshInstancedIndirect 使用的,在頂點(diǎn)著色器階段開始時(shí),Unity會(huì)調(diào)用冒號(hào)后指定的setup()函數(shù)。
      3. setup()函數(shù)的意思是通過實(shí)例化Id也就是unity_InstanceID,找到正確的實(shí)例化數(shù)據(jù),并且調(diào)整Unity的內(nèi)置變量unity_ObjectToWorld——也就是模型矩陣。正如上一篇文章所言,GPU實(shí)例化的關(guān)鍵就在于模型矩陣的重新計(jì)算。在Unity API官方示例中,還修改了其逆矩陣unity_WorldToObject。

      3. 參考

      1. 《Unity3D學(xué)習(xí)筆記6——GPU實(shí)例化(1)》
      2. Graphics.DrawMeshInstancedIndirect
      3. Declaring and using shader keywords in HLSL
      4. Creating shaders that support GPU instancing

      具體實(shí)現(xiàn)代碼

      posted @ 2022-07-08 12:59  charlee44  閱讀(1075)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲一二三区精品美妇| 欧美xxxxhd高清| AV秘 无码一区二| 亚洲国产午夜精品福利| 日韩中文字幕综合第二页| 亚洲国产精品久久久久婷婷老年 | 麻豆精品久久久久久久99蜜桃| 久久天天躁夜夜躁狠狠 ds005.com| 国产成人无码精品亚洲| 国产高清小视频一区二区| 午夜福利国产精品视频| 国产超高清麻豆精品传媒麻豆精品| 国产91小视频在线观看| 日本高清免费不卡视频| 国产成人卡2卡3卡4乱码| 亚洲国产成人片在线观看无码| 日本成人午夜一区二区三区| 九九热99精品视频在线| 免费久久人人爽人人爽AV| 亚洲欧美日韩精品久久| 国产精品久久久久久久9999| 加勒比无码人妻东京热| 久久中文字幕无码专区| 热久久这里只有精品国产| 2020国产成人精品视频| 激,情四虎欧美视频图片| 亚洲男人AV天堂午夜在| 一区二区亚洲人妻av| 波多野结衣免费一区视频| 久久热精品视频在线视频| 噜妇插内射精品| 国产自拍一区二区三区在线| 色偷偷www.8888在线观看| 亚洲旡码欧美大片| 欧美xxxx精品另类| 精品国产AV无码一区二区三区| 色婷婷欧美在线播放内射| 吕梁市| 日韩有码av中文字幕| 国产精品一二三中文字幕| 欧美激情视频一区二区三区免费|