第十天 Shader編程:編寫簡單表面著色器 Addressable資源管理系統 DOTS(面向數據技術棧)入門

前言

作為Unity初學者,在實現復雜場景時經常會遇到性能瓶頸。本文將帶你通過四個關鍵技術的實戰學習,掌握現代Unity開發的核心優化方案:

  1. Shader編程 - 編寫表面著色器控制物體渲染
  2. Addressable系統 - 實現高效資源管理
  3. DOTS技術棧 - 解鎖百萬級物體渲染能力
  4. 綜合實戰 - 大規模動態場景優化演示

全程包含可運行的代碼示例,所有案例基于Unity 2022.3 LTS版本。


第一部分:Shader編程入門

1.1 表面著色器基礎結構

Shader "Custom/SimpleDiffuse" {  Properties {  _MainTex ("Texture", 2D) = "white" {}  _Color ("Color", Color) = (1,1,1,1)  }  SubShader {  Tags { "RenderType"="Opaque" }  CGPROGRAM  #pragma surface surf Lambert  struct Input {  float2 uv_MainTex;  };  sampler2D _MainTex;  fixed4 _Color;  void surf (Input IN, inout SurfaceOutput o) {  fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;  o.Albedo = c.rgb;  o.Alpha = c.a;  }  ENDCG  }  FallBack "Diffuse"  
}  

代碼解析

  • #pragma surface surf Lambert 聲明表面著色器和使用Lambert光照模型
  • Input結構體定義UV坐標輸入
  • surf函數處理表面顏色計算

1.2 擴展高光效果

#pragma surface surf BlinnPhong  // 在SurfaceOutput結構中添加:  
float3 Specular;  
float Gloss;  // 在surf函數中添加:  
o.Specular = _SpecColor.rgb;  
o.Gloss = _Shininess;  

1.3 實戰練習

在場景中創建材質球并應用著色器,通過腳本動態修改顏色參數:

public class ShaderController : MonoBehaviour {  [SerializeField] Material targetMaterial;  void Update() {  float hue = Mathf.PingPong(Time.time, 1);  targetMaterial.SetColor("_Color", Color.HSVToRGB(hue, 0.8f, 0.8f));  }  
}  

第二部分:Addressable資源管理

2.1 系統配置流程

  1. 安裝Package Manager中的Addressables插件
  2. 創建Addressables Groups管理資源
  3. 設置遠程資源加載路徑(可選)

2.2 核心API示例

// 異步加載資源  
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("Prefabs/Enemy");  
handle.Completed += OnEnemyLoaded;  // 場景加載  
Addressables.LoadSceneAsync("Level2");  // 內存釋放  
Addressables.Release(handle);  

2.3 最佳實踐

  • 使用Label分類管理資源
  • 結合Content Update構建增量包
  • 通過Analyze工具檢測冗余

第三部分:DOTS技術入門

3.1 ECS核心概念

public struct RotationSpeed : IComponentData {  public float RadiansPerSecond;  
}  public class RotationSystem : SystemBase {  protected override void OnUpdate() {  float deltaTime = Time.DeltaTime;  Entities.ForEach((ref Rotation rotation,  in RotationSpeed speed) => {  rotation.Value = math.mul(rotation.Value,  quaternion.AxisAngle(math.up(), speed.RadiansPerSecond * deltaTime));  }).ScheduleParallel();  }  
}  

3.2 Burst編譯器加速

[BurstCompile]  
public struct MoveJob : IJobEntity {  public float DeltaTime;  void Execute(ref Translation translation, in MoveSpeed speed) {  translation.Value += new float3(0, 0, speed.Value * DeltaTime);  }  
}  // 在System中調度:  
new MoveJob { DeltaTime = Time.DeltaTime }.ScheduleParallel();  

3.3 Hybrid Renderer配置

  1. 創建Conversion Settings將GameObject轉為Entity
  2. 添加RenderMesh組件
  3. 配置LODGroup轉換規則

第四部分:綜合實戰 - 百萬物體渲染

4.1 場景搭建步驟

  1. 創建基礎Entity預制體
  2. 編寫生成器腳本:
public class Spawner : MonoBehaviour {  public GameObject Prefab;  public int Count = 1000000;  void Start() {  var settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, null);  var entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(Prefab, settings);  var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;  for (int i = 0; i < Count; i++) {  var entity = entityManager.Instantiate(entityPrefab);  var position = new Unity.Mathematics.float3(Random.Range(-50,50), 0, Random.Range(-50,50));  entityManager.SetComponentData(entity, new Translation { Value = position });  }  }  
}  

4.2 性能優化技巧

  • 使用Chunk Component優化內存布局
  • 結合GPU Instancing
  • 配置合適的LOD策略

4.3 性能對比數據

方案10,000物體幀率1,000,000物體幀率
傳統GameObject24 FPS崩潰
DOTS+Hybrid60 FPS52 FPS

結語與進階建議

通過本文的學習,你已經掌握了:

  1. 基礎Shader開發能力
  2. 資源生命周期管理方法
  3. DOTS高性能編程范式
  4. 大規模場景優化實戰經驗

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

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

相關文章

項目自動化測試

一.設計測試用例(細致全面) 二.先引入所需要的pom.xml依賴 1.selenium依賴 2.webdrivermanager依賴 3.commons-io依賴 編寫測試用例–按照頁面對用例進行劃分,每個頁面是Java文件,頁面下的所有用例統一管理 三.common包(放入公用包) 類1utils 可以調用driver對象,訪問url …

ap無法上線問題定位(交換機發包沒有剝掉pvid tag)

一中學&#xff0c;新開的40臺appoe交換機核心交換機旁掛ac出口路由的組網&#xff0c;反饋ap無法上線&#xff0c;讓協助解決。 組網如下&#xff1a; 排查過程&#xff1a; 檢查ac的配置&#xff0c;沒有發現問題 發現配置沒有問題&#xff0c;vlan1000配置子接口&#xff…

第十七屆山東省職業院校技能大賽 中職組網絡建設與運維賽項

第十七屆山東省職業院校技能大賽 中職組網絡建設與運維賽項 賽題 B 卷 第十七屆山東省職業院校技能大賽中職組網絡建設與運維賽項 1 賽題說明 一、競賽項目簡介 “網絡建設與運維”競賽共分為以下三個模塊&#xff1a; ? 網絡理論測試&#xff1b; ? 網絡建設與調試&#xf…

關于QT信號、槽、槽函數的講解

也是好久沒有發帖子了&#xff0c;最近博主主要還是在邊學QT邊完成任務&#xff0c;所以進度很慢&#xff0c;但確實在這幾天對于QT自身槽和信號這類特殊的機制有了一定簡單的理解&#xff0c;所以還是想記錄下來&#xff0c;如果有初學者看到帖子對他有一定的幫助&#xff0c;…

YOLOv8 漲點新方案:SlideLoss FocalLoss 優化,小目標檢測效果炸裂!

YOLOv8優化秘籍&#xff1a;用SlideLoss和FocalLoss提升小目標檢測精度&#xff08;附代碼實戰&#xff09;?? ?&#x1f4cc; 核心問題&#xff1a;YOLOv8在檢測小物體時效果不夠好&#xff1f;?? YOLOv8雖然是強大的目標檢測模型&#xff0c;但在處理小物體或類別不平…

基于cubeMX的hal庫STM32實現MQ2煙霧濃度檢測

一、任務目標 使用STM32F103C8T6單片機&#xff0c;使用單片機AD模塊采集MQ2煙霧傳感器的數據&#xff0c;在OLED屏顯示檢測到的AD值、電壓值和濃度值&#xff08;ppm單位&#xff09;。 二、實現過程 1、MQ2煙霧傳感器的濃度轉化方法 &#xff08;1&#xff09;實驗所用的M…

Android之AI自動化測試--Midscene

文章目錄 前言一、準備工作1.安裝2.準備 API Key3.安裝 adb4.連接設備 二、yaml格式自動化腳本1. 腳本案例2.執行結果 三、文件結構變化android 部分 前言 字節 Web Infra團隊官宣Midscene 從 v0.15 開始支持 Android 自動化測試&#xff0c;本篇文章介紹yaml方式的Android自動…

類的六個默認成員函數

如果一個類中什么成員都沒有&#xff0c;簡稱為空類。 空類中真的什么都沒有嗎&#xff1f;并不是&#xff0c;任何類在什么都不寫時&#xff0c;編譯器會自動生成以下6個默認成員函數。 默認成員函數&#xff1a;用戶沒有顯式實現&#xff0c;編譯器會生成的成員函數稱為默認…

HarmonyOS Grid 網格列表可長按 item 拖動移動位置

方案一 @Component struct WorkCircleCreatePage {// 存儲車控列表的數組@State VehicleDoorArr: IVehicleDoor[] = []// 當前移動的Item索引@State CurrentIndex: number = -1// 拖動時顯示的數據@State MoveItem: IVehicleDoor = { title: , icon: }// 拖動時放大倍數@State…

海量數據筆試題--Top K 高頻詞匯統計

問題描述&#xff1a; 假設你有一個非常大的文本文件&#xff08;例如&#xff0c;100GB&#xff09;&#xff0c;文件內容是按行存儲的單詞&#xff08;或其他字符串&#xff0c;如 URL、搜索查詢詞等&#xff09;&#xff0c;單詞之間可能由空格或換行符分隔。由于文件巨大&…

【數據結構】Map與Set結構詳解

數據結構系列五&#xff1a;Map與Set(一) 一、接口的實現 1.方法上 2.成員上 二、Map的內外雙接口結構 1.實現 1.1外部Map接口的實現 1.1.1臨摹整體 1.1.2外部類實現整體 1.2內部Entry接口的實現 1.2.1臨摹內部 1.2.2內部類實現內部 2.關系 3.意義 3.1邏輯內聚 …

Electron使用WebAssembly實現CRC-32 原理校驗

Electron使用WebAssembly實現CRC-32 原理校驗 將C/C語言代碼&#xff0c;經由WebAssembly編譯為庫函數&#xff0c;可以在JS語言環境進行調用。這里介紹在Electron工具環境使用WebAssembly調用CRC-32 原理格式校驗的方式。 CRC-32 原理校驗函數WebAssembly源文件 C語言實現C…

【晶振】晶振的工作原理及其與單片機關系

晶振(晶體振蕩器)是電子設備中常見的元件,其核心功能是提供穩定的時鐘信號,而單片機(MCU)依賴這一信號來同步內部操作。以下是晶振的工作原理及其與單片機關系的詳細說明: 一、晶振的工作原理 壓電效應與諧振 晶振的核心是石英晶體,利用其壓電效應: 當在晶體兩端施加電…

【Oracle專欄】函數中SQL拼接參數 報錯處理

Oracle相關文檔,希望互相學習,共同進步 風123456789~-CSDN博客 1.背景 最近同事反饋了一個很奇怪的問題,即有一個函數,入參是當前年月,主要作用是通過SQL語句將不合規的數據插入到指定表中,插入數據時帶上入參的年月參數。當前問題:單獨測試SQL沒有問題可以執行成功,…

nodejs之Express-介紹、路由

五、Express 1、express 介紹 express 是一個基于 Node.js 平臺的極簡、靈活的 WEB 應用開發框架,官方網址: https://www.expressjs.com.cn/ 簡單來說,express 是一個封裝好的工具包,封裝了很多功能,便于我們開發 WEB 應用(HTTP 服務) (1)基本使用 第一步:初始化項目并…

Unicode和 ASCII碼以及UTF-8編碼的區別和聯系

Unicode、ASCII 和 UTF-8 是計算機編碼領域的關鍵概念&#xff0c;它們既有聯系又有區別。以下是它們的對比分析&#xff1a; 1. ASCII&#xff08;美國信息交換標準碼&#xff09; 誕生時間&#xff1a;1967 年&#xff08;7 位編碼&#xff0c;共 128 字符&#xff09;。特點…

STM32F103_HAL庫+寄存器學習筆記20 - CAN發送中斷+ringbuffer + CAN空閑接收中斷+接收所有CAN報文+ringbuffer

導言 如上所示&#xff0c;在[[STM32F103_HAL庫寄存器學習筆記19 - CAN發送中斷CAN接收中斷接收所有CAN報文ringbuffer數據結構]]的基礎上&#xff0c;為CAN發送端也引入了ringbuffer&#xff08;環形緩沖區&#xff09;機制。CAN發送有三個發送郵箱&#xff0c;為什么還另外需…

Windows 環境下安裝 MariaDB 及 HeidiSQL 使用教程

引言 本報告旨在提供一份詳盡的操作指南。內容將覆蓋在 Windows 操作系統上安裝 MariaDB Community Server 的全過程。我們還將探討如何利用 HeidiSQL 這款圖形用戶界面&#xff08;GUI&#xff09;工具&#xff0c;直觀地預覽和管理我們新安裝的數據庫。除了安裝與配置的步驟…

美團2024年春招第一場筆試 C++

目錄 1&#xff0c;小美的平衡矩陣 2&#xff0c;小美的數組詢問 3&#xff0c;小美的MT 4&#xff0c;小美的朋友關系 1&#xff0c;小美的平衡矩陣 【題目描述】 給定一個n*n的矩陣&#xff0c;該矩陣只包含數字0和1。對于 每個i(1<i<n)&#xff0c;求在該矩陣中&am…

09-DevOps-Jenkins實現CI持續集成

前面已經把harbor搭建好了&#xff0c;也可以向harbor中推送自定義鏡像。 原計劃是在Jenkins這臺服務器上&#xff0c;完成鏡像構建&#xff0c;然后把鏡像推送的harbor倉庫中。現在改變計劃了&#xff0c;Jenkins所在的服務器&#xff08;192.168.1.10&#xff09;不負責鏡像…