3D LUT 滤镜 shader 源码分析

这篇具有很好参考价值的文章主要介绍了3D LUT 滤镜 shader 源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在做滤镜相关的渲染学习,目前大部分 LUT 滤镜代码实现都是参考由 GPUImage 提供的 LookupFilter 的逻辑,整个代码实现不多。参考网上的博文也有各种解释,参考了大量博文之后终于理解了,所以自己重新整理了一份,方便以后阅读理解,对整体代码的实现过程结合LUT的原理进行一个简单整理。

GPUImageLookupFilter shader 源码

 varying highp vec2 textureCoordinate;      
 varying highp vec2 textureCoordinate2;
 
 uniform sampler2D inputImageTexture;  // 目标纹理,对应原始资源
 uniform sampler2D inputImageTexture2; // 查找表纹理,对应LUT图片
 
 uniform lowp float intensity;
 
 void main()
 {
     //获取原始图层颜色
     highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     
     //获取蓝色通道颜色,textureColor.b 的范围为(0,1),blueColor 范围为(0,63) 
     highp float blueColor = textureColor.b * 63.0;
     
     //quad1为查找颜色所在左边位置的小正方形
     highp vec2 quad1;
     quad1.y = floor(floor(blueColor) / 8.0);
     quad1.x = floor(blueColor) - (quad1.y * 8.0);
     
     //quad2为查找颜色所在右边位置的小正方形
     highp vec2 quad2;
     quad2.y = floor(ceil(blueColor) / 8.0);
     quad2.x = ceil(blueColor) - (quad2.y * 8.0);
     
     //获取到左边小方形里面的颜色值
     highp 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);
     
    //获取到右边小方形里面的颜色值
     highp 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);
     
     //获取对应位置纹理的颜色 RGBA 值
     lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);
     lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);
     
     //真正的颜色是 newColor1 和 newColor2 的混合
     lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));

     gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);
 }

整个源码的主要逻辑为:查找颜色所在位置的小正方形、查找小正方形内的具体颜色、颜色混合。上面注释已将具体的实现过程描述清楚,但与我们的 LUT 图片割裂,接下来结合 LUT 的实现原理以及具体的数据来形象地描述整个实现流程。

假设我们输入的参数为:
textureColor = ver4(.0, .0, 0.5, 1.0)

查找颜色所在位置的小正方形

我们知道LUT有64个小正方形,目标是为了找到对应小正方形里面的对应的颜色,我们需要先确认是第几个小正方形,正是通过 textureColor.b * 63 查找

带入blueColor -> textureColor.b = 0.5
textureColor.b * 63.0 = 31.5

也就是说我们需要第 [31.5] 位置小正方形,但是索引(从0-63共64个)都是正数,对于 31.5 索引 我们该怎么确定是 31 还是第 32 个呢?GPUImage给出的一种插值方式就是两个都要,然后进行一次混合,从而使得值能够俊均匀的在两个小正方形色块中。

具体逻辑为:

quad1.y = floor(floor(blueColor) / 8.0) = 3,确定为小方块在纵坐标索引3,也就是第4行。

3D LUT 滤镜 shader 源码分析,lut滤镜

quad1.x = floor(blueColor) - (quad1.y * 8.0) = 31 - 24 = 7

也就确定了小方块为(3,7) 也就是第4排第8个。

3D LUT 滤镜 shader 源码分析,lut滤镜

同理,对于第2个小方块确定的位置为(4,0) 也就是第5排第1个。

quad2.y = floor(ceil(blueColor) / 8.0) = 4

quad2.x = ceil(blueColor) - (quad2.y * 8.0)= 0

查找小正方形内的具体颜色

已经获取到对应的方块了,接下来需要确定方块内的像素的位置了。一般一个LUT的大小为 512x512,由8x8小方块构成,也就是每个方块的的像素为64x64,如下图所示:

3D LUT 滤镜 shader 源码分析,lut滤镜

计算x坐标的逻辑为:

texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r)

这一段是相对比较难理解的,我们可以分几部分进行理解:

第一部分:(quad1.x * 0.125)

我们得到 quad1.x = 7,也就是第8列,*0.125将坐标转化在(0,1)之间,也就是得到在01坐标系内如图红线的位置。

3D LUT 滤镜 shader 源码分析,lut滤镜

第二部分:((0.125 - 1.0/512.0) * textureColor.r)

我们可以把它当成 (63.0/512.0)* textureColor.r , 63.0/512.0代表着一个512x512中每个小方块的64份数据(为什么是63?别忘了0的存在),textureColor.r 数据在 0-1之间,这样就能确认在第一部分结果基础之上的偏移值。

3D LUT 滤镜 shader 源码分析,lut滤镜

第三部分:0.5/512.0

这一部分主要是 +0.5 做四舍五入运算,为保证第512行取到的是511.5/512,第1行取到的是 0.5/512.0。

同理,计算y的坐标,以及计算另一个小正方形内的位置是一样的。

最后在通过对从两个小正方形获取到的颜色进行 mix,并返回给着色器,GPU再对原始图像进行每一个像素点绘制,从而实现滤镜的效果。

总结

LUT 对应的 Shader 执行过程主要为:查找颜色所在位置的小正方形、查找小正方形内的具体颜色、颜色混合,整个流程都比较好理解,但代码相对而言比较难理解,网上看了很多其他的大佬写的一些文章,最开始自己看的时候也是很难理解的,后面终于悟了,所以想通过自己的理解,尽力更形象地解释(虽然可能也没有很形象),如果还有什么疑问,欢迎一起交流学习。文章来源地址https://www.toymoban.com/news/detail-741739.html

到了这里,关于3D LUT 滤镜 shader 源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • verilog 学习笔记(3)输入查找表(LUT)

    今天做了一个关于输入查找表(LUT)的题目,里面关于8-1 MUX的处理方式让我觉得非常的新奇。 题目很简单,大意就是要求设计一个8位的移位寄存器,同时附加随机访问功能。也就是通过输入的ABC三个数字对应的二进制数转换为一个地址(很像存储中的方式),然后访问移位

    2024年02月13日
    浏览(28)
  • LUT 查找表(Look-Up-Table)

            LUT就是查找表,对于4输入的LUT而言,实际上就是4位地址位,一位数据位的存储器,能够存储16位数据,所以我们在FPGA设计中可以用LUT组建分布式的RAM。         如果用传统的逻辑来实现一个4输入的逻辑电路,需要大致三个步骤:1、看真值表找出输入与输出之间

    2024年02月16日
    浏览(26)
  • 【C++ OpenCV】LUT查找表原理、实操、使用时机

    存在的意义: 在OpenCV中,LUT代表查找表(Lookup Table),它是一种用于像素值映射的技术。查找表是一个数组,其中每个元素对应于输入像素值的一个映射值。使用LUT可以有效地对图像进行像素值的转换,常用于颜色空间转换或者对特定像素值进行操作。 LUT通常在需要将图像

    2024年02月06日
    浏览(40)
  • FPGA的可编程逻辑单元(LUT和寄存器)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 1.根据PLD器件单片集成度的高低,可将PLD分为低密度可编程逻辑器件和高密度可编程逻辑器件。 2.按器件结构类型划分      

    2024年02月19日
    浏览(38)
  • FPGA原理介绍 (CLB, LUT, 进位链, 存储元素, RAM)

    本文首先对 ASIC 和 FPGA 进行了一个对比,然后介绍了 FPGA 的基本结构,最后解释了 FPGA 实现可编程的基本原理。 这里先给出 ASIC 和 FPGA 的优缺点 ASIC FPGA 优点 性能优越 可靠性高 大批量下单位成本低 开发初期无投入资金壁垒 设计工具使用方便,设计简单快速 产品原型机开发

    2024年02月20日
    浏览(31)
  • 【opencv】颜色映射表操作-applyColorMap()和LUT()函数使用介绍

    来自:ColorMaps in OpenCV。 人眼对颜色的变化更敏感,所以当一张灰度图的细微变化不是很明显时,可以对灰度图重新着色。 opencv提供函数 applyColorMap() 实现这种功能。其内部算法基本是查表法LUT实现,首先构建查找表,然后应用查找表。应用表的过程类似: d s t ( i , j ) = L U

    2024年02月11日
    浏览(30)
  • FPGA结构:LUT(查找表)和 MUX(多路选择器)介绍

    如果你想学习有关FPGA的专业术语,可以参考这一篇:FPGA专业术语介绍 一句话概括,通过将函数的真值表存放在少量内存单元中来实现组合逻辑电路功能的模块称为LUT。 这里以简单的一个3-LUT(3输入查找表)为例,以下给出其示意图的简化描述: 输入1 ----┐ 输入2 ----┼---

    2024年02月04日
    浏览(36)
  • FPGA原理与结构(2)——查找表LUT(Look_Up_Table)

    系列文章目录:FPGA原理与结构(0)——目录与传送门 目录 一、查找表(LUT)概述 二、LUT的性能权衡 1、面积效率 2、速度问题 3、权衡结果  三、LUT的组成与应用 1、LUT的组成         2、LUT的应用 3、LUT应用拓展  本文参考xilinx官方手册ug474:ug474         LUT是CLB的重要组成

    2024年02月08日
    浏览(24)
  • Vivado报错:[Opt 31-67] Problem: A LUT6 cell in the design is missing a connection on input pin I5

    具体报错内容如下: [Opt 31-67] Problem: A LUT6 cell in the design is missing a connection on input pin I5, which is used by the LUT equation. This pin has either been left unconnected in the design or the connection was removed due to the trimming of unused logic. The LUT cell name is: design_1_i/pingpang_write_buff_0/inst/FSM_sequential_ram_wr_stat

    2023年04月24日
    浏览(30)
  • 【游戏开发小技】Unity通过UI全屏图来模糊场景画面(Shader | 模糊 | 滤镜 | Blur)

    一、前言 嗨,大家好,我是新发。 以前我写文章都是很长很长,接下来我会尝试用新的方式来写博客,尽量简短,以实用为主。同时也是作为自己零碎的一些记录,方便查阅。 本文我要说的是在 Unity 中通过 UI 全屏图来模糊场景画面的效果。 二、效果演示 这是没用模糊效果

    2024年02月05日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包