GLSL实现Glow效果 【转】
http://blog.csdn.net/a3070173/article/details/3220940
- Glow即辉光效果现在已成为3D图形中一个引人注目的特效.本文主要介绍如何使用GLSL实现一个典型的GLow效果.
- 实现步骤:1.渲染整个场景到一个祯缓冲区中
- 2.将场景中需要进行GLow处理的物体绘制第二个FBO纹理A中
- 3.在FBO纹理A和B之间进行横和纵"高斯"过滤
- 4.将进行过GLow处理后的FBO纹理A与祯缓冲区中的场景图像以glBlendFunc(GL_ONE, GL_ONE)方式进行混合处理
- GLSL文件功能简介:
- FullScreen.vert - 用于绘制覆盖整个视口的四边形以进行Glow效果的高斯过滤
- Filter.frag - 用于横和纵的高斯过滤
- Blend.frag - 用于处理过的GLowFBO纹理与原始场景图像进行混合
- 为了直接进行生成Glow效果的介绍,这里假设程序已正确处理了OpenGL和GLSL的初始化.
- void RenderOrigionalScene()
- {
- if (g_bUseFillRender)
- {
- glPolygonMode(GL_FRONT, GL_FILL);
- }
- else
- {
- glPolygonMode(GL_FRONT, GL_LINE);
- }
- RenderObject();
- }
- 首先让我们绘制原始场景,由于本Demo未绘制除辉光物体外的其它事物,所以此处就直接绘制为进行具有辉光效果的物体.
- void RenderGlowObject()
- {
- // 设置视口
- glViewport(0, 0, g_uiTextureWidth, g_uiTextureHeight);
- // 将原始场景绘制到第二个FBO
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_uiFboColorOne);
- // 清除第一个FBO颜色和深度缓存
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // 绘制辉光物体
- RenderObject();
- }
- 然后设置绘制目标到FBO纹理A并将欲进行Glow处理的物体绘制到上面来,这里需要注意的是必须根据FBO纹理的尺寸设置一个
- 视口使其跟FBO纹理一样大,以使物体能够准确地映射到整个FBO纹理上.清除FBO颜色缓冲区和绘制深度缓冲区是必要的,因为
- 每次绘制到FBO纹理中的图像都不一样.
- void FilterGlowObject()
- {
- glPolygonMode(GL_FRONT, GL_FILL);
- // 将水平过滤后的图像绘制第二个FBO
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_uiFboColorTwo);
- // 清除第二个FBO颜色
- glClear(GL_COLOR_BUFFER_BIT);
- // 重新设置片元着色器
- glUseProgram(g_ProgramObjectOne);
- // 设置水平过滤标志
- GLint iUniformIndex = glGetUniformLocation(g_ProgramObjectOne, "g_bFiterMode");
- glUniform1i(iUniformIndex, 1);
- // 设置纹理
- glBindTexture(GL_TEXTURE_2D, g_uiIDOne);
- // 绘制
- RenderFullScreen();
- // 将竖直过滤后的图像绘制第一个FBO
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_uiFboColorOne);
- // 清除第一个FBO颜色和深度缓存
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // 设置竖直过滤标志
- iUniformIndex = glGetUniformLocation(g_ProgramObjectOne, "g_bFiterMode");
- glUniform1i(iUniformIndex, 0);
- // 设置纹理
- glBindTexture(GL_TEXTURE_2D, g_uiIDTwo);
- // 绘制
- RenderFullScreen();
- }
- 下面到Glow效果处理的重头戏,是否能生成完美的辉光效果关键就在于此步的处理.但其实也很简单,主要就是为Filter着色器设
- 置进行合适横,纵两次过滤的标志和绘制目标,然后绘制全视口四边形,剩下的过滤工作则由GLSL的高斯过滤着色器全权负责.
- void RenderToScreen()
- {
- // 恢复视口
- glViewport(0, 0, g_uiCurrentWindowWidth, g_uiCurrentWindowHeight);
- // 恢复绘制目标为祯缓冲区
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, NULL);
- // 启动混合
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE);
- // 绑定纹理
- glBindTexture(GL_TEXTURE_2D, g_uiIDOne);
- // 重新设置片元着色器
- glUseProgram(g_ProgramObjectTwo);
- // 绘制
- RenderFullScreen();
- // 恢复固定功能管线
- glUseProgram(0);
- // 关闭混合
- glDisable(GL_BLEND);
- }
- 最后一步无非就是将过滤好的Glow纹理与原始场景图像进行混合,当然使用OpenGL固定功能管线或GLSL都可以轻易实现,但首先必
- 须把视口设置回原来的状态.
- 以下是高斯过滤的GLSL着色器代码,粘贴于此以方便读者查阅.
- 顶点着色器:
- void main()
- {
- gl_TexCoord[0] = gl_MultiTexCoord0;
- gl_Position = gl_Vertex;
- }
- 高斯过滤着色器:
- const int g_iFilterTime = 9; // 过滤次数
- const float g_fGene = (1.0/(1.0 + 2.0*(0.93 + 0.8 + 0.7 + 0.6 + 0.5 + 0.4 + 0.3 + 0.2 + 0.1))); // 衰减因子
- uniform sampler2D g_Decal;
- uniform bool g_bFiterMode;
- uniform float g_fGlowGene;
- uniform vec2 g_vec2HorizontalDir; // 水平过滤方向
- uniform vec2 g_vec2VerticalDir; // 竖直过滤方向
- uniform float g_fFilterOffset; // 过滤偏移
- void main()
- {
- float aryAttenuation[g_iFilterTime];
- aryAttenuation[0] = 0.93;
- aryAttenuation[1] = 0.8;
- aryAttenuation[2] = 0.7;
- aryAttenuation[3] = 0.6;
- aryAttenuation[4] = 0.5;
- aryAttenuation[5] = 0.4;
- aryAttenuation[6] = 0.3;
- aryAttenuation[7] = 0.2;
- aryAttenuation[8] = 0.1;
- // 采样原始颜色
- vec2 vec2Tex0 = gl_TexCoord[0].st;
- vec4 vec4Color = texture2D(g_Decal, vec2Tex0)*g_fGene;
- // 计算过滤方向
- vec2 vec2FilterDir = g_vec2HorizontalDir + vec2(g_fFilterOffset, 0.0); // 水平过滤
- if (!g_bFiterMode)
- {
- vec2FilterDir = g_vec2VerticalDir + vec2(0.0, g_fFilterOffset); // 竖直过滤
- }
- // 进行过滤
- vec2 vec2Step = vec2FilterDir;
- for(int i = 0; i< g_iFilterTime; ++i)
- {
- vec4Color += texture2D(g_Decal, vec2Tex0 + vec2Step)*aryAttenuation[i]*g_fGene;
- vec4Color += texture2D(g_Decal, vec2Tex0 - vec2Step)*aryAttenuation[i]*g_fGene;
- vec2Step += vec2FilterDir;
- }
- if (g_bFiterMode)
- {
- gl_FragColor = vec4Color*g_fGlowGene;
- }
- else
- {
- gl_FragColor = vec4Color;
- }
- }
- 混合着色器:
- uniform sampler2D g_Decal;
- void main()
- {
- gl_FragColor = texture2D(g_Decal, gl_TexCoord[0].st);
- }
- Demo效果图:
- 参考资料:Nvidia OpenGL SDK 10.5 Simple Glow
- exe文件:http://www.fileupyours.com/view/219112/GLSL/Glow%20Demo.rar
GLSL实现Glow效果 【转】的更多相关文章
- GLSL实现Glow效果 [转]
http://blog.csdn.net/a3070173/archive/2008/11/04/3220940.aspx Glow即辉光效果现在已成为3D图形中一个引人注目的特效.本文主要介绍如何使 ...
- Glow 效果材质
转自:http://blog.csdn.net/panda1234lee/article/details/60960846 算法较简单,首先来看 Base color 部分: 就是将对事先准备好的三张 ...
- GraphicsLab Project之辉光(Glare,Glow)效果 【转】
作者:i_dovelemon 日期:2016 / 07 / 02 来源:CSDN 主题:Render to Texture, Post process, Glare, Glow, Multi-pass ...
- Bump mapping的GLSL实现 [转]
原文 http://www.cnblogs.com/CGDeveloper/archive/2008/07/03/1234206.html 如果物体表面细节很多,我们可以不断的精细化物体的几何数据,但 ...
- Cesium官方教程8-- 几何体和外观效果
原文地址:https://cesiumjs.org/tutorials/Geometry-and-Appearances/ 几何体和外观效果(Geometry and Appearances) 这篇教 ...
- Unity3D使用过程中常见的20个问题
1:天空盒有接缝怎么解决?答:在贴图导入设置里设置Wrap Mode为"Clamp". 2:DDS格式怎么不显示?答:Unity不支持DDS格式,Unity会将除DDS外的其他格式 ...
- Flex里的特效
Flex中提供了丰富的效果组件.因为效果是一种依据时间渐变的过程,因此全部效果都具有duration属性,用来设置播放时间(以毫秒为单位).也能够通过设置repeatCount属性和repeatD ...
- div使用
div style常用属性 一.常用属性: 1.Height:设置DIV的高度. 2.Width:设置DIV的宽度. 例: <div style="width:200px;height ...
- Unity Shader-后处理:Bloom全屏泛光
一.简介 今天来学习一下全屏Bloom效果,有时候也叫Glow效果,中文一般叫做“全屏泛光”,这是一种可以模拟出HDR的全屏后处理效果,但是实现原理与HDR相差很远,效果比HDR差一些,但是比HD ...
随机推荐
- ubuntu系统更换源
一:问题概述 ubuntu,我们在使用apt新装软件的时候,会使用官方的网站去下载软件,但是会因为国内的转接点太多,而导致下载的速度非常慢 ,我们可以通过换成一些中间的节点来进行下载,比如阿里源,中科 ...
- [洛谷P4925][1007]Scarlet的字符串不可能这么可爱
题目大意:问字符集大小为$k$,长度为$L$的字符串,且没有长度超过$1$的回文段的个数.规定第$s(若为0则无限制)$位为$w$. 题解:懒得写了,根据是否有限制分类讨论 卡点:中途有个地方忘记取模 ...
- [洛谷P3805]【模板】manacher算法
题目大意:给你一个字符串,求出它的最长回文字段 题解:$manacher$算法 卡点:$p$数组未开两倍空间 C++ Code: #include <cstdio> #include &l ...
- nginx+php-fpm配置后页面显示空白的解决方法以及用nginx和php-fpm解决“502 Bad Gateway”问题
For reference, I am attaching my location block for catching files with the .php extension: location ...
- linux——rhel安装yum
在进行下面的操作之前,一定要确保网络正常,如果没有网络,下面的所有操作一个都不能实现.(下次会写个本地源的配置,这个就可以离线的状态下进行,需要用到系统的镜像文件,安装好系统之后不要删掉.) 首先配置 ...
- HDU1520 树形DP入门
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- PAT L1 049 天梯赛座位分配
天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,每队 10 位 ...
- webpack最佳入门实践系列(5)
9.路径相关 原来我们打包的东西都存放到了dist目录下,并没有进行分类存储,乱成一团,这一节我们就要处理一下打包的路径,让打包后的目录看起来更加优雅 9.1.代码准备 我们先建立起这样一个目录结构 ...
- C#的泛型委托Predicate/Func/Action
Predicate<T> 是一个委托,它代表了一个方法,它的定义是: namespace System { // 摘要: 表示定义一组条件并确定指定对象是否符合这些条件的方法. ...
- MFC 将 '当前工作路径' 改为 'exe所在路径'(转)
原文转自 https://blog.csdn.net/morewindows/article/details/8683519 调整进程当前目录为程序可执行文件所在目录是个非常实用的方法.为了更加的让代 ...