cocos creator使用mesh修改圖片為圓形,減少使用mask,j減少drawcall,優化性能

cocos creator版本2.4.11

一個mask占用drawcall 3個以上,針對游戲中技能圖標,cd,以及多玩家頭像,是有很大優化空間

1.上代碼,只適合單獨圖片的,不適合在圖集中的圖片

const { ccclass, property } = cc._decorator;const gfx = cc.gfx;
cc.Class({extends: cc.Component,properties: {radius: 100, // 圓的半徑segments: 32, // 圓的細分段數(頂點數)/*** !#en The sprite frame of the sprite.* !#zh 精靈的精靈幀* @property spriteFrame* @type {SpriteFrame}* @example* sprite.spriteFrame = newSpriteFrame;*/spriteFrame: {default: null,type: cc.SpriteFrame},},onLoad() {let renderer = this.node.getComponent(cc.MeshRenderer);if (!renderer) {renderer = this.node.addComponent(cc.MeshRenderer);}renderer.mesh = null;this.renderer = renderer;let builtinMaterial = cc.MaterialVariant.createWithBuiltin("unlit");renderer.setMaterial(0, builtinMaterial);this._applySpriteFrame();this.setMesh();},setMesh(){// 創建 Meshlet mesh = new cc.Mesh();// 計算頂點和 UVlet positions = [];let uvs = [];let indices = [];let colors = [];// 圓心頂點positions.push(cc.v2(0, 0)); // 圓心uvs.push(cc.v2(0.5, 0.5));  // 圓心 UVcolors.push(cc.Color.WHITE); // 圓心顏色// 圓邊緣頂點for (let i = 0; i <= this.segments; i++) {let angle = (i / this.segments) * Math.PI * 2; // 計算角度let x = Math.cos(angle) * this.radius; // 計算 x 坐標let y = Math.sin(angle) * this.radius; // 計算 y 坐標positions.push(cc.v2(x, y)); // 添加頂點uvs.push(cc.v2((x / this.radius + 1) / 2, 1-(y / this.radius + 1) / 2)); // 添加 UVcolors.push(cc.Color.WHITE); // 添加顏色}// 設置索引(三角形扇)for (let i = 1; i <= this.segments; i++) {indices.push(0); // 圓心indices.push(i); // 當前頂點indices.push(i + 1); // 下一個頂點}mesh.init(new gfx.VertexFormat([{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },]), positions.length, true);mesh.setVertices(gfx.ATTR_POSITION, positions);mesh.setVertices(gfx.ATTR_UV0, uvs);mesh.setIndices(indices);this.renderer.mesh = mesh;},// 更新圖片_applySpriteFrame() {// cc.log('_applySpriteFrame');if (this.spriteFrame) {const renderer = this.renderer;let material = renderer._materials[0];// Reset materiallet texture = this.spriteFrame.getTexture();material.define("USE_DIFFUSE_TEXTURE", true);material.setProperty('diffuseTexture', texture);}}
});

這個js組件,綁定到節點上,把要渲染的spriteFrame掛在上面,運行就可以了,這種方式只適合單獨圖片,不適合圖集中的圖片

運行效果,下面是對比了這個圖片

說明:這種方式是直接修改圖片的mesh網格結構,使用meshRenderer組件,不能掛載sprite組件,使用shader也可以達到效果,但是shader是在Gpu層修改顯示,圖片形狀沒有變,這個是運行的時候直接修改形狀,而且shader修改的話會有問題,例如打斷動態合批,如果項目勾選了動態合批或者圖片在圖集中,shader修改是無效的

這種方式可以降低mask增加的drawcall

2.工具式的,直接調用,升級版,可以修改圖集中的某個圖片的顯示

const { ccclass, property } = cc._decorator;const gfx = cc.gfx;
cc.Class({extends: cc.Component,properties: {radius: 100, // 圓的半徑segments: 32, // 圓的細分段數(頂點數)/*** !#en The sprite frame of the sprite.* !#zh 精靈的精靈幀* @property spriteFrame* @type {spriteFrame}*/spriteFrame: {default: null,type: cc.spriteFrame,},},/**設置數據顯示 需要等spriteFrame加載完成后調用,可以拿到實際的圖片* radius: 半徑* segments: 圓細分段數,越多會越圓滑,但是性能消耗會更大* node:節點,這里需要使用mesheRenderer組件,所以需要把sprite剔除* isAtlas:是否是圖集中的圖片*/setDataShow(node, radius, segments, isAtlas) {// MeshRendererlet renderer = this.node.getComponent(cc.MeshRenderer);if (!renderer) {renderer = this.node.addComponent(cc.MeshRenderer);}renderer.mesh = null;this.renderer = renderer;let builtinMaterial = cc.MaterialVariant.createWithBuiltin("unlit");renderer.setMaterial(0, builtinMaterial);renderer.enabled = false;this.radius = radius;this.segments = segments;let sp = node.getComponent(cc.Sprite);if (sp) {this.spriteFrame = sp.spriteFrame;node.removeComponent(cc.Sprite);}// 把圖片加載到renderer上的材質this.applySpriteFrame();// 設置meshif (isAtlas) {// 大圖集中的texturethis.setMeshByAtlas();} else {// 單個圖片this.setMesh();}// 這里必須延遲一幀,不然不會刷新mesh,顯示不出來圖片setTimeout(() => {if(cc.isValid(renderer)){renderer.enabled = true;}}, 100);},/**更新mesh,在圖集中的 */setMeshByAtlas() {let uv = this.spriteFrame.uv;// 創建 Meshlet mesh = new cc.Mesh();// 計算頂點和 UVlet positions = [];let uvs = [];let indices = [];let colors = [];// 圓心頂點positions.push(cc.v2(0, 0)); // 圓心uvs.push(cc.v2((uv[6] + uv[0]) / 2, (uv[7] + uv[1]) / 2)); // 圓心 UV(取中心點)colors.push(cc.Color.WHITE); // 圓心顏色// 圓邊緣頂點for (let i = 0; i <= this.segments; i++) {let angle = (i / this.segments) * Math.PI * 2; // 計算角度let x = Math.cos(angle) * this.radius; // 計算 x 坐標let y = Math.sin(angle) * this.radius; // 計算 y 坐標positions.push(cc.v2(x, y)); // 添加頂點// 計算 UV 坐標(根據圖集的 UV 信息進行映射)let u = (x / this.radius + 1) / 2; // 歸一化到 [0, 1]let v = (y / this.radius + 1) / 2; // 歸一化到 [0, 1]let uvX = uv[0] + (uv[2] - uv[0]) * u; // 根據圖集 UV 計算實際 UVlet uvY = uv[1] + (uv[5] - uv[1]) * v; // 根據圖集 UV 計算實際 UVuvs.push(cc.v2(uvX, uvY)); // 添加 UVcolors.push(cc.Color.WHITE); // 添加顏色}// 設置索引(三角形扇)for (let i = 1; i <= this.segments; i++) {indices.push(0); // 圓心indices.push(i); // 當前頂點indices.push(i + 1); // 下一個頂點}mesh.init(new gfx.VertexFormat([{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },]), positions.length, true);mesh.setVertices(gfx.ATTR_POSITION, positions);mesh.setVertices(gfx.ATTR_UV0, uvs);mesh.setIndices(indices);this.renderer.mesh = mesh;},// 更新mesh,單獨圖片的setMesh() {// 創建 Meshlet mesh = new cc.Mesh();// 計算頂點和 UVlet positions = [];let uvs = [];let indices = [];let colors = [];// 圓心頂點positions.push(cc.v2(0, 0)); // 圓心uvs.push(cc.v2(0.5, 0.5));  // 圓心 UVcolors.push(cc.Color.WHITE); // 圓心顏色// 圓邊緣頂點for (let i = 0; i <= this.segments; i++) {let angle = (i / this.segments) * Math.PI * 2; // 計算角度let x = Math.cos(angle) * this.radius; // 計算 x 坐標let y = Math.sin(angle) * this.radius; // 計算 y 坐標positions.push(cc.v2(x, y)); // 添加頂點uvs.push(cc.v2((x / this.radius + 1) / 2, (y / this.radius + 1) / 2)); // 添加 UVcolors.push(cc.Color.WHITE); // 添加顏色}// 設置索引(三角形扇)for (let i = 1; i <= this.segments; i++) {indices.push(0); // 圓心indices.push(i); // 當前頂點indices.push(i + 1); // 下一個頂點}mesh.init(new gfx.VertexFormat([{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },]), positions.length, true);mesh.setVertices(gfx.ATTR_POSITION, positions);mesh.setVertices(gfx.ATTR_UV0, uvs);mesh.setIndices(indices);this.renderer.mesh = mesh;},// 更新圖片applySpriteFrame() {// cc.log('_applySpriteFrame');if (this.spriteFrame) {const renderer = this.renderer;let material = renderer._materials[0];// Reset materialmaterial.define("USE_DIFFUSE_TEXTURE", true);material.setProperty('diffuseTexture', this.spriteFrame.getTexture());}},});

外部調用這個組件的方法,setDataShow傳對應的參數就可以,節點上需要掛sprite組件,sprite更新圖片或者初始化加載的時候,調用這個方法setDataShow,同時兼容刪除節點的sprite組件,如果不想掛載sprite組件,默認直接掛上meshRenderer組件,需要自己修改下代碼,把參數node直接改成傳對應的spriteFrame圖片?

Cocos Creator 的紋理坐標系(UV 坐標系)的 Y 軸方向是?從上到下?的,如果結果圖片y是反向的,可以設代碼修改uvs中的y的取值

  • 將?v?的計算改為?1 - (y / radius + 1) / 2,即對 Y 方向取反。

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

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

相關文章

AI重構SEO關鍵詞布局

內容概要 在搜索引擎優化&#xff08;SEO&#xff09;領域&#xff0c;AI技術的深度應用正在顛覆傳統關鍵詞布局邏輯。通過機器學習算法與語義分析模型&#xff0c;智能系統能夠實時解析海量搜索數據&#xff0c;構建動態詞庫并精準捕捉用戶意圖。相較于依賴人工經驗的關鍵詞篩…

泛微ecode的頁面開發發送請求參數攜帶集合

1.在開發過程中我們難免遇見會存在需要將集合傳遞到后端的情況&#xff0c;那么這里就有一些如下的注意事項&#xff0c;如以下代碼&#xff1a; // 新增action.boundasync addQuestion(formData) {var theList this.questionAnswerList;var questionAnswerListArray new Ar…

20250212:linux系統DNS解析卡頓5秒的bug

問題: 1:人臉離線識別記錄可以正常上傳云端 2:人臉在線識別請求卻一直超時 3:客戶使用在線網絡 思路:

道路運輸安全員考試:備考中的心理調適與策略

備考道路運輸安全員考試&#xff0c;心理調適同樣重要。考試壓力往往會影響考生的學習效率和考試發揮。? 首先&#xff0c;要正確認識考試壓力。適度的壓力可以激發學習動力&#xff0c;但過度的壓力則會適得其反。當感到壓力過大時&#xff0c;要學會自我調節。可以通過運動…

LLM - 白話RAG(Retrieval-Augmented Generation)

文章目錄 Pre一、大模型的"幻覺"之謎1.1 何為"幻覺"現象&#xff1f;1.2 專業場景的致命挑戰 二、RAG技術解析&#xff1a;給大模型裝上"知識外掛"2.1 核心原理&#xff1a;動態知識增強2.2 技術實現三部曲 三、RAG vs 微調&#xff1a;技術選型…

探索現代 C++:新特性、工程實踐與熱點趨勢

目錄 一、現代 C 的關鍵特性與熱點關聯 二、精簡代碼示例解析 三、工程實踐中的應用思考 四、總結與展望 近幾年&#xff0c;人工智能、邊緣計算與跨語言開發成為技術熱點&#xff0c;而 C 作為高性能系統編程的主力軍&#xff0c;也在不斷進化。從 C11 到 C20&#xff0c;…

《HTML + CSS + JS 打造炫酷輪播圖詳解》

《HTML CSS JS 打造炫酷輪播圖詳解》 一、項目概述 本次項目旨在使用 HTML、CSS 和 JavaScript 實現一個具有基本功能的輪播圖&#xff0c;包括圖片自動輪播、上一張 / 下一張按鈕切換、小圓點指示與切換等功能&#xff0c;以提升網頁的交互性和視覺吸引力。 二、實現步驟…

257. 二叉樹的所有路徑(遞歸+回溯)

257. 二叉樹的所有路徑 力扣題目鏈接(opens new window) 給定一個二叉樹&#xff0c;返回所有從根節點到葉子節點的路徑。 說明: 葉子節點是指沒有子節點的節點。 示例: 思路&#xff1a;在葉子節點收割結果&#xff0c;如果不是葉子節點&#xff0c;則依次處理左右子樹&a…

【架構差異】SpringとSpringBoot:Bean機制的深入剖析與自動配置原理

目錄標題 SpringBoot框架中Bean機制的深入剖析與自動配置原理摘要1. 引言2. SpringBoot與Spring的架構差異2.1 從Spring到SpringBoot的演進2.2 SpringBoot中的Bean容器體系 3. SpringBoot的自動配置機制3.1 SpringBootApplication解析3.2 自動配置原理深度解析3.2.1 自動配置類…

CSDN博客:Markdown編輯語法教程總結教程(中)

?個人主頁&#xff1a;折枝寄北的博客 Markdown編輯語法教程總結 前言1. 列表1.1 無序列表1.2 有序列表1.3 待辦事項列表1.4 自定義列表 2. 圖片2.1 直接插入圖片2.2 插入帶尺寸的圖片2.3 插入寬度確定&#xff0c;高度等比例的圖片2.4 插入高度確定寬度等比例的圖片2.5 插入居…

ChebyKAN0、ChebyKAN1 網絡閱讀

目錄 ChebyKAN0 Chebyshev Polynomial-Based Kolmogorov-Arnold Networks: An Efficient Architecture for Nonlinear Function Approximation 參考文獻 文章內容 文章詳細結構 5. Experiments and Results 5.1 Digit Classification on MNIST 5.2 Function Approximat…

RK3588部署YOLOv8(2):OpenCV和RGA實現模型前處理對比

目錄 前言 1. 結果對比 1.1 時間對比 1.2 CPU和NPU占用對比 2. RGA實現YOLO前處理 2.1 實現思路 2.2 處理類的聲明 2.3 處理類的實現 總結 前言 RK平臺上有RGA (Raster Graphic Acceleration Unit) 加速&#xff0c;使用RGA可以減少資源占用、加速圖片處理速度。因此…

破局者登場:中國首款AI原生IDE Trae深度解析--開啟人機協同編程新紀元

摘要 字節跳動于2025年3月3日正式發布中國首款AI原生集成開發環境Trae國內版&#xff0c;以動態協作、全場景AI賦能及本土化適配為核心優勢。Trae內置Doubao-1.5-pro與DeepSeek R1/V3雙引擎&#xff0c;支持基于自然語言生成端到端代碼框架、實時上下文感知與智能Bug修復&…

【PyCharm】Python和PyCharm的相互關系和使用聯動介紹

李升偉 整理 Python 是一種廣泛使用的編程語言&#xff0c;而 PyCharm 是 JetBrains 開發的專門用于 Python 開發的集成開發環境&#xff08;IDE&#xff09;。以下是它們的相互關系和使用聯動的介紹&#xff1a; 1. Python 和 PyCharm 的關系 Python&#xff1a;一種解釋型、…

SNIPAR:快速實現親緣個體的基因型分離與推斷

SNIPAR&#xff1a;快速實現親緣個體的基因型分離與推斷 近日&#xff0c;英國劍橋大學研究團隊在Nature Genetics上發表了最新研究成果——SNIPAR&#xff08;SNP-based Inference of Pedigree relationship, Ancestry, and Recombination&#xff09;。這一強大的工具可以幫助…

3.11記錄

leetcode刷題&#xff1a; 1. 334. 遞增的三元子序列 - 力扣&#xff08;LeetCode&#xff09; 方法一&#xff1a;使用貪心算法求解 class Solution(object):def increasingTriplet(self, nums):first nums[0]second float(inf)for i in nums:if i>second:return Truee…

阿里云操作系統控制臺評測:國產AI+運維 一站式運維管理平臺

阿里云操作系統控制臺評測&#xff1a;國產AI運維 一站式運維管理平臺 引言 隨著云計算技術的飛速發展&#xff0c;企業在云端的運維管理面臨更高的要求。阿里云操作系統控制臺作為一款集運維管理、智能助手和系統診斷等多功能于一體的工具&#xff0c;正逐步成為企業高效管理…

大語言模型學習--向量數據庫Milvus實踐

Milvus是目前比較流行的開源向量數據庫&#xff0c;其官網地址 Milvus 是什么&#xff1f; | Milvus 文檔 1.Milvus簡介 Milvus 是一種高性能、高擴展性的向量數據庫。Milvus 提供強大的數據建模功能&#xff0c;能夠將非結構化或多模式數據組織成結構化的 Collections。它支…

DeepSeek Kimi詳細生成PPT的步驟

以下是使用 DeepSeek 和 Kimi 協作生成 PPT 的詳細步驟&#xff0c;結合了兩者的優勢實現高效創作&#xff1a; 第一步&#xff1a;使用 DeepSeek 生成 PPT 大綱或內容 明確需求并輸入提示詞 在 DeepSeek 的對話界面中&#xff0c;輸入具體指令&#xff0c;要求生成 PPT 大綱或…

Visual Studio 安裝及使用教程(Windows)【安裝】

文章目錄 一、 Visual Studio 下載1. 官網下載2. 其它渠道 二、Visual Studio 安裝三、Visual Studio 使用四、Visual Studio 其它設置1. 桌面快捷方式2. 更改主題、字體大小 軟件 / 環境安裝及配置目錄 一、 Visual Studio 下載 1. 官網下載 安裝地址&#xff1a;https://vi…