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

          OpenGL ES 相機(jī) LUT 濾鏡

          共 4562字,需瀏覽 10分鐘

           ·

          2021-10-16 06:09

          OpenGLES 相機(jī) LUT 濾鏡


          左側(cè)為 LUT 濾鏡效果,右側(cè)為原圖


          什么是 LUT ? LUT 是 Look Up Table 的簡稱,稱作顏色查找表,是一種針對色彩空間的管理和轉(zhuǎn)換技術(shù)。

          它可以分為一維 LUT(1D LUT) 和 三維 LUT(3D LUT),其中三維 LUT 比較常用。簡單來講,LUT 就是一個 RGB 組合到另一個 RGB 組合的映射關(guān)系表。

          LUT(R, G, B) = (R1, G1, B1)

          LUT 濾鏡是一種比較經(jīng)典的濾鏡,本質(zhì)上屬于獨(dú)立像素點(diǎn)替換,即根據(jù) OpenGL 采樣器對紋理進(jìn)行采樣得到的像素點(diǎn),再基于像素點(diǎn)的(R,G,B)分量查表,獲得 LUT 映射的(R1,G1,B1),替換原來的輸出。

          一般 RGB 像素占用 3 個字節(jié),包含 3 個分量,每個分量有 256 種取值,那么三維 LUT 模板就可以包含 256 X 256 X 256 種情況,占用 48MB 內(nèi)存空間。

          這樣一個 LUT 模板內(nèi)存占用過大同時也降低了查找的效率,通常會采取下采樣方式來降低數(shù)據(jù)量。

          例如可以對三維 LUT 模板每個分量分別進(jìn)行 64 次采樣,這樣就獲得一個 64 X 64 X 64 大小的映射關(guān)系表,對于不在表內(nèi)的顏色值可以進(jìn)行插值獲得其相似結(jié)果。

          三維 LUT 模板,即64 X 64 X 64 大小的映射關(guān)系表,通常是用一張分辨率為 512 X 512 的二維圖片表示,稱為 LUT 圖(模板圖)。

          三維 LUT 模板

          LUT 圖在橫豎方向上被分成了 8 X 8 一共 64 個小方格,每一個小方格內(nèi)的 B(Blue)分量為一個定值,64 個小方格一共表示了 B 分量的 64 種取值。

          對于每一個小方格,橫豎方向又各自分為 64 個小格,以左下角為原點(diǎn),橫向小格的 R(Red)分量依次增加,縱向小格的 G(Green)分量依次增加。

          Lut 圖中的一個小方格

          至此,我們可以根據(jù)原始采樣像素 RGB 中的 B 分量值,確定我們要選用 LUT 圖中的第幾個小格,然后再根據(jù)(R,G)分量值為縱橫坐標(biāo),確定映射的 RGB 組合。

          OpenGLES 實(shí)現(xiàn) LUT 濾鏡的 GLSL 腳本。

          // Lut 濾鏡
          #version 100
          precision highp float;
          varying vec2 v_texcoord;

          //Lut 紋理
          uniform sampler2D s_LutTexture;
          uniform lowp sampler2D s_textureY;
          uniform lowp sampler2D s_textureU;
          uniform lowp sampler2D s_textureV;

          vec4 YuvToRgb(vec2 uv) {
              float y, u, v, r, g, b;
              y = texture2D(s_textureY, uv).r;
              u = texture2D(s_textureU, uv).r;
              v = texture2D(s_textureV, uv).r;
              u = u - 0.5;
              v = v - 0.5;
              r = y + 1.403 * v;
              g = y - 0.344 * u - 0.714 * v;
              b = y + 1.770 * u;
              return vec4(r, g, b, 1.0);
          }

          void main()
          {
              //原始采樣像素的 RGBA 值
              vec4 textureColor = YuvToRgb(v_texcoord);

              //獲取 B 分量值,確定 LUT 小方格的 index, 取值范圍轉(zhuǎn)為 0~63
              float blueColor = textureColor.b * 63.0;

              //取與 B 分量值最接近的 2 個小方格的坐標(biāo)
              vec2 quad1;
              quad1.y = floor(floor(blueColor) / 8.0);
              quad1.x = floor(blueColor) - (quad1.y * 8.0);

              vec2 quad2;
              quad2.y = floor(ceil(blueColor) / 7.9999);
              quad2.x = ceil(blueColor) - (quad2.y * 8.0);

              //通過 R 和 G 分量的值確定小方格內(nèi)目標(biāo)映射的 RGB 組合的坐標(biāo),然后歸一化,轉(zhuǎn)化為紋理坐標(biāo)。
              vec2 texPos1;
              texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
              texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);

              vec2 texPos2;
              texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
              texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);

              //取目標(biāo)映射對應(yīng)的像素值
              vec4 newColor1 = texture2D(s_LutTexture, texPos1);
              vec4 newColor2 = texture2D(s_LutTexture, texPos2);

              //使用 Mix 方法對 2 個邊界像素值進(jìn)行混合
              vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
              gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), 1.0);
          }

          LUT 濾鏡對比圖

          LUT 濾鏡對比圖



          -- END --


          技術(shù)交流掃碼添加我的微信:Byte-Flo



          免費(fèi)獲取視頻教程和源碼



          推薦:

          FFmpeg + OpenGLES 實(shí)現(xiàn)視頻解碼播放和視頻濾鏡

          一文掌握 YUV 圖像的基本處理

          Android OpenGL ES 從入門到精通系統(tǒng)性學(xué)習(xí)教程

          FFmpeg + OpenGLES 實(shí)現(xiàn)音頻可視化播放

          Hi 小姐姐,這是你要的瘦身大長腿效果?

          OpenGL ES 實(shí)現(xiàn)動態(tài)(水波紋)漣漪效果


          覺得不錯,點(diǎn)個在看唄~

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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  韩国大鸡巴| 欧美亚洲一区 | jjzz欧美 | 伊人午夜视频 | 波多野结衣中文视频 |