GPU Dissolve(GPU 消散)學習GPU Instancing

一:摘要

?

? ? ? ? 通過制作一個模型GPU消散效果來學習GPU Instancing 也就是實例化。

目標效果是楊超大佬文章《GPU shatter》里面的消散效果如圖:

?Tags:模型頂點分裂(Mesh Vertex Splitting), 實例化繪制(GPU Instancing Drawing),頂點運動(Vertex Anim)。

二:實現原理簡述

1:構建獲取數據:(instancing數據及模型信息)

? ? ? ? instancing數據需要的M矩陣,及自己想要傳遞的信息。

????????鹿模型mesh的頂點信息(mesh.vertices)和索引信息(mesh.triangles)以及面數(N)等信息,通過computerBuffer傳遞給材質。

2:構建instancing用的Triangle mesh(uv and?vertices)

3:Render

????????正常render鹿模型。

????????通過instancing繪制三角面,數量位置等信息已通過鹿模型獲取并傳遞,M矩陣也構建,隱藏可以得到另一個鹿模型。

4:構建動畫(compute shader anim? or vertex anim)

? ? ? ? 最簡單的就是使用vertex anim頂點動畫。方便易懂。

? ? ? ? compute shader動畫復雜一點但是性能應該會更好。

5:調參

? ? ? ? 把效果跳的稍微能看一點

三:實現

1:獲取模型數據

? 第一步:構建instaning數據(M矩陣構建)
    //創建對應結構體private struct MeshProperties{public Matrix4x4 drawMeshInsM;}//在初始化時構建M矩陣void OnEnable(){//num為面數for (int i = 0; i < num; i++){Vector3 pos = commonDrawGO.transform.position;pos.x = -pos.x;Quaternion rotation = commonDrawGO.transform.rotation;Vector3 scale = commonDrawGO.transform.localScale;//通過Transform信息構建對應模型tmpProperties.drawMeshInsM = Matrix4x4.TRS(pos, rotation, scale);properties[i] = tmpProperties;}// 通過computeBuffer傳參給Material//(使用computeBuffer是因為之前寫的用到了CS)meshPropertiesBuffer = new ComputeBuffer(num, meshPropertiesSize);meshPropertiesBuffer.SetData (properties);GPUDrawMat.SetBuffer("_Properties", meshPropertiesBuffer);}
第二步:構建mesh數據(頂點等)
        //mesh起始索引等信息uint[] args = new uint[5] { 0, 0, 0, 0, 0 };args[0] = (uint) mesh.GetIndexCount(0);args[1] = (uint) num;args[2] = (uint) mesh.GetIndexStart(0);args[3] = (uint) mesh.GetBaseVertex(0);//verticesGPUDrawMat.SetBuffer("_Properties", meshPropertiesBuffer);meshVerticesBuffer =new ComputeBuffer(TargetMesh.vertexCount, sizeof(float) * 3);meshVerticesBuffer.SetData(TargetMesh.vertices);GPUDrawMat.SetBuffer("_Vertices", meshVerticesBuffer);//triangles meshindicesBuffer =new ComputeBuffer(TargetMesh.triangles.Length, sizeof(int));meshindicesBuffer.SetData(TargetMesh.triangles);GPUDrawMat.SetBuffer("_Indices", meshindicesBuffer);

? ? ? ?2:構建Triangle

構建triangle時為了實現邊線亮中間暗淡效果,同時為了解決邊界鋸齒以及邊界線不等寬問題對uv進行了設計。看采樣貼圖及很好理解。

構建等邊三角形以及漸變貼圖解決(圖片是求美術大佬用sp生成的)

uv信息其實和頂點位置是一樣的,但是頂點位置原點在三角形中心,頂點uv在左下角。

private Mesh CreateTriMesh(){Mesh ans = new Mesh();//等邊三角形三點位置Vector3[] vertices = new Vector3[3];vertices[0] = new Vector3(0, 0.134f, 0) - Vector3.one * 0.5f;vertices[1] = new Vector3(1, 0.134f, 0) - Vector3.one * 0.5f;vertices[2] = new Vector3(0.5f, 1, 0) - Vector3.one * 0.5f;//等邊三角形三點UVVector2[] uvs = new Vector2[3];uvs[0] = new Vector2(0, 0.134f);uvs[1] = new Vector2(1, 0.134f);uvs[2] = new Vector2(0.5f, 1);int[] indices = new int[3];indices[0] = 0;indices[1] = 1;indices[2] = 2;ans.vertices = vertices;ans.uv = uvs;ans.triangles = indices;return ans;}

3:Render

第一步:C++++端
//instancing繪制
Graphics.DrawMeshInstancedIndirect(mesh, 0, GPUDrawMat, bounds, argsBuffer);
//另外一個走默認渲染就行
第二步:shader端(Vert And?Frag)
struct MeshProperties{float4x4 drawMeshInsM;};
StructuredBuffer<MeshProperties> _Properties;StructuredBuffer<float3> _Vertices;StructuredBuffer<int> _Indices;v2f vert(appdata_t i, uint instanceID: SV_InstanceID,uint vertexID : SV_VertexID) {//通過vertexID(0,1,2)和instanceID去_Vertices獲取真實的頂點信息//然后再乘上對應的M矩陣。float4 pos = mul(_Properties[instanceID].drawMeshInsM,float4(_Vertices[_Indices[vertexID + instanceID * 3.0]]  - center,1));//}

4:構建動畫及著色

這里直接以頂點動畫為例,其實也寫了computershader的但是寫的有瑕疵

第一步:構建旋轉函數(Rotate)

前面有提到原點再三角中心,所以先構建一個旋轉函數

經典的構建旋轉矩陣,先把點移動到原點,然后再乘以旋轉函數,再移動回自己的位置

            void Rotate(inout float4 vertex, float3 center, float3 around, float angle){float4x4 translation = float4x4(1, 0, 0, -center.x,0, 1, 0, -center.y,0, 0, 1, -center.z,0, 0, 0, 1);float4x4 translationT = float4x4(1, 0, 0, center.x,0, 1, 0, center.y,0, 0, 1, center.z,0, 0, 0, 1);around.x = -around.x;around = normalize(around);float s = sin(angle);float c = cos(angle);float ic = 1.0 - c;float4x4 rotation = float4x4(ic * around.x * around.x + c           , ic * around.x * around.y - s * around.z, ic * around.z * around.x + s * around.y, 0.0,ic * around.x * around.y + s * around.z, ic * around.y * around.y + c           , ic * around.y * around.z - s * around.x, 0.0,ic * around.z * around.x - s * around.y, ic * around.y * around.z + s * around.x, ic * around.z * around.z + c           , 0.0,0.0                                    , 0.0                                    , 0.0                                    , 1.0);vertex = mul(translationT, mul(rotation, mul(translation, vertex)));if((instanceID  + 1.0) % _BatchCount < _BatchCount * _Range){o.insID = 1;}else{o.insID = 0;}}
第二步:構建位移動畫(Pos And Scale)
                //構建中心點float3 center = _Vertices[_Indices[ instanceID * 3.0]] +_Vertices[_Indices[ instanceID * 3.0 + 1]] + _Vertices[_Indices[ instanceID * 3.0 + 2]];center /=3;//構建位置float4 pos = mul(_Properties[instanceID].drawMeshInsM,float4(_Vertices[_Indices[vertexID + instanceID * 3.0]]  - center,1));float4  pos1 = float4(_Vertices[_Indices[vertexID + instanceID * 3.0]],1);float3 around = normalize(GetRandomF3(pos.xyz));//float3(0.0,1.0,0.0);//動畫時間數據float statyTime = 0.4;float offsetIntensity = saturate((_BatchCount * _Range - (instanceID + 1.0)%_BatchCount)/10 -statyTime);float offsetIntensity1 = max(-statyTime,((_BatchCount * _Range - (instanceID + 1.0)%_BatchCount)/10 - statyTime)) + statyTime;offsetIntensity1 = min(offsetIntensity1 * 3 ,1.0);o.alphaLerp = offsetIntensity1;pos1.xyz = (1 - offsetIntensity) * pos1.xyz + offsetIntensity * center;float angle = _Speed * offsetIntensity;float3 positionWS = pos1;float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - positionWS);//around = viewDir;Rotate(pos1,center,around,angle );pos1 = mul(_Properties[instanceID].drawMeshInsM,pos1);pos1.y += offsetIntensity * _FlowSpeed * 0.1;

第四步:著色

沒有技巧全是smoothstep出來(按理不該這么做,性能很差)

                //frag  //使用insID來表示當前Tri是否還需要顯示是否消失half4 frag(v2f i, uint instanceID: SV_InstanceID) : SV_Target {float insID = i.insID;if(insID > 0.9){fixed4 col = tex2D(_MainTex, i.uv);float uuu1 = smoothstep(_Pos - _Width * 0.5 - _SmoothRange,_Pos - _Width * 0.5,col.r);float uuu2 = 1 - smoothstep(_Pos + _Width * 0.5 ,_Pos + _Width * 0.5+ _SmoothRange,col.r);float lines = uuu1 * uuu2;float tris = saturate((uuu2 - uuu1) * uuu2);return (lines * _LineColor + tris * _TriColor) * i.alphaLerp;}return 0;}

5:調參

????????略

四:總結

? ? ? ? 通過對模型進行拆分使用instancing進行重繪制,對模型數據結構以及instancing做了簡單了解,還有用到的頂點動畫較為簡單,以及有很多可以優化的地方,比如M矩陣其實都是一樣的,有些位置數據是沒用的可以省略等等等。

后續會補上源代碼鏈接

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39516.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39516.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39516.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開源可商業運營的ChatGpt網頁源碼v1.2.2

&#x1f916; 主要功能 后臺管理系統,可對用戶,Token,商品,卡密等進行管理 精心設計的 UI&#xff0c;響應式設計 極快的首屏加載速度&#xff08;~100kb&#xff09; 支持Midjourney繪畫和DALLE模型繪畫,GPT4等應用 海量的內置 prompt 列表&#xff0c;來自中文和英文 一鍵導…

【猿灰灰贈書活動 - 02期】- 【Java從入門到精通2023年7月最新(第7版)】

說明&#xff1a;博文為大家爭取福利&#xff0c;與清華大學出版社合作進行送書活動 圖書&#xff1a;《Java從入門到精通》 一、好書推薦 圖書介紹 Java入門經典&#xff0c;95萬Java程序員的入行選擇。配備升級版Java開發資源庫&#xff0c;在線大咖課在線答疑&#xff0c;學…

C語言 棱形圖案

目錄 一、問題分析 上部分&#xff1a; 下部分&#xff1a; 二、代碼演示 一、問題分析 如上圖所示&#xff0c;我們可以將棱形進行拆解&#xff0c;分為上下兩個部分。 上部分&#xff1a; 通過觀察&#xff0c;我們得到 單邊空格數 上半部分總行數 - 行數 - 1 …

Nginx詳解

1、高并發時代 單臺tomcat在理想情況下可支持的最大并發數量在200~500之間&#xff0c;如果大于這個數量可能會造成響應緩慢甚至宕機。 解決方案是通過多臺服務器分攤并發壓力&#xff0c;這不僅需要有多臺tomcat服務器&#xff0c;還需要一臺服務器專門用來分配請求。這既是…

Mysql - 配置Mysql主從復制-keepalived高可用-讀寫分離集群

目錄 高可用&#xff1a; 為什么需要高可用呢&#xff1f; 高可用的主要作用&#xff1a; keepalived是什么&#xff1f;它用在哪里&#xff1f; 什么是VRRP協議&#xff0c;它的作用是什么&#xff1f; 搭建一個基于keepalived的高可用Mysql主從復制讀寫分離集群 一、項…

MongoDB-yum安裝修改數據目錄后啟動失敗

# 問題 mongodb 進程權限默認會被 SELinux 管理&#xff0c;修改配置中默認 storage.dbPath 、systemLog.path 造成啟動失敗。 # 解決方案 ① 修改為默認路徑或重新安裝 /var/lib/mongo /var/log/mongodb/mongod.log② 臨時關閉 SELINUX 權限控制 setenforce 0③ 永久關閉 SE…

Vue Baidu Map--自定義點圖標bm-marker

自定義點圖標 將準備好的圖標放到項目中 使用import引入&#xff0c; 并在data中進行聲明 <script> import mapIconRed from ./vue-baidu-map/img/marker_red_sprite.png export default {data() {return {mapIconRed,}}, } </script>在<bm-marker>中加入參…

【Linux】進程的基本屬性|父子進程關系

個人主頁&#xff1a;&#x1f35d;在肯德基吃麻辣燙 我的gitee&#xff1a;Linux倉庫 個人專欄&#xff1a;Linux專欄 分享一句喜歡的話&#xff1a;熱烈的火焰&#xff0c;冰封在最沉默的火山深處 文章目錄 前言進程屬性1.進程PID和PPID2.fork函數創建子進程1&#xff09;為什…

C語言學習筆記---數據的存儲詳解

C語言程序設計筆記---015 C語言數據的存儲1、數據類型的意義1.1、unsigned與signed數據類型例程11.2、補碼與原碼相互轉換例程2 2、大小端的介紹2.1、大小端的例程12.2、大小端的例程2 --- 判斷當前編譯器環境屬于大端或小端 3、綜合練習題探究數據的存儲3.1、練習題13.2、練習…

自動化安裝系統(一)

系統安裝過程 加載boot loader加載啟動安裝菜單加載內核和initrd文件加載根系統運行anaconda的安裝向導 安裝光盤中與安裝相關的文件 安裝autofs啟動后會自動出現/misc目錄。 在虛擬機設置中添加CD/DVD&#xff0c;使用系統ISO文件&#xff0c;登錄系統后mount /dev/cdrom …

青翼科技自研2路250MSPS DA回放FMC子卡模塊

FMC150_V30是一款基于VITA57.1規范的2路125MSPS采樣率16位分辨率AD采集、2路250MSPS采樣率16位分辨率DA回放FMC子卡模塊。該模塊遵循VITA57.1規范&#xff0c;可直接與符合VITA57.1規范的FPGA載卡配合使用&#xff0c;板卡ADC器件采用ADI公司的AD9268芯片&#xff0c;板卡DAC器…

機器學習理論筆記(一):初識機器學習

文章目錄 1 前言&#xff1a;藍色是天的機器學習筆記專欄1.1 專欄初衷與定位1.2 本文主要內容 2 機器學習的定義2.1 機器學習的本質2.2 機器學習的分類 3 機器學習的基本術語4 探索"沒有免費的午餐"定理&#xff08;NFL&#xff09;5 結語 1 前言&#xff1a;藍色是天…

mac安裝vscode 配置git

1、安裝vscode 官網地址 下載mac穩定版安裝很慢的解決辦法 (轉自) mac電腦如何解決下載vscode慢的問題 選擇谷歌瀏覽器右上角的3個點&#xff0c;選擇下載內容&#xff0c;右鍵選擇復制鏈接地址&#xff0c;在新窗口粘貼地址&#xff0c; 把地址中的一段替換成下面的vscode.cd…

項目配置中心介紹

目錄 什么是配置中心 為什么要有配置中心 配置中心的做法&#xff08;讀取和通知&#xff09; 配置中心優點: 常用的配置中心中間件 什么是配置中心 配置中心就是用來管理項目當中所有配置的系統&#xff0c;也是微服務系統當中不可或缺的一部分。項目的配置文件不放到本地…

Servlet+JDBC實戰開發書店項目講解第四篇:登錄實現

ServletJDBC 實戰開發書店項目講解第四篇&#xff1a;登錄注冊實現 在本篇博客中&#xff0c;我們將繼續講解 ServletJDBC 實戰開發書店項目。這次我們將重點講解如何實現登錄和注冊功能。 1. 創建數據庫表 首先&#xff0c;我們需要在數據庫中創建兩個表&#xff0c;一個用…

[C++] 模板template

目錄 1、函數模板 1.1 函數模板概念 1.2 函數模板格式 1.3 函數模板的原理 1.4 函數模板的實例化 1.4.1 隱式實例化 1.4.2 顯式實例化 1.5 模板參數的匹配原則 2、類模板 2.1 類模板的定義格式 2.2 類模板的實例化 講模板之前呢&#xff0c;我們先來談談泛型編程&am…

Qt讀寫Excel--QXlsx編譯為靜態庫2

1、概述&#x1f954; 在使用QXlsx時由于源碼文件比較多&#xff0c;如果直接加載進項目里面&#xff0c;會增加每次編譯的時間&#xff1b; 直接將源碼加載進項目工程中&#xff0c;會導致項目文件非常多&#xff0c;結構變得更加臃腫&#xff1b; 所以在本文中將會將QXlsx編譯…

骨傳導耳機頭暈是怎么回事?骨傳導耳機好不好

骨傳導耳機在音頻傳輸上采用了不同于傳統耳機的方式。它們通過將聲音振動傳遞到顳骨&#xff0c;然后通過骨骼傳導到內耳&#xff0c;從而使用戶能夠聽到音樂或聲音。 然而&#xff0c;有些人在使用骨傳導耳機時可能會感到頭暈。這可能與以下幾個原因有關&#xff1a; 1、剛開…

prometheusalert區分告警到不同釘釘群

方法一 修改告警規則 - alert: cpu使用率大于88%expr: instance:node_cpu_utilization:ratio * 100 > 88for: 5mlabels:severity: criticallevel: 3kind: CpuUsageannotations:summary: "cpu使用率大于85%"description: "主機 {{ $labels.hostname }} 的cp…

99%的Python用戶都不知道的f-string隱秘技巧

f-string想必很多Python用戶都基礎性的使用過&#xff0c;作為Python3.6版本開始引入的特性&#xff0c;通過它我們可以更加方便地向字符串中嵌入自定義內容&#xff0c;但f-string真正蘊含的功能遠比大多數用戶知道的要豐富&#xff0c;今天我們就來一起get它們~ 「最基礎用法…