OpenGL 链式滤镜(帧缓冲离屏渲染)
2021/11/8 8:09:54
本文主要是介绍OpenGL 链式滤镜(帧缓冲离屏渲染),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
OpenGL 编写特效在部分应用中可通过单个shader实现,即通过修过修改顶点着色器或片元着色器实现。但更多的场景是要求有多个特效组合而成,例如最终效果是图片灰度加上下颠倒,效果不复杂条件下可以通过修改片元着色器实现,当效果复杂特效、组合特效、特效的模块化开发都会通过链式滤镜实现。
一、链式滤镜概念
链式滤镜 通过帧缓冲离屏渲染技术实现特效的组合和叠加。通过多次draw最终实现预期效果。
二、渲染流程中的帧缓冲
OpenGL的工作流程,输入像素数据和顶点数据,两种数据分别操作后,通过光栅化,得到片段,再经过片段处理,最后绘制到帧缓冲区,最终转化为像素数据。OpenGL 管线渲染的最终目的地就是FrameBuffer(帧缓冲)。下面是OpenGL渲染流程图。
三、帧缓冲对象
在OpenGL渲染管线中,几何数据和纹理经过多次转化和多次测试,最后以二维像素的形式显示在屏幕上。OpenGL管线的最终渲染目的地被称作帧缓存(framebuffer)。帧缓冲是一些二维数组和OpenG所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。一般情况下,帧缓存完全由window系统生成和管理,由OpenGL使用。这个默认的帧缓存被称作“window系统生成”(window-system-provided)的帧缓存。OpenGL允许我们定义我们自己的帧缓冲,也就是说我们能够定义我们自己的颜色缓冲,甚至是深度缓冲和模板缓冲。在一个帧缓存对象中有多个颜色关联点、一个深度关联点,和一个模板关联。每个帧缓存中至少有一个颜色关联点,其数目与实体显卡相关。可以通过GL_MAX_COLOR_ATTACHMENTS_EXT来查询颜色关联点的最大数目。
需要注意:FBO中并没有存储图像,只有多个关联点。
四、自定义帧缓冲
1:创建一个帧缓冲.
unsigned int fbo; glGenFramebuffers(1, &fbo);
2:绑定帧缓冲,帧缓冲会在被绑定时隐士开启glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3:渲染到纹理
glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
五、渲染链条
多个特效组合结构如下,绑定frame buffer 0 作用是再次激活默认帧缓冲,在主窗口中有视觉效果。
1:灰度 fragment shaderGray
precision highp float; uniform sampler2D Texture; varying vec2 TextureCoordsVarying; const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); void main (void) { vec4 mask = texture2D(Texture, TextureCoordsVarying); floatluminance = dot(mask.rgb, W); gl_FragColor = vec4(vec3(luminance), 1.0); }
1:上下颠倒 fragment shaderReverse
precision highp float; uniform sampler2D Texture; varying vec2 TextureCoordsVarying; void main (void) { vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y)); gl_FragColor = color; }
伪代码如下:
// Step one unsigned int fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); unsigned int texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); DrawShaderGray(); //绘制结果在texture //setp two DrawWithGrayInShaderReverse(texture)
这篇关于OpenGL 链式滤镜(帧缓冲离屏渲染)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-04百万架构师第六课:设计模式:策略模式及模板模式
- 2025-01-04百万架构师第七课:设计模式:装饰器模式及观察者模式
- 2025-01-04适用于企业管理的协作工具API推荐
- 2025-01-04挑战16:被限流的CPU
- 2025-01-03企业在选择工具时,如何评估其背后的技术团队
- 2025-01-03Angular中打造动态多彩标签组件的方法
- 2025-01-03Flask过时了吗?FastAPI才是未来?
- 2025-01-0311个每位开发者都应知道的免费实用网站
- 2025-01-03从REST到GraphQL:为什么以及我是如何完成转型的
- 2025-01-03掌握RAG:从单次问答到连续对话