<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>

          兩種方法實(shí)現(xiàn)亮度/飽和度/對比度的調(diào)整!Cocos Creator !

          共 3553字,需瀏覽 8分鐘

           ·

          2020-07-15 09:14


          uniform 方案和 assembler 方案的實(shí)現(xiàn)。

          效果預(yù)覽

          GTAssembler 源碼解讀及使用 一文中提到自定義渲染可以實(shí)現(xiàn)很多酷炫的 shader 特效,目前常用的有兩種方法:

          • 創(chuàng)建自定義材質(zhì),給材質(zhì)增加參數(shù)。這個(gè)參數(shù)會作為 uniform 變量傳入 shader 由于渲染合批要求材質(zhì)參數(shù)保持一致,所以如果大量對象使用自定義材質(zhì)時(shí),并且材質(zhì)參數(shù)各不相同,是無法進(jìn)行合批渲染的,一個(gè)對象占一個(gè) draw call 。
          • 創(chuàng)建自定義 assembler,在頂點(diǎn)數(shù)據(jù)輸入渲染管道前修改它的值。

          本文將用這兩種方案實(shí)現(xiàn)亮度/飽和度/對比度的調(diào)整。(注意效果圖中不同方式的draw call不同)

          如何使用

          uniform 方案

          新建 Sprite 組件,選擇材質(zhì) BrightSaturaContrastUniform.mtl ,添加用戶腳本 BrightSaturaContrastUniform.ts ,調(diào)整對應(yīng)參數(shù)即可。

          c54b2a17208abfc7728c1b1a48dfe145.webp

          assembler 方案

          新建一個(gè)節(jié)點(diǎn),添加用戶腳本 BrightSaturaContrastAssemblerSprite.ts ,選擇材質(zhì) BrightSaturaContrastAssembler.mtl ,調(diào)整對應(yīng)參數(shù)即可。

          492faaeef6f15ee7b62ff5c84f216df4.webp

          實(shí)現(xiàn)步驟

          調(diào)色效果的邏輯參考《Unity Shader入門精要》中的介紹。

          亮度的調(diào)整只需要把原顏色乘以亮度系數(shù) brightness 即可。然后,我們計(jì)算該像素對應(yīng)的亮度值(luminance),這是通過對每個(gè)顏色分量乘以一個(gè)特定的系數(shù)再相加得到的。我們使用該亮度值創(chuàng)建了一個(gè)飽和度為0的顏色值,并使用saturation 屬性在其和上一步得到的顏色之間進(jìn)行插值,從而得到希望的飽和度顏色。對比度的處理類似,我們首先創(chuàng)建一個(gè)對比度為0的顏色值(各分量均為0.5),再使用contrast屬性在其和上一步得到的顏色之間進(jìn)行插值,從而得到最終的處理結(jié)果。

          uniform 方案

          新建一個(gè) BrightSaturaContrastUniform.effect 。

          在片元著色器中定義一個(gè) uniform 塊。

          uniform lamyoung_com {
          float brightness;
          float saturation;
          float constrast;
          };

          寫一個(gè)計(jì)算插值方法。

          vec3 lerp(vec3 a, vec3 b, float w){
          return a + w*(b-a);
          }

          參考《Unity Shader入門精要》中的介紹,翻譯一下計(jì)算過程即可,主要代碼如下。

          CCTexture(texture, v_uv0, o);
          // apply brightness
          vec3 finnalColor = o.rgb * brightness;
          // apply saturation
          float luminance = 0.2125 * o.r + 0.7154 * o.g + 0.0721 * o.b;
          vec3 luminanceColor = vec3(luminance, luminance, luminance);
          finnalColor = lerp(luminanceColor, finnalColor, saturation);
          // apply constrast
          vec3 avgColor = vec3(0.5, 0.5, 0.5);
          finnalColor = lerp(avgColor, finnalColor, constrast);

          o.rgb = finnalColor.rgb;

          接著新建材質(zhì) BrightSaturaContrastUniform.mtl,選擇 BrightSaturaContrastUniform.effect。

          ea464b48e89c501bfde525cf77d937c5.webp

          最后寫一個(gè) BrightSaturaContrastUniform.ts 腳本去控制 uniform 參數(shù),主要代碼如下。

          this._sprite.getMaterial(0).setProperty('brightness',?this._brightness);
          this._sprite.getMaterial(0).setProperty('saturation',?this._saturation);
          this._sprite.getMaterial(0).setProperty('constrast',?this._constrast);

          assembler 方案

          shader

          新建一個(gè) BrightSaturaContrastAssembler.effect 。

          因?yàn)檫@里用的是頂點(diǎn)數(shù)據(jù),所以在頂點(diǎn)著色器中定義一些要傳入片元著色器的屬性。

            in float a_brightness;
          out float v_brightness;

          in float a_saturation;
          out float v_saturation;

          in float a_constrast;
          out float v_constrast;

          并把這些屬性值傳給片元著色器。

          v_brightness = a_brightness;
          v_saturation = a_saturation;
          v_constrast = a_constrast;

          片元著色器接收這些屬性。

          in float v_brightness;
          in float v_saturation;
          in float v_constrast;

          在片元著色器的處理和uniform的類似。

          CCTexture(texture, v_uv0, o);
          // apply brightness
          vec3 finnalColor = o.rgb * v_brightness;
          // apply saturation
          float luminance = 0.2125 * o.r + 0.7154 * o.g + 0.0721 * o.b;
          vec3 luminanceColor = vec3(luminance, luminance, luminance);
          finnalColor = lerp(luminanceColor, finnalColor, v_saturation);
          // apply constrast
          vec3 avgColor = vec3(0.5, 0.5, 0.5);
          finnalColor = lerp(avgColor, finnalColor, v_constrast);

          o.rgb = finnalColor.rgb;

          新建材質(zhì) BrightSaturaContrastAssembler.mtl,選擇 BrightSaturaContrastAssembler.effect

          assembler

          新建 BrightSaturaContrastAssembler.ts 繼承Assembler 源碼解讀及使用 中的 GTSimpleSpriteAssembler2D。

          因?yàn)橐玫搅炼?飽和度/對比度這些屬性,所以定義頂點(diǎn)屬性的時(shí)候要加上這些屬性。

          //?自定義頂點(diǎn)格式,在vfmtPosUvColor基礎(chǔ)上,加入?a_brightness??a_saturation??a_constrast
          let?gfx?=?cc.gfx;
          const?vfmtCustom?=?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?},
          ????{?name:?gfx.ATTR_COLOR,?type:?gfx.ATTR_TYPE_UINT8,?num:?4,?normalize:?true?},
          ????{?name:?'a_brightness',?type:?gfx.ATTR_TYPE_FLOAT32,?num:?1?},
          ????{?name:?'a_saturation',?type:?gfx.ATTR_TYPE_FLOAT32,?num:?1?},
          ????{?name:?'a_constrast',?type:?gfx.ATTR_TYPE_FLOAT32,?num:?1?},
          ]);

          更新頂點(diǎn)數(shù)據(jù)時(shí),只需要找到對應(yīng)的偏移量就可以了。

          let?dstOffset;
          let?verts?=?this._renderData.vDatas[0];
          for?(let?i?=?0;?i?this.verticesCount;?++i)?{
          ????//?fill?
          ????let?floatsOffset?=?this.floatsPerVert?*?i;

          ????dstOffset?=?floatsOffset?+?this.brightnessOffset;
          ????verts[dstOffset]?=?this.brightness;

          ????dstOffset?=?floatsOffset?+?this.saturationOffset;
          ????verts[dstOffset]?=?this.saturation;

          ????dstOffset?=?floatsOffset?+?this.constrastOffset;
          ????verts[dstOffset]?=?this.constrast;
          }

          最后寫一個(gè) BrightSaturaContrastAssemblerSprite.ts 使用BrightSaturaContrastAssembler.ts,并在需要的時(shí)候更新數(shù)據(jù)。更新數(shù)據(jù)的代碼如下。

          assembler.brightness?=?this.brightness;
          assembler.constrast?=?this.constrast;
          assembler.saturation?=?this.saturation;
          this.setVertsDirty();
          更多精彩

          e318359a47ac608ec4391602870c9537.webp57e8cb7c75181f8244ca20d06d3be730.webp792c0fb988889b0b348d8cbb52477e87.webp

          小結(jié)

          需要注意的是 drawcall 數(shù)量并不是越少越好,最佳性能往往是 CPUGPU 負(fù)載均衡的結(jié)果。

          以上為白玉無冰使用 Cocos Creator v2.4.0 實(shí)現(xiàn) "亮度/飽和度/對比度的調(diào)整" 的技術(shù)分享。歡迎分享給身邊的朋友!

          任何行動(dòng)往往都比沒有行動(dòng)好,特別是當(dāng)你一直停滯在不愉快的情勢下很長時(shí)間的時(shí)候。如果這是一個(gè)錯(cuò)誤,至少你學(xué)到了一些東西。這樣一來,它就不再是一個(gè)錯(cuò)誤。如果你仍然選擇停滯不前,那么你就學(xué)不到任何東西。做或者不做。


          1646f6cf39ebed899a2ab5650f0c9ab2.webp
          轉(zhuǎn)一轉(zhuǎn)f7a2a0bfba62ed4d6a88a04f1d28db06.webp
          贊一贊c3c3dd15aed39c1bd2843891848178a6.webp
          看一看


          瀏覽 140
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  九热在线视频 | 五月天色中色在线视频 | 日韩后入在线 | 狼综合网 | 国产对白视频在线观看 |