<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          工序升級(jí)!在 Cocos Creator 里畫一個(gè)完美的矩形

          共 4205字,需瀏覽 9分鐘

           ·

          2021-10-15 02:34

          在認(rèn)識(shí)了 WebGL 的基礎(chǔ)工作原理,以及如何利用 WebGL 繪制后,接下來(lái)的幾章就帶大家了解一下這套流程如何應(yīng)用到 Cocos Creator 3.x


          之前我們利用 WebGL 繪制出了一個(gè)矩形,本章先來(lái)看看要如何在 Cocos Creator 3.x 繪制同樣的矩形


          流程概述


          Cocos Creator 3.x 為了方便用戶使用和定制,對(duì)內(nèi)部功能做了多層封裝,用戶根據(jù)需求自行組裝即可。因此,我們只需要組裝相關(guān)的部分。根據(jù)矩形繪制流程,可以將內(nèi)容很直接地拆分成以下幾個(gè)部分:


          • 第一是數(shù)據(jù)準(zhǔn)備部分,也就是提供頂點(diǎn)數(shù)據(jù)。在之前的案例里,我們是直接提供了固定數(shù)據(jù)。Cocos Creator 3.x 也有多個(gè)地方會(huì)提供頂點(diǎn)數(shù)據(jù),例如:2D 的渲染組件(Sprite、Graphics 等),3D 的模型組件(MeshRenderer、SkinnedMeshRendere 等)等。當(dāng)然,用戶也可以自定義頂點(diǎn)數(shù)據(jù),由于這部分涉及到渲染管線以及引擎底層,超出本章介紹范圍,這里就不再過(guò)多贅述。

          • 第二是畫布清除階段,這部分跟相機(jī)有關(guān)。因?yàn)橛螒驁?chǎng)景往往是由很多對(duì)象構(gòu)造而成,但是實(shí)際呈現(xiàn)的畫面只有其中一小部分,呈現(xiàn)的部分就是相機(jī)照射的部分。由于我們的屏幕畫布只有一塊,因此,由相機(jī)決定是否要擦除之前的內(nèi)容重新繪制,或者在原有內(nèi)容的基礎(chǔ)上繼續(xù)繪制。

          • 第三是著色指令部分,這部分就類似于頂點(diǎn)/片元文本的編寫。在 Cocos Creator 3.x 里通過(guò) Cocos Effect 來(lái)實(shí)現(xiàn)。


          在這里我會(huì)用最基礎(chǔ)繪圖組件 Graphics 進(jìn)行繪制,帶大家了解一下這套流程。


          首先,新建場(chǎng)景,在層級(jí)管理器上創(chuàng)建 Canvas 節(jié)點(diǎn),并在 Canvas 節(jié)點(diǎn)下創(chuàng)建一個(gè) Graphics 節(jié)點(diǎn)。創(chuàng)建腳本 Draw 并掛載在 Graphics 節(jié)點(diǎn)身上并調(diào)用 Graphics 繪圖相關(guān)接口。在這里,同樣繪制一個(gè)矩形:

          import?{?_decorator,?Component,?Node,?Graphics?}?from?'cc';
          const?{?ccclass,?property?}?=?_decorator;

          @ccclass('Draw')
          export?class?Draw?extends?Component?{

          ????start?()?{
          ????????const?g?=?this.getComponent(Graphics);
          ????????g.fillRect(0,?0,?200,?150);
          ????}
          }


          接著,運(yùn)行預(yù)覽,就可以看到繪制了一個(gè)純白色的矩形。



          在這個(gè)過(guò)程中一共經(jīng)歷了以下幾個(gè)階段:



          接下來(lái)說(shuō)說(shuō)開(kāi)發(fā)者需要關(guān)心的幾個(gè)部分。所有之前關(guān)于 gl.xxx 的部分,都在底層直接處理完了,所以并不需要我們手動(dòng)去執(zhí)行,除非整個(gè)流程我們都需要使用自定義的。


          頂點(diǎn)數(shù)據(jù)


          在 Creator 中,頂點(diǎn)坐標(biāo)起源于模型空間,最終需要轉(zhuǎn)換到屏幕空間,這過(guò)程需要經(jīng)歷以下幾個(gè)步驟:



          1. Local Space 局部坐標(biāo),也可以稱之為模型坐標(biāo)??梢岳斫鉃榫褪窍鄬?duì)于父節(jié)點(diǎn)的坐標(biāo)。

          2. World Space 世界坐標(biāo)。世界坐標(biāo)是一個(gè)很大的空間范圍,相對(duì)于世界原點(diǎn)。通過(guò)模型坐標(biāo)結(jié)合模型矩陣得出。

          3. View Space 觀察坐標(biāo)。可以理解為將世界坐標(biāo)轉(zhuǎn)換到相機(jī)空間的坐標(biāo),轉(zhuǎn)換后的值是相對(duì)于相機(jī)原點(diǎn)。通過(guò)世界坐標(biāo)結(jié)合觀察矩陣得出。

          4. Clip Space 裁剪坐標(biāo)。也就是將觀察坐標(biāo)處理到 -1.0 ~ 1.0 的范圍,也就是我們?cè)?WebGL 里提供的標(biāo)準(zhǔn)設(shè)備化坐標(biāo),最終剔除超出 -1 ~ 1 的坐標(biāo)。通過(guò)觀察坐標(biāo)結(jié)合投影矩陣得出。

          5. Screen Space 屏幕坐標(biāo)。這個(gè)過(guò)程其實(shí)就是將 -1.0 ~ 1.0 范圍的坐標(biāo)轉(zhuǎn)換到 gl.viewport 所定義的坐標(biāo)范圍內(nèi)。最后變換出來(lái)的坐標(biāo)會(huì)送到光柵器,轉(zhuǎn)換成片段。


          因此,根據(jù)數(shù)據(jù)類型,最終都需要轉(zhuǎn)換成裁剪坐標(biāo)提供。Graphics 提供的是模型坐標(biāo)。喜歡探究的同學(xué)可以查看引擎底層 graphics.ts 里的 activeMode、_uploadData 和 graphics-assemler 部分,這里就處理了頂點(diǎn)數(shù)據(jù)緩存創(chuàng)建、繪制數(shù)據(jù)收集,綁定等步驟。


          這里順帶提一下標(biāo)準(zhǔn)設(shè)備化坐標(biāo)和屏幕坐標(biāo)之間的關(guān)系。標(biāo)準(zhǔn)化設(shè)備坐標(biāo)是 x 軸向右,y 軸向上,x 和 y 的取值都是從 -1~1,在這個(gè)范圍內(nèi)的頂點(diǎn)可見(jiàn),否則都不可見(jiàn)。屏幕坐標(biāo)是 x 軸向右,y 軸向下,x 和 y 的取值范圍都是從 0 對(duì)應(yīng)到屏幕寬高,在矩陣變換的最后一步,就是將標(biāo)準(zhǔn)化設(shè)備坐標(biāo)轉(zhuǎn)換到屏幕坐標(biāo)后上屏顯示。



          Cocos Effect


          有了頂點(diǎn)數(shù)據(jù)之后,對(duì)應(yīng)的也需要編寫 Shader 文本,在 3.x 里則對(duì)應(yīng) Cocos Effect。Cocos Effect 是一種基于 YAML 和 GLSL 的單源碼嵌入式領(lǐng)域特定語(yǔ)言,YAML 部分聲明流程控制清單,GLSL 部分聲明實(shí)際的著色片段,這兩部分內(nèi)容上相互補(bǔ)充,共同構(gòu)成了一個(gè)完整的渲染流程描述。引擎會(huì)根據(jù)這份描述執(zhí)行相對(duì)應(yīng)的渲染程序。Cocos Effect 無(wú)法單獨(dú)使用,需要搭配材質(zhì)使用。


          > 注意:如果使用 VSCode 編輯自定義 Effect。推薦在 VSCode 上搜索安裝 Cocos Effect 插件,以便獲得代碼高亮提示。


          我們可以通過(guò)在編輯器的資源管理器面板處右鍵,選擇 Effect 創(chuàng)建 .effect 文件即可。


          YAML101


          YAML 是一種序列化語(yǔ)言,也可以理解為是一種專注于寫配置文件的語(yǔ)言。Cocos Creator 3.x 完全支持 YAML 1.2 標(biāo)準(zhǔn)的解析器。YAML 完全兼容 Json 語(yǔ)法,所以 Json 也可以看做是 YAML 的子集。


          YAML 是由 : 和空格分隔的鍵值組合。


          • 所有的引號(hào)和逗號(hào)都可以省略

          key1:?1
          key2:?unquoted?string

          //?注意:冒號(hào)后的空格不可省略


          • 行首的空格縮進(jìn)數(shù)量代表數(shù)據(jù)的層級(jí)

          object1:
          ??key1:?false
          object2:
          ??key2:?3.14
          ??key3:?0xdeadbeef
          ??nestedObject:
          ????key4:?'quoted?string'


          • 以連字符?+?空格開(kāi)頭,表示數(shù)組元素

          -?42
          -?"double-quoted?string"
          ?
          //?最終解析效果如下:
          {[42,?"double-quoted?string"]}


          • YAML 中可以通過(guò) & 定錨點(diǎn),* 來(lái)引用

          object1:?&o1
          ??key1:?value1
          object2:
          ??key2:?value2
          ??key3:?*o1
          ??
          //?最終解析出來(lái)效果如下:

          {
          ????"object1":?{
          ????????"key1":?"value1"
          ????},
          ????"object2":?{
          ????????"key2":?"value2",
          ????????"key3":?{
          ????????????"key1":?"value1"
          ????????}
          ????}
          }


          • << 表示追加,類似繼承

          object1:?&o1
          ??key1:?value1
          ??key2:?value2
          object2:
          ??<<:?*o1
          ??key3:?value3
          ??
          //?最終解析效果如下:

          {
          ????"object1":?{
          ????????"key1":?"value1",
          ????????"key2":?"value2"
          ????},
          ????"object2":?{
          ????????"key1":?"value1",
          ????????"key2":?"value2",
          ????????"key3":?"value3"
          ????}
          }


          以上部分僅羅列出 Cocos Effect 開(kāi)發(fā)中常見(jiàn)的寫法,更多寫法請(qǐng)參考 YAML 官網(wǎng)。


          Cocos Effect 寫法


          Cocos Effect 主要由兩部分構(gòu)成:


          • 一個(gè)是由 CCEffect 包裹的用 YAML 格式編輯的渲染流程清單。這里羅列的內(nèi)容主要涉及到與編輯器交互(供開(kāi)發(fā)者在編輯器中進(jìn)行數(shù)據(jù)調(diào)整)以及與 CCProgram 的數(shù)據(jù)交互。CCEffect 的核心是 Technique 渲染技術(shù)。

          ◇ Technique 渲染技術(shù)代表完成一個(gè)最終效果的方案。一個(gè)方案可以由一個(gè)或者多個(gè) Pass 融合完成。

          ◇?一個(gè) ?Pass 就是一次 GPU 繪制,一般包括一次頂點(diǎn)著色器和片元著色器。

          ◇?每個(gè)頂點(diǎn)/片元著色器都要申明各自的入口函數(shù)并提供返回值,此處入口函數(shù)的返回值會(huì)提供給運(yùn)行平臺(tái)的入口函數(shù)。

          • 另一個(gè)是由 CCProgram 包裹的基于 GLSL 300es 格式的著色器(shader)片段。


          如果要繪制在文章開(kāi)頭的目標(biāo)矩形,內(nèi)容可以如下:

          CCEffect?%{
          ??techniques:
          ??-?name:?opaque
          ????passes:
          ????-?vert:?unlit-vs:vert?#此處的 vert 對(duì)應(yīng) CCProgram 的 vert,指向渲染平臺(tái)的入口函數(shù)。例如:WebGL 就是 main 函數(shù)。
          ??????frag:?unlit-fs:frag
          }%

          CCProgram?unlit-vs?%{
          ??precision?highp?float;
          ??in?vec4?a_position;
          ??in?vec4?a_color;
          ??out?vec4?v_color;

          ??vec4?vert?()?{
          ????v_color?=?a_color;
          ????return?a_position;
          ??}
          }%

          CCProgram?unlit-fs?%{
          ??precision?highp?float;
          ??in?vec4?v_color;

          ??vec4?frag?()?{
          ????return?v_color;
          ??}
          }%


          >注意:Cocos Creator 采用的是 GLSL es300 格式來(lái)編寫 Shader 片段。因此,后續(xù)所有的輸入輸出都使用 “in”、“out” 關(guān)鍵字而非舊版的 “attribute” 和 “varing”。當(dāng)然,如果想繼續(xù)使用,仍然兼容。


          Graphics 組件在繪圖的時(shí)候,也采用了為自己量身定做的 Shader,這個(gè)在 Graphics.ts 內(nèi)有跡可循。采用的是內(nèi)置的 builtin-graphics??梢栽?資源管理器面板->internal->effects 下找到。它的內(nèi)容如下:

          CCEffect?%{
          ??techniques:
          ??-?passes:
          ????#?確定頂點(diǎn)和片元著色器。指向的是 CCProgram 定義的著色器。
          ????-?vert:?vs:vert
          ??????frag:?fs:frag
          ??????#?blendState、rasterizerState?和?depthStencilState?是與測(cè)試與混合有關(guān),可以暫時(shí)忽略
          ??????#?此處設(shè)置的原因是因?yàn)橐鎯?nèi)提供一套默認(rèn)的測(cè)試與混合配置,但是在?2D?上由于當(dāng)前設(shè)計(jì)暫時(shí)不需要深度,因此,需要手動(dòng)修改相關(guān)配置
          ??????blendState:
          ????????targets:
          ????????-?blend:?true
          ??????????blendSrc:?one
          ??????????blendDst:?one_minus_src_alpha
          ??????????blendSrcAlpha:?one
          ??????????blendDstAlpha:?one_minus_src_alpha
          ??????rasterizerState:
          ????????cullMode:?none
          ??????depthStencilState:
          ????????depthTest:?false
          ????????depthWrite:?false
          }%

          CCProgram?vs?%{
          ??//?頂點(diǎn)著色器內(nèi)所有浮點(diǎn)數(shù)精度定義?
          ??precision?highp?float;

          ??//?引入?Creator?3.x?提供的代碼片段
          ??//?cc-global?提供了投影矩陣和觀察矩陣
          ??#include?
          ??//?cc-local?提供了模型矩陣
          ??#include?

          ??//?定義需要輸入的三個(gè)頂點(diǎn)屬性數(shù)據(jù) a_position,a_color 和 a_dist。其中,a_dist 是為了抗鋸齒功能所需提供,可不用關(guān)心。
          ??in?vec3?a_position;

          ??in?vec4?a_color;
          ??out?vec4?v_color;

          ??in?float?a_dist;
          ??out?float?v_dist;
          ??
          ??//?提供最終需要傳給頂點(diǎn)著色器?main?函數(shù)的數(shù)據(jù)值
          ??vec4?vert?()?{
          ????vec4?pos?=?vec4(a_position,?1);
          ????//?將模型坐標(biāo)轉(zhuǎn)換成裁剪坐標(biāo)
          ????pos?=?cc_matViewProj?*?cc_matWorld?*?pos;

          ????v_color?=?a_color;
          ????v_dist?=?a_dist;

          ????return?pos;
          ??}
          }%

          CCProgram?fs?%{
          ??//?低版本處理方案,可不用關(guān)心。
          ??#pragma?extension([GL_OES_standard_derivatives,?__VERSION__?

          ??precision?highp?float;

          ??in?vec4?v_color;
          ??in?float?v_dist;

          ??//?提供最終需要傳給片元著色器?main?函數(shù)的數(shù)據(jù)值
          ??vec4?frag?()?{
          ????vec4?o?=?v_color;
          ????
          ????//?此處也可不用關(guān)心
          ????#if?__VERSION__?
          ??????#ifdef?GL_OES_standard_derivatives
          ????????float?aa?=?fwidth(v_dist);
          ??????#else
          ????????float?aa?=?0.05;
          ??????#endif
          ????#else
          ??????float?aa?=?fwidth(v_dist);
          ????#endif

          ????float?alpha?=?1.?-?smoothstep(-aa,?0.,?abs(v_dist)?-?1.0);
          ????o.rgb?*=?o.a;
          ????o?*=?alpha;

          ????return?o;
          ??}
          }%


          上下一對(duì)比,我們所需要的部分跟上方繪制矩形所需內(nèi)容就差不多重合了。只是多了一層模型坐標(biāo)到裁剪坐標(biāo)的轉(zhuǎn)換。


          最后,這里還差最后一部分內(nèi)容,就是關(guān)于相機(jī)。當(dāng)我們創(chuàng)建 Canvas 節(jié)點(diǎn)的時(shí)候,可以看到默認(rèn)會(huì)創(chuàng)建出一個(gè) Camera 節(jié)點(diǎn),Camera 節(jié)點(diǎn)上的 Camera 組件持有 ClearFlags,ClearColor 以及 Rect 這三個(gè)屬性,在 WebGL 就分別控制了 gl.viewport、gl.clear 和 gl.clearColor 部分。其中:


          • ClearFlags 的 SOLID_COLOR 模式,要求每幀清除屏幕內(nèi)容

          • ClearColor 要求清除屏幕內(nèi)容后默認(rèn)填充什么顏色

          • Rect 定義屏幕空間視口,xy 值限制在 -1~1,wh 值限制在 0~1


          到此為止,我們大致了解了一個(gè)基礎(chǔ)繪圖組件 Graphics 的頂點(diǎn)數(shù)據(jù)的獲取途徑以及它的 Shader 內(nèi)容。下一章,我們來(lái)分析一下在基礎(chǔ)繪圖 Shader 基礎(chǔ)上添加了紋理貼圖處理的 2D 渲染組件 Sprite,并對(duì)它進(jìn)行一些改造。


          擴(kuò)展知識(shí)


          所有場(chǎng)景里的對(duì)象都必須在相機(jī)的可視區(qū)域內(nèi),才能被最終渲染出來(lái)。相機(jī)的可視條件分為兩部分:


          • 條件一:相機(jī)的 Visibility 包含節(jié)點(diǎn)的 Layer 值。比如:2D 相機(jī)的 Visibility 包含 UI_3D 和 UI_2D,節(jié)點(diǎn)的 layer 為 DEFAULT,那么此節(jié)點(diǎn)就無(wú)法被 2D 相機(jī)渲染。

          • 條件二:在條件一滿足的情況下,物體需要在相機(jī)照射的視距框內(nèi),物體才可被渲染。


          最終,所有的內(nèi)容經(jīng)過(guò)渲染管線的處理成為一個(gè)“拍扁”后的 2D 像素。此時(shí)不代表最終呈現(xiàn)的就是這樣的 2D 像素,最后一個(gè)階段是 viewport。假設(shè),此時(shí)將相機(jī) Rect 的 w 分量改為 0.5,可以看看前后渲染內(nèi)容的對(duì)比:



          可以清楚的看到由于視口的調(diào)整,只有左半邊屏幕能夠呈現(xiàn)內(nèi)容,因此,只有以相機(jī)原點(diǎn)為中心所照射的一半內(nèi)容被呈現(xiàn)了出來(lái)。




          Cocos Shader 基礎(chǔ)入門系列


          (一)WebGL & GLSL?基礎(chǔ)

          (二)頂點(diǎn)著色器與片元著色器

          (三)繪制多個(gè)三角形并給頂點(diǎn)換顏色

          (四)紋理映射

          ···更新中···


          該系列教程視頻版

          已更新至 EP05

          歡迎點(diǎn)擊【閱讀原文】

          前往 B 站觀看交流 ↓

          B 站關(guān)注「Cocos 引擎官方」

          https://www.bilibili.com/video/BV1Cq4y1d726


          往期精彩

          瀏覽 98
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  草逼草综合 | 国产精品人妻在线 | 婷婷国产精品免费视频 | 蜜芽欧洲无码精品 | 日韩高清无码人妻 |